Secret rotation reminder (a key that has gone too long unchanged)
A stolen key keeps working until someone changes it. Omniscio keeps a small record of when each developer secret on this computer was last rotated, checks once a week whether any has gone past its interval, and puts one card in the inbox naming what is overdue and how to change it. Changing a key is still entirely a human job at the provider's own console — Omniscio only remembers and reminds.
What it is
Every developer secret this repository materializes — the default credentials bundle, the FlowVoice token, the build-time environment file, the GCP test-runner key, your cloud test key, and your push credential for the shared test-fleet git host — carries an entry in a committed record that ships with the code. Each entry says when that secret was last changed, how many days may pass before it should change again (90 unless an entry says otherwise), and one line about where to go to change it.
The record holds no secret: a label, a date, an interval and a pointer, and nothing you could use to authenticate anywhere. A secret whose rotation nobody has ever recorded is stored as never recorded rather than given a guessed date.
Some values in that record are not credentials at all — the fleet git host's address, and its public SSH host keys. Those are marked as not a rotation target and are never called overdue, because "rotate" has no meaning for them and a reminder that asks you to record a change you cannot make teaches you to record things that did not happen.
Where to find it
- The card arrives in the inbox, one card for everything overdue at once.
- The on/off switch is in Settings → Diagnostics, under Remind me when a key is overdue for a change.
- There is no separate screen: the record is a file in the repository, and the card and the switch are the whole surface.
How it behaves
When it checks. Once a week, and once shortly after Omniscio starts. A machine that was switched off for a while simply checks at its next start.
What it checks. Only the secrets this computer actually holds. The check looks for the local credential file each entry names, so a copy of the app installed on a customer's computer — which carries none of these — never shows the card, and a developer who never seeded their vault is not nagged about a key they do not have. Secrets belonging to shared fleet infrastructure are marked operator-only and are reported only on the operator computer that owns them.
What the card says. One card, listing each secret by name and plain-English label, how stale it is — "38 days past the last recorded change (every 90 days)", or "never recorded as changed" — and its one-line pointer for how to change it. Because it is a single deduped card it never piles up, and it retires itself on the next weekly run once the record shows a fresh date for everything it named.
Recording a change. Rotate the key where it lives — the provider's console, or the repo's own command where there is one — then record the date:
npm run secrets:rotated -- <secret-name>
That writes today's date for that one secret and tells you how many secrets still have no recorded rotation. Commit the record with the rest of your work, so the history travels with the code and every computer sees the same dates. Run the command with no name to see the valid names.
What it never does. It does not read the vault, touch a credential file, or rotate anything. A rotation is an owner decision at a provider, and this feature only remembers that one happened.
An honest limit. This is a reminder, not a control. It cannot stop a stolen key from working, and anyone who can edit the repository can edit the dates — just as they could delete the file. What it buys is that a key going stale becomes visible in the inbox instead of waiting on someone's memory, and that "when did we last change this" has a written answer.
Switching it off. The switch in Settings → Diagnostics stops the check and retires the card. It is deliberately person-only: a paired phone, or an agent driving Omniscio's command line, cannot turn it off, because silencing a security reminder is one of the ways a break-in tries to stay quiet.
For agents
- The record:
scripts/lib/secret-rotation-ledger.json. It is the only writer's target and holdslabel,lastRotatedAt(YYYY-MM-DDornull),rotationIntervalDays(positive integer, ornullfor a value that is not a rotation target),operatorOnly,howToRotate, andtargets(the repo-relative files the secret materializes to). - It must stay in step with
scripts/lib/secret-manifest.mjs: one entry per manifest secret, same targets.tests/unit/services/security/secret-rotation-ledger.test.tsfails on any drift in either direction, on a malformed or future date, and on an entry shape the card cannot render. - The check, the card copy, the presence gate, the operator gate and the weekly timer live in
src/main/services/security/secret-rotation-ledger.ts; it is armed bysrc/main/startup/tasks/2979-secret-rotation-ledger.ts. - The card's alert definition is
src/shared/alert-definitions/security/secret-rotation-overdue.alert.ts(dedup keysecret-rotation-overdue, categorysecurity,developerOnly, and adev-only-commandexemption because its remedy is a provider console plus a terminal command). - The stamp command is
scripts/secrets-rotated.mjs(npm run secrets:rotated -- <name>, with--ledger <path>for tests). Its only write is one date field; it never reads a credential. - Settings key
secretRotationCheckEnabled, defaulttrue, declared insrc/shared/types/settings/system/security-integrity-settings.ts, surfaced bysrc/renderer/src/features/settings/sections/diagnostics/DiagnosticsSettings-definitions.ts, and listed inREMOTE_FORBIDDEN_SETTING_KEYSso no remote or agent caller can flip it. - Invariants and the tests that lock them:
.claude/memory/contracts/secret-rotation-ledger-contract.md.
Related
- Security file integrity check — the other half of "what changed on this computer": a signed record of the files an attacker would edit first.
- Secret Paste Guard — how a key you paste into a session never reaches the model.
- Security alerts by email — why a copy of every security alert also leaves this computer.
Last verified 2026-10-25