AI Engineer Europe 2026

What if the network was the sandbox?

Read the talk

What if the network was the sandbox?

An agent can run inside a container while holding the credential that grants its access. Moving authorization to an identity-aware network changes where that control lives.

From a talk by Remy Guercio

Before you start: Basic familiarity with API credentials, HTTP requests, containers, and coding agents will help; tailnets and network identity are explained as they appear.

A boundary needs permissions

What makes a sandbox useful: the box, or what the agent is allowed to do from inside it? The familiar discussion starts with VMs versus containers, then asks whether the agent belongs inside or outside that boundary. Remy Guercio starts with two simpler components: a boundary separating inside from outside, and permissions, including identity, that determine what can happen across it. Without permissions, the sandbox has no toys: it isolates something without giving it useful access.

Slide listing “A boundary” and “A set of permissions” beneath the question “What are the components of a sandbox?”Open full source frame
A sandbox has a boundary and a set of permissions.

The usual ways of granting that access put credentials inside the environment being constrained.

Access mechanismWhat the agent receivesThe unresolved problem
API keyA credential granting provider accessPossession of the key does not, by itself, express the full authorization policy
OAuth or OIDC loginAccess associated with an authenticated accountThe account session still lives with the agent

Guercio characterizes API-key billing as the full-price route and account-based access as potentially more cost-effective. But the architectural issue is the same. Authentication establishes an identity; authorization decides what that identity may do. Handing an agent a key does not settle that distinction, and even synthetic keys can become objects a long-running agent tries to reuse or manipulate.

An OpenClaw instance running elsewhere with a logged-in account makes the problem concrete. The agent is in a box, but the thing granting its access is in the box too. That leads to the central question: can the network carry the permission boundary instead?

0:430:53
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:43 · section reference included

Connections carry identity

WireGuard gives network nodes cryptographic keys. Tailscale builds an identity layer on top, connecting devices in a private network called a tailnet. Those devices can be containers, GPU servers, laptops, or phones; the useful abstraction is a connection between identified participants, rather than a particular kind of compute environment.

The identity can describe either a person or a workload:

  • Users: A connection from a logged-in laptop can be associated with its user.
  • Groups: SCIM-synchronized membership can identify the user as belonging to an engineering organization or another team.
  • Tags: A GitHub Actions workload can carry a tag identifying it as a particular project's PR review bot.

That information supports two decisions. Network policy can prevent an unauthorized connection from happening at all. If the connection is permitted, the receiving application can also obtain the caller's identity and use it for application-level authorization. The application no longer has to start with an IP address and ask for a separate API key just to learn who is calling.

An identity-provider login connects to a laptop, with blue connections extending to server, database, compute, and service nodes.Open full source frame
Building authentication and authorization into the network.
3:213:37
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

3:21 · section reference included

Keep provider credentials at the gateway

Aperture applies this identity model to an LLM gateway. Like a conventional gateway, it stores provider credentials and forwards requests to upstream services. Guercio names Anthropic, OpenAI, Google's Gemini offerings, Vertex, and Bedrock. The difference is that Aperture is itself a tailnet node, so it can identify the clients connecting to it without issuing each client another provider credential.

For a PR review agent running in GitHub Actions, the authorization path is:

  1. The runner starts and uses GitHub's federated OIDC identity to obtain tailnet access through workload identity federation.
  2. The runner receives a workload tag on the tailnet.
  3. It connects to Aperture, which can resolve that identity.
  4. Aperture's rules determine what the tagged workload may access through the gateway.

The provider key remains on Aperture. The sandbox has no provider API credential to leak, share, or take to another endpoint. It still has network identity and the credentials needed for that identity; the removed secret is the upstream provider key. The agent can request access without possessing the provider credential that fulfills the request.

5:385:53
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

5:38 · section reference included

From a user identity to a request body

In the live dashboard, Guercio switches Aperture to light mode and opens his own usage. His laptop is logged into the corporate tailnet, so Aperture recognizes him as a user. That identity connects the overview—tokens, models, and spending—to the individual requests that produced it.

Opening a request exposes its headers, request body, and response body, including the context Claude Code sends before the user's short instruction. Guercio initially describes the request as asking for a greeting, then corrects himself: it asked for a ten-word story, about a cat sitting on a mat and then vanishing. The distinction matters because the visible user prompt is only a small part of what the client sends.

