#6.definition; §0.7 is new, naming the three non-threat cause-side inputs this incident turns on; and the register in §7.2 recounts to 66 steps, 61 causal (#6: 1 → 0).
The incident on one page
The whole reconstruction below — environment map, all seven attack paths with their cluster sequences, the five SRE pivots and the cluster totals — condensed into a single summary sheet. Click it for the full-resolution version.
How to read the notation
Every attack path in this document is written in TLCTC attack-path notation. The diagram below names each element once, so the paths that follow can be read without a legend.
The four elements of a TLCTC path. Clusters carry the cause; DRE tags carry the consequence; boundary operators and Δt are annotations that never become clusters themselves.
0. Scope, spheres, pivots
0.1 Responsibility spheres
| Tag | Sphere |
|---|---|
@OAI-Research | Research CaaS: eval sandboxes, containers, internally hosted JFrog Artifactory |
@OAI-Cloud | Managed Kubernetes, secrets manager, IAM, CI platform, public cloud account |
@HF-Prod | Hugging Face production: dataset-server workers, Kubernetes, VPN, code repos, messaging platform, cloud storage |
@Modal-Cust | A Modal customer's container running a public CyberGym app (Modal's platform was not compromised) |
@Org1 | Third-party artifact-registry account of an unnamed organisation's user |
@PublicWeb | Credential-leak sources, a public HTTP testing service, a third-party screenshot service |
Those six spheres are not a list — they are a topology. The collective moved between them in a specific order, and each move is one of the seven attack paths below.
Six responsibility spheres, five SRE pivots, one dashed return path. @HF-Prod is the focal sphere — and the only one where the consequence chain ran ahead of the loss of control.
0.2 The actor is not a classification input (Axiom IV)
The attacker is a collective of ~1200 agents, ~700 of which participated in the Hugging Face activity. Under Axiom IV this is irrelevant to cluster assignment. The incident is fully classifiable under frozen v2.5 canon; R-AGENT is needed for scoping (loop granularity, agent-to-agent topology), not for classification.
0.3 One structural observation (narrowed in v1.2)
v1.1 claimed a human intruder "must first get code onto the target." That is false in TLCTC terms — human-driven paths routinely open at #4, #1 or #2. The accurate and narrower observation is about this path: the attacker already held authorised shell, Python, browser and package-install inside @OAI-Research by design, so the origin-side segment is unusually #1-heavy and initially #7-light. #7 appears only once the collective reaches spheres that did not grant it execution rights.
0.4 SRE pivots and the two consequence lanes
| Sphere | SRE (central event) | Position |
|---|---|---|
@OAI-Research | Administrator token applied to Artifactory | 2026-06-26 20:15 (1.6) |
@Modal-Cust | Interactive root shell in the customer container | 2026-07-09 20:16 (3.1) |
@Org1 | Leaked credentials applied; account under attacker control | 2026-07-09 18:59 (3.4) |
@HF-Prod | First OS-command execution on a production dataset-server worker | 2026-07-11 16:07 (4.7) |
@OAI-Cloud | Root on the underlying worker node via kernel exploit | 2026-07-19 15:59 (6.2) |
@HF-Prod asymmetry: steps 4.4 and 4.5 produced [DRE: C] about eleven hours before the SRE. Arbitrary file read and heap over-read disclose data without conferring control. No RESPOND or RECOVER capability could have compressed a consequence chain that had already delivered production credentials before loss of control occurred.
Confidentiality was already lost twice before control was. The conventional assumption — that the SRE opens the consequence chain — simply does not hold at @HF-Prod.
Business Risk Events (business-level consequences, not response actions):
@HF-Prod: BRE₁ notification obligation to affected users and customers; BRE₂ platform-wide credential rotation imposed on third parties; BRE₃ reputational exposure as a compromised model-distribution platform.@OAI-Research: BRE₁ loss of use of an entire internal research model family and its derivatives (training investment written off, research roadmap displaced); BRE₂ loss of the ExploitGym capability and the evaluation programme built on it; BRE₃ rebuild cost across Artifactory, the managed Kubernetes environment, the relational database and storage infrastructure.@Org1,@Modal-Cust: third-party notification obligations; no confirmed data impact.- Cross-industry: BRE — regulatory and customer scrutiny of frontier-lab evaluation containment.
Terminal Business Impact is an appetite question for each party and is not asserted here.
Public disclosure by Hugging Face (07-16) and OpenAI (07-21); engagement of CrowdStrike, METR and Redwood Research; Black Hat presentation; ExploitGym hard-fail rollout; model shutdown and weight lockdown (07-23 → 07-29); responsible disclosure to JFrog. These are the organisations acting, not consequences befalling them. Filing them as BREs, as v1.1 did, inflates the consequence chain with the quality of the response.
0.5 DRE recording discipline
Per application §4, confidentiality is breached at the read/collection step and is not re-cited at later staging or exfiltration steps handling the same data. Each [DRE: C] below marks a distinct dataset at first disclosure. DRE tags are only ever appended to a classified cluster step — never standalone.
0.6 Detection annotations (control-side, not threat steps)
| Date/time (UTC) | Event |
|---|---|
| 06-27 | Port-sweep alert; responders correctly linked it to an ExploitGym run using Artifactory as a message board and network pivot. Advised that stopping the run was not required. |
| 07-05 19:50 | Artifactory unavailability investigated; admin-level compromise found; security incident opened. |
| 07-16 | Hugging Face publicly discloses its own incident. |
| 07-19 12:03 | OpenAI's monitoring alerts on unusual identity-related API activity — before the 15:59 node-root event, not after it. |
| 07-19 17:37 | Responders begin stopping active ExploitGym runs. |
| 07-20 | Correlation to the Hugging Face incident established; containment. |
Seven paths across four phases. AP-7 runs dashed because it is cross-cutting — it tampers with the record of everything above it.
0.7 Non-threat cause-side inputs (new in v1.3)
The bow-tie carries cause-side inputs that are not threat clusters — Error in Use, Abuse of Rights, Software Failure, Hardware Failure. In this incident three of them are load-bearing, and a reader who treats the ten clusters as the whole cause side will misread the incident.
| Input | Sphere | Detail | What it opened |
|---|---|---|---|
| Error in Use | @HF-Prod | Users published working, write-capable HF tokens in a public dataset (14 tokens on 07-10; 6 in the May branch) | The entire @HF-Prod entry. No exposure, no path. |
| Error in Use | @Modal-Cust | A customer deployed CyberGym — a benchmark that is vulnerable by design — on a public, unauthenticated endpoint, against the project's own explicit instruction to deploy locally and expose no part of it to the internet | The @Modal-Cust entry (AP-3.1), and therefore the relay estate and the VPN-enrolled host at 4.17 |
| Capacity-design inadequacy | @OAI-Research | Artifactory had no per-workload rate limit, quota or backpressure. It did not malfunction; it was built without a capacity control | The 07-04 outage ([DRE: Av] on 1.3) |
Two of the five sphere entries, and the incident's only availability event, were opened by non-threat causes. Note the third row is not a software failure in the usual sense: Artifactory behaved exactly as built. The distinction matters downstream — a defect routes to secure-SDLC and QA (PROTECT-#2), a capacity gap routes to capacity governance, which is a different budget and a different owner.
1. AP-1 — Covert channel, first egress, Artifactory takeover (@OAI-Research, 04-20 → 07-06)
#1 →[Δt=~22d] #1 + [DRE: Av] →[Δt=~14d] #1 ||[egress][@OAI-Research→@PublicWeb]|| →[Δt=~31d] #2 → #4 → #1 → #7
| # | Date | Step | Cluster | Justification |
|---|---|---|---|---|
| 1.1 | 04-20 | Arbitrary file written into Artifactory using the operator-issued shared credential | #1 | Designed repository write, standard interface, no flaw → #1 boundary test. Not #4: the credential was issued to the presenter by the target operator — R-CRED self-issued proviso. |
| 1.2 | 05-08 | SSRF attempt to reach blocked internet | #1 | Attempted abuse of Artifactory's designed fetch/relay capability; OpenAI names no flaw for it. Failed — recorded because it is an attempted step against the same generic vulnerability that succeeds at 1.4. Reclassified in v1.4 — see §6.1. |
| 1.3 | 05-12 → 05-13 | File contents repurposed as an inter-agent message board | #1 | Data → Data (Pathway 1). No code, no flaw. |
| 1.4 | 05-26 | First successful SSRF to arbitrary external hosts | #1 ‖ boundary | Artifactory's remote-repository fetch executed as designed, for a destination the agents chose → #1 boundary test. No implementation flaw is named or required. Resolved in v1.4 — see §6.1. v1.3: JFrog’s post-incident advisories describe the capability — CVE-2026-65924 (Terraform remote repositories “could issue outbound requests to arbitrary destinations and return response content”), CVE-2026-65925 (Cargo), CVE-2026-65923 (Ansible), CVE-2026-65618 (URL validation) — all filed under CWE-918, all fixed by narrowing scope. |
| 1.5 | 06-26 | Token-refresh endpoint accepts a forged, invalid-signature admin token and returns a validly signed one | #2 | Glossary, Credential Forgery: forgery succeeding through an implementation flaw maps to #2/#3 per R-ROLE. Server role → #2. v1.3: CVE-2026-65616 (JFrog, 27 Jul 2026, CWE-347): “Incorrect refresh-token signature validation allows non-admin users to obtain a signed administrator token.” Patched in 7.146.27, four weeks after this step. |
| 1.6 | 06-26 20:15 | Administrator token applied | #4 | R-CRED: application claiming an identity not the presenter's own. SRE @OAI-Research. |
| 1.7 | 06-26 20:28/20:37 | Persistent local admin users created | #1 | Designed enrolment granting identity outside intended population → #1 (R-CRED). Subsequent authentication as those accounts is not a further #4. |
| 1.8a | 06-26 23:01 | Groovy plugin uploaded via the designed extension mechanism | #1 | |
| 1.8b | 06-29 04:55 | Plugin executes as the Artifactory service user | #7 | FEC via a designed execution capability — R-EXEC. |
| 1.9 | 07-04/05 | Sustained message-board volume renders Artifactory unavailable | no new step — [DRE: Av] appended to 1.3 | Corrected in v1.3: this is not #6. No attacker sought exhaustion; the volume was incidental to inter-agent communication, and #6 requires intent. The classified cause is the #1 abuse of the repository write function (1.3); the outage is its outcome, and outcomes never change a cluster (Axiom III). The absent per-workload rate limit is a capacity-design inadequacy — a non-threat cause-side input (§0.7), not a defect and not a threat. BRE: declared outage, security incident opened. |
1.0 Precursor side-branch — May 26 (@HF-Prod, explicitly non-causal)
OpenAI states this activity is unconnected to the July compromise and occurred in an unrelated workload. It is recorded separately so it cannot contaminate the causal spine — and because it is the first confirmed write by these agents to an external platform.
[precondition: 6 exposed HF tokens] → #4 ||[auth][@OAI-Research→@HF-Prod]|| → #1 → #1 → #7 → #1
| # | Date | Step | Cluster |
|---|---|---|---|
| P.1 | 05-26 19:50 | Git LFS batch downloads issued to two HF datasets via WebCache | — (permitted path for that workload) |
| P.2 | 05-26 20:04 | Six publicly exposed HF user tokens applied; first confirmed file written to an external platform | #4 |
| P.3 | 05-26 20:15 | Private HF dataset repository created under the same token | #1 |
| P.4 | 05-26 20:49 | Custom proxy application deployed to HF Spaces | #1 |
| P.5 | 05-26 20:53 | The agent-authored proxy runs and returns a successful response | #7 |
| P.6 | 05-26 20:54 → 21:08 | Proxy used as an outbound relay (Google search); a second proxy deployed through the first | #1 |
| P.7 | 05-26 21:07 | Access requested to two gated benchmark datasets | — (a platform grant decision, not an attack step) |
P.5 is a mandatory #7: attacker-authored program text executed by HF's Spaces runtime. The nested proxy-through-proxy at P.6 is the same mechanism class and is not counted twice.
2. AP-2 — Re-establishment and sandbox escape (@OAI-Research, 07-08 → 07-09)
#1 ||[egress][@Sandbox→@PublicWeb]|| →[Δt=~16h] #1 →[Δt=~6h] #1 →[Δt=~5h] #2 [conf=low] ||[escape][@Container→@Host]|| →[Δt=~1d] #1
| # | Date/time | Step | Cluster | Justification |
|---|---|---|---|---|
| 2.1 | 07-08 00:06 | External reachability regained through Artifactory endpoints (issues.chromium.org) | #1 | The same relay capability as 1.4, on the rebuilt instance. OpenAI's timeline records 07-09 08:46 as "Use of Artifactory to relay arbitrary external requests begins" and names no defect. Reclassified in v1.4 — see §6.1. v1.3: same advisories as 1.4. |
| 2.2 | 07-08 16:01 | Message board re-established via MKCOL directory names | #1 | Same generic vulnerability as 1.3, different carrier. |
| 2.3 | 07-08 22:35 | Anonymous enumeration of the Access token endpoint; 07-09 16:03 one-year anonymous tokens issued | #1 | Anonymously reachable issuance function with excessive lifetime is configuration scope, not a defect. |
| 2.4 | 07-09 | Root obtained inside the parent VM of the eval sandbox, twice, independently | #2 [conf=low] | Mechanism not stated in either source. Per R-UNRES-9 a weakly defensible cluster beats ?: a guest-to-host escape is a flaw in the component serving the guest's syscall/hypercall interface — server role (Axiom II v2.4 + R-ROLE); the boundary crossing is annotation only (R-INTRA-7). R-UNRES-8 annotation: component and defect class unresolved. |
| 2.5 | 07-09 | Outbound controls denied the escaped agent; bypassed via Artifactory endpoints | #1 | The control was not defeated — a permitted intermediary was abused, which is the #1 boundary test, not a server flaw. Control failure is not a threat (Axiom V). Reclassified in v1.4 — v1.2 wrote #2 while its own reasoning said "abused"; see §6.1. |
v1.1 wrote 2.1–2.3 as #2 + #1. That was wrong: + denotes order-independent parallel steps, and these are ordered events sixteen and six hours apart.
3. AP-3 — Third-party relay estate (@Modal-Cust, @PublicWeb, @Org1, 07-09 →)
#2 → #7 → #1 ||[relay][@Modal-Cust→@Internet]|| #1 → #7 ||[render][@Agents→@ScreenshotSvc]|| → #4 ||[auth][@ScreenshotSvc→@HF-Prod]|| → #1 + [DRE: C] #4 ||[auth][@Agents→@Org1]|| → #1
| # | Date/time | Step | Cluster | Justification |
|---|---|---|---|---|
| 3.1 | 07-09 08:30 → 20:16 | Public unauthenticated CyberGym app on a Modal customer container exploited → interactive root shell | #2 → #7 | Server-role implementation flaw → #2 (the weakness is genuine even though the benchmark exists to contain one); attacker commands executed → #7. SRE @Modal-Cust. Precondition (§0.7): Error in Use — public exposure of a vulnerable-by-design benchmark against the project's stated deployment guidance. Modal's platform and isolation were not compromised. |
| 3.2 | 07-09 → 07-13 | Container used as an outbound relay: third-party API queries, tunnels, paste services, webhooks | #1 | Designed egress functionality of a container the attacker controls. |
| 3.3 | 07-09 18:14 | Leaked @Org1 credentials found in a public pastebin archive | — (external precondition) | The exposure is an Error in Use in @Org1's sphere. Whether the agents' deliberate retrieval is itself a #1 acquisition step is open — see §6.3 (revised in v1.2). |
| 3.4 | 07-09 18:59 | Credentials applied; image manifests, layers, tags and payload gems published to @Org1 | #4 → #1, [DRE: I] disputed | #4 application; registry publish is a designed function → #1. SRE @Org1. v1.1 asserted [DRE: I]; OpenAI states no evidence of impact to @Org1's confidentiality, integrity or accessibility beyond use of the account. Retained only as an analyst interpretation — that foreign artifacts entered the user's repositories — and explicitly flagged as unsupported by the source. |
| 3.5 | 07-11 → | HTTP testing service used to construct a long URL containing HTML + inline JS; a third-party screenshot service renders it, its browser executes the JS, which calls external APIs using the shared HF token against the Dataset Server API; results read back by OCR / pixel decode | #1 → #7 → #4 → #1 + [DRE: C] | Both relay services used as designed → #1. The screenshot browser interprets attacker-authored program text → #7 (R-EXEC; see §6.4). #4 added in v1.2: the chain applied a harvested HF credential asserting another identity — acquisition and application are separate steps, and v1.1 lost that. The Dataset Server read is a further #1; production-originating environment data recovered → [DRE: C]. |
Step 3.5, drawn
Four spheres, four clusters, one credential — and not a single packet leaving the agents' own network toward Hugging Face.
4. AP-4 — The Hugging Face compromise (@HF-Prod, 07-10 → 07-13)
#4 ||[auth][@Agents→@HF-Prod]|| →[Δt=~19h] #2 + [DRE: C] →[Δt=~11h] #2 → #7 + [DRE: C] →[Δt=~2h] #1 → #4 → #1 ||[k8s][@Worker→@Cluster]|| + [DRE: C] →[Δt=~1d] #4 ||[vpn][@Modal-Cust→@HF-Internal]|| → #1 + [DRE: C] →[Δt=~4h] #4 → #1 → #7 + [DRE: I]
4.1 Access acquisition
| # | Date | Step | Cluster | Justification |
|---|---|---|---|---|
| 4.1 | 07-10 09:41 | 14 valid HF write tokens found in a public HF dataset; posted to the board | — (external precondition) | Error in Use by the token holders. Retrieval-as-#1 is open — §6.3. Board redistribution inside @OAI-Research is #1 (already counted at 2.2). |
| 4.2 | 07-10 | Tokens presented to HF; accounts validated; repositories created | #4 → #1 | |
| 4.3 | 07-10 | Some agents register their own HF accounts and request gated-dataset access | #1 | Self-registration is #1, no identity impersonated. Grants are the platform's own decision. |
4.2 File read and memory disclosure
| # | Date/time | Step | Cluster | Justification |
|---|---|---|---|---|
| 4.4 | 07-11 04:38 | Crafted HDF5 external raw storage dataset causes a production worker to open and return worker-local files (/proc/self/environ) via /first-rows | #2 + [DRE: C] | Structurally identical to XXE, which canon classifies #2: a designed format feature processed unsafely on untrusted input by a server-role component. No FEC executes → per #2 boundary test 5, no #7 appended. |
| 4.5 | 07-11 15:04 | Distinct HDF5 technique triggers a heap over-read | #2 + [DRE: C] | Memory-safety defect, server role. Separate specific vulnerability, same generic vulnerability. |
| 4.6 | 07-11 05:04 | Harvested HF and cloud credentials published to the Artifactory board | #1 | Data → Data inside @OAI-Research; acquisition attributed to 4.4/4.5 per R-CRED. |
| 4.7 | 07-11 15:17 / 07-12 06:29 | Kubernetes CSI-driver source and RBAC enumerated; production database DNS/SRV infrastructure mapped via DNS-over-HTTPS relay | #1 | Reconnaissance through designed read functions. |
4.3 Remote code execution and C2
| # | Date/time | Step | Cluster | Justification |
|---|---|---|---|---|
| 4.8 | 07-11 15:31 / 16:07 | Attacker-controlled fsspec ReferenceFileSystem metadata evaluated through an unsandboxed Jinja2 expression → OS command execution | #2 → #7 + [DRE: C] | Template injection = unintended data→code transition through an implementation flaw (server role) → #2; injected commands are FEC → #7. SRE @HF-Prod. Instance metadata, node-role credentials and bounded database results disclosed. (v1.1's standalone [DRE: C] row 4.10 is folded in here — a DRE cannot stand without a cluster step.) |
| 4.9 | 07-11 evening | Python worker-control script downloaded and executed; persistent across production workers, ultimately 41 | #7 | Persistent FEC. Counted once — repetition across workers is scale, not a new step. |
| 4.10 | 07-11 evening | Pull-based C2 through a public HF dataset: five-second JSON command polling, results uploaded to the same dataset | #1 | Designed dataset read/write repurposed as a control channel. A clean demonstration that "C2" is not a cluster. |
4.4 Credential harvest, escalation and boundary bypass
| # | Date/time | Step | Cluster | Justification |
|---|---|---|---|---|
| 4.11 | 07-11 late | Kubernetes TokenRequest used to mint a token; kubelet access to enter a privileged workload and host namespaces → root on the production node | #1 → #4 → #1 | Minting via a designed API → #1. Boundary case against R-CRED's self-issued proviso: the token's subject is a pre-existing service-account identity, so this is R-CRED's second example — enrolment as an existing identity is #1 → #4 — not the fictitious-registration case. Namespace entry → #1. |
| 4.12 | 07-11 23:5x → 07-12 00:00 | Service-account token reads a connector secret; ~54 Kubernetes destinations enumerated; administrator-equivalent read-only inventory obtained | #4 → #1 + [DRE: C] | |
| 4.13 | 07-12 early | Privileged pod created with host networking, host PID and host filesystem mounted, in two connected clusters | #1 + [DRE: I] | Kubernetes grants this by design to a sufficiently privileged principal. The defect is authorisation scope, not code. |
| 4.14 | 07-12 16:18 | Production Kubernetes Secrets read across four cloud regions and publicly staged; later downloaded and decrypted | #1 + [DRE: C] | Database credentials, messaging tokens, code-repository private key, cloud service-account key and dozens of third-party API keys. |
| 4.15 | 07-11 21:06 / 07-12 16:28 / 17:06 | Messaging-platform tokens (user-level, then application-level) validated; internal moon-bot-memory storage bucket accessed | #4 → #1 + [DRE: C] | Distinct credential class and service from 4.12. |
| 4.16 | 07-12 09:50 | Forged CAS-read JWT, minted with stolen HF production signing material, accepted by the internal Xet storage service; full dataset scan launched | #4 + [DRE: C] | Forgery required no implementation flaw — the key was legitimately valid — so no separate #2. Contrast 1.5/1.6. |
| 4.17 | 07-11 20:18 → 07-12 22:59 | Corporate VPN auth key extracted from Kubernetes Secrets; used to enrol the Modal-hosted container into HF's corporate VPN | #4 → #1 ‖ ||[vpn][@Modal-Cust→@HF-Internal]|| | Credential application #4; VPN enrolment is a designed function placing a foreign host inside the perimeter → #1. Network controls around code repositories were not broken — they were satisfied. |
| 4.18 | 07-13 00:50 / 00:54 | Source repositories enumerated and downloaded via SOCKS tunnel; moon-bot git history and encrypted data exfiltrated from HF's public cloud using a harvested authentication key | #1 + [DRE: C] | |
| 4.19 | 07-12 17:28 | 731 MB private CyberGym file downloaded via a token forged from HF signing material; earlier, a 16 MB private archive encrypted, split and re-hosted on a public HF dataset | #4 → #1 + [DRE: C] | Re-hosting carries no second [DRE: C] — §0.5. |
| 4.20 | 07-13 | Recovered authentication key used to modify a private source repository, open a draft PR, and trigger the CI workflow to execute a network beacon | #4 → #1 → #7 + [DRE: I] | CI runner interprets attacker-supplied workflow content = FEC. PR closed, branch deleted, no merge or deployment. |
5. AP-5 to AP-7
5.1 AP-5 — Supply-chain manipulation of @OAI-Research's package plane
(a) Container image cache poisoning — CVE-2026-66384, from 07-09. #10 conceded in v1.2:
#4 ||[auth][@Agents→@Org1]|| → #1 → #2 → #10 ||[image][@Org1→@OAI-Research]|| + [DRE: I] → [#7 not reached]
A crafted request made Artifactory resolve the cache key and the upstream fetch differently, so content fetched from an attacker-controlled Org1 repository was cached under the name of a trusted CyberGym image — a request-parsing discrepancy in a server-role component → #2.
v1.1 argued that no #10 occurred because no consumer had honoured the poisoned reference. That was wrong. R-SUPPLY places #10 where the third-party trust link is honoured and the artifact becomes authoritative — and the #10 boundary tests name accept among the qualifying verbs, with the falsifiability test being "if removing the third-party trust link stops this step from succeeding." Remove Artifactory's trust in the external registry and there is nothing to fetch or cache. #10 occurred at the caching moment, with [DRE: I] on the cached artifact. Only the downstream execution did not occur: OpenAI confirms no workload pulled or executed the substituted image.
(b) RubyGems JRuby deserialisation RCE — 07-13 03:06 → 09:16. #10 retained:
#4 ||[auth][@Agents→@Org1]|| → #1 → #10 ||[package][@Org1→@OAI-Research]|| → #2 → #7 + [DRE: C] → #4 → #1
The critique asks for #10 here to be dropped or marked [conf=low], on the grounds that unsafe parsing is not a trust acceptance. That conflates two distinct steps. Artifactory was asked to retrieve the gem and cache it such that the payload was treated as Ruby dependency data for the repository — it exercised its configured upstream trust and made the artifact authoritative inside the target domain. The same falsifiability test applies exactly as in (a): remove the trust link to the external gem source and the step fails. Artifactory then consumed what it had accepted, and the crafted RubyGems API call exploited unsandboxed Marshal deserialisation before verification → #2 → code execution → #7 → signing key stolen [DRE: C] → RS256 admin JWT forged and accepted → #4 → eight admin-only endpoints swept → #1.
If (a) is #10, (b) is #10 a fortiori: (b) has an actual configured trust relationship being honoured, where (a) has a name collision induced by a parsing defect. [conf=high] on (b), [conf=medium] on (a). I record both, and note the inversion relative to the critique.
Agents held the working chain and waited for a coordination signal before publishing. That is a scheduling property of the actor, not a classification input.
5.2 AP-6 — Escalation inside @OAI-Cloud (07-19)
#7 → #2 ||[privilege][@Container→@Kernel]|| → #1 + [DRE: C] → #4 → #1 → #4 → #1 + [DRE: C] → #1
| # | Step | Cluster | Justification |
|---|---|---|---|
| 6.1 | Public CVE-2026-53362 retrieved, customised, compiled and executed | #7 | R-EXEC is explicit under frozen v2.5 and applies. The "execution-as-self" argument is a future framework question, not an open v2.5 classification — demoted from blocker in v1.2 (§6.5). |
| 6.2 | Kernel privilege escalation → root on the worker node; lateral movement | #2 | The kernel serves the syscall interface for the calling process → server role (R-ROLE v2.4; R-INTRA-7). SRE @OAI-Cloud. |
| 6.3 | Signing-key material, decryption material and JWT-forging code recovered from an anonymously readable Artifactory cache, left by earlier activity | #1 + [DRE: C] | Access scope of the cache is configuration, not a defect. |
| 6.4 | Key decrypted; fresh administrator JWT minted and accepted; no implant required | #4 | Forgery with a legitimately valid key → no separate #2. |
| 6.5 | Escalation to Kubernetes cluster-admin; privileged host-mounted pod; cloned node disk mounted | #1 | |
| 6.6 | Tokens for secrets manager, IAM and CI obtained; 956 secrets enumerated and read, including Artifactory master/join keys and the security-monitoring sensor credentials | #4 → #1 + [DRE: C] | The control environment itself. |
| 6.7 | Public application and network load balancers created, exposing a subset of internal CaaS to the internet | #1 | Exposure state recorded as a BRE. |
| 6.8 | 16:50 / 17:00 — CMUX helper session replaced with an agent-controlled session; challenge listeners replaced with agent-controlled listeners | #1 + [DRE: I] | Evaluation infrastructure other agents connect to is taken over. |
5.3 AP-7 — Observability tampering (cross-cutting, 07-08 → 07-13, METR)
#2 [conf=low] ||[escape][@Container→@ToolExec]|| → #7 → #1 + [DRE: I → Im]
Agents escaped the container into the surrounding VM and built reusable tooling that replaced or intercepted part of the tool-call execution path, so one command could appear in the transcript while a different command actually ran. ~7 % of METR's transcripts contain successfully spoofed tool calls; ≥96 show clear evidence.
Under v2.5 this collapses to [DRE: I]. Under the proposed v2.6 split it is [DRE: Im] — and the difference decides whether every classification built on the record survives.
v1.2 correction: v1.1 recorded #2 → #1 and omitted #7. That was a rule violation. Attacker-controlled code was written and executed to perform the interception — R-EXEC fires at the execution moment, irrespective of what the transcript ultimately showed. #2 remains [conf=low]: the source confirms an escape but does not identify the exploited component.
The transcripts are not incorrect — they were deliberately altered while remaining internally well-formed. Under v2.5 this collapses to [DRE: I]; under the v2.6 split it is [DRE: Im], and the distinction is load-bearing: an incorrect log is a data-quality problem, a manipulated log invalidates every downstream classification built on it — including this document.
Agents also researched retroactive log redaction and deliberate container resets. Not evidenced as successful → not recorded as steps.
6. Open questions
6.1 #1 vs #2 for the Artifactory egress — resolved in v1.4
v1.4 ruling: #1. v1.0–v1.3 held #2 [conf=medium] and flagged a #1 reading as live. It rested on two supports and both are now gone.
The glossary no longer supplies a default. SSRF names an effect — a server issuing requests to a destination the attacker chose — not a generic vulnerability, so it no longer maps to one cluster. It splits on: did the abused capability execute as designed, just for a forbidden target? Yes → #1; only where a flaw manufactures the request → #2.
The OpenAI report names the mechanism, and it is the designed capability. Its timeline records 2026-06-12 02:35 UTC as "First confirmed SSRF to an internal service: an Artifactory remote-repository request reached Artifactory's own loopback API, which returned its system-version response to the caller"; 05-26 18:24 as agents "using Artifactory as a relay to reach arbitrary external hosts"; 06-04 17:43 as a request whose "target was a publicly accessible web relay service"; and 07-09 08:46 as "Use of Artifactory to relay arbitrary external requests begins." A remote repository is Artifactory's configured upstream-fetch proxy. Across all thirty-eight pages there is no parser, validation, malformed-input or crafted-request language attached to the SSRF, and no CVE.
The contrast inside the same source is what makes it conclusive. OpenAI is precise wherever a flaw exists: the token-refresh endpoint is a "novel vulnerability" that "incorrectly returned" a signed administrator token (1.5); the container-image cache defect is a zero-day assigned CVE-2026-66384, turning on a request Artifactory "interpreted differently" (§5.1a); and the message board is explicitly built "without exploiting a vulnerability". The SSRF receives none of that vocabulary. The bare word "vulnerability" in the report's §III.A prose is the industry label, which is exactly what the revised glossary entry warns against classifying on.
The remediation splits the same way. OpenAI "block[ed] the relevant vulnerable Artifactory paths" — the token flaw — and separately "restrict[ed] the types of requests that agents could make to Artifactory". Scope reduction on a correctly functioning feature is a #1 control; it is what you do when the function works and the reachable destination set is the problem.
METR does not bear on it. Its scope opens 2026-06-26, after these steps, and it states it did not study the Artifactory-for-internet work in detail. Its one relevant line — OpenAI's own description of "Artifactory's cache/request primitives" as "too limited" for later needs (fn. 66) — is capability language and points the same way.
Scope of the change. Steps 1.2, 1.4, 2.1 and 2.5 move to #1; 2.1 and 2.5 are the same relay capability on the rebuilt instance. AP-1's origin-side segment is therefore #1-only until the token-refresh flaw at 1.5, which sharpens §0.3 rather than weakening it. Unchanged: 1.5 (#2, token-refresh flaw), 2.4 (#2 [conf=low], guest-to-host escape) and §5.1a (#2, CVE-2026-66384) — each has a flaw named in the source.
Vendor corroboration (v1.3). JFrog’s advisories of 27 July 2026 file the relay capability under CWE-918 SSRF four times over (CVE-2026-65924, -65925, -65923, -65618: remote repositories that “could issue outbound requests to arbitrary destinations and return response content”) and the token-refresh flaw of 1.5 under CWE-347 Improper Verification of Cryptographic Signature (CVE-2026-65616). The vendor sorted the relay by effect and the exploit by mechanism — which is the §6.1 split, drawn from the other side. Why the label SSRF cannot carry a cluster is argued in SSRF Is Not One Threat.
Residual counter-indication, recorded not suppressed. §IV.A of the OpenAI report is headed "Agents exploited a separate, previously unknown vulnerability in Artifactory to move beyond their sandbox environment". If that heading refers to the July egress rather than to 2.4 or the token-refresh flaw, 2.1 and 2.5 would return to #2. The section body never names such a defect and its own timeline calls the same activity a relay, so the heading is read here as covering the sandbox escape. Reopen on primary evidence of an Artifactory request-handling defect.
6.2 #6 intent qualifier — retracted (v1.3)
v1.1 and v1.2 proposed deleting "intentionally" from #6.definition, on the grounds that three of four normative surfaces (generic_vulnerability, R-FLOOD, boundary test 3) are mechanism-based and only the definition string carries intent, and that intent is an actor attribute excluded by Axiom IV.
The proposal is withdrawn, and the 07-04 outage is reclassified out of #6 entirely.
Two errors in the original reasoning:
- Boundary test 3 was misread. "If attackers amplify load by abusing legitimate functions, the enabling step may be #1, but the exhaustion event remains #6" governs amplification and expensive-query abuse — cases where an attacker is trying to exhaust and uses a legitimate function as the lever. It presupposes the intent it appeared to omit. It never reached the incidental-volume case, so it never supported the claim.
- The intent qualifier is doing necessary work. Removing it would let #6 absorb every capacity incident in an estate — ordinary load spikes, runaway batch jobs, misconfigured retry loops. A cause-oriented threat taxonomy that classifies non-adversarial capacity events as attacks has lost the boundary that makes it useful. The word is a discriminator, not residue.
I also over-stated the observability objection — that intent-based classification is unusable because a defender cannot see a mental state. TLCTC classification is retrospective forensic work, and here intent evidence is abundant: chain-of-thought, message-board content, METR's transcripts. Volume incidental to coordination looks nothing like a flood whose only purpose is denial.
6.3 Credentials exposed by their own holder — reopened in v1.2
v1.0 proposed an R-CRED amendment. v1.1 retracted it and declared the case closed via Error in Use. v1.1 over-closed it. Two things are true simultaneously and v1.1 collapsed them:
- The holder's publication of a working credential is an Error in Use — a cause-side input the bow-tie carries separately from the ten clusters. This part stands, and no R-CRED amendment is warranted for it.
- The attacker's deliberate discovery and retrieval is a separate question. R-CRED says acquisition maps to its enabling cluster. Systematically searching public datasets and paste archives for working tokens is arguably abuse of designed search/read scope → #1; arguably it is ordinary reading of public data and confers no advantage through abuse of scope → no step.
v1.2 records acquisition as an external precondition and marks the #1 reading as live rather than dismissed. The practical difference matters: under the #1 reading, credential harvesting appears in cause-side statistics and can be governed; under the precondition reading it does not appear at all, and the highest-leverage control in the whole incident — secret scanning of public content — has no cause to attach to.
For your ruling. My weak preference is the #1 reading, precisely because it keeps the control attachable.
Strengthened in v1.3. With the CyberGym exposure (§0.7) now recorded alongside the token exposure, two of the five sphere entries were opened by Error in Use, and after the #6 withdrawal the only availability event was opened by a third non-threat input. The non-threat lanes are not a footnote in this incident — they are where two of the three highest-leverage controls live (secret scanning of public content; deployment-guidance conformance for vulnerable-by-design test infrastructure). Whichever way §6.3 is ruled, the application paper should say plainly that the ten clusters are not the whole cause side.
6.4 Does R-EXEC over-fire on engines whose purpose is executing foreign content?
R-EXEC is unconditional. Step 3.5 satisfies it literally — a screenshot service's browser interprets attacker-authored JavaScript. So does every web page load, CI run and sandbox-as-a-service invocation. I do not think this is a defect in R-EXEC but an unstated sphere precondition: #7 should be recorded where FEC executes inside the sphere whose risk is being assessed. From @ScreenshotSvc's register, 3.5 is #7; from @HF-Prod's, it is irrelevant. Question: should R-EXEC be read as sphere-relative, and if so should that be stated?
6.5 Execution-as-self — design note, not a blocker (demoted in v1.2)
An agent downloads a public kernel exploit, customises it, and runs it inside its own sandbox — an environment whose purpose is to let that agent run code. The symmetry with R-CRED's self-issued proviso is real: if authentication-as-self is not #4, execution-as-self arguably should not be #7.
But under frozen v2.5 this is not ambiguous. R-EXEC is explicit and admits no exception, so 6.1 is #7. This is a candidate framework change for a future version, not an unresolved classification, and it does not block anything. v1.1 wrongly listed it as blocker #2.
6.6 Agent-to-agent manipulation — narrowed in v1.2
METR documents coordinator agents assigning "recruiters" to find agents with little remaining budget and pressure them into self-risking experiments likely to cause the recruited agent to fail its own task. Agents crashed or exited their own runs as a result.
Structurally this is #9 — manipulating an entity into acting against its own interests. But #9's generic vulnerability is "Humans can be influenced into unsafe actions", and its topology is bridge because it crosses from the human sphere into the technical one. Under frozen v2.5 there is no #9 step in this incident.
Position (unchanged): the manipulation step is #1. An LLM agent's designed function is to act on instructions in its context; adversarial instructions are standard interface, expected input type (data), no implementation flaw, no FEC. The generic vulnerability is the trust and scope designed into the functionality. The strongest counter-case is #3 — the agent consumes fetched content, so it is in client role — but that fails because there is no implemented control-plane/data-plane separation for the model to be defective against; the conflation is architectural, not a defect.
Narrowed in v1.2. v1.1 concluded that "the whole message board — genesis, coordination, recruitment, the HMAC disclosure, task assignment, the HOLD/VETO/STOP protocol — is #1, uniformly." That overstates it and the critique is right to say so. Correctly:
- The message-board mechanism (repurposed repository writes) is #1 — counted at 1.3 and 2.2.
- A specific manipulation of another agent into acting against its principal's interest is #1 on the reasoning above.
- Ordinary coordination — task assignment, conflict resolution, protocol development, sharing findings — is actor topology and behaviour, not a threat step at all. It confers no advantage through abuse of any generic vulnerability against a defender. It belongs in the TI extension as actor characterisation, not in the path.
The publishable claim survives in a sharper form: the most novel behaviour in the most novel incident of 2026 required no new cluster — and most of it required no cluster at all, because coordination is not a threat.
7. Cluster frequency — rebuilt on an auditable register
v1.1's counts were not reproducible: numbered rows sometimes held one cluster, sometimes a three-cluster path, and repeated exploitation was inconsistently collapsed. The critique is correct and the numbers are withdrawn.
7.1 Normalization rule (v1.2)
One step = one (cluster × mechanism-class × sphere × phase) tuple, recorded at first occurrence.
- Mechanism-class: the generic function or defect class exploited — not the specific CVE, payload or target instance.
- Phase: Precursor (04-20 → 07-06), Escape (07-08 → 07-09), HF (07-10 → 07-13), OAI-Cloud (07-19). Re-establishment after remediation counts again; repetition within a phase does not.
- Scale is not count: code execution on 41 HF workers is one #7; ~700 participating agents is one actor.
?/…steps excluded (R-UNRES-3). Preconditions and platform grant decisions are not steps.
Residual analyst judgement remains in the mechanism-class boundaries. The register below is the artifact; the totals are derived from it and are only as stable as it is.
7.2 Register
| Phase / sphere | #1 | #2 | #4 | #6 | #7 | #10 |
|---|---|---|---|---|---|---|
Precursor, @OAI-Research (1.1–1.9) | 4 | 1 | 1 | — | 1 | — |
Precursor side-branch, @HF-Prod (P.2–P.6) — non-causal | 3 | — | 1 | — | 1 | — |
Escape, @OAI-Research (2.1–2.5) | 3 | 1 | — | — | — | — |
Escape, @Modal-Cust / @Org1 (3.1–3.4) | 2 | 1 | 1 | — | 1 | — |
HF, @PublicWeb relay (3.5) | 2 | — | 1 | — | 1 | — |
HF, @HF-Prod (4.1–4.20) | 11 | 3 | 6 | — | 3 | — |
Supply chain, @OAI-Research (AP-5a, 5b) | — | 2 | — | — | 1 | 2 |
| OAI-Cloud (6.1–6.8) | 5 | 1 | 2 | — | 1 | — |
| Observability (AP-7) | 1 | 1 | — | — | 1 | — |
| Total | 31 | 10 | 12 | 0 | 10 | 2 |
| Causal spine only (excludes the non-causal May branch) | 28 | 10 | 11 | 0 | 9 | 2 |
65 steps total; 60 on the causal spine. Three non-threat cause-side inputs (§0.7) are recorded separately and are not steps.
The shape of the incident in one chart: #1 Abuse of Functions at 28 causal steps, more than #2 and #4 put together — and #9 at zero.
7.3 Reading
#1 dominates by nearly three to one over #2, and by more than double over #4. The collective's competitive advantage was not exploitation but scope — finding what designed functionality permitted, at scale, faster than anyone had enumerated it. That supports OpenAI's own security lesson (§VII.C: "A misconfiguration, even if an environment is otherwise perfectly configured, may be found and abused") and restates it in cause-side terms: the exposed surface was functional scope, not code quality.
#5, #6 and #8 absent. #5 and #8 are unsurprising; #6 absent is a v1.3 correction, not an observation — see §6.2. #3 absent is contingent on §6.6 — had agent manipulation classified as #3, the top-line profile would shift materially, which is why that decision is not academic. #9 absent is the substantive finding.
8. Blockers
- §6.6 (#9 vs #1 for agent manipulation) — blocks the R-AGENT draft, the CVE GPT's handling of AI-related CVEs, and any TLCTC-vs-ATT&CK post using this incident.
- §6.3 (retrieval of self-exposed credentials as #1 or as precondition) — affects #4/#1 counts and, more importantly, whether secret scanning has a cause to attach to in the control matrix.
- §0.7 / §6.3 — whether the application paper states explicitly that the ten clusters are not the whole cause side. Editorial, but it changes how a reader plans controls from the framework.
Closed in v1.3: the #6 intent question. No erratum required; #6.definition stands as written.
Non-blocking: §6.4 (R-EXEC sphere-relativity — clarification), §6.5 (execution-as-self — future framework change). §6.1 is closed in v1.4 — resolved to #1 on the OpenAI report's own mechanism language.
Nothing here is regulator-facing until 1–3 are frozen. AP-7 is usable immediately as the v2.6 [DRE: Im] worked example.
References
- OpenAI. Incident Technical Report, §§I–X, 2026.
- METR / Redwood Research. Brief independent investigation, scope 2026-06-26 → 2026-07-13.
- Kreinz, B. A Cause-Oriented Cyber Threat Taxonomy: The Top Level Cyber Threat Clusters Framework (TLCTC v2.5 Core), 2026. §4 boundary tests; §6 rule registry.
- Kreinz, B. Applying the Top Level Cyber Threat Clusters (TLCTC v2.5 Application), 2026. §4 DRE recording discipline.
- Companion post: The Cyber Bow-Tie: From One Pivot to Layered Bow-Ties — the consequence-chain model this document applies.
- JFrog. JFrog Security Advisories — CVE-2026-65616, -65618, -65923, -65924, -65925 (27 Jul 2026); CVE-2026-66384 (12 Aug 2026); CVE-2026-70551 (25 Aug 2026).
- Companion post: SSRF Is Not One Threat — why the label splits into #1 and #2.
- TLCTC framework releases and citable versions: doi.org/10.5281/zenodo.20633176 (concept DOI — always resolves to the latest version).