The checkout page can't tell your agent from a scraper - and that's your problem
United's position on AI agents booking flights got read as a verdict on whether agents are competent enough to pick a seat and type a card number. I don't think that's what it is at all. It's a verdict on identity.
The booking flow has no way to know that the thing filling in the form is acting for a specific human who asked it to. It sees an HTTP client, a session, some clicks, a card. It cannot distinguish my agent, delegated by me, from a scripted bulk booker holding inventory or testing stolen cards.
So it does the only thing a system without an identity layer can do: it blocks anything that doesn't look like a person on a browser. That's not a technology gap you close with a better planner. My agent could be flawless - correct dates, correct fare class, my actual passport name - and still get the same treatment, because competence was never the input to that decision.
What the flow actually checks
Walk the checkout as if you were the fraud team. You've got a session cookie, a device fingerprint, a velocity check on the IP, a card that may or may not match the billing address, and a form submitted faster than a human thumb would.
Every signal there is about the client. None of it is about who the client is working for. So the agent competes on the same axis as the abuse traffic, and loses by default. The rational response from the airline isn't "verify the agent's reasoning." It's "no."
I've built the naive version of this myself, more than once. One API key in an environment variable, shared by every tool in the loop, with scopes wide enough that it never gets in the way during development. It works great right up until the day you need to answer "what exactly did this thing do, on whose behalf, and can we stop it right now." Then you're reading logs and guessing.
The prediction
Within the next year or so, a scoped, revocable credential anchored to a specific human stops being an auth-team nicety and becomes a product requirement. Travel first, because inventory and fraud pressure are worst there. Then ticketing, then anything with a limited resource and a chargeback risk. Then it works its way down into boring B2B SaaS once one vendor makes it a checkbox on a procurement form.
The shape I expect, roughly:
- Subject: the human, verified to whatever standard the relying party demands. Not an email address. Something the counterparty can hold you to.
- Actor: the agent itself, with a key pair and proof of possession, so a stolen token is a useless token.
- Scope: narrow verbs. "Search and hold one itinerary for twenty minutes," not "book travel." A scope that reads like a job description is too wide.
- Intent binding: a hash of what the human actually asked for, so the agent can't quietly drift from "cheapest direct flight Thursday" into "any flight, any price, Friday, whatever."
- TTL: minutes. An agent credential that lives for a week is a session hijack waiting for a good story.
- Spend cap: independent of scope, because scope gets interpreted generously under pressure.
- Kill switch: a revocation handle the relying party can pull mid-flow, plus an audit record they can read back without asking me for a favour.
None of that is novel cryptography. Macaroons and biscuit tokens solved attenuation years ago; OAuth has had the delegation vocabulary forever; verifiable credentials exist as a spec people keep almost adopting. The hard part isn't the token format. It's the liability clause underneath it.
Who eats the chargeback when the agent books the wrong fare at 3am? Until a terms-of-service document answers that question, no airline will accept any token, no matter how pretty. Which is why I think we get three half-compatible schemes and a pile of adapter code, same as every other auth wave. Maybe I'm wrong. I'd love to be wrong, but I've seen how this goes.
What changes in how you build
The practical consequence is that scope has to come from outside the model. Your planner proposes an action; the credential layer decides whether that action is inside the envelope the human granted. If the model can mint its own scopes, you don't have a scope, you have a suggestion.
That means the delegation object becomes an input to your agent, not an output of it. Somewhere upstream - a UI, a consent screen, a parent agent with narrower authority - a human said "you may do X, for this long, up to this much." Your loop carries that around and refuses anything outside it.
Building that in from day one is maybe a day of work. Bolting it on after your first block, when the whole codebase assumes god-mode credentials, is a month.
Four things I'd do now, before anyone blocks you:
- Give every outbound tool call an actor identity, even internally. If your logs can't say which agent made a call, you'll never debug the interesting failure.
- Make scope a parameter you pass in, never a constant you inherit.
- Ship the revocation path before the feature it revokes. Kill switches written after the incident are always worse.
- Store the human's original request next to the resulting action. That's the artifact you'll wave in the dispute, and the one your own postmortem will need.
The unglamorous version of this future: your agent gets stopped by something stupid first. A WAF rule against headless browsers. A captcha you can't solve without becoming the thing United is banning. You'll lose a day to it and learn nothing. The delegation token is the part that actually matters. Design it while nobody's blocking you yet - it's a lot easier to build a passport than to argue your way through a border.
Comments
No comments yet. Start the discussion.