Keys: the logical key layout¶
The records the service keeps in State, by logical key. The in-memory and legacy adapters use the key as written; the AWS adapters use the storage layout, derived in internal/port/layout5.go. State's contract: ports.
No access pattern needs a secondary index. Sessions are listed per person under ses.<person>., and sid.<sid> resolves a session id to its person. Listing every session scans all ses. partitions.
| Key | Content | Writer | TTL |
|---|---|---|---|
req.<id> |
a pending authorization request, also backing a device-code poll | issuer | 30 min |
code.<id> |
an authorization code | issuer | 5 min |
srp.<handle> |
the half of a password sign-in exchange (SRP) that outlives its first request: the account asked for and the server's private value, for one use; never exported by a backup | issuer, console | 2 min |
codesess.<id> |
legacy: the session a redeemed code opened, as an older version wrote it. Never written or read now | issuer | 5 min |
issuer:code-spent:<sha256> |
the tombstone of a redeemed code, keyed by the code's SHA-256: the client, the access token's jti and the session id it issued, for a reuse to revoke. Never the code or a token. It has no dot-spelling form |
issuer | until that access token expires, at least 5 min |
ses.<person>.<sid> |
a per-client session: identity, client, how it began, how the person was proved (method: a provider's kind or recovery), scopes, SSO session, refresh token (hashed), authentication time |
issuer | the session lifetime |
sid.<sid> |
pointer from a session id to <person>; written with the session, deleted with it |
issuer | the session lifetime |
rt.<hash> |
live refresh token to <person>.<sid>. Once spent, the same key holds spent:<unix ms>:<sealed successor>:<session id>: when it was spent, the successor sealed with AES-256-GCM under a key derived from the spent token (SHA-256 of a label, a zero byte and the token), and the session it belonged to. Inside the 30-second grace a replay is answered with the successor; after it, a presentation ends that session (sessions) |
issuer | the session lifetime; once spent, the family's absolute deadline, max(auth_time + absolute limit - now, 30 s) (24 h by default), or the session's end when there is no auth_time or no absolute limit (at most 12 h) |
rtrot.<hash> |
legacy: a spent refresh token's successor, as an older version wrote it. The spent mark is now carried by rt.<hash> itself (see the rt.<hash> row). Still read for one release, never written, then removed |
issuer | 30 s |
sso.<id> |
the browser-wide SSO session and the clients it covers; the record carries cookie_hash |
issuer | the session lifetime |
issuer:sso-cookie:<hash> |
the browser's SSO cookie, hashed, pointing to the sign-in id; the cookie itself is a random secret and is never stored. It has no dot-spelling form because it was introduced after that layout | issuer | the sign-in's |
tok.<jti> |
a minted token's own record, for userinfo and revocation | issuer | until the token expires |
keyring.<kid> |
a signing key's schedule: first seen, activation | issuer replicas | 30 days, renewed on each poll |
ws.dir.google.<id> |
a connected Google Workspace: its record, with its credential in Secrets (credentials/google/workspace/<id>/<ref>) |
console | permanent |
ws.slack.<workspace> |
a connected Slack workspace: its record, with its client secret and bot token in Secrets | console | permanent |
gh.org.<org> |
a connected GitHub organisation: its record, with its App key in Secrets | console | permanent |
gh.link.<account> |
a GitHub account's link, keyed by the account id; the token pair is in Secrets, the rest of the link, RefreshingSince and the Revision counter included, is plain |
link flow, GitHub tick | permanent |
app.gh.link |
the link App: record, with the client secret in Secrets | console | permanent |
app.gh.runner.<tier>.<org> |
a runner App: record, with the key in Secrets | console | permanent |
app.gh.cat.<id> |
a catalogue GitHub App: record, with the key in Secrets | console | permanent |
app.slack.cat.<id> |
a catalogue Slack App: record, with the client secret and bot token in Secrets | console | permanent |
rec.slack.shared.<name> |
a Slack Connect channel's definition | console | permanent |
rec.slack.channel.<workspace>.<name> |
a console channel's record | console | permanent |
rec.console.session-key |
the key the console signs its sessions with, in Secrets (credentials/oidc/console/session-key); created by the first replica that starts |
console | permanent |
rec.recovery.off |
the switch an operator throws to turn the recovery sign-in off: {disabled: [{generation, at, by}]}, a set that only grows. Recovery is off while recovery.generation of the document is in it; a generation never disabled is on. In the oidc module's table, never in a backup, never written by a restore (ADR 0075) |
console | permanent |
rec.maintenance |
the maintenance flag: present while the module's table is being restored; the module refuses writes until it is gone | restore function | permanent |
rec.backup.run.<id> |
one backup run: its state, counts and the object's size; the backup module's table only, never in a backup | backup | permanent |
rec.backup.restore.<id> |
one restore: its state, the backup it restores from, the counts of the last slice and whether the maintenance flag is still set; the backup module's table only, never in a backup | restore | permanent |
rec.backup.retention |
the last retention pass: what it kept and removed | backup | permanent |
lease.<kind>:<target> |
the holder of a target's tick, by id | ticks | seconds, renewed |
gate.<target>.<name> |
a held-once ledger entry, a breaker, a fingerprint. Written today: gate.github.<org>.confirm and .pass, gate.slack.<workspace>.confirm[.<channel>] and .pass (an operator's confirmation of a removal set, 24 h; a request for a pass now, 24 h), gate.github-claim.<account> (the marker of a link claim, below) |
ticks, console | by gate |
share.<host>.<channel> |
a Slack Connect share: the guests that were invited and each side's state; written by the host's tick, its write enqueues the guest's tick, and the guest's tick marks its own side accepted | host tick, guest tick | 14 days while a guest is pending, then 7 days once every guest has accepted |
cache.slack.user.<workspace>.<id> |
who a Slack member is (address, team, bot, guest): users.info once a day, not once a pass. A deactivated account is never cached |
slack tick | 24 h |
cache.<digest>.<name> |
a shared input (a group's holders, an address's state), keyed by the policy digest. Not written yet: the Slack controller's shared inputs stay in memory (why) | ticks | the digest's lifetime |
dedupe.<id> |
an idempotency marker for an external write | ticks | by use |
Only the records marked permanent (ws., gh.org., gh.link., app., rec.) have no TTL. A key absent from the table is not written. Name segments (id, login, channel) encode every byte but letters, digits, - and _ as ~XX, so a dot cannot end a segment.
A credential is never written to State. Domain stores put it in Secrets at its storage layout address and leave a marker in the record.