trading-system-docs/tolaria/tolaria-write-auth/AUTH3D_DESIGN.md
Red Queen 10761f52b2 AUTH.3E: Executor Command Channel + Runtime Boundary Contract
- job_schema: geschlossene Job-Type-Allowlist (C5_SAVE_OBJECT/C5_DELETE_OBJECT), Pfad-/Längen-Validierung
- job_state_machine: deterministische States (CREATED/READY/CLAIMED/EXECUTING/SUCCEEDED/FAILED)
- job_claim: atomare Claim-/Lease-/Recovery-Logik (kein TOCTOU)
- job_store: getrennte SQLite-Inbox-DBs (c5a_save.db/c5a_delete.db), delegiert an job_claim
- save_executor_core: SAVE-only, Content-Rekonstruktion, Provenance-Validierung
- delete_executor_core: DELETE-only, AUTH.3D-Composition, TOCTOU-Defense (Re-Read nach Claim)
- test_job_channel: T1-T40 + adversarial (72 Tests)
- test_job_channel_adversarial: adversarial + Substitution + DB-Manipulation
- sensitivity_proof_auth3e: Mutationen A-L (12/12 Invarianten PRESENT)
- AUTH3B/3C/3D/3E_DESIGN: autoritative Security-Dokumentation (e25 Reconciliation)

COMMAND != AUTHORIZATION. Kein generischer Dispatcher. RQ credential-free.
Keine produktive Mutation. Keine echten Credentials.
2026-08-27 10:03:32 +00:00

