ProofedMesh/db/trust/migrations/0003_agent_keys.up.sql

44 lines
2.1 KiB
MySQL
Raw Normal View History

-- 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);