2d0bbb0c372748d32dafeb0db47b07799fbc6d25
Root is machine authority, not a human identity, so `felis breakGlass` now also records WHICH SysAdmin broke the glass. Even under `sudo felis breakGlass` an account and password are entered in the TUI; the root gate is necessary but no longer sufficient for accountability. The console resolves one of three modes up front and audits the difference: - bootstrap (no staff account exists yet): the typed credential mints the first Owner; the act is attributed to the OS user ($SUDO_USER, else root) and recorded verified:false. - recovery (an admin already exists): the operator authenticates as an existing admin via bcrypt; the verified identity is the accountable actor and the row is recorded verified:true. - root override (the typed credential did not verify): a deliberate OVERRIDE token proceeds under local-root authority, attributed to the OS user and recorded verified:false. Break-glass never refuses - recovering when no admin password can be produced is its whole job. Attribution is best-effort, not proof (whoever runs this is root and can edit Postgres directly); the audit row is honest about which it is. - internal/api: AuditEntry gains an optional jsonb Payload (nil maps to SQL NULL, so existing callers are unaffected); PGRepo.Audit writes it and a new PGRepo.AdminExists drives the bootstrap-vs-recovery switch. - the accountability row is written the instant the credential changes, before local auth is enabled, so a failed toggle write can never leave a reset credential with no "who did it" record. - local_auth_enabled is now one exported api.LocalAuthEnabledKey shared by the break-glass writer and the per-request reader, replacing two drifting copies of the literal. - break-glass password entry reuses the panel's 8-72-byte rule so a credential set here is never later rejected by web change-password. Covered by Go unit tests over a fake owner store: auth match/non-match, the three audit modes and their payloads, that a dead audit sink does not fail the recovery, that the audit precedes the toggle write, and a headless drive of the TUI state machine asserting no credential reaches provisioning without a verified admin or an explicit OVERRIDE.
Languages
Go
62.7%
TypeScript
22.5%
Shell
7.4%
Java
7.1%
Dockerfile
0.2%
Other
0.1%