3.2 KiB
Secrets and recovery material
Storage contract
sops.operationalSecretsPathdefaults to<workspace>/operational-secrets.sops.yaml. It is a SOPS-encrypted input containing operational secrets, keyed by logical OpenBao paths. It is never plaintext Git content.sops.ageKeyPathdefaults to<workspace>/.age/key.txt. This Flux SOPS identity is private local material; do not commit, print, or copy it.sops.recoveryIdentityPathdefaults to<workspace>/.age/recovery-key.txt. This separate OpenBao-recovery identity is private local material; do not commit, print, or copy it.sops.recoveryBundlePathdefaults to<workspace>/.recovery/openbao-recovery.age. This bundle is encrypted tosops.recoveryRecipient; it contains OpenBao recovery material and is never plaintext Git content.- During generated Flux repository reconciliation, recovery material is rendered only into
base/openbao/unseal.sops.yaml, encrypted with the Flux SOPS identity. This is the narrowly scoped encrypted recovery path for theopenbao-unsealcontroller; no plaintext recovery material belongs in a workload, config, log, or command argument.
Bootstrap gates
bootstrap resolves and validates the configuration before reconciliation. Any bootstrap requires a readable SOPS age identity. talos.autoBootstrapFlux: true additionally requires an existing encrypted operational-secrets file and a nonempty recovery recipient. A non-webhook bootstrap additionally requires configured, existing recovery-identity and recovery-bundle files.
The webhook-only path requires a complete delivery contract, an approved configuration, and a readable SOPS age identity. It must reseed OpenBao and observe the refreshed forgejo-webhook target Secret plus the EventListener and Pipeline before Forgejo is changed. The registry-token, delivery-status-token, and webhook-authorization flows also require an explicit configuration; they are live credential operations and are not offline-safe.
Rules
- Credential values are accepted only at an approved secure input boundary and stored only in encrypted operational or recovery material.
- Never pass credential values in CLI arguments, URLs, logs, Git commits, generated config, tickets, or evidence.
- Do not revoke a previous credential until OpenBao, External Secrets, and every listed consumer have passed validation.
- Use the sanitized procedure in runbooks/credential-rotation.md for any live rotation.
- Application, artifact, and shared-secret access is documented in secret-grants.md. Secret values remain outside that declaration.
Automated app-secret identities
Use bootstrap --provision-app-secret-identities --e2e-app <app> to create a
short-lived non-root admin identity and an exact-path E2E probe identity.
Bootstrap reads root recovery material only through its encrypted recovery
bundle, writes the generated tokens only into encrypted operational state, and
never prints either value. app secret --identity admin and
app secret --identity e2e:<app> create a temporary local token file only for
the command lifetime. Root tokens, recovery bundles, and unseal shares are not
valid app-secret identities.