Skip to main content
The auth proxy lets sandbox code call external APIs (OpenAI, Anthropic, GitHub, etc.) without hardcoding credentials. When configured on a sandbox, an egress proxy running outside the sandbox automatically injects authentication headers into matching outbound requests using your workspace secrets or write-only credentials you provide in the proxy config.
You must configure your secrets (e.g., OPENAI_API_KEY) in your LangSmith workspace settings before creating a sandbox that references them.

Egress and network access control

The same proxy_config that injects credentials also controls which destinations a sandbox can reach. Access control is enforced per connection on the sandbox host, so changes to access_control take effect immediately.

How egress works

  • Access control applies to every outbound TCP connection, HTTP or not.
  • HTTPS to a host matched by a rule or callback is decrypted by the proxy so it can inject headers; sandboxes trust the proxy’s CA. HTTPS to unmatched hosts and every non-HTTP connection, including PostgreSQL, SSH, and Redis, passes through unchanged. Ports 80 and 443 are reserved for HTTP and TLS; a non-HTTP protocol on either port does not work.
  • Address destinations by hostname. A direct raw TCP connection to a literal IP address on a non-HTTP port is dropped, even when that IP is on an allow_list. HTTPS to a literal IP is dropped too, because the proxy needs a hostname in the TLS handshake. Only cleartext HTTP on port 80 works against a literal IP.
  • Only TCP leaves the sandbox. UDP (including QUIC) and ICMP are dropped.

Default egress posture

With no access_control, every hostname is reachable on every TCP port, unless your organization is on restricted egress. The only exception is hosts that resolve to private, loopback, or cloud-metadata addresses, which the proxy always refuses to dial. Add an access_control to restrict this. To allow HTTP and HTTPS to any host while blocking every other port, use a port-qualified allow list. * matches every hostname:
Add host:PORT entries to open specific raw TCP destinations on top of that, such as db.example.com:5432.

Allow and deny lists

Add an access_control object to proxy_config with either an allow_list or a deny_list (not both—the request is rejected if both are set): Both lists apply to HTTP, HTTPS, and raw TCP alike. Neither mode distinguishes protocols; use a port suffix to restrict an entry to one port.
A deny_list only blocks the hosts you list. {"deny_list": ["example.com"]} blocks example.com on every port and leaves every other host reachable on every port, including DNS, SSH, and database ports. To turn off raw TCP everywhere, use an allow_list such as ["*:80", "*:443"].

Pattern syntax

Each allow_list/deny_list entry uses the following forms: Matching is on the destination exactly as the sandbox addressed it. A hostname entry matches requests made to that hostname; an IP or CIDR entry matches requests made to a literal IP address. Neither is resolved: deny_list: ["203.0.113.0/24"] does not block foo.example.com even when it resolves into that range, and allow_list: ["203.0.113.7"] does not allow it either. Because raw TCP and HTTPS to a literal IP are dropped before access control runs (see How egress works), IP and CIDR entries only ever affect cleartext HTTP requests on port 80 that name the IP directly. Entries that do not parse—example.com:abc, example.com:99999, or a CIDR with a port—are rejected when the sandbox is created or updated.

Organization-level restricted egress

An organization can be placed on restricted egress. When it is, LangSmith replaces each sandbox’s access_control with a fixed allow list of package registries, OS package mirrors, source-code and container-image hosts, CDNs, and model-provider APIs, each pinned to specific ports (HTTPS, plus HTTP for the Ubuntu and Debian mirrors). Caller-supplied allow_list and deny_list values are accepted by the API but have no effect while the policy is active.

Connecting to a database (raw TCP)

To let sandbox code reach an external PostgreSQL database with psql, dbt, or any driver, allow-list the host on its port. Because allow_list is default-deny, also list any HTTP(S) hosts the sandbox needs. Pin them to :443 unless you need other ports too:
The connection to db.example.com:5432 is passed through at the TCP layer with no interception, so the PostgreSQL wire protocol—and TLS, host-key checking, and any other end-to-end protocol on top of it—works unchanged.
Creating a sandbox boots it and returns once it reports ready, so there is no wait step to add. GET /api/v2/sandboxes/boxes/{name}/status reports the current state if you need to re-check it later.

