<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" submissionType="IETF" docName="draft-nivalto-agentroa-route-authorization-00" category="info" ipr="trust200902" obsoletes="" updates="" xml:lang="en" symRefs="true" sortRefs="false" tocInclude="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.33.0 -->
  <!-- Generated by id2xml 1.5.2 on 2026-04-10T22:29:10Z -->
	<front>
    <title abbrev="Agent Route Origin Authorization (AgentR">Agent Route Origin Authorization (AgentROA): A Cryptographic Policy Enforcement Framework for AI Agent Actions over the Model Context Protocol (MCP)</title>
    <seriesInfo name="Internet-Draft" value="draft-nivalto-agentroa-route-authorization-00"/>
    <author initials="J." surname="Michalak" fullname="Joseph Michalak">
      <organization>Nivalto, Inc.</organization>
      <address>
        <postal>
          <city>Tampa</city>
          <region>Florida</region>
          <country>United States of America</country>
        </postal>
        <email>jmichalak@nivalto.com</email>
        <uri>https://nivalto.com</uri>
      </address>
    </author>
    <date year="2026" month="April" day="8"/>
    <workgroup>Internet Engineering Task Force</workgroup>
    <abstract>
      <t>
   This document specifies the Agent Route Origin Authorization
   (AgentROA) framework, a cryptographic policy enforcement model for
   governing the actions of autonomous AI agents operating over the
   Model Context Protocol (MCP) and Agent-to-Agent (A2A) protocols.
   AgentROA introduces three core protocol objects: the Agent Route
   Origin Authorization (ROA) envelope, the Agent Route Attestation
   (ARA) per-hop receipt, and the Agent Execution Receipt (AER).
   Together these objects enable: (1) cryptographic binding of an
   agent's authorized action scope to a signed policy envelope at
   session initialization, (2) per-hop attestation across multi-agent
   delegation chains with monotonic scope-narrowing semantics (no
   policy envelope may be expanded by a downstream delegation), and
   (3) cryptographic receipts produced intrinsically by the enforcement
   decision at each MCP tool call boundary.  The framework is modeled
   on the BGP Route Origin Authorization (ROA) concept from RPKI
   (RFC 6480) applied to the AI agent execution domain.</t>
      <t>
   The Border Gateway enforcement model positions a cryptographic
   enforcement proxy at the MCP protocol boundary — external to the
   agent's execution context — reducing the risk that governance
   decisions are influenced by the governed agent by placing
   enforcement in a separate process boundary.  This document
   establishes the architectural model, protocol object schemas, and
   enforcement semantics for the AgentROA framework.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="sect-1" numbered="true" toc="default">
      <name>Introduction</name>
      <section anchor="sect-1.1" numbered="true" toc="default">
        <name>Motivation</name>
        <t>
   Autonomous AI agents are increasingly being deployed in enterprise
   and regulated environments.  These systems can investigate incidents
   across cloud infrastructure, invoke external tools, initiate
   transactions, and delegate tasks to downstream agents without human
   review at each step.</t>
        <t>
   The Model Context Protocol (MCP) provides a common mechanism for
   connecting agents to external tools, data sources, and APIs.  The
   Agent-to-Agent (A2A) protocol provides complementary support for
   inter-agent communication and task delegation.</t>
        <t>
   These protocols address connectivity and interoperability.  They do
   not, by themselves, define a cryptographic mechanism that binds an
   agent's authorized action scope to protocol execution, enforces that
   scope at the protocol boundary, or produces receipts that can be
   independently verified after the fact.</t>
        <t>
   Existing governance approaches often rely on application-layer
   monitoring, behavioral detection, or post-execution audit logging.
   In deployments where such governance mechanisms are co-located with
   the governed agent, a compromised, manipulated, or misconfigured
   agent may influence the governance outcome.</t>
        <t>
   AgentROA addresses this concern by positioning enforcement at the
   protocol boundary, external to the agent's execution context.  The
   Border Gateway enforcement proxy intercepts MCP tool call requests
   before they reach the target MCP server, validates the caller's ROA
   envelope, enforces monotonic scope-narrowing semantics across
   delegation chains, and produces a cryptographic AER receipt as an
   intrinsic output of the enforcement decision.</t>
        <t>
   The governing question AgentROA answers is: was this agent
   authorized to perform this specific action under this specific
   policy envelope at this specific moment — and can that be shown to a
   third party, including a regulator, auditor, or counter-party,
   without relying on the agent's own account of execution?</t>
      </section>
      <section anchor="sect-1.2" numbered="true" toc="default">
        <name>BGP RPKI Analogy</name>
        <t>
   AgentROA draws an analogy from the BGP Route Origin
   Authorization framework specified in RFC 6480 (RPKI) and RFC 6811
   (BGP Prefix Origin Validation).</t>
        <t>
   In BGP RPKI, a Route Origin Authorization (ROA) is a cryptographically
   signed object that states which Autonomous System (AS) is authorized
   to originate routes for a specific IP address prefix.  Border routers
   validate incoming route announcements against the ROA database before
   accepting them into the routing table.  This prevents route hijacking
   by ensuring that only authorized ASes can announce specific prefixes.</t>
        <t>
   AgentROA applies the same model to AI agent execution:</t>
        <ul spacing="normal">
          <li>
            <t>An Agent ROA envelope states which agent identity is authorized
      to invoke specific MCP capabilities under specific policy
      constraints, signed by the authorizing entity.</t>
          </li>
          <li>
            <t>The Border Gateway validates incoming MCP tool calls against the
      ROA envelope before forwarding them to the target MCP server.
      This prevents capability hijacking by ensuring that agents can
      only invoke capabilities they are explicitly authorized for.</t>
          </li>
          <li>
            <t>The Agent Route Attestation (ARA) provides per-hop attestation
      across multi-agent delegation chains, analogous to BGP path
      validation, ensuring that each hop in a delegation chain operated
      within its declared scope.</t>
          </li>
        </ul>
        <t>
   The key structural insight from RPKI that AgentROA preserves is the
   separation of the authorization infrastructure (the ROA envelope and
   its signing) from the enforcement infrastructure (the Border
   Gateway).  This separation ensures that the enforcement mechanism
   does not depend on trusting the party being governed.</t>
      </section>
      <section anchor="sect-1.3" numbered="true" toc="default">
        <name>Scope</name>
        <t>
   This document specifies:</t>
        <ul spacing="normal">
          <li>
            <t>The AgentROA framework architecture and trust boundary model.</t>
          </li>
          <li>
            <t>The protocol object schemas for ROA envelopes, ARA per-hop
      attestations, and AER execution receipts.</t>
          </li>
          <li>
            <t>The monotonic scope-narrowing semantics for multi-agent
      delegation chains.</t>
          </li>
          <li>
            <t>The Border Gateway enforcement proxy model for MCP and A2A.</t>
          </li>
        </ul>
        <t>
   Future extensions, including voice-triggered actions and agent
   identity addressing, are outside the scope of this document.</t>
        <t>
   This document does not specify a wire protocol for MCP or A2A,
   which are governed by their respective specifications.  AgentROA
   operates as an enforcement layer above the MCP OAuth 2.0
   authorization mechanism specified in the MCP Authorization
   specification.</t>
      </section>
    </section>
    <section anchor="sect-2" numbered="true" toc="default">
      <name>Terminology</name>
      <t>
   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
   and "OPTIONAL" in this document are to be interpreted as described
   in BCP 14 <xref target="RFC2119" format="default"/> <xref target="RFC8174" format="default"/>.</t>
      <dl newline="true" spacing="normal" indent="3">
        <dt>Agent:</dt>
        <dd>
	An autonomous software system that perceives its environment,
      makes decisions, and takes actions — including invoking tools via
      MCP and delegating tasks to other agents via A2A — without
      constant human oversight at each step.
	</dd>
        <dt>Agent Route Origin Authorization (ROA) Envelope:</dt>
        <dd>
	A cryptographically signed data structure that specifies the
      authorized action scope for a specific agent session, including
      the set of permitted MCP capabilities, the policy digest binding,
      the session identity, the device attestation reference, and the
      approval state.  Analogous to a BGP ROA for IP prefix origin
      authorization.
	</dd>
        <dt>Agent Route Attestation (ARA):</dt>
        <dd>
	A cryptographically signed per-hop attestation produced at each
      delegation boundary in a multi-agent execution chain.  Each ARA
      object references the upstream ROA or ARA, the downstream
      agent's declared scope, and certifies that the downstream scope
      is a proper subset of the upstream scope (monotonic scope-
      narrowing).
	</dd>
        <dt>Agent Execution Receipt (AER):</dt>
        <dd>
	A cryptographically signed artifact produced by the Border
      Gateway at the moment an MCP tool call enforcement decision is
      made.  The AER is produced intrinsically by the enforcement
      decision, not generated by a separate logging system after
      execution.  The AER includes the policy digest active at decision
      time, the capability identifier, the session identity, and the
      enforcement outcome.
	</dd>
        <dt>Border Gateway:</dt>
        <dd>
	An enforcement proxy that sits at the MCP protocol boundary
      between an agent and one or more MCP servers.  The Border Gateway
      is external to the agent's execution context, operating in a
      separate process with its own trust domain.  The Border Gateway
      validates ROA envelopes, enforces monotonic scope-narrowing
      semantics, and produces AER receipts.
	</dd>
        <dt>Capability Identifier:</dt>
        <dd>
	A structured identifier for a specific MCP tool invocation,
      consisting of the MCP server identifier and the tool name,
      formatted as mcp:&lt;server-id&gt;.&lt;tool-name&gt;.
	</dd>
        <dt>Delegation Chain:</dt>
        <dd>
	An ordered sequence of ARA objects representing the authorization
      path from the root ROA envelope to the current executing agent.
      Each element in the chain represents one agent-to-agent
      delegation hop.
	</dd>
        <dt>Monotonic Scope-Narrowing:</dt>
        <dd>
	The property of a delegation chain where each downstream agent's
      authorized scope is a proper subset of — or equal to — its
      upstream delegator's scope.  The scope MUST NOT be expanded at
      any delegation boundary.  This is the "no-loosen" invariant.
	</dd>
        <dt>No-Loosen Invariant:</dt>
        <dd>
	The fundamental enforcement rule of AgentROA: a downstream agent
      in a delegation chain MAY NOT be authorized for capabilities or
      policy scopes broader than those of its upstream delegator.
      Formally: scope(ARA[n]) ⊆ scope(ARA[n-1]) for all n.
	</dd>
        <dt>Policy Digest:</dt>
        <dd>
	A cryptographic hash of the policy document governing an agent's
      authorized behavior at a specific version.  The policy digest
      binds the ROA envelope to the specific policy in effect at the
      time of authorization.
	</dd>
        <dt>Session Identity:</dt>
        <dd>
	A cryptographically bound identifier for a specific agent
      execution session, including the agent's principal identity, the
      device or infrastructure attestation, and the session inception
      timestamp.
	</dd>
        <dt>SCITT:</dt>
        <dd>
	Supply Chain Integrity, Transparency and Trust <xref target="I-D.ietf-scitt-architecture" format="default"/>.
      AgentROA receipts are designed to be compatible with SCITT
      transparency logs.
	</dd>
      </dl>
    </section>
    <section anchor="sect-3" numbered="true" toc="default">
      <name>Architecture Overview</name>
      <section anchor="sect-3.1" numbered="true" toc="default">
        <name>System Components</name>
        <t>
   The AgentROA framework consists of the following components:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>a) Agent Identity Registry</dt>
          <dd>
	A registry mapping agent identifiers to cryptographic public keys
      and capability declarations.  Agents register their identity and
      declared capability scope prior to session initiation.
	</dd>
          <dt>b) Policy Engine</dt>
          <dd>
	A system that evaluates agent action requests against policy
      documents and produces ROA envelopes at session initiation.
      The policy engine is operated by the enterprise or regulated
      entity deploying the agent.
	</dd>
          <dt>c) Border Gateway</dt>
          <dd>
	The enforcement proxy described in <xref target="sect-7" format="default"/>.  The Border
      Gateway is the critical enforcement point.  It MUST be deployed
      external to the agent's execution context.
	</dd>
          <dt>e) SCITT Transparency Log (optional)</dt>
          <dd>
	An append-only transparency log compatible with <xref target="I-D.ietf-scitt-architecture" format="default"/>
      that records AER receipts.  When deployed, the SCITT log
      provides independent third-party verifiability of the agent's
      execution history.
	</dd>
        </dl>
      </section>
      <section anchor="sect-3.2" numbered="true" toc="default">
        <name>Trust Boundary Model</name>
        <t>
   The fundamental trust boundary in AgentROA separates two domains:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>The Agent Execution Domain:</dt>
          <dd>
	The process or container in which the AI agent framework
      executes.  This domain includes the agent's model inference,
      tool orchestration, and application-layer code.  This domain
      is considered untrusted from the perspective of the enforcement
      infrastructure.
	</dd>
          <dt>The Enforcement Domain:</dt>
          <dd>
	The process or container in which the Border Gateway executes.
      This domain is separate from and external to the Agent Execution
      Domain.  The Enforcement Domain holds the signing keys for AER
      receipts and has sole authority to authorize MCP tool calls.
	</dd>
        </dl>
        <t>
   This separation is the critical architectural distinction from
   application-layer governance approaches in which the policy engine
   and the agents it governs run in the same process.  When a
   governance layer runs in the same process as the agent, a
   compromised agent may influence the governance outcome.</t>
        <t>
   AgentROA assumes that the Border Gateway enforcement proxy runs in
   a separate process from the governed agent.  Deployment MAY use
   sidecar containers in a Kubernetes pod, separate virtual machines,
   or hardware-isolated enclaves.  The architectural model in this
   document does not assume a policy decision point that is co-located
   within the agent's execution context.</t>
      </section>
      <section anchor="sect-3.3" numbered="true" toc="default">
        <name>Enforcement Proxy Architecture</name>
        <t>
   The Border Gateway implements the following request handling model
   for MCP tool calls:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Step 1: Intercept</dt>
          <dd>
	The Border Gateway receives the MCP tool call request from the
      agent.  The agent MUST present its current ROA envelope or a
      valid ARA chain in an authorization header or equivalent
      protocol metadata field.
	</dd>
          <dt>Step 2: Validate Envelope</dt>
          <dd>
            <t>
	The Border Gateway validates:
      a) The ROA envelope signature (EdDSA verification against the
         agent's registered public key in the Agent Identity Registry).
            </t>
            <dl newline="true" spacing="normal" indent="3">
              <dt>b) The policy digest (the hash of the policy document in the</dt>
              <dd>
	envelope MUST match the current policy version for this
         agent's scope).
	</dd>
              <dt>c) The session identity (the session MUST be active and not</dt>
              <dd>
	expired).
	</dd>
              <dt>d) The device attestation reference (if required by policy).</dt>
              <dd/>
            </dl>
          </dd>
          <dt>Step 3: Validate Scope</dt>
          <dd>
	The Border Gateway validates that the requested capability
      (mcp:&lt;server-id&gt;.&lt;tool-name&gt;) is within the authorized scope
      declared in the ROA envelope or ARA chain.
	</dd>
          <dt>Step 4: Apply No-Loosen Check</dt>
          <dd>
	If the request originates from a delegation chain (ARA present),
      the Border Gateway validates the monotonic scope-narrowing
      invariant: scope(current-ARA) ⊆ scope(parent-ARA-or-ROA).
      A delegation chain that attempts to expand scope MUST be
      rejected.
	</dd>
          <dt>Step 5: Produce AER</dt>
          <dd>
	The Border Gateway produces an Agent Execution Receipt (AER)
      as an intrinsic output of the enforcement decision.  The AER
      is signed by the Border Gateway's private key.  The AER is
      produced regardless of whether the enforcement outcome is
      PERMIT or DENY.
	</dd>
          <dt>Step 6: Forward or Reject</dt>
          <dd>
	If the outcome is PERMIT, the Border Gateway forwards the MCP
      tool call to the target MCP server.  If the outcome is DENY,
      the Border Gateway returns an authorization error to the agent
      and records the denial event.
	</dd>
          <dt>Step 7: Write to Ledger</dt>
          <dd>
	The AER is written to the local audit store and, if configured,
      to the SCITT transparency log.
	</dd>
        </dl>
      </section>
    </section>
    <section anchor="sect-4" numbered="true" toc="default">
      <name>Agent Route Origin Authorization (ROA) Envelope</name>
      <section anchor="sect-4.1" numbered="true" toc="default">
        <name>ROA Envelope Structure</name>
        <t>
   The AgentROA ROA Envelope is a JSON object with the following
   top-level fields.  All fields are REQUIRED unless noted.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>schema_version:</dt>
          <dd>
	String.  MUST be "1.0".
	</dd>
          <dt>envelope_id:</dt>
          <dd>
	String.  A unique identifier for this envelope instance,
      formatted as "env:&lt;random-hex-16&gt;".
	</dd>
          <dt>issued_at:</dt>
          <dd>
	String.  ISO 8601 datetime at which this envelope was issued.
	</dd>
          <dt>expires_at:</dt>
          <dd>
	String.  ISO 8601 datetime at which this envelope expires.
      Enforcement decisions MUST fail for expired envelopes.
	</dd>
          <dt>session:</dt>
          <dd>
            <t>
	Object.  Session context.
      - session_id: String.  Unique session identifier.
      - channel: String.  One of: "api", "mcp_client", "voice",
        "browser", "mobile_app".
            </t>
            <ul spacing="normal">
              <li>
                <t>agent_id: String.  The agent identifier of the governed agent.</t>
              </li>
              <li>
                <t>device_attestation_ref: String, OPTIONAL.  Reference to a
        device attestation artifact (e.g., WebAuthn assertion).</t>
              </li>
            </ul>
          </dd>
          <dt>authorized_scope:</dt>
          <dd>
            <t>
	Object.  The authorized capability scope.
      - capabilities: Array of Strings.  Each element is a capability
        identifier of the form mcp:&lt;server-id&gt;.&lt;tool-name&gt; or the
        wildcard form mcp:&lt;server-id&gt;.*.
            </t>
            <ul spacing="normal">
              <li>
                <t>max_delegation_depth: Integer.  Maximum number of delegation
        hops permitted.  MUST be &gt;= 0.</t>
              </li>
              <li>
                <t>cross_org_permitted: Boolean.  Whether delegation across
        organizational boundaries is permitted.</t>
              </li>
              <li>
                <t>data_classification_ceiling: String, OPTIONAL.  Maximum data
        classification level accessible.</t>
              </li>
              <li>
                <t>budget_ceiling: Number, OPTIONAL.  Maximum total spend or
        resource budget permitted for this session, in the unit
        declared by budget_unit.  Downstream delegations MUST NOT
        declare a budget_ceiling exceeding this value.</t>
              </li>
              <li>
                <t>budget_unit: String, OPTIONAL.  Unit for budget_ceiling
        (e.g., "USD", "tokens", "api_calls").  Required when
        budget_ceiling is present.</t>
              </li>
              <li>
                <t>price_class: Integer, OPTIONAL.  Maximum price tier permitted
        (lower value = lower cost).  Downstream delegations MUST NOT
        declare a price_class exceeding this value.</t>
              </li>
              <li>
                <t>slo_class: Integer, OPTIONAL.  Minimum required service level
        (higher value = stricter SLO).  Downstream delegations MUST
        NOT declare an slo_class below this value.</t>
              </li>
            </ul>
          </dd>
          <dt>policy:</dt>
          <dd>
            <t>
	Object.  Policy binding.
      - policy_id: String.  Identifier of the governing policy.
      - policy_version: String.  Version of the governing policy.
      - policy_digest: String.  SHA-256 hash of the policy document,
        formatted as "sha256:&lt;hex&gt;".
            </t>
            <ul spacing="normal">
              <li>
                <t>policy_uri: String, OPTIONAL.  URI at which the policy
        document may be retrieved.</t>
              </li>
            </ul>
          </dd>
          <dt>authorization:</dt>
          <dd>
            <t>
	Object.  Authorization requirements.
      - auth_strength: String.  One of: "session_only",
        "device_bound", "device_bound_with_attestation",
        "dual_control".
            </t>
            <ul spacing="normal">
              <li>
                <t>approval_state: String.  One of: "pending", "granted",
        "not_required".</t>
              </li>
              <li>
                <t>approval_artifact_ref: String, OPTIONAL.  Reference to
        the signed approval artifact.</t>
              </li>
            </ul>
          </dd>
          <dt>evidence:</dt>
          <dd>
            <t>
	Object.  Evidence references.
      - session_hash: String.  Hash of the session establishment
        event.
            </t>
            <ul spacing="normal">
              <li>
                <t>model_provenance: Array of Strings.  Identifiers of the
        AI models that may execute within this session.</t>
              </li>
            </ul>
          </dd>
          <dt>signatures:</dt>
          <dd>
	Array of Objects.  One or more signatures.
      - signer: String.  Identifier of the signing entity.
      - alg: String.  Signature algorithm.  MUST be "EdDSA".
      - sig: String.  Base64url-encoded signature over the
        canonical JSON serialization of all fields except
        "signatures".
	</dd>
        </dl>
      </section>
      <section anchor="sect-4.2" numbered="true" toc="default">
        <name>Policy Digest Binding</name>
        <t>
   The policy_digest field binds the ROA envelope to a specific
   version of the governing policy document.  This binding serves
   two purposes:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>a) Enforcement time validation: The Border Gateway MUST verify</dt>
          <dd>
	that the policy_digest in the ROA envelope matches the hash
      of the current policy document for this agent's scope.  If the
      policy has been updated since the envelope was issued, the
      envelope MUST be rejected and a new envelope issued against
      the current policy.
	</dd>
          <dt>b) Receipt auditability: The AER receipt includes the policy_digest</dt>
          <dd>
	from the envelope at the time of the enforcement decision.  This
      allows an auditor reviewing the receipt to retrieve the specific
      policy version that governed the action, even if the policy has
      subsequently changed.
	</dd>
        </dl>
        <t>
   The canonical policy digest is computed as:</t>
        <artwork name="" type="" align="left" alt=""><![CDATA[
policy_digest = "sha256:" || hex(SHA-256(policy_document_bytes))
]]></artwork>
        <t>
   where policy_document_bytes is the UTF-8 encoding of the policy
   document in its canonical JSON serialization.</t>
      </section>
      <section anchor="sect-4.3" numbered="true" toc="default">
        <name>Monotonic Scope-Narrowing Semantics</name>
        <t>
   This section specifies the no-loosen invariant, which is the
   foundational enforcement property of AgentROA.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>DEFINITION (Monotonic Scope-Narrowing):</dt>
          <dd>
	For any two consecutive elements ARA[n-1] and ARA[n] in a
      delegation chain, the full policy envelope of ARA[n] MUST be
      no broader than the policy envelope of ARA[n-1] across all
      constrained dimensions.
	</dd>
        </dl>
        <t>
   AgentROA applies a tighten-only partial-order algebra across three
   distinct constraint dimensions.  Each dimension has its own
   ordering operator, and a violation of ANY dimension MUST cause the
   Border Gateway to reject the delegation with a DENY AER receipt.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Dimension 1 — Capability Scope (set containment):</dt>
          <dd>
	Let C(x) denote the set of capabilities authorized by envelope
      or attestation x.  Then for all n &gt; 0:
	</dd>
        </dl>
        <artwork name="" type="" align="left" alt=""><![CDATA[
      C(ARA[n]) ⊆ C(ARA[n-1])

   where ARA[0] is the root ROA envelope.
]]></artwork>
        <dl newline="false" spacing="normal" indent="3">
          <dt/>
          <dd>
      An ARA that claims capabilities outside the authorized set of
      its parent violates this dimension.  The denial reason code
      MUST be SCOPE_EXPANSION_DENIED.</dd>
        </dl>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Dimension 2 — Budget and Price Class (less-than-or-equal):</dt>
          <dd>
	Let B(x) denote the budget_ceiling declared in envelope x and
      P(x) denote the price_class.  Then for all n &gt; 0:
	</dd>
        </dl>
        <artwork name="" type="" align="left" alt=""><![CDATA[
      B(ARA[n]) ≤ B(ARA[n-1])
      P(ARA[n]) ≤ P(ARA[n-1])
]]></artwork>
        <dl newline="false" spacing="normal" indent="3">
          <dt/>
          <dd>
      A downstream delegation that raises the budget ceiling or
      escalates the price class above the parent's declared maximum
      violates this dimension.  The denial reason code MUST be
      BUDGET_EXPANSION_DENIED.</dd>
        </dl>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Dimension 3 — Service Level Objective (greater-than-or-equal):</dt>
          <dd>
	Let S(x) denote the slo_class declared in envelope x, where
      higher numerical values denote stricter service levels.  Then
      for all n &gt; 0:
	</dd>
        </dl>
        <artwork name="" type="" align="left" alt=""><![CDATA[
      S(ARA[n]) ≥ S(ARA[n-1])
]]></artwork>
        <dl newline="false" spacing="normal" indent="3">
          <dt/>
          <dd>
      A downstream delegation that relaxes the required service level
      below the parent's declared floor violates this dimension.  The
      denial reason code MUST be SLO_RELAXATION_DENIED.</dd>
        </dl>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Combined invariant:</dt>
          <dd>
	The Border Gateway MUST evaluate all three dimensions at each
      delegation boundary.  A delegation envelope that satisfies
      Dimension 1 but violates Dimension 2 or 3 MUST be rejected.
      Partial conformance is not sufficient.
	</dd>
          <dt>IMPLEMENTATION REQUIREMENT:</dt>
          <dd>
	The Border Gateway MUST evaluate this invariant at each
      delegation boundary.  An ARA that violates any dimension of the
      tighten-only partial-order algebra MUST be rejected.  The
      rejection MUST produce a DENY AER receipt containing the
      applicable reason code.
	</dd>
        </dl>
        <t>
   This invariant prevents privilege escalation through agent
   delegation chains.  An agent that delegates a task to a downstream
   agent CANNOT grant the downstream agent permissions, budget, or
   relaxed service levels that the delegating agent does not itself
   possess.</t>
        <t>
   Scope comparison algorithm:</t>
        <t>
   The Border Gateway compares capability sets using the following
   procedure:</t>
        <ol spacing="normal" type="1"><li>
            <t>Resolve each capability identifier to its canonical form.
      Wildcard capabilities (mcp:&lt;server-id&gt;.*) are expanded to
      include all capabilities advertised by the named MCP server's
      capability manifest.</t>
          </li>
          <li>
            <t>For each capability in the downstream ARA, verify that the
      capability is present in or subsumed by a wildcard in the
      parent's capability set.</t>
          </li>
          <li>
            <t>If any downstream capability is not subsumed, reject the
      delegation with a SCOPE_EXPANSION_DENIED error.</t>
          </li>
          <li>
            <t>If the downstream ARA declares a budget_ceiling, verify that:
         budget_ceiling(ARA[n]) ≤ budget_ceiling(ARA[n-1])</t>
            <dl newline="true" spacing="normal" indent="0">
              <dt>If violated, reject with BUDGET_EXPANSION_DENIED.</dt>
              <dd/>
            </dl>
          </li>
          <li>
            <t>If the downstream ARA declares a price_class, verify that:
         price_class(ARA[n]) ≤ price_class(ARA[n-1])</t>
            <dl newline="true" spacing="normal" indent="0">
              <dt>If violated, reject with BUDGET_EXPANSION_DENIED.</dt>
              <dd/>
            </dl>
          </li>
          <li>
            <t>If the downstream ARA declares an slo_class, verify that:
         slo_class(ARA[n]) ≥ slo_class(ARA[n-1])</t>
            <dl newline="true" spacing="normal" indent="0">
              <dt>If violated, reject with SLO_RELAXATION_DENIED.</dt>
              <dd/>
            </dl>
          </li>
        </ol>
      </section>
      <section anchor="sect-4.4" numbered="true" toc="default">
        <name>ROA Envelope Signing</name>
        <t>
   ROA envelopes MUST be signed using EdDSA with the Ed25519 curve
   as specified in <xref target="RFC8032" format="default"/>.  The signature is computed over the
   canonical JSON serialization of the envelope excluding the
   "signatures" field.</t>
        <t>
   Canonical JSON serialization follows the JSON Canonicalization
   Scheme (JCS) as specified in <xref target="RFC8785" format="default"/>.</t>
        <t>
   The signing key MUST correspond to the public key registered in
   the Agent Identity Registry for the authorizing entity.  The
   key identifier MUST be included in the "signer" field of the
   signature object.</t>
      </section>
    </section>
    <section anchor="sect-5" numbered="true" toc="default">
      <name>Agent Route Attestation (ARA) Per-Hop Protocol</name>
      <section anchor="sect-5.1" numbered="true" toc="default">
        <name>ARA Object Structure</name>
        <t>
   An Agent Route Attestation (ARA) object is produced at each
   agent-to-agent delegation boundary.  The ARA attests that:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>a) The delegating agent (the upstream agent) authorized the</dt>
          <dd>
	downstream agent to act on its behalf.
	</dd>
          <dt>b) The downstream agent's authorized scope is within the</dt>
          <dd>
	delegating agent's scope (monotonic scope-narrowing).
	</dd>
        </dl>
        <t>
   c) The delegation occurred within a valid session.</t>
        <t>
   The ARA object has the following structure:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>schema_version:</dt>
          <dd>
	String.  MUST be "1.0".
	</dd>
          <dt>ara_id:</dt>
          <dd>
	String.  Unique identifier for this ARA, formatted as
      "ara:&lt;random-hex-16&gt;".
	</dd>
          <dt>issued_at:</dt>
          <dd>
	String.  ISO 8601 datetime at which this ARA was issued.
	</dd>
          <dt>upstream_ref:</dt>
          <dd>
	Object.  Reference to the parent in the delegation chain.
      - ref_type: String.  One of: "roa_envelope", "ara".
      - ref_id: String.  The envelope_id or ara_id of the parent.
      - ref_digest: String.  SHA-256 hash of the parent object's
        canonical serialization.  This creates a hash chain over
        the delegation path.
	</dd>
          <dt>delegating_agent:</dt>
          <dd>
	Object.  Identity of the delegating agent.
      - agent_id: String.  agent identifier of the delegating agent.
      - session_id: String.  Session identifier of the delegating
        agent's current session.
	</dd>
          <dt>delegated_agent:</dt>
          <dd>
	Object.  Identity of the agent receiving the delegation.
      - agent_id: String.  agent identifier of the delegated agent.
      - capability_declaration_ref: String, OPTIONAL.  Reference
        to the delegated agent's declared capability manifest.
	</dd>
          <dt>delegated_scope:</dt>
          <dd>
            <t>
	Object.  The scope being delegated.  MUST satisfy the
      monotonic scope-narrowing invariant with respect to the
      parent scope.
      - capabilities: Array of Strings.  Capability identifiers
        authorized for the delegated agent.
            </t>
            <ul spacing="normal">
              <li>
                <t>task_context: String, OPTIONAL.  Plain-language description
        of the task being delegated.</t>
              </li>
              <li>
                <t>max_delegation_depth: Integer.  Remaining permitted
        delegation depth.  MUST be strictly less than the parent's
        max_delegation_depth.</t>
              </li>
            </ul>
          </dd>
          <dt>policy:</dt>
          <dd>
            <t>
	Object.  Policy binding for this delegation.
      - policy_digest: String.  MUST match the policy_digest of
        the root ROA envelope in the delegation chain.
            </t>
            <ul spacing="normal">
              <li>
                <t>policy_version: String.</t>
              </li>
            </ul>
          </dd>
          <dt>signatures:</dt>
          <dd>
	Array of Objects.  Signatures as specified in <xref target="sect-4.4" format="default"/>.
      The ARA MUST be signed by the delegating agent.
	</dd>
        </dl>
      </section>
      <section anchor="sect-5.2" numbered="true" toc="default">
        <name>Delegation Chain Construction</name>
        <t>
   A delegation chain is constructed as follows:</t>
        <ol spacing="normal" type="1"><li>
            <t>The root element is the ROA envelope issued by the Policy
      Engine at session initiation (ref_type: "roa_envelope").</t>
          </li>
          <li>
            <t>Each subsequent element is an ARA object produced at a
      delegation boundary (ref_type: "ara").</t>
          </li>
          <li>
            <t>The chain forms a singly-linked list through the upstream_ref
      fields.  The ref_digest field creates a cryptographic hash
      chain: each ARA commits to the exact bytes of its parent.</t>
          </li>
          <li>
            <t>The chain terminates at the agent currently requesting a
      MCP tool call.</t>
          </li>
        </ol>
        <t>
   When a Border Gateway receives a MCP tool call, the requesting
   agent presents its delegation chain (an ordered array of
   serialized ARA objects, from root to current).  The Border
   Gateway validates the entire chain before making an enforcement
   decision.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Chain length:</dt>
          <dd>
	The chain length MUST NOT exceed the max_delegation_depth
      specified in the root ROA envelope.
	</dd>
          <dt>Chain integrity:</dt>
          <dd>
	The Border Gateway MUST verify:
      a) The root ROA envelope signature.
      b) Each ARA signature in the chain.
      c) The hash chain integrity (ref_digest field).
      d) The monotonic scope-narrowing invariant at each hop.
	</dd>
        </dl>
      </section>
      <section anchor="sect-5.3" numbered="true" toc="default">
        <name>Chain Verification Algorithm</name>
        <t>
   The following algorithm MUST be implemented by the Border Gateway:</t>
        <artwork name="" type="" align="left" alt=""><![CDATA[
FUNCTION VerifyChain(chain, requested_capability):

  INPUT:
    chain: ordered array [root_envelope, ara_1, ..., ara_n]
    requested_capability: capability identifier being requested

  OUTPUT:
    PERMIT or DENY, with reason

  STEP 1: Verify root envelope
    IF NOT VerifySignature(chain[0]) THEN
      RETURN DENY, "invalid_root_signature"
    IF chain[0].expires_at < NOW() THEN
      RETURN DENY, "envelope_expired"
    current_scope = chain[0].authorized_scope.capabilities
    current_budget = chain[0].authorized_scope.budget_ceiling
    current_slo = chain[0].authorized_scope.slo_class

  STEP 2: Verify hash chain and monotonic narrowing
    FOR i = 1 TO length(chain) - 1:
      ara = chain[i]
      parent = chain[i-1]
      parent_digest = SHA-256(canonical_json(parent))

      IF ara.upstream_ref.ref_digest != parent_digest THEN
        RETURN DENY, "chain_integrity_violation"

      IF NOT VerifySignature(ara) THEN
        RETURN DENY, "invalid_ara_signature_at_hop_" + i

      IF NOT Subset(ara.delegated_scope.capabilities, current_scope) THEN
        RETURN DENY, "scope_expansion_violation_at_hop_" + i

      IF ara.delegated_scope.budget_ceiling IS PRESENT AND
         current_budget IS PRESENT AND
         ara.delegated_scope.budget_ceiling > current_budget THEN
        RETURN DENY, "budget_expansion_denied_at_hop_" + i

      IF ara.delegated_scope.slo_class IS PRESENT AND
         current_slo IS PRESENT AND
         ara.delegated_scope.slo_class < current_slo THEN
        RETURN DENY, "slo_relaxation_denied_at_hop_" + i
]]></artwork>
        <artwork name="" type="" align="left" alt=""><![CDATA[
      current_scope = ara.delegated_scope.capabilities
      current_budget = ara.delegated_scope.budget_ceiling
      current_slo = ara.delegated_scope.slo_class
]]></artwork>
        <ul empty="true" spacing="normal">
          <li>
            <dl newline="true" spacing="normal" indent="2">
              <dt>STEP 3: Verify requested capability is in current scope</dt>
              <dd>
	IF NOT In(requested_capability, current_scope) THEN
         RETURN DENY, "capability_not_in_scope"
	</dd>
              <dt>STEP 4: Verify policy digest consistency</dt>
              <dd>
	FOR i = 1 TO length(chain) - 1:
         IF chain[i].policy.policy_digest != chain[0].policy.policy_digest THEN
           RETURN DENY, "policy_digest_mismatch_at_hop_" + i
	</dd>
            </dl>
          </li>
        </ul>
        <dl newline="false" spacing="normal" indent="2">
          <dt/>
          <dd>
     RETURN PERMIT</dd>
        </dl>
        <t>
   END FUNCTION</t>
      </section>
    </section>
    <section anchor="sect-6" numbered="true" toc="default">
      <name>Agent Execution Receipt (AER)</name>
      <section anchor="sect-6.1" numbered="true" toc="default">
        <name>AER Structure</name>
        <t>
   The Agent Execution Receipt (AER) is produced by the Border
   Gateway as an intrinsic output of each enforcement decision.
   The AER is a cryptographically signed artifact intended to provide
   independently verifiable evidence that a specific enforcement
   decision was made for a specific agent action under a specific
   policy at a specific time.</t>
        <t>
   The AER is not a log entry.  It is a signed commitment produced
   by the enforcement layer at the moment of the decision.  The
   distinction is architecturally significant: a log entry is
   produced after the fact by a logging system that may or may not
   have observed the exact enforcement logic.  An AER is produced
   by the enforcement logic itself, committed before the action
   executes (for PERMIT) or when the action is rejected (for DENY).</t>
        <t>
   AER structure:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>schema_version:</dt>
          <dd>
	String.  MUST be "1.0".
	</dd>
          <dt>aer_id:</dt>
          <dd>
	String.  Unique receipt identifier, formatted as
      "aer:&lt;random-hex-16&gt;".
	</dd>
          <dt>produced_at:</dt>
          <dd>
	String.  ISO 8601 datetime at which this receipt was produced.
      This MUST be the timestamp of the enforcement decision, not
      the timestamp of execution completion.
	</dd>
          <dt>enforcement_outcome:</dt>
          <dd>
	String.  One of: "permit", "deny".
	</dd>
          <dt>enforcement_mode:</dt>
          <dd>
	String.  One of: "normal", "degraded".  "degraded" indicates
      that the enforcement decision was made against locally cached
      materials because the Agent Identity Registry or revocation
      infrastructure was unavailable.  Relying parties that require
      non-degraded receipts SHOULD reject receipts with
      enforcement_mode "degraded".  See Section 9.4.3.
	</dd>
          <dt>denial_reason:</dt>
          <dd>
	String.  Present only when enforcement_outcome is "deny".
      One of: "invalid_signature", "envelope_expired",
      "envelope_revoked", "replay_detected",
      "chain_integrity_violation", "scope_expansion_violation",
      "budget_expansion_denied", "slo_relaxation_denied",
      "capability_not_in_scope", "policy_digest_mismatch",
      "approval_required", "auth_strength_insufficient".
	</dd>
          <dt>session:</dt>
          <dd>
	Object.  Session context.
      - session_id: String.
      - agent_id: String.  agent identifier of the requesting agent.
      - device_attestation_ref: String, OPTIONAL.
	</dd>
          <dt>action:</dt>
          <dd>
	Object.  The action subject to enforcement.
      - capability: String.  The capability identifier requested.
      - mcp_server_id: String.  Target MCP server identifier.
      - mcp_tool_name: String.  Target tool name.
      - input_hash: String.  SHA-256 hash of the canonical
        serialization of the tool call inputs.  The inputs
        themselves are NOT included in the AER.
	</dd>
          <dt>policy:</dt>
          <dd>
	Object.  Policy binding at enforcement time.
      - policy_id: String.
      - policy_digest: String.  The policy digest from the ROA
        envelope.  This records the exact policy version that
        governed this enforcement decision.
	</dd>
          <dt>chain_summary:</dt>
          <dd>
            <t>
	Object.  Summary of the delegation chain.
      - chain_depth: Integer.  Number of hops in the chain.
      - root_envelope_id: String.  The envelope_id of the root
        ROA envelope.
            </t>
            <ul spacing="normal">
              <li>
                <t>chain_digest: String.  SHA-256 hash of the canonical
        serialization of the complete delegation chain.</t>
              </li>
            </ul>
          </dd>
          <dt>border_gateway:</dt>
          <dd>
            <t>
	Object.  Border Gateway identity.
      - gateway_id: String.  Identifier of the producing Border
        Gateway instance.
            </t>
            <ul spacing="normal">
              <li>
                <t>gateway_version: String.  Software version.</t>
              </li>
            </ul>
          </dd>
          <dt>plan_hash:</dt>
          <dd>
	String, OPTIONAL.  A cryptographic hash of the frozen artifacts
      that governed this enforcement decision, enabling deterministic
      or tolerance-bounded replay.  The plan_hash binds at minimum:
      the prompt template identifier and version, the model identifier
      and version, the operator and governance library versions, and
      the policy-pack identifiers active at enforcement time.  When
      present, it is formatted as "sha256:&lt;hex&gt;" and computed over
      the canonical JSON serialization of the frozen artifact
      manifest.  Auditors or compliance systems MAY use plan_hash to
      re-execute the enforcement decision logic against the same
      frozen inputs and verify that the original allow/deny outcome
      is reproduced within declared tolerances.  Implementations that
      support deterministic replay SHOULD populate this field.
	</dd>
          <dt>signatures:</dt>
          <dd>
	Array of Objects.  The AER MUST be signed by the Border
      Gateway's private key using EdDSA/Ed25519.  The Border
      Gateway signing key MUST be registered in the Agent Identity
      Registry.
	</dd>
        </dl>
      </section>
      <section anchor="sect-6.2" numbered="true" toc="default">
        <name>Receipt Generation at Enforcement Boundary</name>
        <t>
   The following invariants apply to AER generation:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Invariant 1 (Pre-execution commitment):</dt>
          <dd>
	For enforcement_outcome "permit", the AER MUST be produced
      and persisted to the local audit store BEFORE the MCP tool
      call is forwarded to the target MCP server.  This ensures
      that the AER exists regardless of whether the tool call
      subsequently succeeds or fails.
	</dd>
          <dt>Invariant 2 (Denial receipt):</dt>
          <dd>
	For enforcement_outcome "deny", the AER MUST be produced
      and persisted before returning the authorization error to
      the requesting agent.
	</dd>
          <dt>Invariant 3 (Policy digest capture):</dt>
          <dd>
	The policy_digest in the AER MUST be captured from the
      ROA envelope at enforcement time.  If the policy has been
      updated between envelope issuance and enforcement time,
      the enforcement decision MUST fail with denial reason
      "policy_digest_mismatch".
	</dd>
          <dt>Invariant 4 (Input hash binding):</dt>
          <dd>
	The input_hash field MUST be computed from the actual tool
      call inputs presented at enforcement time.  This ensures
      that the AER receipt is bound to the specific inputs, not
      merely to the capability identifier.
	</dd>
        </dl>
      </section>
      <section anchor="sect-6.3" numbered="true" toc="default">
        <name>SCITT Transparency Log Integration</name>
        <t>
   AgentROA AER receipts are designed to be submitted to SCITT-
   compatible transparency logs <xref target="I-D.ietf-scitt-architecture" format="default"/>.  When a SCITT log
   is configured:</t>
        <t>
   a) The Border Gateway submits each AER as a SCITT Statement.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>b) The SCITT log returns a SCITT Receipt (a countersignature</dt>
          <dd>
	over the log entry).
	</dd>
        </dl>
        <t>
   c) The SCITT Receipt is appended to the AER's signatures array.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>d) The combined AER (with SCITT Receipt) is returned to the</dt>
          <dd>
	requesting agent and stored in the local audit store.
	</dd>
        </dl>
        <t>
   SCITT integration provides three additional properties:</t>
        <ol spacing="normal" type="1"><li>
            <t>Third-party verifiability: Any party with the SCITT log's
      public key can verify the AER without trusting the Border
      Gateway operator.</t>
          </li>
          <li>
            <t>Tamper evidence: The append-only SCITT log structure
      prevents modification of historical receipts.</t>
          </li>
          <li>
            <t>Transparency: Deployments MAY use transparency logs to support
      independent verification or audit requirements.</t>
          </li>
        </ol>
      </section>
    </section>
    <section anchor="sect-7" numbered="true" toc="default">
      <name>Border Gateway Enforcement Model</name>
      <section anchor="sect-7.1" numbered="true" toc="default">
        <name>Enforcement Proxy Position</name>
        <dl newline="true" spacing="normal" indent="3">
          <dt>The Border Gateway MUST be positioned as follows:</dt>
          <dd>
	Agent (Execution Domain)
           |
           | MCP tool call request
           | (with ROA envelope or ARA chain in auth header)
           |
           v
      Border Gateway (Enforcement Domain) &lt;-- separate process | | Validated and authorized MCP tool call | (after enforcement decision, AER produced) | v MCP Server </dd>
        </dl>
        <t>
   The Border Gateway acts as a reverse proxy for MCP connections.
   From the MCP server's perspective, all requests arrive from the
   Border Gateway.  From the agent's perspective, the Border Gateway
   is the target endpoint for MCP tool calls.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>This architecture ensures:</dt>
          <dd>
	a) The MCP server never receives unauthorized tool calls.
   b) The enforcement decision is made by infrastructure the agent
      cannot influence.
	</dd>
          <dt>c) Every tool call — authorized or denied — produces a signed</dt>
          <dd>
	receipt in the enforcement domain.
	</dd>
        </dl>
      </section>
      <section anchor="sect-7.2" numbered="true" toc="default">
        <name>MCP Protocol Integration</name>
        <t>
   MCP uses OAuth 2.0 for authorization as specified in the MCP
   Authorization specification.  AgentROA operates as an additional
   layer above MCP's OAuth authorization mechanism.</t>
        <t>
   AgentROA DOES NOT replace MCP's OAuth authorization.  Both
   mechanisms operate in sequence:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Step 1 (MCP OAuth): The agent obtains an OAuth access token</dt>
          <dd>
	scoped to the target MCP server.  This token is validated
      by the MCP server's authorization server.
	</dd>
          <dt>Step 2 (AgentROA envelope): The agent presents its ROA envelope</dt>
          <dd>
	or ARA chain to the Border Gateway in an authorization header or
      equivalent protocol metadata field.
	</dd>
          <dt>Step 3 (Border Gateway validation): The Border Gateway performs</dt>
          <dd>
	the chain verification algorithm specified in <xref target="sect-5.3" format="default"/>
      and produces an AER receipt.
	</dd>
          <dt>Step 4 (Forwarding): If the enforcement outcome is PERMIT, the</dt>
          <dd>
	Border Gateway forwards the tool call to the MCP server with
      the OAuth token.  The AER receipt identifier or receipt object
      is returned to the agent in response metadata.
	</dd>
          <dt>OAuth token audience validation:</dt>
          <dd>
	The Border Gateway MUST validate that the OAuth token's
      audience claim (aud) matches the target MCP server's
      registered identifier.  This prevents token reuse across
      MCP servers.
	</dd>
          <dt>MCP server registration:</dt>
          <dd>
	MCP servers that participate in AgentROA enforcement MUST
      register their capability manifests with the Agent Identity
      Registry.  The capability manifest declares all tools the
      server exposes, used by the Border Gateway for wildcard
      scope resolution.
	</dd>
        </dl>
      </section>
      <section anchor="sect-7.3" numbered="true" toc="default">
        <name>A2A Protocol Integration</name>
        <t>
   When agents communicate using the A2A protocol, AgentROA
   governs the delegation of tasks between agents.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Task delegation over A2A:</dt>
          <dd>
	When an orchestrating agent delegates a task to a downstream
      agent over A2A, the orchestrating agent MUST produce an ARA
      object for the delegation (see <xref target="sect-5" format="default"/>) and include it in
      the A2A task request.
	</dd>
          <dt>Cross-organization delegation:</dt>
          <dd>
	When a delegation crosses an organizational boundary, the
      ROA envelope's cross_org_permitted field MUST be true.
      Additional cross-organization agreement semantics are outside
      the scope of this document.
	</dd>
        </dl>
      </section>
      <section anchor="sect-7.4" numbered="true" toc="default">
        <name>Enforcement Decision Algorithm</name>
        <t>
   The complete enforcement decision algorithm is:</t>
        <artwork name="" type="" align="left" alt=""><![CDATA[
FUNCTION Enforce(request):

  INPUT:
    request: MCP tool call request with auth headers

  OUTPUT:
    PERMIT or DENY, with AER receipt

  STEP 1: Extract credentials
    envelope_or_chain = ExtractFromHeader(request)

  STEP 2: Determine chain type
    IF envelope_or_chain is ROA envelope:
      chain = [envelope_or_chain]
    ELSE:
      chain = envelope_or_chain (ARA chain)

  STEP 3: Resolve capability
    capability = mcp:<request.server_id>.<request.tool_name>

  STEP 4: Execute chain verification
    result = VerifyChain(chain, capability)

  STEP 5: Check approval state if required
    IF chain[0].authorization.auth_strength IN
        ["device_bound", "device_bound_with_attestation"]:
      IF chain[0].authorization.approval_state != "granted":
        result = DENY, "approval_required"

  STEP 6: Produce AER
    aer = ProduceAER(
      session = ExtractSession(chain),
      action = ExtractAction(request),
      policy = ExtractPolicy(chain[0]),
      chain_summary = SummarizeChain(chain),
      outcome = result.outcome,
      denial_reason = result.reason
    )
    SignAER(aer, border_gateway_private_key)
    PersistAER(aer)

  STEP 7: Submit to SCITT (if configured)
    IF scitt_enabled:
      scitt_receipt = SubmitToSCITT(aer)
      AppendSignature(aer, scitt_receipt)

  STEP 8: Return
    IF result.outcome == PERMIT:
      ForwardToMCPServer(request)
      RETURN response WITH receipt metadata referencing aer.aer_id
    ELSE:
      RETURN 403 Forbidden WITH receipt metadata referencing
             aer.aer_id
]]></artwork>
        <t>
   END FUNCTION</t>
      </section>
    </section>
    <section anchor="sect-8" numbered="true" toc="default">
      <name>Security Considerations</name>
      <section anchor="sect-8.1" numbered="true" toc="default">
        <name>Threat Model</name>
        <t>
   AgentROA is designed to protect against the following threats:</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>T1 - Capability escalation through delegation:</dt>
          <dd>
	A malicious or compromised agent attempts to grant a
      downstream agent capabilities it does not possess.
      Mitigation: No-loosen invariant (<xref target="sect-4.3" format="default"/>).
	</dd>
          <dt>T2 - Prompt injection leading to unauthorized tool calls:</dt>
          <dd>
	An adversary embeds malicious instructions in data the
      agent processes, causing the agent to attempt tool calls
      outside its declared scope.
      Mitigation: Border Gateway scope enforcement (<xref target="sect-7" format="default"/>).
      The agent cannot invoke capabilities outside its envelope
      regardless of what instructions it receives.
	</dd>
          <dt>T3 - Replay attacks using captured envelopes:</dt>
          <dd>
	An attacker captures a valid ROA envelope and replays it
      to authorize actions not intended by the original issuer.
      Mitigation: Session identity binding and envelope expiry.
      The session_id in the envelope MUST be unique per session,
      and the Border Gateway MUST maintain a replay prevention
      cache for recently-seen envelope identifiers.
	</dd>
          <dt>T4 - Governance bypass through in-process compromise:</dt>
          <dd>
	A compromised agent attempts to modify or disable the
      governance layer.
      Mitigation: Trust boundary separation (<xref target="sect-3.2" format="default"/>).
      The Border Gateway runs in a separate process that the
      agent cannot access.
	</dd>
          <dt>T5 - Policy drift — agent scope expands over time:</dt>
          <dd>
	An agent's effective capability scope expands through
      learned skills or updated configuration without the policy
      envelope being reissued.
      Mitigation: Policy digest binding (<xref target="sect-4.2" format="default"/>).  The
      policy digest in the ROA envelope is validated against the
      current policy at each enforcement decision.
	</dd>
        </dl>
      </section>
      <section anchor="sect-8.2" numbered="true" toc="default">
        <name>Key Management</name>
        <t>
   Private keys used for signing ROA envelopes, ARA objects, and
   AER receipts MUST be stored in hardware security modules or
   equivalent secure key storage, or in device-bound key storage
   for device-bound approval flows.</t>
        <dl newline="true" spacing="normal" indent="3">
          <dt>Key rotation:</dt>
          <dd>
	Implementations SHOULD support periodic rotation of ROA envelope
      signing keys and Border Gateway signing keys according to local
      deployment policy and risk requirements.
	</dd>
        </dl>
      </section>
      <section anchor="sect-8.3" numbered="true" toc="default">
        <name>Implementation Considerations</name>
        <artwork name="" type="" align="left" alt=""><![CDATA[
Implementers SHOULD note that this framework requires the
Border Gateway to process every MCP tool call.  The Border
Gateway is therefore a potential bottleneck and single point
of failure.  Implementations SHOULD provide:
]]></artwork>
        <dl newline="true" spacing="normal" indent="3">
          <dt>a) High availability deployment (multiple Border Gateway</dt>
          <dd>
	instances with consistent state).
	</dd>
          <dt>b) Low-latency enforcement appropriate to the deployment, noting</dt>
          <dd>
	that enforcement occurs at the protocol boundary rather than in
      application middleware.
	</dd>
          <dt>c) Audit store durability (AER receipts MUST survive Border</dt>
          <dd>
	Gateway failures).
	</dd>
        </dl>
      </section>
      <section anchor="sect-8.4" numbered="true" toc="default">
        <name>Revocation and Degraded Operation</name>
        <t>
   This section specifies requirements for ROA envelope revocation
   and for continued operation when the Border Gateway cannot reach
   the Agent Identity Registry or policy infrastructure.</t>
        <section anchor="sect-8.4.1" numbered="true" toc="default">
          <name>Envelope Expiry and Revocation</name>
          <t>
   ROA envelopes include an expires_at field (<xref target="sect-4.1" format="default"/>).  The
   Border Gateway MUST reject any envelope whose expires_at timestamp
   is in the past.  The denial reason code MUST be "envelope_expired".</t>
          <t>
   In addition to time-based expiry, implementations SHOULD support
   explicit revocation.  The Agent Identity Registry SHOULD publish
   revocation information for ROA envelopes whose corresponding
   sessions have been administratively terminated or whose signing
   keys have been compromised.  Revocation information SHOULD be
   distributed as delta-encoded updates identified by a monotonically
   increasing epoch and sequence number, enabling validators to
   maintain current revocation state without full re-download.</t>
          <t>
   When a validator processes a revocation delta, it MUST update its
   local revocation cache and MUST reject any subsequently presented
   envelope whose envelope_id or signing key appears in the revocation
   cache.  The denial reason code for a revoked envelope MUST be
   "envelope_revoked".  AER receipts for revoked envelopes SHOULD
   include the revocation epoch and sequence number at which the
   revocation was applied.</t>
        </section>
        <section anchor="sect-8.4.2" numbered="true" toc="default">
          <name>Replay Prevention Cache</name>
          <t>
   To prevent replay attacks using captured but unexpired envelopes,
   the Border Gateway MUST maintain a replay prevention cache of
   recently-seen (envelope_id, session_id) pairs.  The cache MUST
   cover at minimum the full validity window of the longest-lived
   envelope the deployment issues.  On restart, the Border Gateway
   MUST either restore the cache from durable storage or refuse to
   process envelopes issued before the restart until their natural
   expiry time has elapsed.</t>
          <t>
   When a duplicate (envelope_id, session_id) pair is detected, the
   Border Gateway MUST reject the request with denial reason
   "replay_detected" and produce a DENY AER receipt.</t>
        </section>
        <section anchor="sect-8.4.3" numbered="true" toc="default">
          <name>Degraded Operation</name>
          <t>
   When the Border Gateway cannot reach the Agent Identity Registry
   to verify an agent's public key or to retrieve current revocation
   data, it MAY continue enforcement against locally cached materials
   subject to the following constraints:</t>
          <dl newline="true" spacing="normal" indent="3">
            <dt>a) The Border Gateway MUST mark AER receipts produced during</dt>
            <dd>
	degraded operation with an enforcement_mode field set to
      "degraded".  Relying parties that require non-degraded
      receipts MAY reject degraded receipts.
	</dd>
            <dt>b) The Border Gateway MUST NOT serve stale revocation data beyond</dt>
            <dd>
	its declared cache TTL without marking the resulting receipts
      as degraded.
	</dd>
            <dt>c) The Border Gateway SHOULD record the reason for degraded</dt>
            <dd>
	operation (e.g., "registry_unreachable", "revocation_cache_ stale") in the AER receipt for audit purposes.
	</dd>
            <dt>d) Implementations SHOULD provide configuration to fail-closed</dt>
            <dd>
	(reject all requests) rather than fail-open (permit with
      degraded receipts) during registry outages, particularly for
      deployments in regulated industries where degraded receipts
      may not satisfy compliance requirements.
	</dd>
          </dl>
        </section>
      </section>
    </section>
    <section anchor="sect-9" numbered="true" toc="default">
      <name>IANA Considerations</name>
      <t>
   This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8032" target="https://www.rfc-editor.org/info/rfc8032" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml">
          <front>
            <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <author fullname="I. Liusvaara" initials="I." surname="Liusvaara"/>
            <date month="January" year="2017"/>
            <abstract>
              <t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves. An example implementation and test vectors are provided.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8032"/>
          <seriesInfo name="DOI" value="10.17487/RFC8032"/>
        </reference>
        <reference anchor="RFC8785" target="https://www.rfc-editor.org/info/rfc8785" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8785.xml">
          <front>
            <title>JSON Canonicalization Scheme (JCS)</title>
            <author fullname="A. Rundgren" initials="A." surname="Rundgren"/>
            <author fullname="B. Jordan" initials="B." surname="Jordan"/>
            <author fullname="S. Erdtman" initials="S." surname="Erdtman"/>
            <date month="June" year="2020"/>
            <abstract>
              <t>Cryptographic operations like hashing and signing need the data to be expressed in an invariant format so that the operations are reliably repeatable. One way to address this is to create a canonical representation of the data. Canonicalization also permits data to be exchanged in its original form on the "wire" while cryptographic operations performed on the canonicalized counterpart of the data in the producer and consumer endpoints generate consistent results.</t>
              <t>This document describes the JSON Canonicalization Scheme (JCS). This specification defines how to create a canonical representation of JSON data by building on the strict serialization methods for JSON primitives defined by ECMAScript, constraining JSON data to the Internet JSON (I-JSON) subset, and by using deterministic property sorting.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8785"/>
          <seriesInfo name="DOI" value="10.17487/RFC8785"/>
        </reference>
        <reference anchor="RFC6480" target="https://www.rfc-editor.org/info/rfc6480" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6480.xml">
          <front>
            <title>An Infrastructure to Support Secure Internet Routing</title>
            <author fullname="M. Lepinski" initials="M." surname="Lepinski"/>
            <author fullname="S. Kent" initials="S." surname="Kent"/>
            <date month="February" year="2012"/>
            <abstract>
              <t>This document describes an architecture for an infrastructure to support improved security of Internet routing. The foundation of this architecture is a Resource Public Key Infrastructure (RPKI) that represents the allocation hierarchy of IP address space and Autonomous System (AS) numbers; and a distributed repository system for storing and disseminating the data objects that comprise the RPKI, as well as other signed objects necessary for improved routing security. As an initial application of this architecture, the document describes how a legitimate holder of IP address space can explicitly and verifiably authorize one or more ASes to originate routes to that address space. Such verifiable authorizations could be used, for example, to more securely construct BGP route filters. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6480"/>
          <seriesInfo name="DOI" value="10.17487/RFC6480"/>
        </reference>
        <reference anchor="RFC6811" target="https://www.rfc-editor.org/info/rfc6811" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6811.xml">
          <front>
            <title>BGP Prefix Origin Validation</title>
            <author fullname="P. Mohapatra" initials="P." surname="Mohapatra"/>
            <author fullname="J. Scudder" initials="J." surname="Scudder"/>
            <author fullname="D. Ward" initials="D." surname="Ward"/>
            <author fullname="R. Bush" initials="R." surname="Bush"/>
            <author fullname="R. Austein" initials="R." surname="Austein"/>
            <date month="January" year="2013"/>
            <abstract>
              <t>To help reduce well-known threats against BGP including prefix mis- announcing and monkey-in-the-middle attacks, one of the security requirements is the ability to validate the origination Autonomous System (AS) of BGP routes. More specifically, one needs to validate that the AS number claiming to originate an address prefix (as derived from the AS_PATH attribute of the BGP route) is in fact authorized by the prefix holder to do so. This document describes a simple validation mechanism to partially satisfy this requirement. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6811"/>
          <seriesInfo name="DOI" value="10.17487/RFC6811"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="MCP-SPEC" target="https://spec.modelcontextprotocol.io/">
          <front>
            <title>Model Context Protocol Specification</title>
            <author>
              <organization>Anthropic</organization>
            </author>
            <date year="2024"/>
          </front>
        </reference>
        <reference anchor="A2A-SPEC">
          <front>
            <title>Agent-to-Agent (A2A) Protocol Specification</title>
            <author>
              <organization>Google</organization>
            </author>
            <date year="2025"/>
          </front>
        </reference>
        <reference anchor="I-D.ietf-scitt-architecture" target="https://datatracker.ietf.org/doc/html/draft-ietf-scitt-architecture-22" xml:base="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-scitt-architecture.xml">
          <front>
            <title>An Architecture for Trustworthy and Transparent Digital Supply Chains</title>
            <author fullname="Henk Birkholz" initials="H." surname="Birkholz">
              <organization>Fraunhofer SIT</organization>
            </author>
            <author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-Lavaud">
              <organization>Microsoft Research</organization>
            </author>
            <author fullname="Cedric Fournet" initials="C." surname="Fournet">
              <organization>Microsoft Research</organization>
            </author>
            <author fullname="Yogesh Deshpande" initials="Y." surname="Deshpande">
              <organization>ARM</organization>
            </author>
            <author fullname="Steve Lasker" initials="S." surname="Lasker"/>
            <date day="10" month="October" year="2025"/>
            <abstract>
              <t>Traceability in supply chains is a growing security concern. While verifiable data structures have addressed specific issues, such as equivocation over digital certificates, they lack a universal architecture for all supply chains. This document defines such an architecture for single-issuer signed statement transparency. It ensures extensibility, interoperability between different transparency services, and compliance with various auditing procedures and regulatory requirements.</t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-scitt-architecture-22"/>
        </reference>
        <reference anchor="OWASP-AGENTIC">
          <front>
            <title>OWASP Agentic AI Top 10 2026</title>
            <author>
              <organization>OWASP</organization>
            </author>
            <date month="December" year="2025"/>
          </front>
        </reference>
        <reference anchor="FIDO-PASSKEY">
          <front>
            <title>Passkey Technical Specification</title>
            <author>
              <organization>FIDO Alliance</organization>
            </author>
            <date year="2023"/>
          </front>
        </reference>
      </references>
    </references>
    <section anchor="sect-a" numbered="true" toc="default">
      <name>JSON Schema Definitions</name>
      <section anchor="sect-a.1" numbered="true" toc="default">
        <name>ROA Envelope Schema</name>
        <!--
   draft-nivalto-agentroa-route-authorization-00.txt(1341): Warning: Expected a
   back section, found '{'
   -->
      </section>
    </section>
  </back>
</rfc>