The session view groups the activity into two requests: a Haiku summary request and the story request. Guercio reports that the initial story request cost $0.20 with Claude Code's supplied context. That is the displayed session's cost, not a price for ten-word stories independent of their surrounding context.

7:227:32
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

7:22 · section reference included

Follow a PR review bot through the gateway

The same inspection works for a workload. Guercio opens a small PR review check that runs on every PR update. Instead of his user identity, its activity is attributed to a dogfood tag, with a view covering the previous 30 days. Guercio reports a displayed bot request costing $0.04 and running three commands together. Drilling into it exposes the Bash commands involved.

The extraction happens at the LLM gateway, outside the container and outside the agent harness. In the session's tool-call view, Guercio follows an MCP request to update the code review, Bash and grep activity, and another update to the review comment. The inspected frame also shows Read among the listed tools. This is visibility into tool calls represented in model traffic routed through Aperture, not a record of every local process or unrelated network request.

A Session Tool Calls dialog lists requests containing a comment-update tool, Bash, Read, and Grep over the Tool Use dashboard.Open full source frame
Aperture displays a session’s tool calls.

That placement also changes revocation. If access through the gateway is cut off, the sandbox cannot rescue the request by taking its provider key to another endpoint: it never had that key. The control does not depend on the agent accepting an instruction to stop or on a logging hook inside its own harness.

9:4710:00
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

9:47 · section reference included

A placeholder key, then a failed word count

The client configuration is deliberately small. In the agent sandbox script, Claude Code runs in API-key mode, receives a literal - as its placeholder key, and uses Aperture's endpoint as its base URL. The dash satisfies the client's expectation that the key field contain something; it is not what authorizes the request. Guercio then shows the same arrangement in his actual settings.json, names Codex and Gemini CLI as other supported clients, and starts a live ten-word-story request.

While the request runs, he observes that the same prompt has shifted from stories about robots to dogs to cats over roughly three weeks. The live cat story introduces a more immediate problem: an audience member counts only nine words. Guercio identifies the model as Opus 4.6 and jokes about its one-million-token context capacity while it misses this small constraint. Context capacity is not the amount of context used by this request. The correction adds finally to the ending.

A word-count failure is funny in a demo and consequential in a pipeline. A PR review bot may depend on a response having a particular structure; when that structure changes, the workflow can break far from the interactive session that would make the cause obvious. Back in Aperture, the session now contains three requests: the summary, the initial context-bearing story request, and the follow-up asking whether the answer was correct. The request and response bodies preserve both the failure and the model's acknowledgment that it supplied nine words.

11:4111:50
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

11:41 · section reference included

Shared budgets and gateway hooks

A shared gateway can apply spending controls across providers. Guercio's example is a single $1,000 allowance whose owner can choose how to distribute usage, rather than a separate $1,000 allocation at every provider. The budget follows the access policy through the gateway instead of being fragmented across upstream accounts.

Aperture also offers webhooks that send tool-call information to a third party. Placing the integration in the gateway means routed interactions can trigger it without depending on a cooperative hook inside the agent. Guercio connects that centralized path to reliable hook invocation; it does not establish unconditional delivery to an external receiver. A smaller quota example—$5 per day—shows how the same gateway can bound experimentation. Provider coverage depends on support for the relevant interfaces.

14:0714:21
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

14:07 · section reference included

Build the same identity boundary into a Go service

Aperture is one application of these primitives. Guercio describes it as available on Tailscale's free plan at the time of the talk. Its underlying building block is the open-source tsnet library, which lets a Go program become a tailnet node and read the identity of incoming connections. An internal MCP server or API endpoint can use that identity without becoming publicly reachable or requiring a separate OAuth integration for its callers.

For an internal service, the essential operation is to resolve the requester before acting on the request. This Go example uses the documented tsnet.Server and LocalClient.WhoIs interfaces to return the connecting node and, when present, its user identity. It illustrates the public API rather than reproducing a code listing from the recording.

go

package main

import (
	"encoding/json"
	"log"
	"net/http"

	"tailscale.com/tsnet"
)

func main() {
	node := &tsnet.Server{Hostname: "identity-demo"}
	defer node.Close()

	listener, err := node.Listen("tcp", ":80")
	if err != nil {
		log.Fatal(err)
	}

	client, err := node.LocalClient()
	if err != nil {
		log.Fatal(err)
	}

	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		identity, err := client.WhoIs(r.Context(), r.RemoteAddr)
		if err != nil {
			http.Error(w, "identity lookup failed", http.StatusForbidden)
			return
		}

		result := map[string]string{"node": identity.Node.Name}
		if identity.UserProfile != nil {
			result["user"] = identity.UserProfile.LoginName
		}

		w.Header().Set("Content-Type", "application/json")
		if err := json.NewEncoder(w).Encode(result); err != nil {
			log.Printf("write response: %v", err)
		}
	})

	log.Fatal(http.Serve(listener, handler))
}

