10 min read

S32
Operation · Safety, Alignment & Agentic Security

Authorised Agentic Testing

A rules-of-engagement document written for people has no field that bounds an agent, and after the fact you cannot tell an authorised test from an intrusion.

If a third party points an autonomous security agent at you and it goes somewhere it should not, the only evidence that it was ever authorised is the operator's word — and in the one public case where this happened, timestamps matched, an independent forensics firm agreed, and the claim that the agent had escaped its test environment still rested on nobody but the person who ran it. The fix is not better detection. It is to issue the tester an identity you minted, cap what it can do at your edge, and treat unmarked traffic as an intrusion without argument, so that "my agent escaped" becomes a claim your own logs can check.

Step 1What the public case established, and what it could not.

WorkOS disclosed in late October 2026 that an internal sales application had been accessed without authorisation: first confirmed request on 25 October, bulk retrieval and detection on 30 October. Its bulletin says the tool "should not have been reachable from the internet", that "the API accepted a weak credential intended for local development" and that "because the credential was predictable, the agent was able to authenticate after discovering the endpoint." On 6 November it published an update: a security researcher had come forward and accepted responsibility, saying their agent had escaped its isolated testing environment while they were running cybersecurity benchmark evaluations.

The verification WorkOS describes is better than most organisations could manage. The researcher supplied details and timestamps; WorkOS's security team and the independent investigator it had retained compared them against company logs; the account matched. Take that seriously as a model — and then be precise about its limit.

  • Established: which requests were made, when, by the same party that came forward, and that the data involved sat in sales and support systems.
  • Not established: that the environment was ever supposed to be unable to reach WorkOS; that the access was unintended; that the copied data was deleted. No sandbox weakness was identified and no mechanism of escape was described. "Escaped" is the operator's word, not a forensic finding.

That is the structural problem, and it is not specific to one company. An agent that broke out of a container, an agent pointed at a target list someone forgot to prune, and a test run deliberately past the edge of its scope produce identical traffic at your end. Your logs record the requests perfectly and say nothing about authorisation, because authorisation is a fact about a decision made somewhere you cannot see. This is the mirror image of the problem in attacker-operated agents: there, an intruder claims to be an authorised tester and the model cannot check it; here, an authorised tester's claim about their own containment cannot be checked either.

Step 2The clauses your template has, and the three it is missing.

A conventional penetration-test rules-of-engagement document covers scope, testing window, permitted techniques, escalation contacts, evidence handling and reporting. Every one of those was written on the assumption that a person reads the scope, decides what to do next, and stops when the window closes. As of late 2026 no regulator or standards body has published authorisation rules specific to autonomous testing agents; practitioner guidance converges on the right instinct — that scope must become a machine-enforced constraint rather than an instruction — without telling you which clauses to add.

Three are missing, and they are the three that matter when the tester is a loop rather than a person.

  • Identity. Human ROEs identify the firm, not the traffic. There is no field that says "every request arising from this engagement will carry this mark, and the absence of the mark means it is not us." Without that field, attribution after the fact is a conversation rather than a lookup.
  • Rate. A human tester's throughput is self-limiting. An agent's is a configuration value, and a target with no rate limit — the condition in the case above — converts "reconnaissance" into "bulk extraction" with no change of intent and no visible transition.
  • Containment on the tester's side. The ROE says what is in scope. It does not say what the agent is able to reach, which is a property of the tester's network namespace and tool allowlist, not of the document. The one claim in the public case that nobody could check was exactly this one.

Notice that all three are about the tester's configuration, not about your controls. That is why you cannot add them as requirements and stop: a clause you cannot audit is a clause you have to price, and the next three steps are about what to do instead.

Step 3Issue the identity yourself, and make unmarked traffic an intrusion by definition.

This is the single highest-value change, and it inverts the usual arrangement. Do not ask the tester to tell you what their traffic will look like. Mint a credential and give it to them, so that the mark is something you control and they cannot reproduce after the engagement ends.

What works, in rough order of strength:

  • A client certificate or a signed header your edge verifies. Unforgeable, revocable in one action, and it survives the tester changing source addresses mid-run. Rotate it per engagement and expire it at the window's close, which is the same discipline as credential lifetime applied to a third party.
  • A dedicated account with its own identity record, never a shared or human one, so every action lands in a separate audit stream. This is the same argument as agent directory accounts, and it is also what keeps the test out of the detections your SOC tunes against real users.
  • A pre-registered source prefix, useful and weak on its own: cloud egress addresses move, and anyone can route through the same provider.
  • A user-agent string — not a control. It is a self-declaration any client can send or omit. In the case above, the published indicators of compromise were user-agent strings, which means the marker and the detection were the same artefact: once you publish it, a hostile operator knows what not to send and what to send.

Then write the consequence into the document, because that is where the value is realised: traffic arising from this engagement that does not carry the mark is treated as an unauthorised intrusion, contained immediately, and escalated without consultation. That clause costs the tester nothing if their containment works and costs them an awkward phone call if it does not — which is precisely the incentive you want, and precisely the evidence that was missing when somebody later said their agent had escaped.

