Add mciasdb rekey command
- internal/db/accounts.go: add ListAccountsWithTOTP, ListAllPGCredentials, TOTPRekeyRow, PGRekeyRow, and Rekey — atomic transaction that replaces master_key_salt, signing_key_enc/nonce, all TOTP enc/nonce, and all pg_password enc/nonce in one SQLite BEGIN/COMMIT - cmd/mciasdb/rekey.go: runRekey — decrypts all secrets under old master key, prompts for new passphrase (with confirmation), derives new key from fresh Argon2id salt, re-encrypts everything, and commits atomically - cmd/mciasdb/main.go: wire "rekey" command + update usage - Tests: DB-layer tests for ListAccountsWithTOTP, ListAllPGCredentials, Rekey (happy path, empty DB, salt replacement); command-level TestRekeyCommandRoundTrip verifies full round-trip and adversarially confirms old key no longer decrypts after rekey Security: fresh random salt is always generated so a reused passphrase still produces an independent key; old and new master keys are zeroed via defer; no passphrase or key material appears in logs or audit events; the entire re-encryption is done in-memory before the single atomic DB write so the database is never in a mixed state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
//
|
||||
// pgcreds get --id UUID
|
||||
// pgcreds set --id UUID --host H --port P --db D --user U
|
||||
//
|
||||
// rekey
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -107,6 +109,8 @@ func main() {
|
||||
tool.runAudit(subArgs)
|
||||
case "pgcreds":
|
||||
tool.runPGCreds(subArgs)
|
||||
case "rekey":
|
||||
tool.runRekey(subArgs)
|
||||
default:
|
||||
fatalf("unknown command %q; run with no args for usage", command)
|
||||
}
|
||||
@@ -259,6 +263,9 @@ Commands:
|
||||
pgcreds set --id UUID --host H [--port P] --db D --user U
|
||||
(password is prompted interactively)
|
||||
|
||||
rekey Re-encrypt all secrets under a new master passphrase
|
||||
(prompts interactively; requires server to be stopped)
|
||||
|
||||
NOTE: mciasdb bypasses the mciassrv API and operates directly on the SQLite
|
||||
file. Use it only when the server is unavailable or for break-glass recovery.
|
||||
All write operations are recorded in the audit log.
|
||||
|
||||
Reference in New Issue
Block a user