A service proxying MCP operations could use the resolved identity when authorizing or constructing the downstream operation. Knowing the caller is the starting point; the service must still decide which operations that caller may perform.

Aperture's own design constraint was to use those public building blocks. It could be built on top of Tailscale, but could not depend on private Tailscale API endpoints. That makes the architecture reusable: another application can join the network, identify callers, and apply its own policy without needing Aperture's internal implementation.

15:3115:42
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

15:31 · section reference included

Configure permissions in the UI or in policy

The first audience question asks how to configure permissions, particularly whether some tool calls can be allowed and others denied. Guercio shows two configuration paths. In Aperture's Grants editor, administrators select who a grant applies to and configure categories such as model access, quotas, MCP access, hooks, and roles. Aperture also contains an MCP server/proxy. Group selection in that editor is described as forthcoming in the demonstrated version.

The declarative path uses the main Tailscale policy file. Application capabilities attach application-specific metadata to identity, backed by the Tailscale control plane. The receiving application can therefore get more than a user or tag: it can receive policy data relevant to its own authorization decisions. JSON configuration and an API let teams manage this through GitOps instead of making every change in the visual editor.

17:0417:13
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

17:04 · section reference included

Why configure a base URL explicitly?

Another audience member asks whether Tailscale could intercept requests to Claude Code's default destination and substitute Aperture automatically. Guercio says transparent interception was discussed and is technically possible, but it is not the chosen approach.

The tradeoff is predictability. Explicitly setting a base URL makes the gateway part of the client's visible configuration. Hidden interception can break behavior or become confusing as underlying systems change. The intended experience pairs easy LLM access for developers with usable controls and tool-call visibility for IT and security administrators, without concealing where requests go.

18:4618:51
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

18:46 · section reference included

Model permissions are not yet arbitrary tool permissions

Asked directly about role-based access to individual tools, Guercio distinguishes the implemented controls from work underway. At the time of the demonstration, model, provider, and quota permissions are available; finer tool-specific permissions are still being developed. Group identity, including groups defined through a SCIM provider, supplies the basis for assigning access.

The budget examples span a larger team allowance and smaller individual allowances, or unrestricted use of internal GPU endpoints alongside a capped Opus 4.6 allowance. Guercio calls the team/individual combination a union but does not specify its enforcement algorithm, so those allowances should not be read as automatically adding together.

20:2520:31
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

20:25 · section reference included

Generated code exposes the harder boundary

The final question pushes beyond structured tool calls. If an agent writes and executes code, that code can make network requests whose meaning is harder to recover than a named MCP operation. Guercio agrees that permissioning becomes more complicated. This was a reason to observe the LLM layer rather than build only an MCP proxy: an MCP-only view would miss much of the activity that coding agents express through other mechanisms.

Skills and generated code still commonly involve commands represented in the model interaction, making those commands available for inspection. But an agent could write code, obfuscate it, and then execute it. Seeing the outer command does not automatically reveal everything that program will do. Guercio acknowledges that complication rather than presenting command visibility as complete semantic understanding.

For many teams, discovery comes before blocking: they first want to know whether people are using MCP tools, Bash, or something else. Guercio says Bash dominates usage in Tailscale's internal instance, distinct from the demo instance on screen. The gateway makes those command-bearing interactions inspectable.

Guardrails that reject dangerous commands, such as rm -rf /, are described as future additions. The substantive boundary is therefore between observing an operation and enforcing its permitted effects. Moving credentials and policy outside the agent gives an independent place to authorize, record, and revoke model access. Understanding arbitrary generated code remains harder, and the visibility applies to the particular agents whose model traffic is routed through Aperture.

21:2821:37
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

21:28 · section reference included

Resources

From the talk

Updates since the talk

  • Current configuration reference: all matching quota buckets must have positive balances and are charged together. Also covers current commercial conditions, providers and hooks.

  • Later documentation describes additive grants, group identities, and MCP capability permissions; this is distinct from the tool-specific permissions still under development in the recording.

Transcript download
Read the transcript and explore slides

Loading transcript and slides…