
Check agent access where misuse actually happens
Agent integrations need more than a successful demonstration. Wildo’s test scenarios exercise tool and conversation entry points with wrong audiences, foreign records and unauthorized requests, alongside permitted controls.
The useful question is whether the boundary holds on the agent surface itself.
Example — Check both sides of an organization boundary
The same caller first reads its own record successfully, then attempts to read another organization’s record through the same tool endpoint.
For engineers
These commands run from the Wildo repository root against the running Wonder Todos development stack. They invoke the complete scenarios, including helpers that the excerpt below relies on:
pnpm --dir examples/wonder-todos exec tsx e2e/mcp-hostile.e2e.ts
pnpm --dir examples/wonder-todos exec tsx e2e/a2a-hostile.e2e.ts
Use a disposable test deployment. The runners provision organizations and users, seed OAuth clients and records, attempt reads and writes, inspect stored effects and clean up their fixtures. They are not read-only probes.
| Prerequisite | Why the runner needs it |
|---|---|
| Running application backend and backing services | Reach actual HTTP endpoints and inspect stored records through the test adapters |
| Current application configuration and named agent/tool instances | Exercise the configured support/operations boundaries instead of an absent route |
| Test identity and infrastructure credentials | Provision fixtures, mint audience-bound tokens and inspect their effects |
| Model provider and credentials for A2A model legs | Make the conversational agent actually attempt a tool call |
e2e/wt-config.ts resolves endpoints through the testing environment contract and local defaults. Infrastructure credentials come from the configured WILDO_E2E_* inputs or the running stack’s gitignored .env.wildo-platform; fixture helpers own the disposable users and OAuth clients. Keep those values outside the website and result report. Pointing only the HTTP URL at another application does not adapt its resource names, fixture model or backing-store configuration.
The related a2a-dialects.e2e.ts, a2a-resubscribe.e2e.ts, a2a-push-notifications.e2e.ts and a2a-approval-hostile.e2e.ts scenarios use the same pnpm --dir examples/wonder-todos exec tsx e2e/<file> entry pattern. Callback-delivery acknowledgement additionally needs a reachable receiver admitted by the outbound-address policy; a registration or delivery attempt alone is not proof that it arrived.
Record what the run proved
Record the application/deployment, source revision, addressed endpoint/instance, scenario command, positive controls and storage effects. A failure to reach the endpoint or provider is an unexecuted scenario, not a passed refusal test. Independent client verification remains tracked in #6 for MCP and #7 for A2A.
MCP can assert directly on a tool response. A2A is model-mediated: a safe final answer does not establish that the model attempted the prohibited call. Inspect attempted-tool evidence and the resulting storage effects. An own-record control proves the model can use the tool; it does not prove it tried the foreign-record action as well.
Pair refusal with a working control
A refused call could mean the tool was unavailable. The MCP hostile scenario first proves the addressed surface can serve the caller’s own row, then targets a foreign row with the same token. This selected test excerpt uses the lane’s existing rpc, check and disclosesId helpers:
const ownRead = await rpc('tools/call', { name: 'todos__read', arguments: { todoId: aTodoId } }, tokenASupport, 'support');
check('C-0 CONTROL org A CAN read its OWN row on the support surface',
disclosesId(ownRead, aTodoId));
const foreignRead = await rpc('tools/call', { name: 'todos__read', arguments: { todoId: bTodoId } }, tokenASupport, 'support');
check('C-1 org A canNOT READ org B\'s row through tools/call',
!disclosesId(foreignRead, bTodoId));
The broader lane checks collection reads, write effects, named-instance confusion and token audience mismatch. A2A scenarios separately exercise skill routing, tenant writes and approval paths, because a REST or MCP test does not automatically prove the conversation path.
Verify the effect, not just the response
| Scenario | Evidence to inspect |
|---|---|
| Cross-tenant read | Own row present, foreign row absent |
| Forbidden write | Target storage unchanged |
| Wrong endpoint audience | Invocation refused and intended side effect absent |
| Approval-required action | No protected action before the authorized decision |
These are test assets and a repeatable verification approach, not a claim that every application is independently certified. Run the relevant scenarios against the configured deployment when changing exposure, roles or task routing; preserve the positive controls that establish what each refusal actually proves.