OpenFreyt Protocol — Abuse Case Catalogue
Generated from
security/abuse-cases.md. Edit the canonical source file, not this page.
Status: Normative
Version: 1.0.0-draft
Locked by: M001-S01-T03
Last reviewed: 2026-08-31
Overview
Section titled “Overview”This catalogue documents adversarial abuse cases for the OpenFreyt Protocol (PCX). Each entry describes a concrete attack scenario from an attacker’s perspective, the protocol controls that prevent or limit it, and the residual risk.
Abuse cases complement the threat model. Where the threat model organises findings by threat category, this catalogue organises them by attacker goal and concrete exploitation technique.
Required coverage per task plan:
- Unauthorized data access via UUID guessing
- Double-commitment race
- Stale decision replay
- Scope elevation
- Relationship flood
- Webhook SSRF
- Oversized payload DoS
- Decision policy bypass
- Audit trail poisoning
- Token audience confusion
AC-01 — Unauthorized Data Access via UUID Guessing
Section titled “AC-01 — Unauthorized Data Access via UUID Guessing”Goal: Access CapacityOffer or LoadRequest records belonging to another organization.
Preconditions:
- Attacker holds a valid JWT with
capacity:readorloads:readscope for their own organization. - Attacker knows the general UUID format used by the broker.
Attack steps:
- Observe one or more resource IDs from legitimate API responses (e.g., own CapacityOffer IDs).
- Attempt to infer ID generation patterns (sequential counters, timestamp-based prefixes).
- Enumerate IDs by issuing GET requests with mutated or incremented UUIDs.
- For UUIDv7 IDs, attempt timestamp-range scanning: generate all UUIDv7 values for a known creation time window and iterate.
- If any guessed ID returns data, read confidential counterparty payload.
Protocol controls:
- All resource IDs are UUIDv7 with a randomly generated 62-bit node/clock-seq component; the probability of a valid guess for a single request is ≈ 2⁻⁶² ≈ 2.2 × 10⁻¹⁹.
- Every resource GET filters on
ownerOrganizationIdderived from the token’sorg_idclaim; a correct UUID belonging to another org returns404 Not Found(never403), per R-001. - Brokers MUST apply rate limiting on read endpoints (per-org, per-token); aggressive enumeration
triggers
429 Too Many Requestsbefore a statistically meaningful number of IDs can be tested.
Residual risk: NEGLIGIBLE — the combination of 62-bit entropy and 404-not-403 renders systematic guessing computationally infeasible and observationally indistinguishable from legitimate not-found responses.
Related threats: T-06 (Resource Enumeration Resistance), API1.
AC-02 — Double-Commitment Race
Section titled “AC-02 — Double-Commitment Race”Goal: Commit the same MatchDecision twice, creating duplicate binding records or bypassing bilateral approval requirements.
Preconditions:
- Attacker controls one side of a bilateral MatchDecision (e.g., the initiator organization).
- Attacker can issue concurrent HTTP requests.
Attack steps:
- Obtain a MatchDecision in
PENDING_INITIATOR_ACCEPTstate. - Issue two or more simultaneous COMMIT (or ACCEPT) requests with the same payload.
- If the broker uses non-serialized writes, both requests may pass a read-check-write sequence concurrently before either commits, causing two state transitions.
- Alternatively, issue one ACCEPT and immediately one COMMIT before the ACCEPT is persisted, attempting to skip the bilateral approval gate.
Protocol controls:
- Every mutating state transition on a MatchDecision MUST use a compare-and-swap on
resourceVersion; only one transition can win the CAS; all others receive409 Conflict. - The
resourceVersionfield is a monotonically increasing integer; the client MUST supply the current version in the request body; mismatches are rejected. - Idempotency keys are REQUIRED on all mutating requests; a duplicate idempotency key within the idempotency window (24 h) returns the original result without re-executing.
- State machine is defined such that a COMMIT from state
PENDING_ACCEPTOR_ACCEPTis rejected; the machine enforces ordering regardless of concurrency.
Residual risk: LOW — CAS + idempotency keys eliminate the double-commit window.
Related threats: T-12 (Double-Commitment Race), API5.
AC-03 — Stale Decision Replay
Section titled “AC-03 — Stale Decision Replay”Goal: Re-apply an old ACCEPT or COMMIT action on a MatchDecision that has since moved to a terminal state (REJECTED, EXPIRED, or COMMITTED), resurrecting a dead commitment.
Preconditions:
- Attacker captured a valid signed ACCEPT request from a prior session.
- The MatchDecision has since been REJECTED by the counterparty or has EXPIRED.
Attack steps:
- Re-send the captured ACCEPT request verbatim, using the original idempotency key, or with a new idempotency key to bypass the idempotency cache.
- If the broker does not validate terminal state transitions, the decision is incorrectly re-activated.
- Attacker now holds a fraudulently re-activated commitment.
Protocol controls:
- State machine explicitly defines terminal states (
REJECTED,EXPIRED,COMMITTED,CANCELLED). Transitions into or from terminal states are PROHIBITED; any attempt returns409 ConflictwithcurrentStatein the error body. - The
resourceVersionin the replayed request will not match the current version of the terminal record; CAS rejects the transition. - Idempotency key cache stores the terminal outcome; a replay within the cache window returns the original rejected/expired response.
- Webhook delivery timestamps are validated against a 300 s window; replayed webhook events are discarded.
Residual risk: LOW — terminal state + versioned CAS prevents resurrection.
Related threats: T-04 (Replay Resistance), API5.
AC-04 — Scope Elevation
Section titled “AC-04 — Scope Elevation”Goal: Perform an operation (e.g., COMMIT a MatchDecision, write an OutcomeReport) using a
token that was granted only a lower-privilege scope (e.g., matches:read).
Preconditions:
- Attacker holds a valid JWT with a read-only scope.
- Attacker understands the API surface sufficiently to craft valid request payloads.
Attack steps:
- Obtain a
matches:readtoken (e.g., through a compromised read-only service account). - Issue a POST to
/match-decisions/{id}/acceptwith a valid body, expecting the broker to validate only authentication and not scope. - If scope validation is missing or misimplemented (e.g., only checking for any valid token), the ACCEPT succeeds with a read scope.
Protocol controls:
- Each endpoint declares a minimum required scope in the authorization matrix; the
middleware MUST reject requests where the token’s
scopeclaim does not include the required scope before any handler logic runs. - Scope check is performed BEFORE ownership check to avoid information leakage about valid IDs.
- Scope strings are exact-match only;
matches:readdoes NOT implymatches:decide. - The 9 PCX scopes form a non-hierarchical flat set; there is no implicit scope inheritance.
Residual risk: LOW — flat non-hierarchical scope set eliminates implicit elevation.
Related threats: T-03 (Token Audience and Scope Validation), API5.
AC-05 — Relationship Flood
Section titled “AC-05 — Relationship Flood”Goal: Exhaust broker storage and processing capacity by creating a large number of PartnerRelationship invite records, consuming quota or triggering notification storms.
Preconditions:
- Attacker holds a valid JWT with
relationships:managescope. - Attacker can generate many distinct target
organizationIdvalues (real or fabricated).
Attack steps:
- In a tight loop, issue POST
/partner-relationshipswith a different target organization ID per request. - Each invite creates a pending PartnerRelationship record and triggers a notification to the target organization.
- At scale, this floods the target organization’s notification inbox and consumes broker storage quota.
- Alternatively, flood the same target with repeated invites after each is declined.
Protocol controls:
- Per-organization rate limit on
relationships:managewrite operations (normative minimum: 10 invites per minute, 50 per hour, configurable by broker). - Broker MAY enforce a maximum number of PENDING outbound relationships per organization (recommended cap: 100).
- Duplicate invite detection: a second invite to the same target organization while one is
already PENDING MUST return
409 Conflictrather than creating a second record. - Invite payload is size-limited (64 KiB maximum body); no large embedded documents.
Residual risk: LOW — rate limits and duplicate detection prevent flood at protocol level; brokers tune thresholds per deployment.
Related threats: T-08, API4 (Unrestricted Resource Consumption).
AC-06 — Webhook SSRF
Section titled “AC-06 — Webhook SSRF”Goal: Use the broker’s webhook delivery infrastructure as a proxy to reach internal services (metadata APIs, internal databases, internal admin endpoints) that are inaccessible from the attacker’s network.
Preconditions:
- Attacker holds a valid JWT with
relationships:managescope (webhook URL is set during PartnerRelationship creation or update). - Attacker knows or can guess an internal URL (e.g.,
http://169.254.169.254/latest/meta-data/for AWS IMDSv1, orhttp://10.0.0.1/admin).
Attack steps:
- Register a PartnerRelationship with
webhookUrlset to an internal endpoint URL. - Trigger a protocol event (e.g., capacity published) that causes the broker to deliver a webhook POST to the configured URL.
- If the broker does not validate the URL, the POST reaches the internal endpoint.
- Observe the webhook delivery response payload (echoed back in delivery logs or API response) to exfiltrate internal service responses.
Protocol controls:
- Webhook URL validation at registration time MUST:
- Reject
http://scheme (HTTPS only). - Resolve the hostname and reject if it resolves to: RFC 1918 ranges (10/8, 172.16/12, 192.168/16), loopback (127/8, ::1), link-local (169.254/16, fe80::/10), or cloud metadata addresses (169.254.169.254, fd00:ec2::254).
- Reject URLs with embedded credentials (
https://user:pass@host/).
- Reject
- DNS re-resolution at delivery time with the same blocklist (prevents DNS rebinding).
- HTTP redirect following is PROHIBITED;
3xxresponses cause delivery failure. - Delivery response body is NOT echoed back to the registering organization in API responses or logs (prevents exfiltration).
- Delivery is performed by a dedicated egress process with no access to internal credential stores or metadata endpoints.
Residual risk: MEDIUM — DNS rebinding with short TTLs remains a theoretical vector; bounded by time-limited re-validation on each delivery attempt (TTL floor: 60 s) and isolated egress network segment recommendation.
Related threats: T-05 (Webhook Authentication), API7 (SSRF).
AC-07 — Oversized Payload DoS
Section titled “AC-07 — Oversized Payload DoS”Goal: Exhaust broker memory, CPU, or storage by submitting extremely large JSON payloads, causing out-of-memory errors, parser slowdowns, or disk exhaustion.
Preconditions:
- Attacker holds any valid JWT with a write scope.
Attack steps:
- Construct a JSON body significantly larger than a legitimate resource payload (e.g., 50 MB
CapacityOffer with a large
notesstring or deeply nestedexternalReferencesarray). - POST to any write endpoint (e.g.,
POST /capacity-offers). - If the broker reads the full body before validating size, the parser allocates memory for the entire payload, causing memory pressure or OOM.
- Repeat concurrently from multiple tokens to amplify impact.
Protocol controls:
- API boundary enforces maximum request body size before parsing:
- Standard resources: 256 KiB.
- PartnerRelationship payloads: 64 KiB.
- Requests exceeding limits receive
413 Payload Too Largeimmediately without body parsing.
externalReferencesarray is limited to a maximum of 20 items; each item is a string of maximum 512 characters.- Per-organization write rate limits prevent sustained flood from a single token.
- Schema validation rejects unexpected deeply-nested structures before any business logic runs.
Residual risk: LOW — body-size enforcement at the boundary prevents parser exploitation.
Related threats: T-08 (Oversized Payload Handling), API4.
AC-08 — Decision Policy Bypass
Section titled “AC-08 — Decision Policy Bypass”Goal: Commit a MatchDecision without obtaining the counterparty’s consent, by exploiting a misconfigured or improperly enforced decision policy.
Preconditions:
- Attacker controls one organization in a bilateral PartnerRelationship.
- The PartnerRelationship uses
BILATERAL_REQUIREDdecision policy (the default).
Attack steps:
- Create a MatchDecision as the initiator.
- Issue two ACCEPT requests from two different member accounts of the same organization (not the counterparty), attempting to satisfy the “two-party acceptance” check using own members.
- Alternatively, manipulate the PartnerRelationship
decisionPolicyfield after the relationship is established, changing it fromBILATERAL_REQUIREDtoINITIATOR_ONLY, then issue a single ACCEPT to commit. - Alternatively, find an endpoint that applies the wrong policy for a given decision or skips policy validation on the COMMIT path.
Protocol controls:
- Decision policy is immutable after PartnerRelationship activation; updates to
decisionPolicyare REJECTED with422 Unprocessable Entityonce the relationship is inACTIVEstate. - BILATERAL_REQUIRED state machine evaluates acceptance against the two distinct organization
IDs stored at MatchDecision creation time, not against the calling token’s
org_id. - A second ACCEPT from the same
organizationIdas the first ACCEPT is idempotent and does not advance the state to COMMITTED; state only advances when a distinct secondorganizationIdsubmits ACCEPT. - COMMIT is not a distinct endpoint; it is the implicit result of the second distinct ACCEPT under BILATERAL_REQUIRED. Brokers MUST NOT expose a separate COMMIT endpoint that bypasses policy evaluation.
Residual risk: LOW — policy immutability and org-ID-based evaluation eliminate the bypass paths above.
Related threats: T-12, API5 (Broken Function Level Authorization), API6.
AC-09 — Audit Trail Poisoning
Section titled “AC-09 — Audit Trail Poisoning”Goal: Insert false, modified, or deleted entries into the audit log to conceal unauthorized actions or frame a legitimate organization.
Preconditions:
- Attacker has write access to the audit log via application-layer API (no direct DB access).
- Alternatively, attacker has compromised an application service account.
Attack steps:
- Issue API calls that normally generate audit events, then attempt to DELETE or PATCH the corresponding audit log entries via the API.
- Submit a crafted OutcomeReport with a forged timestamp to backdate an event.
- Issue audit events using a legitimate token to falsely attribute actions to a different organization member.
- Flood the audit log to push older genuine entries out of the retention window.
Protocol controls:
- Audit log entries are append-only; there is no DELETE or PATCH endpoint for audit records.
- Audit entries are written by the protocol service itself, not accepted from clients; clients cannot inject audit entries directly.
- Each audit entry includes the server-generated
createdAttimestamp and the token’ssubclaim; client-supplied timestamps are ignored. - Audit entries include a cryptographic chaining hash (SHA-256 of previous entry + current payload) to detect gaps or insertions.
outcomes:reviewscope provides read-only access to audit records; no write scope exists for the audit log API.- Retention window is enforced by the broker; volume-based flooding is bounded by write rate limits and storage quotas.
Residual risk: LOW — append-only + chained hashes make tampering detectable.
Related threats: T-09 (Sensitive Log Redaction), API6.
AC-10 — Token Audience Confusion
Section titled “AC-10 — Token Audience Confusion”Goal: Use a JWT issued for one PCX service (e.g., a reporting service) to authenticate against a different PCX service (e.g., the core broker API), gaining unintended access.
Preconditions:
- Attacker holds a valid JWT with a broad or wrong
audclaim. - Multiple PCX services share the same signing key or the broker does not validate
aud.
Attack steps:
- Obtain a JWT issued for
aud: pcx-reporting.example.comwith broad scopes. - Present this token to the core broker API at
pcx-broker.example.com. - If the broker validates signature only (not
aud), the token is accepted and the attacker gains access to broker resources. - Alternatively, obtain a JWT issued for an internal service-to-service call (e.g., a batch
job with
capacity:publishscope) and use it to publish capacity offers on behalf of an organization the batch job should not control.
Protocol controls:
- The broker MUST validate that the
audclaim contains its own service identifier (a non-guessable URL or URN configured at deployment time). - Tokens with
audthat does not exactly match (or contain) the broker’s expected audience are rejected with401 Unauthorizedbefore scope or org checks run. - Service-to-service internal tokens MUST use a separate
audvalue that is not accepted by the external broker API. - JWKS endpoint is pinned at configuration time; dynamically discovered JWKS endpoints are PROHIBITED without explicit allow-listing.
- The
org_idclaim in the token ties every authorized action to a specific organization; even a valid broad-scope token cannot act for an organization it was not issued for.
Residual risk: LOW — strict aud validation at the gateway eliminates cross-service reuse.
Related threats: T-03 (Token Audience and Scope Validation), API2 (Broken Authentication).
Risk Summary
Section titled “Risk Summary”| AC ID | Abuse Case | Residual Risk | Status |
|---|---|---|---|
| AC-01 | UUID guessing | NEGLIGIBLE | ACCEPTED |
| AC-02 | Double-commitment race | LOW | ACCEPTED |
| AC-03 | Stale decision replay | LOW | ACCEPTED |
| AC-04 | Scope elevation | LOW | ACCEPTED |
| AC-05 | Relationship flood | LOW | ACCEPTED |
| AC-06 | Webhook SSRF | MEDIUM | ACCEPTED — DNS rebinding residual; time-bounded re-validation required |
| AC-07 | Oversized payload DoS | LOW | ACCEPTED |
| AC-08 | Decision policy bypass | LOW | ACCEPTED |
| AC-09 | Audit trail poisoning | LOW | ACCEPTED |
| AC-10 | Token audience confusion | LOW | ACCEPTED |
No unresolved CRITICAL or HIGH findings.
The single MEDIUM residual risk (AC-06 DNS rebinding) is accepted with the requirement for
a 60-second TTL floor and an isolated egress network segment. This risk is reviewed at M002
(webhook delivery implementation milestone).