Configure via SDK

Configure auth proxy rules

Add a proxy_config when creating a sandbox, or update an existing sandbox by patching its proxy_config. A proxy_config has: Each rule specifies:

Header types

Each header has a required type that controls how its value is stored and displayed:

Set environment variables from a rule

A rule’s env_vars are plaintext environment variables set for every command in the sandbox while that rule is enabled. Use them for tools that refuse to run unless a credential variable is present, even though the proxy injects the real credential on the wire: give the variable a placeholder value so the command starts, and the proxy supplies the real credential. Values are plaintext and are returned by the API, so never put a secret in env_vars. Use a header with the workspace_secret or opaque type instead. Environment variables resolve in this order, from lowest precedence to highest:
  1. The snapshot image’s ENV, when the sandbox opted into apply_image_config.
  2. Enabled proxy rules: When two enabled rules declare the same name, the later rule in rules wins.
  3. The sandbox’s own env_vars: Explicit per-sandbox values override values from rules.
Variables managed by an enabled AWS or GCP auth rule (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_EC2_METADATA_DISABLED, AWS_CA_BUNDLE; CLOUDSDK_AUTH_ACCESS_TOKEN, CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE) sit outside this order: a rule or a sandbox env_vars entry that declares one of them is rejected while the matching auth rule is enabled. Every sandbox also has the common CA-bundle environment variables pointed at the system trust store, which includes the proxy’s CA, so tools that pin their own bundle still verify proxy-injected hosts. Set any of them yourself to override.

Authenticate AWS requests

Use an AWS auth rule when sandbox code needs to call AWS services with an AWS SDK or CLI. The proxy keeps the real AWS credentials outside the sandbox, then signs outbound HTTPS requests to *.amazonaws.com endpoints with AWS SigV4. This is useful when agent code needs to inspect S3 objects, call Bedrock, or use another AWS endpoint without exposing long-lived AWS access keys in sandbox files, environment variables, shell history, or logs. The sandbox receives placeholder AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY values (plus AWS_EC2_METADATA_DISABLED=true and AWS_CA_BUNDLE) so SDK credential detection works, while the proxy replaces whatever the request carries with a real SigV4 signature. Only service.region.amazonaws.com hosts, S3 virtual-hosted and path-style hosts, and a few global endpoints such as iam, sts, and s3 are signed; plaintext HTTP to a matched AWS host is rejected with 403.
Do not set real AWS access keys as sandbox environment variables. Configure them as workspace_secret or opaque proxy values. Plaintext AWS credential values are rejected.
AWS auth rules are different from header injection rules:
  • Set type to aws.
  • Put credentials under the aws object.
  • Do not set match_hosts, match_paths, or headers; AWS host matching is built into the proxy.
  • Configure at most one AWS auth rule per sandbox. The limit counts every AWS rule, including disabled ones.

Configure AWS auth via SDK

After the sandbox is ready, use AWS SDKs or CLIs normally inside the sandbox. The SDK or CLI discovers the placeholder AWS environment variables, and the proxy applies the real SigV4 signature to outbound AWS requests. The proxy does not set a region: set AWS_REGION through the sandbox’s env_vars or the rule’s env_vars, or most SDK and CLI calls fail before they reach the proxy.
AWS auth proxy rules currently support access key ID and secret access key credentials. They do not include a session token or assume-role configuration.

Authenticate GCP requests

