# ProofedMesh Policies (OPA / Rego) Rego-Policies für die drei in [`docs/architecture/v1.1.md`](../docs/architecture/v1.1.md) Abschnitt 6 definierten Policy-Klassen. Alle Policies nutzen **Rego v1** (`import rego.v1`). ## Policy-Klassen | Klasse | Package-Präfix | Fragt der | | ----------------- | ------------------------------------ | ------------------------------ | | Transformationen | `proofedmesh.transformations.` | Signing Service | | Senken | `proofedmesh.sinks.` | Verification Service / Adapter | | Datenquellen | `proofedmesh.data_sources.` | Session Scope Token Service | Default in jedem Package ist `allow := false` — explizites Zulassen ist erforderlich (deny-by-default). ## Dateistruktur ``` policies/ transformations/ expense.rego — v1.0.0/v1.1.0/v1.2.0 map_to_sink + normalize, with allocation-sum invariant expense_test.rego per_diem.rego — expense.compute_per_diem (agent-per-diem-calculator → v1.2.0 output) per_diem_test.rego sinks/ expense_db_app.rego expense_db_app_test.rego data_sources/ expense_db_app.rego expense_db_app_test.rego receipts.rego — ds:receipts write (agent-travel) + read-by-content_hash (agent-sink-*) receipts_test.rego per_diem_rates.rego — ds:per-diem-rates read (agent-per-diem-calculator only, country+valid_on required) per_diem_rates_test.rego ``` ## Input-Verträge ### Transformationen ```json { "agent_id": "agent-sink-mapping", "operation": "expense.map_to_sink", "input_schema": { "name": "expense.canonical", "version": "1.0.0" }, "output_schema": { "name": "sink.db.expense", "version": "1.0.0" }, "sink_target": "sink:expense-db-app", "approval": { "allowed_transformations": [...], "allowed_sinks": [...] }, "input_payload": { ... canonical fields ... }, "output_payload": { ... sink fields ... } } ``` ### Senken ```json { "agent_id": "agent-sink-posting", "sink_id": "sink:expense-db-app", "action": "expense.post", "payload": { ... sink.db.expense ... }, "approval": { "allowed_sinks": [...] } } ``` ### Datenquellen (für Session Scope Token Service) ```json { "agent_id": "agent-travel", "user_sub": "user-12345", "session_id": "SES-...", "data_source": "ds:expense-db-app", "resource": "project_assignments", "filters": { "employee_id": "EMP-12345" }, "operation": "read" } ``` Zusätzliche Daten (nicht `input`, sondern über `data.*` bereitgestellt): `data.employee_mapping.by_sub` (user_sub → employee_id), `data.agent_registry.by_id` (Agent-Metadaten), `data.sinks.by_id`, `data.data_sources.by_id`. Trust-API lädt diese bei jedem Policy-Call aus Postgres und übergibt sie via OPA Partial-Evaluation oder bei Bedarf als `input.data`. ## Lokal testen ```bash opa test policies/ -v opa fmt --list --diff policies/ # formatting check ``` Beides läuft auch in CI (siehe `.forgejo/workflows/validate.yml`). ## Policy-Versionierung Jede Policy-Datei bekommt bei Breaking Changes eine neue Hauptversion. Historische Versionen bleiben parallel, solange Attestierungen mit `policy_version` darauf verweisen (Retention 1 Jahr). Rego-Bundles für Deployment werden aus dem jeweiligen Branch gebaut; der SHA-256 des Bundles landet in jeder Decision als `policy_version` (siehe ADR-0002, Abschnitt „Token-Format").