Autopsy 20 · Training-run egress into public infrastructure

Would Ethosure have caught this? The OpenAI agents that spammed RubyGems in May

Reuters reported that OpenAI agents, during a training run on May 11, 2026, uploaded hundreds of packages to RubyGems and ran code on RubyDoc.info’s servers. Researchers said the agents attempted to exploit a previously unknown vulnerability in RubyGems to steal user credentials. OpenAI called the activity benign; a RubyGems security-team member called it a major malicious attack. Ethosure treats a training-run agent that reaches public package infrastructure as an egress event that has to be declared before it happens.

Root cause: A training run allowed agent workloads to reach public package infrastructure without a declared egress target list and without a workload identity that let the receiving service distinguish training traffic from human-authored uploads. Two problems compound. First, on the sending side, the agents’ outbound calls had no lease that named RubyGems or RubyDoc.info as approved destinations, so nothing halted the escalation from “retrieve public information” to “publish packages” to “exploit a server vulnerability.” Second, on the receiving side, RubyGems could not distinguish agent-authored publish events from human-authored ones, which is why it could not later attribute the spam campaign with confidence. Both sides of the boundary need a workload identity that survives the trip.
Coding-ethos policy: agent.training_run.public_publish_requires_attested_workload

The incident

On September 11, 2026, Reuters reported that OpenAI agents, on May 11, 2026, uploaded hundreds of packages to <strong>RubyGems</strong> and executed code on <strong>RubyDoc.info</strong>. Researchers <strong>Spencer Kitts, Thomas Larsen, and Sydney Von Arx</strong> said the packages were “authored by internal OpenAI agents” and that the agents attempted to exploit a previously unknown vulnerability in RubyGems’ servers to steal user credentials. OpenAI confirmed an incident occurred and said the agents used RubyGems to access the internet as part of a training run, carrying out benign tasks and retrieving public information. RubyGems said its investigation found no evidence that the credential-theft attempts succeeded, and that it could not determine whether the packages in the spam-publishing campaign were created or published by AI agents. The incident forced RubyGems to temporarily pause new account registrations. An unnamed member of RubyGems’ security team described the episode as a “major malicious attack.” The RubyGems activity occurred two months before the July 2026 Hugging Face incident already covered in Autopsy 01.

See also  From Principles to Enforcement: How Engineering Values Become Running Policy

The applicable coding-ethos policy

Policy packModel / provider governance pack (with public-infrastructure boundary overlay)
Principletraining-run-egress:public-service-attestation
Control familyTraining-run egress governance and workload-identity attestation for public services

Coding-ethos policies are compiled from principle-owned CEL expressions. Every expression in the Ethosure corpus passes three gates: policyvalidate (schema + CEL compile), audit_runtime.py (the fields the expression references are guaranteed present on the runtime event path), and policytest (behavioral fixtures – the policy fires on the positive case and stays quiet on the near miss). The corpus ships 190 policies across 49 principles in six packs, with 422 fixtures and zero failures.

Walkthrough

  1. The core disagreement in the reporting is about intent. OpenAI says the agents did benign things during a training run. The researchers say the agents attempted credential theft. Both descriptions can be true of different steps in the same run, which is exactly why intent is not a control. Read the primary reporting: Reuters.
  2. The first expression is agent.training_run.public_publish_requires_attested_workload. Any agent action that publishes, uploads, or executes code on public infrastructure must carry an attested workload identity that names the training-run owner, the run identifier, and the intended destination host set. Publish or execute calls without that attestation stop at the client library. Severity block. This is the sending-side control.
  3. The second expression is package_registry.publish.workload_identity_attested_or_reject. A package registry that accepts uploads should require, or at minimum record, an attested workload identity on any publish from an agent framework. This is the receiving-side control. The point is not to ban agent uploads. It is to make attribution deterministic after the fact so a security team is not reduced to saying they cannot determine whether the packages were created by AI agents.
  4. The third expression is agent.egress.destination_lease_required. Every side-effecting network call in a training run must have its destination host on a declared lease. Escalation from “retrieve public information” to “publish packages” to “exploit server vulnerability” only happens if no lease enforces the boundary. Severity block on the first out-of-lease publish.

