Skip to content

RFC: verifiable residency across delegation chains (implements ADR-0008 problems 4 and 5) #3658

Description

Summary

ADR-0008 identified data residency and trust-tier composition as open problems (numbers 4 and 5 of the five raised in #1386) and deliberately scoped them to "framing decisions" rather than concrete answers. Neither has been implemented. This RFC proposes closing both, together, because they turn out to be the same problem: residency is only meaningful if it survives delegation, and delegation is only safe if residency composes.

The concrete gap: ADR-0008 models residency as declared metadata (PolicyMetadata.processing_regions: list[str], AgentPolicyClaims.data_residency). A declared region string is unverifiable. Nothing binds it to evidence, and nothing carries it across more than one hop. So an agent can satisfy every check ADR-0008 specifies and still route data out of its permitted jurisdiction through a sub-agent, with no record that it happened.

Motivation

Three reasons this is worth doing now.

1. It is already on the roadmap and has stalled. #1386 raised it in April. ADR-0008 answered problems 1 to 3 and deferred 4 and 5. Both ADR-0007 and ADR-0008 are still proposed, and neither has landed in code: AgentPolicyClaims, PolicyMetadata, processing_regions and PolicyFederationProvider have zero implementations in the Python tree today. The one data_residency occurrence is an unrelated optional field in agent-os/nexus.

2. The regulatory date referenced in the original discussion has now passed. #1386 and ADR-0008 both cite EU AI Act Article 12 record-keeping, enforcement 2026-08-02. That date is behind us. AGT ships an Annex IV exporter (governance/annex_iv.py) and an evidence pipeline (governance/evidence_pipeline.py), so the toolkit already takes conformity documentation seriously. Residency is the one obligation in that family with no mechanism behind it.

3. The declared-versus-verified distinction is where sovereignty claims actually fail. Deploying in an EU region is necessary and not sufficient. If an agent delegates and the sub-agent calls an endpoint outside the permitted set, the deployment was compliant and the data flow was not. This is the failure mode a regulator will ask about, and today no part of AGT can answer.

Worked example, which is the acceptance test I would want:

A resource owner permits processing in FR only. A lead agent delegates summarisation to a sub-agent, which calls a model endpoint that is EU-branded but served from a region outside FR. Every component behaved as configured. Expected behaviour: the delegation fails closed before any data moves, and the resulting record lets a third party verify that it failed closed.

Detailed Design

Deliberately specified as required properties and interface surface rather than a chosen mechanism. Mechanism detail is a follow-up, see "staging" below.

Properties the design must satisfy

  1. Attested, not declared. A jurisdiction assertion must be backed by evidence, not a configuration string. Concretely, it must bind to (a) attestation evidence for what is running, and (b) a signed statement from an identified, accountable operator for where it is running. These are separate roots of trust with different strengths, and the design must not conflate them. See Security Implications.
  2. Composes transitively. A residency constraint must intersect across every hop of a delegation chain and must never widen. This is the same monotonicity property already enforced for capabilities by identity/delegation.py (ScopeChain, DelegationLink), so the mechanism should reuse that machinery rather than parallel it.
  3. Fails closed, pre-flight. Enforcement happens at derivation time, before data moves, consistent with ADR-0008's pre-flight framing. An out-of-jurisdiction delegation is never issued rather than detected afterwards.
  4. Offline-verifiable. A relying party must be able to recompute the residency verdict from the record with no live call to any participant. AGT already has the substrate for this in governance/audit.py Merkle chaining and governance/decision_bom.py.
  5. Graduated conformance. A declared region and an attested one must not be indistinguishable to a verifier. The design needs explicit levels so a deployer cannot read the weakest form as the strongest.

Interface surface affected

  • governance/policy_evaluator.py and governance/async_policy_evaluator.py: jurisdiction becomes a predicate in evaluation, deny-by-default rather than absent.
  • identity/delegation.py: DelegationLink carries a jurisdiction assertion; ScopeChain.verify() gains a residency check alongside capability narrowing.
  • governance/federation.py: PolicyCategory has DATA_EXPORT but it carries no geography. This is where ADR-0008's processing_regions would actually land.
  • identity/attestation.py: attestation evidence needs to carry, or reference, the placement statement.
  • identity/provider_chain.py: an EU trust-list-backed provider is additive under ADR-0007, which is why this does not require reworking identity.
  • governance/decision_bom.py: residency verdict becomes part of reconstructible decision context.

Staging. I would propose this as two RFCs rather than one. This RFC settles whether the capability is wanted, where it lands, and what properties it must satisfy. A second RFC specifies the mechanism and data model. I am splitting it because the mechanism has an intellectual-property review in flight and I do not want to hold up the direction decision on that, nor pre-empt it. If maintainers would rather see the whole thing at once, say so and I will wait and post one RFC.

Alternatives Considered

Extend ADR-0008 rather than a new RFC. Attractive, and my first instinct. Rejected because ADR-0008 is a policy-federation document whose problems 1 to 3 are coherent and implementable on their own. Bolting an attestation-backed jurisdiction model into it would roughly double its scope and stall the parts that are ready. ADR-0008 should land as-is.

Declared regions only, matching ADR-0008 as written. Cheapest option and it is what the ADR currently specifies. Rejected because an unverifiable residency claim is worse than none: it creates documented, auditable confidence in a property nobody checked. If the project prefers this, my strong suggestion is to label it explicitly as declared-only so it cannot be mistaken for enforcement.

Detect after the fact instead of enforcing pre-flight. Cheaper, and post-hoc detection is where most of the industry sits. Rejected on the evidence: the best published agentic attack detector (Uber's ADR) reports 67% of attacks caught at zero false positives on ADR-Bench, which is state of the art and still misses roughly one in three. A residency violation that is detected 67% of the time is not a control a regulator will accept. Detection and evidence compose; neither substitutes for the other.

Do it outside AGT entirely. Discussed under Target Placement below, because it is really a placement question rather than a design alternative.

Security Implications

The limitation that most matters, stated plainly. Hardware attestation proves what code is running. It does not prove where the machine is. There is no trustworthy geography in an SEV-SNP or TDX report, because nothing in the silicon knows what country it is in.

So this design cannot deliver cryptographic proof of location, and any RFC claiming otherwise would be wrong. What it can deliver is a split claim:

  • What is running: hardware-rooted, verifiable offline against a vendor root, requiring no trust in the operator. Strong.
  • Where it is running: rooted in a signed statement from an identified operator. This is operator-trust, not hardware-trust. An operator with physical control of the machine can defeat it.

The security property gained is therefore non-repudiation rather than prevention: an operator has signed a statement, bound to a specific attested instance, that is attributable to them afterwards. I think that is the strongest claim available and the RFC should say so in those words, so that no deployer reads more into it.

Additionally out of scope, and worth naming so it is not assumed: an adversary with physical access to the host is not defended against here, and per published work on TEE fault and memory attacks, is not currently defended against by any shipping confidential-computing silicon.

New attack surface introduced: the placement statement becomes a forgery target, and the trust list that roots operator identity becomes an availability and integrity dependency in the policy path. Both need treatment in the mechanism RFC.

Migration / Backward Compatibility

No breaking changes intended. Jurisdiction is absent today, so every construct is additive. Two compatibility notes:

  • Deny-by-default on jurisdiction only applies once a policy declares a permitted set. Policies that say nothing about jurisdiction behave exactly as they do now.
  • ScopeChain.verify() gaining a residency check is additive for chains carrying no jurisdiction assertion.

Timing note: this touches the policy evaluation path, which the ACS v5 migration (#3444) and the cedarling removal (#3451) also touched recently. I would rather build on top of settled ACS v5 than land alongside it. Happy to sequence behind whatever is still in flight, and I would appreciate a pointer on what that is.

Scope

Cross-package (2 to 3 packages). Primarily agent-mesh, touching agent-os policy surfaces.

Target Placement

This is the question I most want maintainer input on, and I would rather ask it openly than assume an answer.

Sovereign deployment brings dependencies that AGT may reasonably not want to carry: eIDAS-anchored trust lists, EUDI wallet identity, EU-operated key custody profiles, and jurisdiction-specific policy packs. Those are European regulatory plumbing. They date, they need maintenance by someone tracking EU rulemaking, and they are useful to a subset of AGT users.

Three options as I see them:

  1. In agent-mesh directly. Best for coherence, since delegation and attestation already live there. Worst for maintenance burden, since AGT inherits EU regulatory plumbing.
  2. A separate package inside AGT. Keeps it in the project with a clean dependency boundary. Someone still has to maintain the EU-specific parts.
  3. A separate sovereign-scoped project, reusing agent-mesh under MIT with attribution. Lowest burden on AGT. Costs some coherence and risks drift.

I have a preference for 3 and an interest in declaring it, so discount it accordingly: I would be the one maintaining it, and I would rather carry EU regulatory tracking myself than ask this project to. I am also conscious that I wrote much of the delegation and trust-scoring code in question, which is a reason to be more careful about proposing to take it elsewhere, not less. If maintainers prefer 1 or 2, I will implement it here and that is a good outcome.

If 3 is the answer, I would want it to be explicit and on the record rather than a quiet fork: a distinct distribution name (not agentmesh-platform), Microsoft copyright headers and attribution preserved, upstream contribution of anything genuinely general, and no claim on the AGT name.

Prior Art

  • Discussion: cross-org policy federation beyond identity (follow-up to #1234 / ADR-0007) #1386, which raised all five problems. This RFC addresses 4 and 5.
  • ADR-0007 (external JWKS federation), ADR-0008 (cross-org policy federation), both proposed. ADR-0009 (RFC 9334 RATS alignment) is accepted and is the attestation vocabulary this should align to rather than reinvent.
  • IDSA Rulebook and Gaia-X: usage-control contracts and connector-mediated policy enforcement, mature for datasets. The gap is that a data space contract assumes a dataset moving between two connectors, whereas agents delegate and compose calls at runtime, so the contracted party is not necessarily the party that touches the data. That mismatch is the substance of this RFC.
  • Google DeepMind, February 2026, on delegation as a transfer of authority, responsibility and accountability requiring zero-trust verification. Framework-level, no implementation.
  • W3C DIDs and Verifiable Credentials, and Cisco AGNTCY's agent identity framework, for the identity substrate. Note that the crowded part of the landscape (Entra Agent ID, Okta XAA, Auth0 for GenAI, AGNTCY) is caller-side identity. None of them make jurisdiction a policy predicate or compose it across delegation, which is what this RFC is about.
  • EU AI Act Regulation 2024/1689 Articles 11 and 12, and Annex IV, already partly served by governance/annex_iv.py.

Checklist

Activity

  1. imran-siddique commented on Aug 10, 2026

    @imran-siddique
    CollaboratorAuthor

    liamcrumm MohammadHaroonAbuomar tagging you both for a decision on Target Placement specifically, since that is the one part that blocks me starting rather than something I can figure out as I go.

    Everything else in the RFC I can iterate on in review. But options 1, 2 and 3 lead to different first commits, so I would rather have your call up front than build in the wrong place and redo it.

    My ask is a yes or no on option 3: a separate sovereign-scoped project reusing agent-mesh under MIT. To be concrete about what I would be committing to, so you are not approving something vague:

    • Distinct distribution name. Nothing published as or near agentmesh-platform.
    • Microsoft copyright headers preserved, attribution in the README, MIT throughout.
    • Anything that turns out to be generally useful rather than EU-specific comes back upstream as a PR here.
    • No claim on the AGT name, no parallel release track, no competing roadmap.
    • Scope limited to agent-mesh. Nothing else copied out.

    If you would rather this lands in AGT as option 1 or 2, that genuinely is a good outcome and I will implement it here instead. I only prefer 3 because the eIDAS trust lists, EUDI wallet identity and EU key-custody profiles need someone tracking European rulemaking to stay correct, and volunteering this project for that maintenance burden felt like the wrong thing to assume.

    Two things I want to flag rather than have you discover:

    On timing. Liam, you landed the ACS v5 migration (#3444) and the cedarling removal (#3451) recently, and this touches the same policy evaluation path. I do not want to land across the top of work still in flight. If there is more of that sequence to come, tell me and I will wait. A pointer to what is still outstanding would help either way.

    On my position. I wrote much of the delegation and trust-scoring code this builds on, which cuts against me here rather than for me: it makes me the wrong person to decide unilaterally where it goes. Hence asking rather than announcing.

    No urgency on my side this week. Happy to take it to a call if that is easier than issue comments.

  2. github-actions commented on Aug 10, 2026

    @github-actions

    🔴 Contributor Check: HIGH

    Check Result
    Profile HIGH
    Credential LOW
    Overall HIGH

    Automated check by AGT Contributor Check.

  3. aetherxeg-source commented on Oct 2, 2026

    @aetherxeg-source

    We are working on ExecSurface (https://github.com/AETHERXGLOBAL/execsurface), an open-source runtime behavioral-integrity / execution-surface drift tool. One boundary that may be worth making explicit in this RFC is temporal rather than geographic:

    "valid attestation at T0 != valid authority at T1"

    The proposed split between hardware-rooted "what is running" evidence and operator-signed "where it is running" evidence is useful, but both claims have a freshness/revocation lifetime that may be shorter than the lifetime of a delegation chain.

    A chain can be cryptographically well-formed and still become unacceptable after issuance because, for example:

    • the operator signing key is revoked;
    • a trust-list entry is removed or its status changes;
    • the placement assertion expires;
    • the workload measurement changes after restart/upgrade;
    • the attested instance is replaced while preserving a logical agent identity;
    • the relying party's permitted-jurisdiction policy changes;
    • an intermediate delegation survives longer than the evidence on which it was admitted.

    So I would separate at least three properties:

    1. evidence authenticity/integrity;
    2. evidence freshness and current trust status;
    3. the residency/delegation verdict derived from that evidence.

    Conceptually:

    "evidence object -> verification epoch/status -> delegation decision -> execution attempt"

    rather than allowing a previously verified residency claim to become an indefinitely reusable property of the agent or delegation object.

    A compact invariant is:

    "verified once != authorized indefinitely"

    This seems especially important for the RFC's offline-verifiable goal. Offline verification and current revocation status pull in different directions: an auditor can verify historical signatures offline, but a runtime making a present-tense authorization decision may need a bounded freshness proof or a versioned trust snapshot whose age/policy is explicit.

    One possible model is to bind every residency decision to a verification epoch containing, at minimum:

    • attestation evidence digest;
    • placement-statement digest;
    • trust-list / trust-bundle version or snapshot identity;
    • verification time;
    • expiry / max-age policy;
    • revocation or status-check result and its source;
    • resulting jurisdiction claim.

    Then a downstream delegation can inherit the jurisdiction constraint without silently inheriting stale verification authority. If the evidence exceeds its permitted age or the trust snapshot is no longer acceptable, the next consequential hop re-verifies or fails closed.

    This also gives historical audit a more precise claim. Instead of saying "agent X was verified as FR," the record can say "agent X's evidence was accepted as FR under trust snapshot S at verification epoch E." That is a claim an auditor can actually reconstruct later.

    In ExecSurface we use a similar separation around runtime evidence: the fact that evidence was valid under one observer epoch does not make it authoritative for a later execution epoch.

    A useful conformance test might therefore construct a valid multi-hop delegation, revoke or expire one placement/trust assertion after the first hop, and assert that a later hop cannot reuse the earlier verified result merely because the delegation chain and signatures remain intact.

    That would preserve the RFC's transitive monotonicity while adding temporal monotonicity: trust can narrow or expire over time, but cannot silently widen through cached verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-review:HIGHContributor reputation check flagged HIGH risktriageNeeds triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions