ProofedMesh/db/trust/migrations/0003_agent_keys.up.sql
CTO (Paperclip) 51733d8b36
Some checks failed
build-images / signing-service image (push) Failing after 14s
validate / JSON Schema (ajv) (push) Successful in 19s
validate / Rego (opa fmt + opa test) (push) Successful in 14s
validate / DB (migrate up/down dry-run) (push) Failing after 18s
validate / Go (vet + test) (push) Successful in 34s
db+ci: Agent Registry schema (agents + agent_keys), Phase-1 seed, migrate up/down CI (DEV-607)
- 0002_agents / 0003_agent_keys migrations per architecture v1.1 §4.4
  (incl. (k8s_namespace, k8s_service_account) uniqueness for the signing
  service's dual identity check and an agent_id, valid_from index for the
  verification lookup path)
- idempotent seed db/trust/seeds/0001_phase1_agents.sql with the three
  Phase-1 identities: agent-approval-service, agent-testagent-transform,
  agent-dummy-sink (namespace agent-trust)
- new db CI job in validate.yml: runs postgres:16-alpine, migrate up ->
  down 2 -> up, applies the seed twice, verifies three agents

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-25 19:23:20 +00:00

43 lines
2.1 KiB
SQL

-- Migration: 0003_agent_keys
-- Signatur-Schlüsselhistorie je Agent gemäß docs/architecture/v1.1.md §4.4.
--
-- Design-Entscheidungen (siehe §4.4, TUF-Pattern):
-- * public_key_pem wird als PEM gespeichert, Format (Ed25519/ECDSA/RSA)
-- wird NICHT in der DB erzwungen — die signing-/verification-Services
-- parsen und entscheiden. Rotation Default alle 90 Tage, Retention
-- 1 Jahr → max. ~5 nicht-archivierte Schlüssel pro Agent.
-- * valid_from / valid_to spannen den Autoritätszeitraum. Verifikation
-- alter Attestations wählt den Schlüssel, bei dem issued_at im
-- [valid_from, valid_to] liegt. valid_to ist NOT NULL (bei Ausstellung
-- wird ein geplantes Ablaufdatum gesetzt, auch wenn später rotiert
-- wird).
-- * revoked_at ist eine ausserordentliche Verkürzung (Kompromittierung).
-- Verification muss revoked_at <= issued_at ausschliessen.
-- * archived_at markiert Schlüssel, die weder aktuell noch für Retention
-- verifiziert werden müssen — nur noch Audit-Zeuge.
CREATE TABLE IF NOT EXISTS agent_keys (
key_id TEXT PRIMARY KEY
CHECK (length(key_id) BETWEEN 1 AND 256),
agent_id TEXT NOT NULL REFERENCES agents(agent_id),
public_key_pem TEXT NOT NULL
CHECK (position('-----BEGIN ' IN public_key_pem) = 1),
valid_from TIMESTAMPTZ NOT NULL,
valid_to TIMESTAMPTZ NOT NULL,
revoked_at TIMESTAMPTZ,
revocation_reason TEXT CHECK (revocation_reason IS NULL
OR length(revocation_reason) BETWEEN 1 AND 500),
archived_at TIMESTAMPTZ,
CONSTRAINT agent_keys_valid_range CHECK (valid_to > valid_from),
CONSTRAINT agent_keys_revocation_consistent
CHECK ((revoked_at IS NULL) = (revocation_reason IS NULL))
);
-- Aktive-Schlüssel-Scan je Agent (TUF-Pattern, §4.4).
CREATE INDEX idx_agent_keys_lookup
ON agent_keys (agent_id, archived_at)
WHERE archived_at IS NULL;
-- Verification-Pfad: finde Schlüssel, der zu einem gegebenen issued_at galt.
CREATE INDEX idx_agent_keys_agent_valid_from
ON agent_keys (agent_id, valid_from);