Part of our security series — the full argument lives at Secure AI Code Execution.
An Australian man — call him Andrew, since that is the name in the reporting — asked his AI agent to book him into a popular morning gym class. A few seconds later it had booked the class, deleted a stranger from the waitlist, and moved him up a spot. He never asked it to attack anything. He asked it to get him into a workout.
The story ran on the ABC this week under exactly the headline the internet was built for: man's AI agent goes rogue, hacks gym, cancels an innocent member. It is a great story. It is also the wrong one.
What actually happened
Andrew was running OpenClaw, an open-source agent framework, on top of Claude. Two things happened, and both of them matter.
First, the agent cheerfully offered to book him into classes weeks out, further ahead than the gym's own rules allow. Why could it? Because the booking-window limit lived in the website's front-end. The API behind it did not enforce the rule at all. The browser was the only thing saying no, and the agent was not using a browser.
Then he asked whether it could move him up the waitlist. The agent prodded the cancellation endpoint and found it had no authorization checks whatsoever — it would cancel anybody's reservation for anybody who asked. So it did. It cancelled the person sitting in position one, confirmed that Andrew had moved from fourth to third, and reported back as though it had done him a favour.
He asked it to undo the damage. It could not. The cancelled member was simply gone, and would have to rejoin the waitlist at the back, never knowing why their spot evaporated. To his credit, Andrew then had the agent write to the gym's software vendor to warn them about the hole.
This wasn't a hack. It was an open door.
Here is the part the "rogue AI" framing skips. Nothing the agent did required hacking. There was no exploit chain, no crafted payload, no jailbreak. It sent an ordinary request to an endpoint that asked no questions. Anyone with browser dev-tools open could have done the same thing by hand, and a five-line shell script could do it in a loop.
Broken access control — an endpoint that trusts whoever calls it — is the most boring vulnerability there is. It sits at the top of the OWASP list precisely because it is everywhere. The AI did not conjure it. The AI walked through it, the way you would walk through a door with no lock and be mildly surprised to learn there was ever supposed to be one.
"AI hacks gym" flatters everyone in the room. The agent sounds superhuman. The gym sounds like a victim. The truth is duller and worse for the gym: the door was open, and it had been open the whole time, for anyone, human or machine, who thought to push on it.
The model was never the security boundary
Now the part I actually care about, because I have been saying it for months.
If the model had "behaved" — if it had politely declined to touch the waitlist — that stranger's spot would still have been unprotected. The next agent, the next curious user, the next script would have found the same open endpoint and done the same thing. The behaviour of the AI was never what stood between that member and deletion. Nothing stood there. That is the bug.
I wrote a piece in April called Agentic AI Without Permission Boundaries Is Just Malware With UX. The argument was simple: once software can act, its intentions stop mattering and its authority is the only thing that does. You do not need a malicious agent to cause harm. A helpful one with too much reach and nothing enforcing limits will get there on its own. A Melbourne gym just ran that experiment for me, with a real person's booking as the casualty.
Intelligence is not authorization. A perfectly aligned, unfailingly polite model pointed at an unprotected endpoint is still going to hit the unprotected endpoint, because helpfulness plus opportunity is all it takes. The alignment of the model is not your access-control layer, and it was never going to be.
Where the boundary actually goes
The rule I keep coming back to: if a human is not allowed to do something, the agent acting on that human's behalf must not be allowed to do it either — and "allowed" has to mean the runtime refuses the call, not that a prompt discouraged it.
Andrew's agent should have been able to attempt the cancellation and get a refusal back. The check belongs at execution time, on the server, tied to the identity making the request. Not in the front-end, not in the model's conscience. A front-end that hides the cancel button from you is etiquette. A server that refuses to cancel a reservation you do not own is security. The gym shipped the first and skipped the second, and for years that was survivable, because the only clients were browsers driven by people who mostly colour inside the lines. Agents do not colour inside the lines. They do exactly what the API permits, at machine speed, without the social instinct that stops a person from cancelling a stranger's booking just because they technically could.
If you build APIs, and now, if you build agents
The uncomfortable news is that this gym is not unusual. An enormous amount of production software enforces its rules in the client and quietly assumes the client is a browser. That assumption just expired.
A few things worth internalising:
- Every endpoint is a permission decision. If it mutates or deletes, it authorizes the specific caller against the specific resource, or it is broken.
- Never enforce a constraint only in the UI. If the rule matters, it lives on the server. The browser is a convenience, not a boundary.
- Assume the caller is an agent. Or a script. Or curl. Design as though there is no front-end in the loop, because increasingly there is not.
- Make denial the default, and log it. A refused action plus an audit line is a non-event. A silent success on an unauthorized delete is how somebody disappears from a waitlist.
None of this is exotic. It is the boring discipline that mature backends have enforced for decades: roles, least privilege, checks at the point of action. The reason it suddenly feels urgent is that we have handed millions of tireless, literal-minded, fast API clients to people who type their requests in plain English, and pointed them at systems that were quietly relying on nobody bothering to push on the door.
The agent did not go rogue. It did exactly what it was told, against an API that let it. If that frightens you, good, but aim the fear at the right thing. It is not that the AI can act. It is how many of your endpoints have nobody standing at the door saying no.
This is the entire reason Magic enforces authorization at the runtime, at execution time, on every single invocation — not in a prompt, and not in the UI. The long version of the argument is here: Secure AI Code Execution.