422 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AUTH.3D — HUMAN DELETE APPROVAL AUTHENTICITY
**Status:** SECURITY DESIGN + CODE + ISOLATED TESTS + REVIEW ONLY (KEIN produktives Deployment)
**Datum:** 2026-08-27
**Mission Type:** SECURITY DESIGN + CODE + ISOLATED TESTS + REVIEW ONLY
**Baseline:** AUTH.1 (40bbc40) + AUTH.2 (edcb4902) + AUTH.3A (a11c1bb) + AUTH.3B + AUTH.3C = COMPLETE
> ⚠️ Dies ist ein **Design + Code + Test-Dokument**. Es wird KEIN produktives
> Deployment ausgeführt, kein echter Signing Key erzeugt, kein Christians Private
> Key erzeugt, kein echter Public Key deployed, keine ENV geändert, kein Container
> erstellt, kein Executor deployed, keine produktive SAVE/DELETE-Probe. Bei Zweifel:
> FAIL CLOSED + HARD STOP.
---
## 1. CURRENT APPROVAL FLOW (Phase 1) — rekonstruiert (READ-ONLY)
### 1a. Vollständiger Flow
```
Delete Request → State Machine → Approval Creation → Approval Persistence
→ DeleteExecutor → Approval Validation → Tolaria DELETE → Ledger/Consumption
```
1. **Delete Request:** Ein Forgejo-Commit enthält einen DELETE-ObjectChange (`operation == OP_DELETE_REQUEST`).
2. **State Machine:** Commit wird in C5-State-Machine verarbeitet (C5AStore, c5a.db).
3. **Approval Creation:** `cmd_c5_delete_approve` (CLI, rq_c5_cli.py Z.355) → `store.create_delete_approval()`.
4. **Approval Persistence:** SQLite-Tabelle `delete_approvals` (c5a.db).
5. **DeleteExecutor:** `cmd_c5_delete_execute` (CLI, Z.424) → `DeleteExecutor.execute()`.
6. **Approval Validation:** `_validate_approval()` (rq_c5_delete.py Z.105) — Invarianten D/E/F/I.
7. **Tolaria DELETE:** `_do_delete()``client.delete()`.
8. **Ledger/Consumption:** `mark_delete_approval_used()``approval_status='USED'`, Commit → ST_UPDATING_SEARCH.
### 1b. Wer kann Approval heute erzeugen?
- **NUR der CLI-Befehl `approve-delete`** (`cmd_c5_delete_approve`). Kein Code erzeugt Approval automatisch (Invariante B/C).
- **Jeder, der die CLI im RQ-Container ausführen kann** (User `hermes`), kann eine Approval erzeugen.
- **`approved_by` ist ein frei wählbares CLI-Argument** (Default `human:christian`). **KEINE kryptographische Bindung an Christian.**
### 1c. Exakte Felder (DB-Tabelle `delete_approvals`)
| Feld | Typ | Bedeutung |
|---|---|---|
| `approval_id` | TEXT (uuid4) | Eindeutige ID |
| `workflow_commit` | TEXT | Commit-Binding |
| `object_change_id` | INT | ObjectChange-Binding |
| `object_id` | TEXT | Objekt-Binding |
| `path` | TEXT | Pfad-Binding |
| `operation` | TEXT | 'DELETE' |
| `approval_status` | TEXT | APPROVED/USED/REVOKED |
| `approved_by` | TEXT | **frei wählbar** (Default human:christian) |
| `approval_nonce` | TEXT (uuid4) | Nonce (kryptographisch zufällig, aber NICHT signiert) |
| `approved_at` | INT (ms) | Zeitpunkt |
| `used_at` | INT (ms) | Single-Use-Zeitpunkt |
### 1d. Bestehende Bindings (im Code verifiziert)
- **Object-Binding:** `_validate_approval` Z.143 — `approval.object_id == oid` (Invariante E).
- **Commit-Binding:** Z.136 — `approval.workflow_commit == commit_sha` (Invariante F).
- **Path-Binding:** Z.150 — `approval.path == path` (Invariante I).
- **Operation-Binding:** `create_delete_approval` setzt `operation='DELETE'` fest.
- **Nonce:** `approval_nonce` = uuid4, aber **nicht signiert, nicht verifiziert**.
- **Single-Use:** `mark_delete_approval_used``approval_status='USED'`; `_validate_approval` prüft `approval_status == 'APPROVED'`.
- **Mission-Binding:** **FEHLT** — kein `mission_id`-Feld.
- **Provenance-Binding:** **FEHLT** — kein `expected_provenance_hash`-Feld.
- **Expiry:** **FEHLT** — kein `expires_at`-Feld.
- **Actor-/Identity-Information:** `approved_by` (frei wählbar).
- **Authentizitätsprüfung:** **KEINE** — es gibt keine kryptographische Prüfung, dass die Approval von Christian stammt.
### 1e. Kernbefund
**HUMAN_APPROVAL_AUTHENTICITY_GAP = OPEN.** Die Approval ist eine reine DB-Zeile mit
frei wählbarem `approved_by`. Jeder mit CLI-/DB-Zugriff (RQ/Hermes, User `hermes`)
kann eine syntaktisch perfekte Approval erzeugen. Es gibt **keine kryptographische
Bindung an Christian**. → DELETE_OPERATION_ACTIVATION bleibt BLOCKED.
---
## 2. THREAT MODEL (Phase 2)
> ⚠️ NUR ANALYSE. FAIL CLOSED.
| Threat | CURRENT_PROTECTION | CURRENT_GAP | TARGET_CONTROL | FAIL_CLOSED_BEHAVIOR |
|---|---|---|---|---|
| **T1 RQ erzeugt selbst Approval** | CLI-Zugriff (User hermes) | RQ kann `approve-delete` ausführen | RQ besitzt keinen Signing Key → kann keine gültige signierte Approval erzeugen | DELETE_DENIED |
| **T2 Hermes erzeugt selbst Approval** | Gleiche Boundary wie RQ | Hermes kann CLI ausführen | Hermes besitzt keinen Signing Key | DELETE_DENIED |
| **T3 Rain erzeugt Approval** | Separater Container | Rain hat keinen CLI-Zugriff auf c5a.db | Rain besitzt keinen Signing Key | DELETE_DENIED |
| **T4 SAVE Executor erzeugt Approval** | Separater Container (AUTH.3C) | Kein CLI-Zugriff auf c5a.db | SAVE Executor besitzt keinen Signing Key | DELETE_DENIED |
| **T5 DELETE Executor erzeugt Approval** | Separater Container (AUTH.3C) | Kein CLI-Zugriff auf c5a.db | DELETE Executor ist **verify-only**, besitzt keinen Signing Key | DELETE_DENIED |
| **T6 Agent verändert gespeicherte Approval** | DB-Zugriff | DB-Zeile kann geändert werden | Signatur über Payload → Änderung invalidiert Signatur | DELETE_DENIED |
| **T7 Agent verändert Object nach Approval** | Object-Binding (E) | Nur DB-Vergleich, nicht kryptographisch | Object im signierten Payload → Änderung invalidiert Signatur | DELETE_DENIED |
| **T8 Agent verändert Commit nach Approval** | Commit-Binding (F) | Nur DB-Vergleich | Commit im signierten Payload | DELETE_DENIED |
| **T9 Agent verändert Path nach Approval** | Path-Binding (I) | Nur DB-Vergleich | Path im signierten Payload | DELETE_DENIED |
| **T10 Approval wird kopiert** | approval_id uuid4 | Kopie ist gültig (keine Signatur) | Signatur + Single-Use → Kopie hat gleiche Signatur, aber Nonce/consumed | DELETE_DENIED (Replay) |
| **T11 Approval wird wiederverwendet** | Single-Use (USED) | Nur DB-Status | Signatur + consumed-check | DELETE_DENIED |
| **T12 Approval wird zwischen Missions übertragen** | Kein mission_id | Kein Mission-Binding | mission_id im signierten Payload | DELETE_DENIED |
| **T13 alte Approval nach State Change** | Commit-Status-Check (Gate 2) | Nur DB-Status | State-Check + Signatur | DELETE_DENIED |
| **T14 Nonce wird wiederverwendet** | uuid4 | Nonce nicht signiert/verifiziert | Nonce im signierten Payload + consumed-check | DELETE_DENIED |
| **T15 DB-Eintrag wird manipuliert** | — | DB-Zeile allein erzeugt gültige Approval | Signatur → DB-Forgery ohne Private Key unmöglich | DELETE_DENIED |
| **T16 Approval aus Backup wiederhergestellt** | — | Backup enthält gültige Approval | Signatur + consumed-check + expires_at | DELETE_DENIED |
| **T17 Approval nach Executor-Restart erneut verwendet** | Single-Use (USED) | Nur DB-Status | consumed-check + Signatur | DELETE_DENIED |
| **T18 Race zwischen Verify und Delete** | — | TOCTOU-Fenster | Atomare Reservation (RESERVED) | DELETE_DENIED |
| **T19 LLM erzeugt syntaktisch perfekte Fake-Approval** | — | Keine Signatur | Signatur → LLM ohne Private Key kann nicht signieren | DELETE_DENIED |
| **T20 kompromittierter RQ-Prozess versucht Approval-Bypass** | — | RQ kann CLI ausführen | RQ besitzt keinen Signing Key | DELETE_DENIED |
**Kern-Gap:** Alle Bindings (Object/Commit/Path) sind nur DB-Vergleiche, nicht
kryptographisch. `approved_by` ist frei wählbar. **Es fehlt eine kryptographische
Bindung an Christian.**
---
## 3. HUMAN IDENTITY ROOT (Phase 3) — Optionen
> ⚠️ NUR BEWERTUNG. KEINE Keys erzeugen.
| Option | HUMAN_AUTH | LLM_CAN_FORGE | RQ_CAN_FORGE | DELETE_EXEC_CAN_FORGE | PRIVATE_SECRET_EXPOSURE | REPLAY_RES | AUDIT | ROTATION | REVOCATION | BACKUP_RISK | OP_COMPLEXITY | STACK_COMPAT | OFFLINE_RECOVERY |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| **A: HMAC (geteiltes Secret)** | Mittel | Nein (ohne Secret) | Nein (ohne Secret) | Nein (verify-only) | **Hoch** (Secret muss bei Verifier liegen) | Mittel | Mittel | Ja | Ja | Mittel | Niedrig | Hoch | Ja |
| **B: Asymmetrisch (Ed25519)** | **Hoch** | **Nein** | **Nein** | **Nein** (verify-only) | **Niedrig** (nur Public Key bei Verifier) | **Hoch** | **Hoch** | Ja | Ja | Niedrig | Mittel | **Hoch** (Python stdlib/cryptography) | Ja |
| **C: Forgejo-signiertes Artefakt** | Mittel | Nein | Nein | Nein | Mittel (Key bei Forgejo) | Mittel | Hoch | Ja | Ja | Mittel | Hoch | Hoch | Mittel |
| **D: Separater Approval-Service** | Hoch | Nein | Nein | Nein | Niedrig | Hoch | Hoch | Ja | Ja | Niedrig | **Hoch** (neue Infrastruktur) | **Niedrig** | Mittel |
| **E: Telegram + kryptogr. Bindung** | Mittel | Nein | Nein | Nein | Mittel | Mittel | Mittel | Ja | Ja | Mittel | Mittel | Hoch | Ja |
| **F: Andere minimal sichere** | — | — | — | — | — | — | — | — | — | — | — | — | — |
**Bewertung:**
- **OPTION B (Ed25519 asymmetrisch)** ist die **stärkste und stack-kompatible** Lösung:
Christian besitzt den Private Key, der DELETE Executor kennt nur den Public Key.
**LLM/RQ/SAVE/DELETE-Executor können ohne Private Key nicht signieren.**
Python `cryptography`-Bibliothek (oder `pynacl`) unterstützt Ed25519 nativ.
- **OPTION A (HMAC)** ist schwächer: das geteilte Secret müsste beim Verifier liegen,
was die Exposure-Fläche vergrößert. Nicht bevorzugt.
- **OPTION C (Forgejo-signiert)** ist möglich, aber komplexer und bindet an Forgejo.
- **OPTION D (separater Service)** erfordert neue Infrastruktur → Scope-Creep.
- **OPTION E (Telegram)** allein ist KEIN kryptographischer Proof (siehe §7).
**Empfehlung: OPTION B (Ed25519 asymmetrisch).**
---
## 4. PREFERRED SECURITY PROPERTY (Phase 4)
**Bevorzugte Eigenschaft (bestätigt):**
- **Christian:** PRIVATE KEY (Ed25519)
- **DELETE Executor:** PUBLIC KEY ONLY (verify-only)
- **RQ/Hermes:** NO PRIVATE KEY
- **SAVE Executor:** NO PRIVATE KEY
- **Rain:** NO PRIVATE KEY
- **Tolaria:** NO PRIVATE KEY
**Gegen reale Architektur bewertet:**
- Python `cryptography`/`pynacl` ist im Stack verfügbar (C5-Caller sind Python).
- Keine neue Infrastruktur nötig.
- Der DELETE Executor kann eine Approval **verifizieren**, aber **nicht erzeugen**.
- **Bestätigt als bevorzugte Lösung.**
---
## 5. APPROVAL PAYLOAD (Phase 5) — kanonisch
### Kanonischer Payload
```json
{
"approval_version": 1,
"approval_id": "<uuid4>",
"mission_id": "<mission-id>",
"delete_request_id": "<delete-request-id>",
"operation": "DELETE",
"object_id": "<object-id>",
"vault_path": "<vault-path>",
"expected_commit": "<commit-sha>",
"expected_provenance_hash": "<sha256>",
"nonce": "<uuid4>",
"issued_at": "<ISO-8601-UTC>",
"expires_at": "<ISO-8601-UTC>"
}
```
### Canonicalization
- **CANONICALIZATION:** Deterministische Serialisierung: Felder in fester Reihenfolge
(wie oben), keine Duplikate, keine Whitespace-Varianz, UTF-8, keine Unicode-Normalisierung
(exakte Bytes), Pfad-Normalisierung (kein `./`, kein `..`, keine doppelten Slashes).
- **ENCODING:** UTF-8, JSON ohne optionale Felder (nur die 12 Pflichtfelder).
- **HASH:** SHA-256 über den kanonisierten Payload-Bytes.
- **SIGNATURE_INPUT:** Die kanonisierten Payload-Bytes selbst (nicht der Hash) werden
signiert (Ed25519 signiert intern den Hash). Keine Signatur über frei formatierte Texte.
---
## 6. APPROVAL SIGNATURE (Phase 6) — Ed25519
- **SIGNATURE_ALGORITHM:** **Ed25519** (RFC 8032), via Python `cryptography` oder `pynacl`.
- **PRIVATE_KEY_OWNER:** Christian (einziger Besitzer).
- **PRIVATE_KEY_LOCATION:** Christians vertrauenswürdiges Gerät (NICHT im Stack).
- **PUBLIC_KEY_LOCATION:** DELETE Executor-Konfiguration (read-only, injiziert via Secret/File).
- **KEY_ID:** SHA-256-Hash des Public Keys (kurz, zur Key-Identifikation).
- **SIGNATURE_FORMAT:** Ed25519-Signatur (64 Bytes), Base64-URL-encoded.
- **VERIFICATION:** `verify(public_key, canonical_payload_bytes, signature)`.
- **ROTATION:** Neuer Key → neue KEY_ID; alte Approvals mit altem Key bleiben bis Expiry gültig (Multi-Key-Transition).
- **REVOCATION:** Key-Revocation-Liste (KEY_ID → revoked); verifier prüft.
- **MULTI_KEY_TRANSITION:** Verifier akzeptiert mehrere Public Keys (aktuelle + vorherige), markiert ältere als "transitioning".
**Private Key darf NICHT liegen in:** RQ ENV, Hermes ENV, Rain ENV, SAVE Executor,
DELETE Executor, Forgejo Repo, C5 DB, Tolaria, Logs, Reports.
---
## 7. APPROVAL CREATION CHANNEL (Phase 7)
> ⚠️ NUR DESIGN. KEINE Implementierung in AUTH.3D (nur Code + Tests).
### Modelle
| Modell | UX | Sicherheit | Stack-Kompatibilität |
|---|---|---|---|
| **A: Lokales Signing Tool auf Christians Gerät** | Mittel (Christian signiert manuell) | **Hoch** (Private Key nie im Stack) | Hoch (Python-Skript) |
| **B: Separater Approval-Container/Service** | Niedrig | Hoch | **Niedrig** (neue Infrastruktur) |
| **C: Telegram Approval → separater Signer** | Hoch | Mittel (Signer muss getrennt sein) | Mittel |
| **D: Forgejo Workflow** | Mittel | Mittel | Hoch |
| **E: Anderer sicherer Kanal** | — | — | — |
**Empfehlung: OPTION A (lokales Signing Tool auf Christians Gerät).** Christian
erzeugt den kanonischen Payload (aus dem Delete-Request), signiert ihn mit seinem
Private Key, und übergibt die signierte Approval (Payload + Signatur + KEY_ID) an
den DELETE Executor (via CLI/Inbox). Der Executor verifiziert mit dem Public Key.
**WICHTIG (strikte Unterscheidung):**
- **HUMAN_INTENT:** Ein Telegram-Text "Ja"/"Approve"/"Delete" ist NUR Intent, KEIN kryptographischer Proof.
- **CRYPTOGRAPHIC_APPROVAL_ARTIFACT:** Die signierte Approval (Payload + Signatur) ist der einzige gültige Proof.
- RQ darf NICHT aus einem Telegram-Text den finalen Approval-Datensatz erzeugen können (ohne Christians Private Key).
---
## 8. APPROVAL VERIFICATION (Phase 8)
**DeleteExecutor MUSS VOR DELETE prüfen (alle, sonst DELETE_DENIED):**
1. Schema gültig (kanonischer Payload)
2. Unterstützte Approval-Version
3. Signatur gültig (Ed25519, Public Key)
4. Key nicht revoked
5. Operation == DELETE
6. Mission stimmt
7. Delete Request stimmt
8. Object stimmt
9. Path stimmt
10. Commit stimmt
11. Provenance stimmt
12. Nonce stimmt
13. issued_at plausibel (nicht in der Zukunft)
14. expires_at nicht überschritten
15. Approval noch nicht consumed
16. State erlaubt Delete
17. kein Replay
18. kein Cross-Object-Reuse
19. kein Cross-Mission-Reuse
**Jeder Fehler → DELETE_DENIED. KEIN Tolaria HTTP DELETE.**
---
## 9. TOCTOU / RACE SAFETY (Phase 9)
- **VERIFY → STATE CHANGE → DELETE:** Zwischen Verification und Mutation gibt es ein Fenster.
- **Lösung:** Atomare **Reservation** in der DB: Approval-Status `APPROVED → RESERVED`
(mit `execution_attempt_id` + `idempotency_key`) in einer SQLite-Transaktion, BEVOR
der Tolaria-DELETE ausgeführt wird. Nur eine Reservation pro Approval möglich.
- **DB Transaction:** `UPDATE ... SET approval_status='RESERVED' WHERE approval_status='APPROVED'`
— atomar, nur wenn noch APPROVED.
- **Crash before delete:** Approval bleibt RESERVED → Recovery: prüfen, ob DELETE
tatsächlich ausgeführt wurde (Read-Back). Wenn nicht → zurück zu APPROVED (oder
neuer Attempt mit neuem idempotency_key).
- **Crash after delete before ledger:** Read-Back zeigt Ziel absent → Ledger nachtragen,
Approval → CONSUMED.
- **Retry:** Idempotenz via `idempotency_key` — gleicher Attempt wird nicht doppelt ausgeführt.
- **Uncertain network result:** **DELETE_OUTCOME_UNKNOWN** — der Executor darf bei
Unsicherheit NICHT blind wiederholen. Er meldet OUTCOME_UNKNOWN und wartet auf
manuelle Klärung (Read-Back).
**Recovery State für DELETE_OUTCOME_UNKNOWN:** Approval bleibt RESERVED; ein manueller
Read-Back entscheidet, ob CONSUMED (Ziel absent) oder zurück zu APPROVED (Ziel noch da).
---
## 10. SINGLE USE (Phase 10)
**Approval Lifecycle:**
```
CREATED → VERIFIED → RESERVED → EXECUTED → CONSUMED
```
| Zustand | Verhalten |
|---|---|
| **INVALID** | DELETE_DENIED (Signatur/Binding-Fehler) |
| **EXPIRED** | DELETE_DENIED (expires_at überschritten) |
| **REVOKED** | DELETE_DENIED (Key oder Approval revoked) |
| **FAILED** | DELETE_DENIED (Execution-Fehler) |
| **OUTCOME_UNKNOWN** | Kein blinder Retry; manuelle Klärung |
**Eine Approval darf nach CONSUMED niemals erneut ausführbar sein.** Der consumed-check
ist Teil der Verification (§8, Punkt 15) und der Reservation (§9).
---
## 11. STORAGE (Phase 11)
**Was wird gespeichert:**
- Payload (kanonisch)
- Signature (Ed25519, Base64-URL)
- Public Key ID (KEY_ID)
- Verification Result (PASS/DENIED + Reason)
- consumed_at
- execution_attempt (attempt_id, idempotency_key)
- Result (DELETE_OK / DELETE_OUTCOME_UNKNOWN / DELETE_DENIED)
**Was wird NICHT gespeichert:**
- Private Key
- Signing Secret
**DB-Manipulationsrisiko:** Eine DB-Zeile allein darf keine gültige Approval erzeugen.
Selbst vollständige Schreibkontrolle über die Approval-DB darf ohne Christians
Private Key keine neue gültige Approval erzeugen können (Signatur fehlt → DENIED).
---
## 12. ISOLATED IMPLEMENTATION (Phase 12)
> ⚠️ NUR Code + Tests. KEIN produktives Deployment.
**Modular (keine Vermischung mit Tolaria HTTP):**
- `approval_payload.py` — kanonischer Payload, Canonicalization, Encoding, Hash
- `approval_signature.py` — Ed25519 sign/verify (synthetische Test-Keypairs)
- `approval_verifier.py` — Verification-Logik (alle §8-Checks)
- `approval_state.py` — Lifecycle (CREATED→VERIFIED→RESERVED→EXECUTED→CONSUMED), Single-Use, Reservation
**Bestehende C5-Invarianten erhalten.** Keine Änderung an Tolaria-HTTP-Code.
---
## 13. TEST CONTRACT (Phase 13)
> ⚠️ NUR synthetische Test-Keypairs. KEINE echten Keys.
**T1T30 (siehe Freigabe):**
- T1 gültige Christian-Approval → PASS
- T2 falsche Signatur → DENIED
- T3 falscher Public Key → DENIED
- T4 Payload nach Signatur verändert → DENIED
- T5 Object verändert → DENIED
- T6 Path verändert → DENIED
- T7 Commit verändert → DENIED
- T8 Provenance verändert → DENIED
- T9 Mission verändert → DENIED
- T10 Request-ID verändert → DENIED
- T11 Nonce verändert → DENIED
- T12 expired → DENIED
- T13 future-issued invalid → DENIED
- T14 falsche Operation → DENIED
- T15 unbekannte Version → DENIED
- T16 malformed payload → DENIED
- T17 malformed signature → DENIED
- T18 Replay → DENIED
- T19 consumed Approval → DENIED
- T20 cross-object reuse → DENIED
- T21 cross-mission reuse → DENIED
- T22 DB fake row ohne Signature → DENIED
- T23 DB fake row mit erfundener Signature → DENIED
- T24 DELETE Executor kann keine Approval erzeugen
- T25 RQ besitzt keinen Signing Key
- T26 SAVE Executor besitzt keinen Signing Key
- T27 Logs enthalten keinen Private Key
- T28 DB enthält keinen Private Key
- T29 Retry nach confirmed delete führt nicht zu zweitem Delete
- T30 OUTCOME_UNKNOWN führt nicht zu blindem Retry
**Adversarial:** canonicalization ambiguity, duplicate JSON keys, Unicode normalization,
path normalization, signature substitution, key-id substitution, oversized payload,
malformed timestamps, nonce collision, stale state, concurrent execution.
---
## 14. TEST SENSITIVITY (Phase 14)
**Mutationen (jede muss Tests ROT machen):**
- A Signaturprüfung entfernen
- B Object Binding entfernen
- C Commit Binding entfernen
- D Nonce Binding entfernen
- E Expiry entfernen
- F consumed-check entfernen
- G Operation-check entfernen
- H Mission Binding entfernen
- I Provenance Binding entfernen
- J Replay-Schutz entfernen
---
## 15. REGRESSION (Phase 15)
Volle relevante C5-Test-Suite. Keine bestehenden Sicherheitsinvarianten abschwächen.
Baseline-Fails separat beweisen. Keine unrelated Reparaturen.
---
## 16. SECURITY REVIEW (Phase 16)
- NO_PRIVATE_KEY_IN_REPO / ENV / DB / LOGS
- RQ_CANNOT_SIGN / HERMES_CANNOT_SIGN / RAIN_CANNOT_SIGN / SAVE_EXECUTOR_CANNOT_SIGN / DELETE_EXECUTOR_CANNOT_SIGN
- DELETE_EXECUTOR_VERIFY_ONLY
- SIGNATURE_FAIL_CLOSED / REPLAY_FAIL_CLOSED / EXPIRY_FAIL_CLOSED / STATE_FAIL_CLOSED
---
## 17. COMMIT / PUSH (Phase 17)
Nur AUTH.3D-relevante Dateien. Vor Commit: git diff, git status, Secret-Scan,
Private-Key-Pattern-Scan. Keine echten Keys. Tests nur mit synthetischen Test-Keypairs.
FF-only Push. HEAD == origin/main verifizieren.
---
## 18. FRESH CHECKER (Phase 18)
> ⚠️ Wird als unabhängiger Subagent ausgeführt.
---
## 19. FINAL REPORT (Phase 19)
> ⚠️ Wird nach Fresh Checker ausgefüllt.