A2A SERVER · AUTHORIZE, THEN READ
Server-side agent: authorize before reading a tenant record
A client agent for tenant acme asks a server agent for four invoices; choose where the tenant comes from and whether ownership is checked before or after the read.
Your experiment
The client’s OAuth token says acme. It asks for acme’s INV-101, globex’s INV-204 honestly, INV-204 again with the message’s tenant field set to globex, and a non-existent INV-999. Start with the payload tenant and an after-read check, then move the check, trust the token and unify the errors.
Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, Speed changes the pace and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.
Event trace
Computed data
Final metrics
Decision model of one A2A server agent; message fields, invoices and tenants are fictional. The token is assumed valid and verified. A tenant-scoped query cannot load another tenant’s row. Real servers also rate-limit lookups, audit denials and avoid putting tenant data in traces and logs.
Whose tenant is it?
A client agent with an OAuth token for tenant acme asks a server agent for four invoices: its own INV-101, globex’s INV-204, INV-204 again with the message’s tenant field set to globex, and a non-existent INV-999. With the opening settings the server takes the tenant from the message and checks ownership after loading the record. The spoofed request claims globex, the owner matches, and globex’s invoice is returned: LEAKED. A tenant written into the message by the caller is a claim, not an identity.
Trust the verified token
Set Tenant used for authorization to Verified token claim. Every request is now evaluated as acme, so neither INV-204 request is returned. But with the after-read check both are still loaded first, and with Data layer logs loaded records on, globex’s invoice lands in acme’s request logs twice: READ BEFORE AUTHORIZING. Clearing the logging only removes the copy in the logs; the read itself still happened.
Check before the read
Choose Before any read (tenant-scoped query). With the token tenant, the query cannot return another tenant’s row, so nothing foreign is loaded or logged. With the payload tenant, the spoofed request still passes the check and one foreign record is returned. Moving the check earlier helps only if the identity it uses is trustworthy.
Errors that answer questions
With the token and the early check, the server still answers 403 for INV-204 and 404 for INV-999, which tells the caller that INV-204 exists in some other tenant: IDS ENUMERABLE. Set Error for a foreign or missing invoice to 404 for both and the responses are identical: AUTHORIZED BEFORE READ. The Ownership check None returns both foreign requests outright.
Reading the run and its limits
Play, Next event, Restart, Speed and Inspection time step through each request and the summary across sixty seconds; the table records the tenant claimed, the owner, whether the record was loaded, the status and whether it was returned. The token is assumed valid and verified; key rotation, delegation chains and rate limits on lookups are out of scope.