Skip to main content
Mesh separates storing an agent’s GitHub or GitLab PAT from permission to send it to that agent’s execution environment. This does not create shared accounts or grants to another agent’s identity. See the identity invariant. An agent’s own GitHub or GitLab PAT is usable in that agent’s own sandbox by default. Operators can turn off delivery under Coding account access in the agent’s capability editor. New permissions use source=automatic; explicit operator choices and existing legacy_migration records are preserved, including existing disabled permissions. Native GitHub API calls remain a separate audience. MCP OAuth, model, connector, master, and execution-provider credentials are never included in the sandbox environment. Each run receives one immutable issuance per provider recording the owning agent, credential kind, permission revision, and whether a credential was available. The durable run must belong to the agent. Credential writes/deletions and permission edits invalidate earlier issuances. A running sandbox cannot silently acquire a newer permission or credential; a new run is required. Continuations must satisfy the original sandbox’s credential revision as well. Invalidated inherited sandboxes are eligible for cleanup even before the child run first acquires a handle. Permission changes and credential rotation also retire retained project snapshots from reuse, because shell code may have copied a token into the project tree. Snapshot capture is serialized with revocation. Delivery uses a protected file inside the sandbox, not a token in the backend’s exec URL. Shell tools see authorized GH_TOKEN/GITHUB_TOKEN and/or GITLAB_TOKEN. The same authorization path applies to Modal and Fly Sprites and preserves the agent’s selected backend or inherited instance default. Git clone, push, and gh/glab use each granted PAT’s actual provider permissions. A default repository is not a security scope in an unrestricted shell. Revocation prevents new authorized delivery and invalidates active and held sandboxes. Handles revalidate before operations and monitor running operations; a background worker checks for pending teardown every five seconds, independently of the agent loop. In-flight operations are rechecked every second; each authorization read has a five-second deadline so a database outage cancels the operation rather than leaving its last permission active indefinitely. Disabling backend acquisition does not disable teardown with retained backend credentials. Provider unavailability can delay physical destruction; durable authorization still fails closed. Exact plaintext tokens are redacted from command output, file reads, and returned errors. This is not an exfiltration barrier: shell code that can use a PAT can transform or copy it. Revoke or rotate the PAT at its provider to invalidate copies already exposed outside Mesh. A future broker can replace long-lived PATs with short-lived credentials; current delivery does not provide that capability. Grant issuance is recorded in workspace_credential_issuances; operator permission changes appear in the existing Activity audit with the connection and agent. Records contain permission metadata, never plaintext tokens. Per-agent, per-provider delivery locks serialize credential-file writes with revocation; agent commands do not hold that lock. Issuance is an authorization record, not proof that a vendor received credential bytes. Authorization-store failures fail closed by destroying the sandbox, including transient database errors. Cancelling a tool request alone cannot stop detached processes that already hold credentials. This deliberately favors authorization over availability: after such a failure the agent must start a new run. An absent coding key allows unauthenticated work; an existing key that cannot be decrypted surfaces the decryption error instead of a misleading git authentication failure. GitHub and GitLab permissions default on only for the owning agent. Existing disabled rows remain disabled. A mixed-provider sandbox is invalidated when either provider changes, but that does not alter the other provider’s saved permission. See GitLab coding.

Agent-vault entries in the sandbox

workspace_exec accepts secrets: [name, …], the agent’s own vault entries (Agent vault), delivered to that command as MESH_SECRET_<NAME> through the same protected grant file the PATs use and redacted from output the same way. They are deliberately not in workspace_credential_permissions or workspace_credential_issuances: those record an operator’s grant of an acting identity to a run, with the revision machinery that retires a sandbox when the operator changes their mind. A vault entry is something a person handed the agent for its own work, requested by the agent per command; rotating or forgetting one does not tear down a running sandbox, and the next command naming it gets the new value or a refusal. The entries are written to the grant file for the one command and withdrawn when it returns, so a later file read sees only the run’s grants. Exact-plaintext redaction applies to the credential grants by key and to every per-command value at any length. Two entries that would meet at one variable after uppercasing (api_key, API_KEY) are refused rather than letting one win.

The workspace broker (built, off)

internal/workspacebroker (0084_workspace_broker.sql) can carry a provider’s git traffic through Mesh so its token never enters the sandbox: git’s configuration rewrites the provider’s URLs to PUBLIC_URL/workspace-broker/..., the sandbox holds a run-scoped Mesh token, and Mesh adds the agent’s PAT per request. No provider is brokered. GitHub was, briefly, and it made agents unable to do their work: the broker speaks only git, so gh, GitHub Packages (npm.pkg.github.com), and every other tool that reads GH_TOKEN had nothing to authenticate with. GitHub delivers the agent’s own PAT again. It is the agent’s own token on purpose — commits, pull requests and comments carry the agent’s identity — so an app-minted short-lived token is not a substitute. The broker and its tests remain (coding.Provider.Brokered); it is dormant, not deleted, so its schema and code stay consistent with the applied migration.