Threat Model — Quick Reference

The full normative threat model is RFC-ACDP-0008 Security. This document is a non-normative summary.

Threats addressed in v0.1.0

ThreatMechanism
Body tamperingcontent_hash recomputation + producer signature verification.
Lineage forgeryDeterministic lineage_id derivation; derived_from is part of the signed body.
Producer impersonationDID-bound signing key; verifiers resolve from the producer's DID document.
Cross-registry impersonationorigin_registry is registry-assigned, not producer-controlled.
Existence leak via 404 differentiationVisibility-restricted contexts return not_found (HTTP 404) indistinguishably from genuinely missing contexts. visibility_denied is internal logging only.
Replay of publish requestsContent-addressed bodies; idempotent at the content level.
DoS via oversize bodieslimits.max_payload_bytes and 64 KB embedded cap.
Spam / SybilPer-agent rate limiting required.
Algorithm downgradeAlgorithm named in body; verifier checks against registry's supported_signature_algorithms and the resolved key type.
Race on supersessionRegistry serializes supersession events; the loser of a race gets superseded_target.
Server-side request forgery (SSRF)Producer did:web resolution, cross-registry acdp:// resolution, and external data_refs[].location fetches all dereference producer-controlled URLs. Each applies HTTPS-only, DNS-level IP-range filtering on every resolved address, IP pinning against rebinding, and same-authority redirect caps. See RFC-ACDP-0008 §4.7–§4.9 and RFC-ACDP-0006 §7.
Cross-tenant authorization bypassACDP defines no protocol-level tenant identifier. Where a deployment partitions by tenant, attribution MUST rest on an authenticated signal (deployment policy at a trust boundary, an authenticating gateway that stamps the tenant, or signed token claims) — never an unauthenticated X-Tenant header, hostname, or path segment. The §4.5 visibility checks run after tenant attribution and cannot catch a forged one. See RFC-ACDP-0008 §6.4.
Cross-registry leak of non-public contextsCross-registry acdp:// resolution is public-only in v0.1.0 — no credential is forwarded to the remote registry, so restricted/private contexts return not_found (404) rather than leaking to an unauthenticated cross-registry caller. See RFC-ACDP-0006 §4.4.

Known gaps in v0.1.0

GapMitigation
No retractionUse supersession; RFC-ACDP-0009 reserves a formal lifecycle-events mechanism.
No real-time key revocation pushPull-based; consumers consult DID documents on retrieval.
No third-party attestationsRFC-ACDP-0009 reserves attestations in registry state.
No third-party builds_on claimsderived_from is producer-only.
No push subscriptionsPolling only; RFC-ACDP-0009 reserves push semantics.
No federation peeringCross-registry resolution via acdp:// is the federation primitive.
No multi-party / threshold signaturesUse contributors for joint authorship.
No quality scoring by registriesConsumers compute their own trust from DID + signature evidence.

Attack scenarios (summary)

1. Hostile registry serves a tampered body

Result. Consumer recomputes content_hash → mismatch ⇒ rejected. Or signature verification fails against the producer's DID document ⇒ rejected.

2. DNS spoof against a producer DID

Result. TLS validation at the producer's HTTPS endpoint catches the spoof unless the attacker also has a valid TLS cert. Even with a forged DID document, the attacker still needs the real private key to sign anything.

3. Producer rotates keys; old context

Result. The signing key has been removed from the producer's current DID document. The signature won't verify against the producer's current keys, and most DID methods don't expose historical key authorization data. v0.1.0 consumers SHOULD verify against the current DID document and either reject the old context (strict) or accept the residual risk (pragmatic). External transparency logs or the registry-receipts mechanism reserved in RFC-ACDP-0009 §2.7 will close this gap in a future version. See RFC-ACDP-0008 §9.3.

4. Replay of a captured publish request

Result. Idempotent at the content level — the registry assigns a new ctx_id but the body is identical. Producers wishing to suppress duplicates deduplicate locally on content_hash.

5. Visibility-restricted lookup by an unauthorized consumer

Result. Registry returns not_found (HTTP 404). Consumer cannot distinguish "doesn't exist" from "exists but you can't see it".

Scenarios 1–5 above are the RFC-ACDP-0008 §7 attack scenarios. One further class is worth calling out:

6. SSRF via a producer-controlled URL

Setup. A producer publishes a body whose agent_id/signature.key_id or data_refs[].location points at an internal address — e.g. did:web:169.254.169.254 (cloud metadata) or https://data-host.example/x whose DNS resolves to 127.0.0.1. A registry verifying the publish, or a consumer verifying end-to-end and fetching the DataRef, is induced to make the request. Result. The resolver/fetcher resolves the hostname, rejects it because a resolved IP falls in a private/loopback/link-local/IMDS range, and refuses before connecting. The resolved IP is pinned so a second DNS lookup cannot rebind to an internal target, and a cross-authority redirect is refused. When DNS returns several addresses and any is forbidden, the entire resolution is rejected — filtering out the bad answers and connecting to the rest ("filter and proceed") is non-conformant (RFC-ACDP-0006 §7.1). "Same authority" for the redirect cap is scheme + host + effective port, so a redirect to the same host on a different port is refused (§7.5). A registry refusing a producer DID fails the publish with key_resolution_failed; a consumer treats the context (or the DataRef) as unverifiable. See RFC-ACDP-0008 §4.7–§4.9 and RFC-ACDP-0006 §7.

7. Cross-tenant access via a forged tenant header

Setup. A multi-tenant deployment scopes contexts by tenant. An attacker authenticated to tenant A sets an X-Tenant: B header (or targets a path/hostname segment) hoping the registry attributes the request to tenant B before running visibility checks. Result. A conformant deployment never trusts a client-supplied tenant indicator. Tenant attribution is established from an authenticated signal — deployment policy at a trust boundary, an authenticating gateway that stamps the tenant after authentication, or a signed token claim bound to the requester's DID — and any client-supplied value is stripped or overwritten. The §4.5 visibility checks then run within the correctly-attributed tenant. ACDP defines no protocol-level tenant field; this is a deployment obligation. See RFC-ACDP-0008 §6.4.