Hi Jijie,
Thank you. I will treat those payloads as the normative std/mcp-v1 vectors
for this thread.
Certificate parameters:
{"tools":["read_file","list_dir"]}
JSON-RPC decision Result
tools/call read_file ALLOW (200)
tools/call list_dir ALLOW (200)
tools/call bash DENY (403)
tools/call delete_file DENY (403)
initialize / ping / tools/list No tools/call decision (200)
This correctly exercises the first predicate: tool identity is bound by the
AIC rather than by the model emission itself. bash is therefore not
authorized simply because the model emits it; it falls outside the
principal-signed allowlist. Fail-closed enforcement at gateway-http is the
appropriate sink behaviour whenever the AIC-JWT is presented.
Two additional predicates are not yet exercised by the current matrix and,
in my view, should remain explicit.
1. *Argument subset within an allowlisted tool.*
Under the current std/mcp-v1 vectors, read_file with path=/etc/shadow
would still satisfy the tool-name predicate because the certificate
constrains the tool name, not its arguments. The wallet and database
examples in the same repository already demonstrate field-level
restrictions such as recipient, table, and limit. If MCP later binds path
prefixes or other argument fields in the same way, the enforcement model
remains unchanged; only the set of certificate-bound fields expands. Until
then, the tool allowlist is effectively a class grant for the named tool.
2. *Enforcement placement.*
The same matcher can be applied earlier in the execution path, for
example at host invoke(name, args) before dispatch reaches gateway-http.
This is not a separate policy model: the certificate, bounds, and
comparison semantics remain the same; only the first enforcement point
moves earlier.
I have not yet run scenario-demo.py --scenario mcp on this host. I will
report only if the observed behaviour diverges from the specified 200/403
matrix.
For the write-up, I suggest keeping the four-row decision table together
with these two predicates so that tool-identity denial is not conflated
with argument-subset denial.
Best,
Sangam
On Wed, 2 Sept 2026 at 11:10, Jijie Wei <[email protected]> wrote:
> Sangam,
>
> Thank you for the precise read -- and for framing the in-process path as
> a placement question rather than a defect. I agree: gateway-http enforces
> every call that crosses it; a host wrap that invokes the same bound-check
> before dispatch is the natural extension for local function tables, and it
> reuses the same certificate and bounds.
>
> On the mapping offer -- yes, please. A concrete test vector against
> std/mcp-v1:
>
> Allowlist (from the AIC certificate parameters):
> {"tools":["read_file","list_dir"]}
>
> Expected ALLOW:
> {"jsonrpc":"2.0","id":1,"method":"tools/call",
> "params":{"name":"read_file","arguments":{"path":"/tmp/a.txt"}}}
>
> Expected DENY (fail-closed, tool not allowlisted):
> {"jsonrpc":"2.0","id":2,"method":"tools/call",
> "params":{"name":"bash","arguments":{"cmd":"rm -rf /"}}}
>
> Protocol methods (initialize/ping/tools/list) pass without a tools/call
> decision. The repo's scenario-demo.py --scenario mcp runs these against
> the live gateway and reports the matrix (read_file 200, bash 403,
> list_dir 200, initialize 200, delete_file 403).
>
> If you run it and your result differs, that is exactly the kind of
> divergence worth pinning down. Happy to align on whatever format you
> prefer.
>
> Best,
> Jijie Wei
>
>
> ------------------ Original ------------------
> *From: * "Sangam Das"<[email protected]>;
> *Date: * Wed, Sep 2, 2026 01:33 PM
> *To: * "Jijie Wei"<[email protected]>;
> *Cc: * "wimse"<[email protected]>; "oauth"<[email protected]>;
> *Subject: * Re: [WIMSE] Re: Binding OAuth-authorized calls to specific
> tool-call arguments in agentic/MCP flows
>
>
> Dear Jijie,
>
> Thank you for the pointer to the demo repo, and for stating the boundary
> so clearly.
>
> Your three points match what I see in aic-capability-demo:
>
> 1. Bounds come from the principal (and role intersection at the CA),
> not from the model’s emitted arguments.
> 2. The HTTP/MCP gateway checks the concrete parameters against those
> bounds per request and fails closed.
> 3. That enforcement is at the gateway / MCP endpoint, not inside the
> host’s first local dispatch.
>
> That is a real answer for every call that actually crosses gateway-http.
> The wallet / database / deploy / MCP matrices in the README are the right
> kind of evidence for this thread.
>
> I agree AIC composes with RAR and mission-bound authorization rather than
> replacing them: the certificate is the offline-verifiable assertion; an
> online decision can still narrow it.
>
> The remaining case is the one you already named — the in-process function
> table (or any other path that never presents the AIC-JWT to the gateway).
> On that path the host would need to invoke the same bound-check before
> invoke(), or it is an alternate route around the sink you implemented.
>
> I do not read that as a defect in AIC. It is a placement question: gateway
> for networked MCP/HTTP, host wrap for local dispatch.
>
> I will look through the repo in more detail. Happy to map a single MCP
> tools/call against your std/mcp-v1 allowlist if that is useful.
>
> Thanks again,
> Sangam
>
> On Wed, 2 Sept 2026 at 10:56, Jijie Wei <[email protected]> wrote:
>
>> Sangam, you asked whether this gap is already solved somewhere. We have
>> implemented an answer in the AIC work and it is running; details and test
>> matrices are in the public demo repo below.
>>
>> The pattern, in the vocabulary this thread has converged on:
>>
>> 1. The policy assertion is certificate-bound and independent of the model
>> output. A principal signs a DelegationAuthorization carrying capability
>> declarations with precise parameters (database: tables, columns,
>> row_filter, limit; wallet: assets, per-transaction amount, recipient
>> allowlist; MCP: tool allowlist). These are encoded in an X.509 agent
>> certificate and its JWT carrier. The authorized bounds come from the
>> principal (optionally intersected with the operator role's policy at
>> issuance) -- never from the model's emitted arguments.
>>
>> 2. Enforcement happens at the sink boundary. An AIC-aware gateway verifies
>> the presented credential, then checks per request that the concrete
>> operation parameters fall within the certificate's declared bounds
>> before forwarding. For MCP, a tools/call must reference an allowlisted
>> tool; the structured operation (table, amount, recipient, environment,
>> tool) is matched against the bound parameters. Unknown or out-of-bounds
>> operations are denied (fail-closed).
>>
>> 3. One boundary I want to state explicitly: this enforces at the network
>> gateway / MCP endpoint, not inside the host process's first dispatch
>> (the function table). In-process enforcement would require the host to
>> invoke the same verifier at that earlier point; that is a different
>> layer.
>>
>> The credential is transport-identity anchored (X.509 presented over mTLS,
>> or a short-lived JWT issued from the same CA). This composes with, rather
>> than replaces, RAR / mission-bound dynamic authorization: the certificate
>> supplies offline-verifiable bounds, and an online policy decision can
>> further narrow them.
>>
>> Running implementation (capability schemes, gateway plugins, test
>> matrices): https://github.com/varwof/aic-capability-demo
>>
>> Happy to map the details if useful.
>>
>> Best,
>> Jijie Wei
>> --
>> WIMSE mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]
>>
>
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]