Use a GCP auth rule when sandbox code needs to call Google APIs with Google SDKs or CLIs. The proxy keeps the service account JSON outside the sandbox, then authenticates outbound HTTPS requests to googleapis.com and its subdomains. This is useful when agent code needs to inspect GCS objects or call another Google API without exposing service account JSON in sandbox files, environment variables, shell history, or logs. The sandbox receives a placeholder CLOUDSDK_AUTH_ACCESS_TOKEN (plus CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE) so gcloud runs, while the proxy replaces whatever authorization the request carries with a token minted from the configured service account. Google client libraries that discover credentials through Application Default Credentials do not read these variables and fail to find credentials; only gcloud and direct HTTPS calls are supported.
Do not set real service account JSON as a sandbox environment variable. Configure it as a workspace_secret or opaque proxy value. Plaintext GCP credential values are rejected.
GCP auth rules are different from header injection rules:
  • Set type to gcp.
  • Put credentials under gcp.service_account_json.
  • Set gcp.scopes to a non-empty list of OAuth scopes.
  • The proxy matches googleapis.com and its subdomains automatically and authenticates those requests with the configured service account. Hosts under google.com are not matched. Plaintext HTTP to a matched host is rejected with 403.
  • Configure at most one GCP auth rule per sandbox. The limit counts every GCP rule, including disabled ones.
The SDK gcp_auth and gcpAuth helpers build this same rule shape.

Configure GCP auth via SDK

After the sandbox is ready, use gcloud or direct HTTPS calls to googleapis.com hosts normally inside the sandbox. The proxy applies the real GCP authentication without exposing service account JSON inside the sandbox.

Single API example

Create a sandbox that automatically injects an OpenAI API key into outbound requests:
Requests to api.openai.com are now authenticated by the proxy; no real key is stored in the sandbox. SDKs that refuse to start without an API key still need a placeholder—set one with the rule’s env_vars, as in the GitHub example.

Multiple API example

Add multiple rules to authenticate with several services at once:

GitHub example

Open SWE authenticates GitHub access by minting a short-lived GitHub App installation token outside the sandbox, then patching the sandbox with write-only opaque proxy rules. This keeps the short-lived GitHub access token out of the sandbox filesystem and out of deployment environment variables. Configure two rules:
Python
Call configure_github_proxy after creating or reattaching to a sandbox. GitHub App installation tokens expire, so refresh the proxy config whenever you reuse a sandbox for a new run.
PATCH replaces the stored proxy_config wholesale. If the sandbox also uses access_control or callbacks, include them in every update or they are dropped. Opaque header values you leave empty are carried over from the current config.
The github-api rule sets GH_TOKEN to a non-secret placeholder, which satisfies the gh CLI’s local credential check. Commands then run without a per-command prefix:
The placeholder never leaves the sandbox. The proxy injects the real Authorization header into the outbound request.

Configure via SDK

Callback credential example

Static workspace_secret rules pull credentials from your workspace when the proxy configuration is applied, and opaque rules let your application patch in short-lived credentials such as the GitHub token example. For credentials that must be resolved by your own service at proxy time, use a callback. The proxy POSTs to a URL you provide, your endpoint returns the headers to inject, and the proxy caches the result. Callbacks are configured alongside rules under proxy_config: Static rules win. If an enabled header-injection rule matches both the host and the path, the callback is skipped for that request. Within rules, first-match-wins; the same applies between callbacks if multiple match.

Callback contract

The proxy makes the following request whenever it needs to resolve credentials for a matched host on a cache miss:
identity tells your endpoint which sandbox is asking, so one callback URL can serve many sandboxes and mint per-sandbox or per-user credentials. ls_user_id is the creating user and is omitted when the sandbox was created with a workspace or service key. Ignore fields and headers you do not recognize; the proxy may add more. Your endpoint must respond 2xx with a JSON body:
The proxy injects every header in the response into the sandbox’s outbound request and caches the response for ttl_seconds. Any non-2xx response, transport error, or malformed JSON fails closed: the sandbox’s request is rejected with 502 callback resolution failed (no headers injected, response not cached). Redirects are not followed and count as failures.

Verify callback requests

request_headers let your endpoint check a shared secret you chose. To verify that a request came from LangSmith and was not altered in transit, check the X-LangSmith-Signature-JWT header. It is a JWT signed with an Ed25519 key (alg: EdDSA) whose public half is published at <LANGSMITH_ENDPOINT>/.well-known/jwks.json, selected by the token’s kid. Verify the signature against the JWKS, check every claim above, hash the body you received, and compare it to body_sha256. Then trust identity in the body.

Example

Use a callback when your OAuth tokens are minted on demand by your own service:

Configure via SDK