← All config-management frames
Flow 3 · Secrets & audit · Frame (h) · /config (secret keys)

Secret values — write-only by default

A secret input is not a text input with a password mask. The value is never returned by the ordinary read — value is always null and isSet reports only whether one exists. Every state below follows from that one fact, and a build that treats a secret as "a string you re-render into the field" has already leaked it.

A · isSet: false — no value stored

Empty, and it says so in words. An empty mask (••••) here would claim a credential exists — the user would never think to set one, and delivery would fail with no visible cause.

Provider API keynotifications.provider.apiKey
secretsecret
No value set
Never set at any scope
B · isSet: true — masked, and unreadable by design

There is no "show" toggle on this field, because the browser never received the value to show. Replace and Clear are the only writes. The mask is fixed-width and carries no length information.

Provider API keynotifications.provider.apiKey
secretsecret
••••••••••••••••
Set here · portal Acme Portal · last changed 2026-07-14 by j.okafor

Excluded from export. Recorded in the audit trail as a redaction, never as plaintext.

C · Replacing — write-only field

The field starts empty rather than pre-filled, because there is nothing to pre-fill it with. Cancelling restores the mask and changes nothing; leaving it blank is not the same as Clear, and the Save control stays disabled until a value is typed.

Provider API keynotifications.provider.apiKey
secretsecret

Replacing overwrites the stored credential immediately on save. The previous value is not recoverable from the audit trail — history records that it changed, not what it was.

D · Reveal — separately authorized, individually audited, shown once

Reveal is its own operation, not a field on the bulk read. The dialog states the consequence before the value appears, and the value is shown exactly once — dismissing it means re-authorizing a new, separately-audited reveal. There is no re-open.

Shown once — copy it now

EXAMPLE-PLACEHOLDER-NOT-A-REAL-CREDENTIAL

Once dismissed this value cannot be displayed again. Revealing it a second time is a new authorization and a new audit entry.

E · SECRET_UNAVAILABLE — set, but not retrievable

A stored secret that cannot currently be decrypted (key material unavailable). This is not "no value set" — telling the user it is unset would invite them to overwrite a working credential that is merely temporarily unreadable. Replace stays available; reveal does not.

Provider API keynotifications.provider.apiKey
secretsecret
••••••••••••••••
F · May set, may not reveal

Write and read are separate grants. An operator who can rotate a credential does not automatically get to read it, so Replace is enabled while Reveal is refused — and the refusal is shown in place, not as a dead button that 403s.

Provider API keynotifications.provider.apiKey
••••••••••••••••

Contract. EffectiveConfigEntry.value is always null for an isSecret key; isSet carries existence. Writes go through the same PUT /v1/config set / unset operations. SECRET_UNAVAILABLE and FORBIDDEN are from ErrorCode.
Anticipated (FF-EPIC-18-S1). The reveal operation in block D is a separate, individually authorized and individually audited endpoint that does not exist in the frozen contract today — these frames commission it. It must never become a field on the bulk read.

← Catalog states Next: audit history & revert →
Review · config-management approve or reject each flow ↓
settings-editorapproved · izzywdev
key-catalogapproved · izzywdev
secret-auditapproved · izzywdev