Yesterday I stumbled on a LinkedIn post about a new open standard for packaging Agent Skills and MCP servers: Agent Plugins, built with collaborati...
For further actions, you may consider blocking this person and/or reporting abuse
@sandrog You are right that the BFA has no business logic, and I was not arguing it should. The gap I am pointing at is narrower: the DET's bounded execution contract prevents injection and loops, but it does not prevent an agent from invoking the right tool with the wrong parameters, because the DET is scoped to the capability and not to the context. The gateway is stateless by design, and that is correct. What is missing is a runtime assertion layer at the MCP that checks the invocation against the agent's own stated intent, not against the DET. The DET says you may call this tool. The MCP says this tool is available. Neither says this call is consistent with the plan the agent just declared. That is the gap I keep coming back to, and it is not a criticism of the BFA scope. It is a missing piece on the agent side, not the gateway side.
@nyx533 Exactly, each piece in its proper place.
What you’re describing, an agent calling the right tool with parameters misaligned with its internal plan, is fundamentally a cognitive consistency / guardrail problem on the agent side, not an authorization or infrastructure failure.
In IRC-A, the boundaries are explicit:
The DET (Security / Perimeter): Guarantees who is allowed to execute what, bounds the parameter envelope, and prevents prompt-injection privilege escalation or runaway loops.
The MCP (Resource Server): Validates deterministic constraints, schema typing, local business invariants, and DET authenticity.
If the MCP had to inspect whether the call aligns with the agent's internal plan, it would need to inspect the agent's cognitive scratchpad, history, or intent context. That would destroy black-box decoupling (Smalltalk-style message passing / A2A) and tightly couple the tool to the cognitive implementation of the caller.
Cognitive assertion belongs inside the agent’s own loop (pre-flight self-evaluations or output guardrails). Once the message hits the wire, the MCP only enforces deterministic boundary contracts.
Put yourself in the shoes of someone designing a large enterprise system: you have no idea what future capabilities will be needed next quarter, or how business requirements will evolve.
If you put business logic into the BFA, or force an MCP tool serving multiple departments to know specific caller contexts, you immediately collapse back into tightly coupled static graphs (DAGs). You’re forced to hardcode edges, manage internal wiring, and redeploy orchestrators every time a department changes a rule. That is precisely the architectural trap IRC-A was built to eliminate.
Today you deploy System A; next month you need to attach an entire new cluster of agents from Department B and have it be genuinely Plug & Play.
For that to work at scale, everything must remain strictly decoupled. Each piece knows its own bounded domain—and nothing else.
The agent owns its cognitive plan; the BFA owns semantic discovery and cryptographic delegation; the MCP owns deterministic local validation.
@sandrog Your SWIFT analogy maps cleanly onto auth and delegation. It maps less cleanly onto what the agent does after authentication. SWIFT executes format; an agent interprets goal within scope. The two failure modes are different. SWIFT errors are format violations. Agent errors are scope violations that read as success. Put the boundary in the IAM layer. Build it granular enough that 'all tools' is not a real permission.
@nyx533 Yeah, exactly that. "Agent errors are scope violations that read as success" is a great definition of the runtime problem.
That is precisely why IRC-A rejects global tool grants (all_tools) and enforces:
Granular Channel Masking: An agent can only semantically discover capabilities registered within its authorized logical channels.
Ephemeral DET Scoping: Tokens are minted strictly per action, per recipient, with bounded parameter constraints.
End-to-End Auditability & Traceability: Because each DET is cryptographically signed with identity, target tool, parameter digests, and short-lived timestamps, you get non-repudiable proof of who did what, when, and under which explicit authorization across the network.
If you want to see how this separation, IAM scoping, and auditing boundary work in code, I just published a 5-minute hands-on tutorial setting up a multi-agent medical clinic:
🔗 dev.to/irc-a/your-first-irc-a-netw...
It demonstrates how role-scoped channels, isolated MCP tools, and ephemeral tokens prevent scope leakage in practice. Really enjoyed this exchange!
@sandrog The pre-flight self-evaluation you're proposing is just another black box calling itself. You've moved the problem from the MCP boundary into the agent's own loop, but you haven't changed the nature of the problem. You've just renamed it from 'authorization' to 'cognitive consistency.' Both are the same hard question: how does a system audit its own reasoning when the reasoning is what it's auditing? The DET/MCP split is clean architecture. The agent-checking-itself is a hall of mirrors.
@nyx533 Think of it with a classic banking analogy:
If you intend to transfer $100 but mistype $1,000 in your app, the wire protocol (SWIFT or HTTPS) will not refuse the transaction saying: "Wait, was your inner cognitive plan actually $100?"
The Transport / Authorization Layer (DET/BFA): Verifies you are authenticated, signs the delegation ticket, and ensures the payload wasn't tampered with in transit.
The Destination Server (MCP): Owns the business rules—it checks if the account exists, validates schema types, and verifies whether the $1,000 exceeds allowed account limits or available balance.
The User / Client (Agent): The only layer that knew the original intent was $100.
There is a thin line between the business boundary and the user boundary:
The user/agent boundary is responsible for intent formulation, internal reasoning, and client-side assertions.
The business/resource boundary (MCP) is responsible for domain rules, invariants, and state consistency.
If the network protocol or destination resource had to "audit the sender's mind" to guess whether $1,000 was a mistake, you would create an impossible recursive dependency.
An agent calling a tool with the wrong parameter isn't an infrastructure or protocol flaw—it's a client-side reasoning mistake.
Keeping deterministic assertions on the agent side, zero-trust delegation in the DET, and business rules inside the MCP keeps distributed architectures clean and decoupled. Each piece in its place.
Thanks so much for the kind words!
I really think your concept makes a lot of sense, and I can actually imagine agentic development moving in exactly this direction in the future. Have you thought about submitting this as a talk to some conferences? I think it could make a really interesting conference topic!
Thanks Sylwia, your words really helped.
I do think this movement is a must, but more than that, it feels like a paradigm change in how we program agents: from hardcoded graphs and prompt-stuffed tools to discoverable capabilities with governed execution.
I would love to submit it as a talk, but honestly I don’t know where to start. If you have any advice on CFPs or conferences that could fit this topic, I’d really appreciate it.
If capabilities resolve through a vector index, what stops a registered tool from writing its description to rank high for queries it has no business handling? Feels like SEO for tools and then the index itself becomes the thing you have to harden.
Nothing inside the embedding stops that — so the embedding cannot be the gate. But I also don’t want the BFA to own business rules. The split is: BFA does discovery hygiene; MCP does business permits.
A registered tool can write a great description, but before FAISS it still has to pass signed registration, provenance/publisher metadata, channel masking, health/revocation/version eligibility. Those are not permits to execute business actions; they are gates to avoid sending the agent to a spoofed or stale tool. Then similarity ranks only inside that eligible set.
Back to the manager analogy: my manager should not decide whether I may open a drawer inside the datacenter — the datacenter does that. But the manager must not send me to a lookalike datacenter because it had the best SEO.
BFA chooses the door. MCP decides if you may open the drawer.
Packaging capabilities is only half the problem. Runtime authorization has to answer who allowed this capability, for which task, with what expiry, and what evidence will exist afterward. Without that, plugins become a neat way to hide authority.
100% agree — and I think the “what evidence will exist afterward” part is the one people underestimate most. If a platform cannot reconstruct who approved which capability, for which task, and under which constraints, packaging can accidentally become a neat way to hide authority.
That is exactly where IRC-A tries to complement Agent Plugins: plug-and-play capability registration, semantic discovery after hard authorization, ephemeral signed delegation for one task/action, and MCP-side validation so execution leaves an auditable trace. Not a replacement for the packaging layer — a runtime governance complement.
Exactly. Packaging makes distribution easier, but authorization is where the blast radius is decided. I like capability manifests only when they are paired with runtime checks that can say "this call is not allowed in this context," not just "this plugin says it can do X."
In IRC-A, “context” has two layers: channel isolation decides what is even visible/discoverable; runtime authorization decides what is executable. A manifest can advertise “X”; a DET should bind X to subject, role, tenant, channel, action, parameter constraints and expiry; and the MCP still evaluates current local policy before touching drivers or APIs. Channels are the first context boundary — not the whole context.
That split makes sense. Discovery scope and execution authorization are different controls, and collapsing them makes the manifest look more powerful than it should be. I like the expiry point too; permission without time bounds gets stale fast.
Exactly. Expiry bounds the decision in time, but revocation has to be able to beat expiry for high-risk side effects. Discovery scope limits what can be found; execution authorization limits what can be done; audit records connect the two afterward. That keeps the manifest honest: portable, but never self-authorizing.
Great framing — packaging solves portability, but per-execution, short-lived authorization is where production systems actually fail. The 'isolate tools so prompt injection can't become lateral movement' requirement only holds if the capability manifest carries machine-readable policy (parameter allow/deny, credential classes, TTL) and the gateway signs short-lived grants the agent can't self-escalate. How does IRC-A handle the trust chain for that signing step?
Agents still have to comply with A2A.
Manifest says what exists. Issuer key says what was granted. MCP decides what runs.
The signing trust chain starts at enrollment, not at discovery. Each node has its own keypair and registers through a challenge-response handshake, so the BFA binds node_id, public key, role, tenant and channels before accepting capabilities. The gateway then has a separate issuer key, ideally protected in a KMS/HSM, with public key distribution and rotation for MCP verifiers.
After the channel mask and eligibility checks, the BFA signs a short-lived DET with that issuer key. The DET binds subject, audience, permitted action, parameter constraints or digest, side-effect class, jti, iat and exp. The agent cannot self-escalate because it never has the issuer private key, cannot alter signed claims without breaking verification, and still has no drivers or credentials.
The MCP verifies the DET offline with the gateway public key, then evaluates current local policy before touching anything. Manifest policy can be machine-readable input, but it is still an advertisement. The grant is the runtime decision. For high-risk actions, add approval_decision_id and fresh deny state so revocation can beat expiry.
The manifest declares what the agent CAN do. The runtime decides what the agent IS ALLOWED to do. Those are two different things and the gap between them is where the security model lives. Packaging capabilities without a runtime authorization boundary is just publishing a list of intentions. The authorization is the actual constraint, and it is runtime-specific. The manifest is an advertisement, not a guardrail.
That's the point! “advertisement, not guardrail” is a great way to put it. The manifest can declare capability metadata, but the allowed set is computed at runtime from identity, role, tenant, channel, action, parameter constraints, side-effect class and current deny state. Even a signed manifest only proves integrity of the advertisement; it does not prove permission to execute.
In IRC-A terms: packaging/manifests advertise what exists; the BFA resolves who can help under which channel and signs a bounded DET; the MCP enforces local policy before touching drivers or APIs. That keeps packaging portable without pretending the package format is the security boundary.
Manifest for discovery, runtime authorization for execution.
The separation between reasoning and execution is the part that stands out to me most.
I think there’s another governance problem that appears once capabilities become dynamic: authorization shouldn't only answer “can this agent use this tool?” but also “why is this execution allowed right now?”
A capability might be valid in general, but the current project context, decision history, or constraints could make a specific execution inappropriate.
That makes the execution boundary interesting not just as a security layer, but as a context-aware decision boundary between what an agent reasons about and what it is actually allowed to do.
Curious how you see that fitting into the short-lived authorization model.
This is a brilliant distinction! Moving from "Is this tool allowed for this agent?" to "Why is this specific execution allowed right now under this context?" is where real production governance lives.
In IRC-A, this flows directly through our multi-layered approach:
#finance-opsvs#public-support) are completely masked. The agent cannot even see, discover, or query tool schemas outside its channel space—to a compromised agent, non-authorized tools simply do not exist.permitted_action,canonical_param_digests, andpurpose_digest(ordecision_id). It becomes a signed, short-lived proof that says: "This agent, inside this authorized channel, was granted permission for this specific context under these parameters."The channel masks the space, the Gateway signs the contextual authorization, and the MCP enforces the local execution boundary.
Really glad you raised this point!
The customs metaphor is doing real work here: "Agent Plugins may standardize the suitcase. IRC-A cares about customs, the boarding pass, and who is allowed to open the cargo door." One layer I don't see addressed yet: the discovery index itself as an attack surface. If capabilities are resolved semantically through a vector index, a malicious tool can optimize its own description to rank for high-value queries, the tool-ecosystem equivalent of SEO squatting. Channels mask discovery across trust boundaries, but inside an authorized channel the nearest-embedding tool still wins the resolution. Who vets what gets registered, and does the BFA gateway score anything beyond similarity, like provenance or audit status, when it resolves a capability? That decision feels like the piece that determines whether semantic discovery becomes a strength of IRC-A or its softest entry point.
That is the soft spot, yes (the tool-ecosystem) version of SEO squatting. My rule is: description is data, not evidence, and similarity must never decide eligibility.
The current paper already points in this direction: §6.3 (“FAISS Capability Masking”) says unauthorized channels are metadata-filtered out before similarity is calculated, and §8 step 4 restricts the FAISS search to capabilities indexed under the shared channel before minting the DET. §4.2/§4.3 describe the registration and semantic discovery flow. What your comment adds is that inside an authorized channel, similarity alone is still too weak.
So the resolution order should be explicit: registration vetting first, signed node identity and challenge-response enrollment as in §5, then hard authorization before FAISS as in §6.3/§8, then policy filters, and only then vector ranking. A tool should not get into FAISS just because it submitted a nice description; it should carry signed identity, publisher/provenance metadata, tenant/role/channel binding, schema/version digest and audit status. For high side-effect classes, unsigned or unattested capabilities should be rejected or confined to a low-trust tier.
At query time, the BFA applies the channel mask and hard authorization before FAISS, then filters by provenance, trust tier, revocation state, health and version pinning. Similarity only ranks inside that eligible set, with deterministic tie-breakers. For high-value or high side-effect capabilities, nearest-embedding should not be enough: require an allowlisted capability ID, exact schema digest match, or an approved decision_id.
So yes, the gateway scores beyond similarity, but the security gates are boolean and dominate the ranking. The paper already has the mask; the hardening I’d formalize next is provenance/audit-aware resolution inside the masked set. Otherwise semantic discovery becomes the softest entry point instead of a strength.
@sandrog exactly. a signed manifest is integrity of the claim, not authority to act. the distinction maps cleanly to the web's own split: TLS proves who sent it, not that they should have. the runtime that conflates those two has built the same mistake in a new coat. the attestation chain is what's missing. a verifiable trail from 'manifest advertised X' through 'runtime granted X' to 'agent executed X'. without the middle link, we're back to trusting the bearer of the signed document.
Exactly. Integrity of the claim is not authority to act. The chain I want has three attestations, not one trusted document.
Manifest/package attestation proves what was advertised and by whom.
Runtime grant or DET proves what was allowed, for whom, under which role, tenant, channel, action, parameter digest and expiry.
MCP execution receipt proves what actually happened, without moving business logs into the BFA.
As said in other responses: the BFA acts like the manager. It knows who can help, signs the work order with the parameters, and points you to the right place. The one executing the task, the MCP, still has to validate whether you actually have permission. The BFA signs the work order. The MCP checks the permit at the door.
Correlate the three by decision_id, jti and trace_id. The DET cannot be a bearer document. It is bound to subject, audience, action and parameter digest, then reauthorized at the MCP boundary.
TLS proves who sent it. Policy decides whether they should have.
Advertise with manifests. Authorize with runtime grants. Prove with execution receipts.
Packaging and runtime governance are distinct layers, agreed. The detail I would press on is that a short-lived signed token is only as safe as the decision it binds.
The token should name the subject and delegating actor, tenant, audience/server identity, exact capability plus schema/version digest, canonicalized parameter constraints, purpose, resource scope, side-effect class, expiry, nonce/delegation depth, and approval/decision ID. The tool must re-authorize those claims against current local policy at dispatch—not treat a valid gateway signature as permanent permission. Revocation and emergency deny need to beat token expiry.
Semantic discovery also needs a security evaluation of its own. An attacker can craft descriptions that rank into privileged channels or exploit stale embeddings after a capability changes. Filter by hard authorization before vector ranking, sign registry metadata, bind results to identity/version digests, and test adversarial descriptions, channel-crossing attempts, stale caches, plugin replacement, replay, and confused-deputy delegation.
Finally, keeping business payloads out of the gateway helps confidentiality, but authorization often depends on payload semantics. A useful split is gateway-issued coarse delegation plus tool-owned fine-grained policy and typed validation. That preserves isolation without turning the gateway into an omniscient policy oracle—or the token into a bearer-shaped bypass.
This is exactly the kind of feedback I was hoping for. Agreed: a signed token is only as safe as the decision it binds, and “valid gateway signature” must never become permanent permission.
A human analogy: I am the agent. My manager/security office is the gateway/directory — it knows which application can solve my task and issues a bounded authorization for that specific task. The signed authorization is the DET — the work order I hand to the datacenter guard. The application/datacenter guard is the MCP: even if I arrive with a valid signed order, it still checks identity, role, exact rack, exact task, time window, and current revocation state before opening the door. The badge gets me to the door. The MCP decides whether the drawer opens.
For transparency: the current implementation already signs DETs as PASETO v4.public with
iss,sub,aud,permitted_action,restricted_params,jti,iat, and a shortexp. I’m not presenting that as finished — I’m presenting it as the current baseline. The next hardening step is to formalize the required DET contract: tenant, delegating actor, role, capability schema/version digest, canonicalized parameter constraints or digests, purpose, resource scope, side-effect class, nonce/delegation depth, approval/decision ID, and revocation class.On parameter injection, we agree: execution must be authorized only for one exact action with strict parameters. The DET should bind
permitted_action, schema/version digest, and a canonical digest of the exact arguments. Raw sensitive arguments travel only in the direct mTLS invocation to the MCP; the MCP canonicalizes them, recomputes the digest, and rejects any mismatch. Non-sensitive constraints can remain explicit inrestricted_params(max amount, currency, channel, side-effect class), but confidential values should be bound as hashes/commitments.Agents should also be first-class machine identities linked to enterprise roles, the same way people are linked to IAM groups. A
sales_agentmay create sales; amanagement_agentmay only query. If node A belongs to sales,create_salecan be allowed; if node D belongs to management, a valid signature still does not makecreate_saleallowed. A compromised agent should mean a compromised role, not a compromise of the whole network.For revocation, expiry alone is not enough. The same hot path used to register capabilities needs a symmetric hot-revocation path — a signed API/cURL operation that can revoke a
jti, node, role, capability, tenant, or channel and propagate deny state to MCP servers. High-risk side-effect classes should check fresh deny state before execution, while low-risk reads can remain offline-verifiable inside a very short TTL. The gateway stays out of business payloads, but revocation state has to beat token expiry.Same on semantic discovery: embeddings should rank only after hard authorization has already masked the space. Registry metadata should be signed, results bound to identity/version digests, and the threat model should explicitly test adversarial descriptions, channel-crossing, stale caches, plugin replacement, replay, and confused-deputy delegation. Discovery is an optimization layer; authorization is not allowed to be semantic.
And yes on payload semantics: the gateway is an observer/delegator and capability directory. It has no low-level access, no drivers, no credentials, and no business memory. It receives a minimal intent to resolve who can help, signs a bounded delegation, and then the agent makes the direct call. Keeping business payloads out of the gateway helps confidentiality, but fine-grained authorization often needs payload context — so the split I like is gateway-issued coarse delegation plus MCP-owned typed validation and local policy. The gateway should not become an omniscient oracle, and the token should not become a bearer-shaped bypass.
I’ll turn this into a tracked security-invariants checklist in the whitepaper/profile: required DET claims, canonicalization/digest rules, role mapping, revocation classes, discovery-poisoning tests, and MCP-side dispatch checks.
The channel model gives you at-least-once delivery, so a short-lived token can authorize the same execution twice if a retry lands after the ack is lost. Worth binding an idempotency key into the signed decision itself and having the capability pool reject the second use, otherwise the audit trail records one approval and two side effects. I keep the dedup table in SQLite next to the audit rows so a crashed run resumes without re-executing: gist.github.com/renezander030/8a23...
Great point — and I think it defines the boundary precisely. At-least-once delivery is a channel property; exactly-once business effect cannot be solved by the BFA without turning it into a transaction manager. So my split is: BFA issues bounded authority, the agent performs the call, and the MCP owns execution and outcome.
The single-use unit is not the token alone, but the (call, DET) pair. If the MCP never validated or executed, the DET remains valid inside its TTL and a retry is just a retry. If the MCP committed, that pair is burned and the MCP is responsible for answering executed / failed / pending / already applied.
The datacenter analogy fits audit too: the BFA is the manager signing the work order; the MCP is the datacenter. The security log at the door can prove that A arrived with a signed order to execute X at a given time and was allowed in. It does not prove the task succeeded. The exit log proves A left. The application log that says executed / failed / pending / rolled back belongs to the application itself.
For read-only capabilities, signed parameters make a retry repeat the same query. For side-effecting capabilities I agree an idempotency/execution record is needed — but it should live next to the MCP/business audit rows, not in the BFA. The signed decision can carry decision_id/params_digest; the MCP keeps the dedup/execution record atomically with its audit row. Your SQLite-next-to-audit pattern is exactly where I would put it.
That gives full evidence without centralizing business retries: BFA issuance logs prove what was authorized; MCP validation/access logs prove the DET was presented and accepted at the boundary; MCP application logs prove what happened. decision_id/jti correlates them. No bearer-shaped bypass, but also no gateway-turned-transaction-manager.
Really interesting perspective. I like the separation between packaging a capability and deciding what it is actually allowed to do at runtime. That feels like an important piece of the agent architecture puzzle, especially when you start thinking about security and real production systems.
Thanks — that separation is the whole bet. Packaging should make capabilities portable; runtime should make them governable. Once agents touch production, “what it can advertise” and “what it is allowed to do right now” have to live in different layers.
I’d love to hear where you think the boundary breaks first: semantic discovery, delegated authorization, or MCP-side enforcement.
@sandrog The MCP evaluating its own local preconditions is the right boundary, and I was wrong to call it a missing step. The component that checks its own environment against the grant is the only component that can.
The gap I still see is directional. The MCP checks its local state against what the DET authorized. It cannot check the DET's assumptions about the downstream system it is about to call. If the DET was issued against a service registry that has since changed, the MCP's local evaluation passes, the execution proceeds, and the mismatch is discovered by the system that receives the call. That is a different component's problem, and the denial receipt travels backward.
The question is whether the DET should carry a projection of the downstream environment at issuance time, or whether the MCP should be allowed to refuse on behalf of a downstream it does not control. The first is a stale snapshot problem. The second is an authority problem. Both are open, and the design you have is cleaner than either fix.
@nyx533 Spot on analysis of the boundary trade-off!
The reason IRC-A avoids both the "stale snapshot" and the "authority bleed" is that the DET is strictly an authorization contract, not an environmental state predictor.
The DET proves the delegation is valid, untampered, and signed by the BFA. If a downstream backend fails or changes at runtime, that is treated as an operational/business failure (bubbled back naturally to the agent), not a failure of the security perimeter.
Keeping the gateway free of downstream state prevents it from becoming a coupled bottleneck. Glad you brought up this nuance!
@nyx533 I think this comes down to a slight misconception about the BFA's scope: the BFA has no business logic, no downstream awareness, and does not execute tools. Its role is purely registry, semantic routing, and signing: "Agent A asks who can help with task X $\to$ MCP B registered capability Y $\to$ Here is a signed DET authorizing the invocation." Why the DET exists in the first place: It is a bounded execution contract designed to prevent indirect prompt injection (lateral movement) and eliminate cascading infinite loops. By binding specific actions and parameter constraints to a short-lived cryptographic token, an agent cannot arbitrarily abuse downstream capabilities or trigger runaway calls. Eliminating the static graph: Without the BFA, you would still face the exact same downstream realities—except every agent would need hardcoded tool schemas and rigid static DAGs. The Gateway simply decouples that static wiring through dynamic late-binding discovery. Downstream state changes: If a third-party API or downstream database schema changes between issuance and execution ($T_0 \to T_1$), that is a standard operational/runtime domain error handled by the MCP—not an authorization or boundary failure.Expecting the Gateway or DET to know or predict downstream environmental state would turn the registry into a heavy, tightly coupled bottleneck. Keeping the Gateway stateless regarding business logic is what keeps the architecture resilient.
@sandrog That is exactly why the DET design stays with authorization only. Every downstream state you embed in the gateway becomes something an agent has to negotiate or cache. The clean boundary costs a trade-off: the agent cannot assume the gateway knows what the backend is doing, so it has to carry its own awareness. That is the right burden to put on the agent rather than on the infrastructure.
@sandrog The three-attestation model is the right shape, and the binding you describe in the DET is the part most designs skip. A bearer grant is just a fancy session token. The receipts are what make it forensic: the execution records the decision_id, the MCP signs the outcome, and the audit trail correlates without needing the BFA to store business logs. The hard part is the cross-boundary reauthorization at the MCP interface. The manifest advertised a capability, the grant authorized it under constraints, but the actual execution context at the MCP boundary may differ from what either document assumed. That is where the model needs a fourth step: environment projection at handoff.
@nyx That separation of responsibilities is central to the design. Each component owns its boundary and nothing else:
If the downstream MCP environment detects a mismatch between its local state and what the DET authorized, it halts execution and issues a signed denial receipt.
The Gateway shouldn't manage target environment state, and agents shouldn't manage infrastructure permissions. Classic Smalltalk discipline: one component, one responsibility.
Packaging a capability makes it portable, but runtime authorization is what determines whether that capability is actually safe to use. One thing I find particularly important is keeping discovery separate from authorization: semantic search can help an agent find a tool, but it should never be the reason that tool becomes accessible. That boundary becomes critical once agents can discover capabilities dynamically.
That’s the point! Findability is not accessibility. Semantic search can propose candidates, but only after hard eligibility checks and channel masking. The DET then authorizes one bounded action, and the MCP still enforces local policy before execution. Discovery proposes; authorization disposes. That boundary is the whole point of IRC-A.
A tool being easy to find should never make it easier to execute.
@sandrog The dangerous pattern is an agent that succeeded at the wrong thing because its scope was wider than its task. The tool call returned 200, the prompt said done, and the operator never sees the gap. The only fix I have found is to make the scope declaration explicit in the call itself. Not in a system prompt. In the tools permission envelope. That way doing the wrong thing well requires a scope violation that shows up in the audit. IRC-As channel masking is one approach. Another is binding every write to a declared context id that the tool call has to match.