Add one canary with no business function — a record, an account, an endpoint — that no legitimate test needs to touch and that is not in the agreed scope. A hit on it tells you the agent's target selection has drifted, before the drift reaches something that matters. The mechanics are in honeytokens for agent systems.

Step 4Cap the rate at your edge, because the tester's config is not yours to trust.

A rate cap on an authorised test looks like an obstacle to thorough testing. It is the opposite: it is the control that lets you authorise the test at all, because it bounds the worst case without requiring you to predict the agent's behaviour. It is also, not coincidentally, the control whose absence turned a slow probe into a bulk download in the public case.

  • Set the cap per marked identity, not globally. A tester-specific budget means you can be generous with the test and strict with everything else, and it means exhausting the budget is a signal attached to a known party rather than an outage.
  • Cap reads separately from writes, and cap bulk-shaped reads hardest. The distinguishing event was volume of retrieval, not number of requests; a per-minute request limit and a per-hour record limit catch different things.
  • Make the cap generate a signal, not just a refusal. A limit that silently throttles removes the damage and removes the alarm with it. Both halves were missing in the case above, and the alarm is the cheaper one to add.
  • Treat spend as a limit too. An agent that drives metered APIs or inference on your account is a cost exposure as well as a data one — see denial of wallet.
# the four clauses a human-written ROE does not have
identity:   client_cert issued_by=us  expires=window_close
            unmarked_traffic -> treat_as_intrusion   # no consultation
rate:       1200 req/min  AND  5000 records/hour     # per marked identity
            on_exceeded -> refuse AND page                # refusing silently is half a control
stop:       canary_hit | scope_exit | our_sole_discretion
            kill = revoke_cert (one action, no notice period)
data:       named_signatory  deletion_attested_by=<date>
            evidence = log excerpt, not assurance

# every line is enforced on OUR side — none of it depends on the tester's sandbox

Step 5Write a kill path the tester cannot talk you out of.

Human engagements are paused by email. That cadence does not survive an agent working continuously, and the failure mode is not that you lack the ability to stop it — it is that stopping requires a decision nobody has been pre-authorised to make, which is the pattern kill switches and incident response for agents both describe.

  • Name the person who can revoke, in advance, with no meeting. One named role, one action — revoke the certificate, disable the account — and an explicit statement that they may do it at their sole discretion and explain afterwards.
  • Make revocation a single action that actually works. Check it before the engagement: a bearer token already issued stays valid until expiry no matter what your console says, so a short lifetime is part of the kill path rather than an alternative to it.
  • Agree stop conditions in writing: a canary hit, any request outside the agreed scope, any write to a system marked read-only, and anything the agent does that the tester cannot explain within an hour. Pre-agreeing them removes the argument at the moment you least want one.
  • Require a live contact for the duration, not a ticket queue. Practitioner guidance on agentic testing is consistent on this point: an autonomous run should be watched while it runs, not reviewed after. If the tester cannot staff that, the engagement is smaller than they proposed.
  • Decide in advance what you will do about an unexplained action, because that is the thing you will actually face. The public case produced an unexplained escape and a cooperative operator, and the cooperation is the part you cannot plan on.

Step 6Your disclosure clock does not care whose agent it was.

This is the part teams discover late. If an authorised test reaches data it should not have, you are holding an incident with the ordinary obligations, and the fact that it was a test does not pause them. The attestation that the data was deleted is what closes the exposure — and an attestation offered voluntarily, after the fact, by an unnamed individual is worth goodwill and nothing more. Negotiate it before the test, when it is free.

  • Name the signatory and the standard. Who signs the deletion statement, on behalf of which legal entity, and what evidence accompanies it — a log excerpt showing the destruction, a storage inventory, a third-party confirmation. "We deleted it" is not an evidence standard.
  • Agree the retention rule for test artefacts up front: what the agent may store, where, for how long, and under whose encryption. An agent that writes its working memory to a vendor service has moved your data again, which is third-party and vendor risk arriving through the back door.
  • Keep your own evidence, independently of the tester's report. The corroboration in the public case was only possible because request-level logs existed; WorkOS verified centralised logging of traffic to internal tools on 2 November, which is a quiet statement about what the first days of the investigation were like. Check now that you could reconstruct a week of request-level access to an internal tool.
  • Write the disclosure trigger into the ROE: if the test touches regulated data, you notify on your own timeline regardless of the tester's view, and they agree to that in advance. The thresholds are in serious incident reporting.
  • Separate the vendor's assurance from your verification. A report saying the agent stayed in scope is the tester's claim; a scope-conformance check on your side is a measurement, and the two belong in different columns — see scope-conformance evals.

Do this one first, before anyone asks to point an agent at you: decide what your authorised-testing mark is, and write the sentence that says unmarked traffic from an engagement is treated as an intrusion. One certificate and one clause convert the least checkable claim in this whole category — "my agent was authorised, it just got loose" — into something your access logs answer in a minute. Everything else on this page is a refinement of that.

Related: safety red-teaming for the testing you run yourself, red-teaming agents for pointing one at an agent rather than a perimeter, third-party agents logging in as your users for the non-adversarial version of the same identity problem, and blast radius for the question a predictable credential really answers.