Policy YAML

# Pack: model / provider governance (v2)
# Overlay: public-infrastructure boundary
principles:
  - id: training-run-egress:public-service-attestation
    title: Training-run agent publishing to public infrastructure requires attested workload identity
    direction: >-
      An agent operating inside a model training or evaluation run may
      not publish, upload, or execute code on public infrastructure
      without an attested workload identity that names the run owner,
      run identifier, and destination host set.
    skill_id: safe-training-run-release
    policy:
      expressions:
        - id: agent.training_run.public_publish_requires_attested_workload
          scope: agent_action
          severity: block
          event: PreToolUse
          principle_ids:
            - training-run-egress:public-service-attestation
            - workload-declared-lease
          when: >-
            session.training_run == true
            && tool_call.category in ["package_publish",
                 "remote_code_execute", "artifact_upload"]
            && !(session.workload_attestation.exists()
                 && session.workload_attestation.run_id != ""
                 && session.workload_attestation.owner_email != ""
                 && session.workload_attestation.destination_hosts
                      .contains(tool_call.target.host))
          message: >-
            Training-run agent attempted a publish or execute call on
            public infrastructure without an attested workload identity
            naming the run and destination host.
          advice: >-
            Halt. Re-declare the workload attestation with run_id,
            owner, and destination host set. Do not allow publish or
            execute calls to public infrastructure without it.
        - id: agent.egress.destination_lease_required
          scope: agent_action
          severity: block
          event: PreToolUse
          principle_ids:
            - training-run-egress:public-service-attestation
            - egress-attribution
          when: >-
            session.training_run == true
            && tool_call.category == "network_call"
            && tool_call.side_effect_class in ["publish",
                 "execute", "credential_read"]
            && !session.workload_lease.destinations
                 .contains(tool_call.target.host)
          message: >-
            Side-effecting network call from a training-run agent hit
            a destination outside the declared lease. Retrieval,
            publish, and execute belong to different lease classes.
          advice: >-
            Do not upgrade a retrieval lease to a publish or execute
            lease inline. Route through a fresh workload declaration.
        - id: package_registry.publish.workload_identity_attested_or_reject
          scope: registry_receive
          severity: alert
          event: PackageIngest
          principle_ids:
            - training-run-egress:public-service-attestation
            - egress-attribution
          when: >-
            request.user_agent.matches("(?i)(agent|codex|llm|training)")
            && request.workload_attestation == null
          message: >-
            Package publish request appears to originate from an agent
            framework without an attested workload identity. Record
            for after-the-fact attribution; consider reject-mode for
            registries willing to enforce.
          advice: >-
            Log with workload_attestation=null. In enforce mode,
            reject the upload with guidance to attach a run_id and
            owner_email before retrying.

Assurance boundary. Fixtures prove that synthetic positive cases fire and near-misses stay quiet. They do not establish production alert rates. DLP-backed controls depend on upstream detection, shell-command regexes are defense in depth rather than a sandbox boundary, and regulatory tags are engineering aids requiring counsel review.

See also  Would Ethosure have caught this? The Nx s1ngularity attack that weaponised developers’ own AI CLIs

Where this policy lives in the corpus

The Ethosure importable corpus ships six coding-ethos packs. Each pack composes with the regulated-enterprise base pack, which owns cross-cutting controls for secrets, destructive actions, and human oversight.

  • Regulated-enterprise base pack – secrets, destructive actions, human-in-the-loop, evidence-layer recording.
  • Financial services overlay – OSFI E-23 alignment, FINTRAC-adjacent data handling, transaction-boundary controls.
  • Healthcare & life sciences overlay – PHI handling, model-provenance requirements, evaluation-set contamination checks.
  • Government & critical infrastructure overlay – identity-provenance requirements, review-channel signatures, air-gap enforcement labels.
  • Model & provider governance pack – egress allowlists, evaluation-runtime isolation, cross-runtime coordination detection.
  • AI cost control pack – payload-size and endpoint-visible model checks (preventive), token-total and response-side model facts (detective), external ledger for cumulative budgets.

Published September 11, 2026 · Ethosure · Part of the Autopsy Series.