Context
Observed on a fresh self-hosted private deployment during post-redeploy verification. The identity roster was healthy — 19 AgentIdentity nodes present, auto-provisioned from auth provenance — but every attempt to initiate a message failed:
Unauthorized: Cannot send to @<recipient>. Requires CAN_REPLY_TO permission or prior message history.
The gate is behaving exactly as written. The problem is that it has no bootstrap.
The Problem
add_message admits a send when the sender holds CAN_REPLY_TO or there is prior message history. On a newly provisioned plane there is neither, and there is no way to obtain the second without the first. So the mailbox is installed, correctly fail-closed, and unusable: no member can initiate to any other member until someone grants permissions out of band.
For a deployment with ~15 members that is up to 210 pairwise grants to make a fundamental capability work at all — and every new member re-opens the problem. The result is that A2A reads as broken to the deployment's users even though identity, transport, and storage are all healthy.
This capability never existed — it is not a regression. There is currently no notion of "members of the same private deployment are mutually reachable by default."
The Architectural Reality
The current model is per-pair permission with a history escape hatch. That is the right default for a multi-tenant plane, where two callers who share a server share nothing else. It is the wrong default for a single-organisation private deployment, where every authenticated member is already inside one trust boundary — the auth provider decided that at login.
So the missing concept is deployment-scoped trust: the admission decision belongs to the deployment's posture, not to each pair of members inside it. autoProvisionIdentitySources already encodes exactly this reasoning for identity creation — GitLab PAT auto-provisions because a self-hosted GitLab is a scoped caller set, while public GitHub does not. Mailbox admission needs the same distinction and does not have it.
The Fix (one PR)
Add an AiConfig leaf governing default intra-deployment mailbox reachability, with an env binding, registered in the config-leaf parity manifest:
- Members authenticated by the same deployment may initiate to one another without a prior grant when the posture is private/self-hosted.
- Multi-tenant and public-identity postures keep today's pairwise behaviour.
- Explicit grants and revocations continue to work and continue to win; this changes the default, not the mechanism.
- Cross-deployment sends are unaffected — this is strictly intra-plane.
Acceptance Criteria
Out of Scope
- Broadcast semantics (
AGENT:*) — unchanged.
- Wake/subscription authorization — separate surface.
- Any change to identity auto-provisioning.
Related
autoProvisionIdentitySources — the existing precedent for posture-scoped admission
- #15798 (Local Runtime Parity) — the epic this deployment posture belongs to
Context
Observed on a fresh self-hosted private deployment during post-redeploy verification. The identity roster was healthy — 19 AgentIdentity nodes present, auto-provisioned from auth provenance — but every attempt to initiate a message failed:
The gate is behaving exactly as written. The problem is that it has no bootstrap.
The Problem
add_messageadmits a send when the sender holdsCAN_REPLY_TOor there is prior message history. On a newly provisioned plane there is neither, and there is no way to obtain the second without the first. So the mailbox is installed, correctly fail-closed, and unusable: no member can initiate to any other member until someone grants permissions out of band.For a deployment with ~15 members that is up to 210 pairwise grants to make a fundamental capability work at all — and every new member re-opens the problem. The result is that A2A reads as broken to the deployment's users even though identity, transport, and storage are all healthy.
This capability never existed — it is not a regression. There is currently no notion of "members of the same private deployment are mutually reachable by default."
The Architectural Reality
The current model is per-pair permission with a history escape hatch. That is the right default for a multi-tenant plane, where two callers who share a server share nothing else. It is the wrong default for a single-organisation private deployment, where every authenticated member is already inside one trust boundary — the auth provider decided that at login.
So the missing concept is deployment-scoped trust: the admission decision belongs to the deployment's posture, not to each pair of members inside it.
autoProvisionIdentitySourcesalready encodes exactly this reasoning for identity creation — GitLab PAT auto-provisions because a self-hosted GitLab is a scoped caller set, while public GitHub does not. Mailbox admission needs the same distinction and does not have it.The Fix (one PR)
Add an AiConfig leaf governing default intra-deployment mailbox reachability, with an env binding, registered in the config-leaf parity manifest:
Acceptance Criteria
ai/scripts/lint/config-leaf-parity.jsonin the same commit.add_messageto another member of the same deployment.revoke_permissionstill blocks a send that the default would otherwise allow; the default is a floor, not an override.Out of Scope
AGENT:*) — unchanged.Related
autoProvisionIdentitySources— the existing precedent for posture-scoped admission