| Control | State | How it works |
| Access control | IMPLEMENTED | Scoped API keys per organization; seven roles; a key's max_execution_class can make PHI structurally unreachable for an integration. |
| Authentication | IMPLEMENTED | 24 bytes of CSPRNG per key; only sha256(key) is stored; lookup is by full-hash index, not by prefix-then-compare. |
| Authorization | IMPLEMENTED | Per-endpoint scope requirements; cross-tenant reads return 404, not 403, so an id's existence is not confirmed to a stranger. |
| Encryption in transit | DEPLOYMENT | TLS is terminated at the reverse proxy. A HEALTH_SECURE provider endpoint must be https (or loopback) or registration is refused. |
| Encryption at rest | IMPLEMENTED | AES-256-GCM with a per-job key derived by HKDF from the deployment key. Without a configured key, retention=customer_defined is refused rather than storing plaintext. |
| Audit logging | IMPLEMENTED | Hash-chained rows; every meta object passes a field allowlist, so an audit row cannot carry patient data. GET /health/v1/audit/verify walks the chain. |
| Audit immutability | PARTIAL | The chain makes tampering detectable, not impossible: sqlite is not WORM storage. Externalising the chain head is planned. |
| Retention & deletion | IMPLEMENTED | Three policies; hard DELETE on request and on expiry; deletion records are retained as evidence. |
| Provider approval | IMPLEMENTED | Registration is open, approval is an operator action with the deployment token, and every transition is audited. Revocation takes effect on the next job — there is no provider cache. |
| Execution isolation | PARTIAL | Providers declare an isolation level and it is recorded in the receipt. Animica does not verify it. |
| Hardware attestation | PLANNED | Attestation kinds (tpm, sev_snp, tdx, nitro) can be recorded. No attestation document is verified by this build, and every receipt says attestation_verified: false. |
| Key management | PARTIAL | Signing and encryption keys come from the environment, 0600 on disk. There is no HSM or KMS integration; that is deployment work. |
| Incident logging | IMPLEMENTED | Authentication failures, policy refusals, provider transitions and anchor failures are audited and exported as metrics. |
| Data-flow documentation | IMPLEMENTED | See below. |
| BAA | PROCESS | An organization-level field with four states. It is a record of an out-of-band legal agreement, not a substitute for one. |
| Stage | Sensitive data present? | Notes |
| TLS termination (nginx) | Yes, in memory | Request bodies are not written to access logs; the health locations set access_log off for request bodies and never log query strings. |
| Gateway process memory | Yes, transiently | Parsed request, execution, response. Not written to disk unless retention says so. |
| Application logs | No | Structural allowlist (redact.js). Unknown fields are dropped and counted, never serialised. |
| Metrics | No | Labels are closed enumerations: operation, execution class, error code, status. |
| Audit log | No | Same allowlist. |
| Database | Only under retention | One table, health_payloads, AES-256-GCM, per-job key, explicit expiry. |
| Execution receipt | No | Field allowlist plus a value-shape check refuses free text before signing. |
| Chain anchor | No | Seven fixed fields; a field-vocabulary assertion runs before every write. |
| x402 discovery | No | Only PHI-incapable operations are listed, each with PHI_ALLOWED: false. |
| Secure provider | Yes, during execution | Your approved infrastructure, or ours under contract. Retention there is the provider's configuration. |
| Public network (AICF) | Never for HEALTH_SECURE | Enforced in the scheduler's SQL, re-asserted independently before execution, and covered by tests that fail the build. |
| Threat | Mitigation |
| Secure workload reaching a public worker | Class is bound in an immutable column; eligibility is a single parameterised query; an independent assertion runs on the returned row; no fallback path exists; tested. |
| Receipt forgery | ML-DSA-65 over canonical bytes. Any altered field changes the canonical form and breaks the signature. Model substitution is caught separately by comparing model_hash against the registry. |
| Model substitution | Version and artifact hash are a unit; a UNIQUE index makes republishing changed bytes under an existing version a constraint violation. |
| Cross-tenant access | Every read is org-scoped; a foreign id returns 404. |
| Replay / double billing | Org-scoped idempotency on job creation plus a UNIQUE index of one usage row per job. |
| Revoked credentials | Key status is checked per request with no cache. Provider state is read per dispatch with no cache. |
| Log leakage | Allowlist, not denylist; a dedicated test asserts canary strings never appear in logs, metrics, receipts, anchors or discovery. |
| Malicious payloads (SSRF, injection, archive bombs) | No user-supplied URL is fetched on the PHI path; every query is parameterised; no shell is invoked; bodies are capped and depth-bounded. |
| Prompt injection | Model output is never executed and never used to select a provider, a model or a policy. Literature synthesis discards sentences citing sources outside the retrieved set. |