Govern Where You Own the Destination
Governing Agents at the Boundary — part 1 of 4
The plan fit on one page. A gateway in front of every agent, a policy surface for every hop, one place to write the rules. It is the picture most agent-governance designs start from, and ours started there too.
Before building on it, the team did something slower. Every written claim the plan relied on, whether from the platform’s documentation or from a reference architecture, was turned into a probe and run against a live development project. One claim, one test, one recorded result.
This series is about what happened next: the first time the doctrine this blog spent the summer on met a running, enforced system end to end. These are field notes rather than doctrine.
The probe ledger
Most of the ground the plan stood on did not hold for us.
- A self-managed gateway variant the design depended on was not offered on any API version or in any location we tried.
- The access-policy surface everything was going to hang from governed egress only. Ingress rules were rejected.
- A service-account caller could not reach the managed gateway at all. The private endpoint to it stayed pending indefinitely.
- The routing path that would have carried our own serverless workloads through the gateway was gated behind an allowlist.
The reference architecture fared the same way. Of twenty-eight claims checked, five were confirmed. The rest were wrong, inaccurate or still unproven. A pattern showed up in the results. The network plumbing was sound in concept, and its defects were wiring. The product-capability claims were the part that failed.
None of this is a complaint. Each item is a measured constraint, and the design records each one with a condition for revisiting it. But a design built on those claims would have spent weeks debugging things that did not exist.
The one layer that held
One arrangement worked end to end, every time: a load balancer we run, in front of a service we own, with our own extensions and our own decision callout attached.
A content-safety screen blocked malicious requests there before they reached the service. A workload identity presented as a client certificate, issued by our own certificate authority, could be matched exactly. An impostor certificate carrying the right identity string from a different authority was refused. A decision service of our own ran as a callout in the request path, adding roughly ten to twenty-five milliseconds.
What this layer has that the others lacked is ownership. We own the destination, so we own the path into it. Nothing about it depends on how the caller was built, which platform it runs on, or which route its traffic took.
The organizing rule
The design was rebuilt around one sentence: who owns the destination decides where enforcement sits.
That gives four classes of destination, and each gets one named enforcement point:
| Destination | Where the decision sits |
|---|---|
| Our own endpoints: agents, tool servers, agent-to-agent services | at the callee, on ingress we run, with our own decision point |
| The model | the platform’s content-safety floor, which screens every prompt and response whatever path the call took |
| Data services: storage, warehouse, document stores | identity and access management, plus the platform’s perimeter controls |
| Third-party services | the caller’s egress path, deferred until there is a path we can govern |
The last row is deliberately unfinished. Writing it down as “deferred” is more useful than drawing an arrow to a control that does not exist yet.
The table also shows its own gaps. The content floor covers only what reaches a model. Agent-to-agent messages, tool arguments sent to our own tools, and data that leaves without passing a model are not screened by it. Those gaps are why the first row needs a decision point of its own. They are also listed in the design, so nobody has to rediscover them.
The floor needs a word too. In one development project it was set to inspect only. During a probe it flagged a prompt injection, correctly, and let the call proceed. Detection and enforcement are separate settings, and whether to switch to blocking is a decision for each environment, recorded as one.
Two votes on every agent-to-agent call
The clearest confirmation came from the running reference deployment, and it arrived as a failure.
Three agents cooperate in the deployment. An orchestrator calls two specialists over an agent-to-agent protocol, and every call crosses a managed egress gateway. During rehearsal the gateway allowed the orchestrator’s call to a specialist. The message went through. The specialist answered:
Tool execution denied.
The orchestrator held only a read role on the specialist’s runtime, a rehearsal misconfiguration. The gateway had allowed the edge. The specialist’s own access control had not allowed the caller.
That is the organizing rule seen from the other side. A gateway allowing an edge does not end the decision. The owner of the thing being called keeps a vote, and the gateway cannot cast it on their behalf. The fix was a grant: the orchestrator now holds a role that lets it invoke each specialist. The second vote stays in place on purpose.
It is also the answer to a question that comes up whenever a design places a gateway in the middle: isn’t that a single point of trust? On these calls it is one of two owners.
What changed
Every written claim is a hypothesis until a probe says otherwise. The design carries a ledger of claim, test and result, and the reference architecture is scored line by line in an appendix. Copy the shape. Verify the claims.
Each destination class has exactly one named enforcement point, and a design row that says why. When a new destination appears, the first question is who owns it. The answer places the control.
Registered is not the same as vetted. Some workloads register themselves in the platform’s registry when they are deployed. The decision point’s admission check is therefore designed to test an explicit vetted marker, not the fact of registration.
Rules are designed to be written once, in a neutral schema, and compiled to whichever enforcement point owns the destination. A rule should not need rewriting when a gated path opens later.
The line that stays
A boundary holds where its owner sits. Every layer that depended on someone else’s path was absent, gated or one-directional when we measured it. The layer in front of a destination we own held end to end.
The boundary belongs to whoever owns the thing being protected. Everyone else is a messenger.