SERGIO RODRIGUEZRESEARCH / 006

AUTHORIZATION / ORIGINAL LOCAL EXPERIMENT / 27 SEP 2026

Same tool.
Different permission.

A tool can be available while a particular call is unauthorized. What happens when the target changes after approval?

Change the call
One approval, one callEXACT SCOPESINGLE USE
CALL BOUNDARY / SIGNED SCOPE
PYTHON STANDARD LIBRARYHMAC-SHA256 + SQLITEDURABLE REPLAY LEDGER
01 / TRY THE BOUNDARY

Approval has a shape.

Select a change, then verify it. The browser creates a fresh demo key and signs an approval for each case. The case changes the proposal, host context, clock, or replay state.

The approved report is public-summary. The proposed call asks for the private report using the same tool.

HOST APPROVED

One specific request.

reports.read
target: public-summary
args: {"format":"text"}
actor: reviewer / audience: local-report-service
SIGNED SCOPE

PROPOSED AT DISPATCH

A different target.

reports.read
target: private-report
args: {"format":"text"}
actor: reviewer / audience: local-report-service
TARGET CHANGED

Preparing the browser experiment…

    This separate, limited Web Crypto demonstration uses fixed ASCII inputs and an in-memory nonce set. It shares the Python signature domain and nonce encoding; it is not a port of the full verifier. The Python implementation below also validates strict input types and uses a transactional SQLite ledger to reject replay across processes and restarts. Neither version executes a tool.

    02 / THE QUESTION

    What did
    the user approve?

    Imagine a host approves reading one report. A later message asks for a different report using the same tool name. A check against the tool catalog accepts both calls. That check answers an availability question; it has no record of the approved request.

    Call Boundary signs the actor, service audience, tool, target, complete argument digest, issue time, expiry, and nonce. The verifier compares those claims with the host context and the proposed call. A successful verification consumes the nonce.

    Changing the arguments invalidates the scope. Editing the grant invalidates its signature. Reusing an otherwise valid grant fails the nonce check. Benign controls verify that a correctly scoped call still passes.

    03 / THE PYTHON RECORD

    Inspect every decision.

    The table is loaded from the saved Python run. It is a fixed set of controlled cases, not a live-model evaluation or a measurement of attacks in the wild.

    Loading the recorded run…
    Controlled vectors: baseline compared with the signed call verifier
    CaseTool-name onlySigned callDecision
    Read results.json for the full record.
    Reproduce the Python run
    python verify.py

    Run from a checkout of call-boundary with Python 3.10 or later. The command runs the tests and regenerates the fixture results and test report.

    04 / DESIGN CONTEXT

    Standards first.
    Then a narrow test.

    The July 2026 MCP specification treats tool annotations from untrusted servers as untrusted input. Its security guidance also discusses audience validation, consent bound to a specific client, and short-lived, single-use state.

    Those boundaries motivate this experiment. Call Boundary is an independent reference implementation of exact-call authorization; it is not an MCP server, an OAuth implementation, or a newly discovered MCP vulnerability.

    WHAT REMAINS OUTSIDE THIS TEST

    The gate is one boundary.

    A compromised approval signer can authorize the wrong thing. A mutable resource can change after approval. Consuming a nonce before dispatch does not make an external action atomic or guarantee exactly-once execution. Production use needs trusted identity, resource-version binding where appropriate, key management, and a durable dispatch protocol. Prompt injection detection and model behavior are not evaluated here.