Files
agentic-coding-workflow/migrations/0021_secret_key_versioning.up.sql
2026-06-22 08:55:57 +08:00

45 lines
2.6 KiB
SQL

-- ============ Secret key versioning (master-key rotation) ============
-- crypto_keys tracks WHICH key versions exist and which one is the current
-- write ("active") key. The key material itself stays in env/KMS — only the
-- version number lives in the DB, both here and in each encrypted row's
-- key_version column. This lets master-key rotation re-encrypt blobs version by
-- version without a magic ciphertext prefix.
CREATE TABLE crypto_keys (
version INT PRIMARY KEY,
provider TEXT NOT NULL DEFAULT 'env',
key_ref TEXT,
status TEXT NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'retiring', 'retired')),
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Seed the historical single key as version 1, active.
INSERT INTO crypto_keys (version, provider, status) VALUES (1, 'env', 'active');
-- Per-row key_version on every encrypted-blob owner. DEFAULT 1 backfills every
-- existing row to the historical key. The re-encrypt job finds rows on an old
-- version and Decrypt selects the right key by this column.
ALTER TABLE acp_agent_kinds ADD COLUMN key_version SMALLINT NOT NULL DEFAULT 1;
ALTER TABLE acp_agent_kind_config_files ADD COLUMN key_version SMALLINT NOT NULL DEFAULT 1;
ALTER TABLE workspace_run_profiles ADD COLUMN key_version SMALLINT NOT NULL DEFAULT 1;
-- 注意:git 凭据密文在 git_credentials.encrypted_secret,不在 workspaces(后者无密文列)。
ALTER TABLE git_credentials ADD COLUMN key_version SMALLINT NOT NULL DEFAULT 1;
ALTER TABLE llm_endpoints ADD COLUMN key_version SMALLINT NOT NULL DEFAULT 1;
-- Partial indexes to make the re-encrypt scan (WHERE key_version < active AND
-- blob IS NOT NULL) cheap. Only index rows that actually carry ciphertext.
CREATE INDEX acp_agent_kinds_keyver_idx ON acp_agent_kinds (key_version)
WHERE encrypted_env IS NOT NULL OR encrypted_mcp_servers IS NOT NULL;
CREATE INDEX acp_agent_kind_config_files_keyver_idx ON acp_agent_kind_config_files (key_version)
WHERE encrypted_content IS NOT NULL;
CREATE INDEX workspace_run_profiles_keyver_idx ON workspace_run_profiles (key_version)
WHERE encrypted_env IS NOT NULL;
CREATE INDEX git_credentials_keyver_idx ON git_credentials (key_version)
WHERE encrypted_secret IS NOT NULL;
CREATE INDEX llm_endpoints_keyver_idx ON llm_endpoints (key_version)
WHERE api_key_encrypted IS NOT NULL;
-- Record which sandbox mode a session ran under (audit/forensics). Cheap and
-- recommended by the spec; NULL for sessions that predate this column.
ALTER TABLE acp_sessions ADD COLUMN sandbox_mode TEXT;