Providers
AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called providers.
Create and manage providers that supply credentials to sandboxes.
Provider profiles define provider credentials, policy, and refresh behavior. See Profiles for the profile format and custom profile workflow.
Provider profiles include metadata for known endpoints and binaries. View the available profiles before creating a provider:
Create a Provider
Providers can be created from local environment variables or with explicit credential values.
For refresh-backed providers such as google-vertex-ai --from-gcloud-adc, openshell provider create now waits for the gateway to configure refresh metadata and mint the initial access token before it reports success.
From Local Credentials
The fastest way to create a provider is to let the CLI discover credentials from your shell environment:
This reads ANTHROPIC_API_KEY or CLAUDE_API_KEY from your current environment
and stores them in the provider.
With Explicit Credentials
Supply a credential value directly:
Bare Key Form
Pass a key name without a value to read the value from the environment variable of that name:
This looks up the current value of $NVIDIA_API_KEY in your shell and stores it.
From the Current OIDC Login
Profile-backed token-exchange providers can store the current gateway OIDC access token as their subject credential. The subject credential stays gateway-only and is not emitted into sandbox environment material or static credential bindings:
OpenShell infers the destination credential from the provider profile when the
profile has exactly one token_grant.subject_token.credential. If the profile
has more than one, pass --credential <key>. Refresh the stored subject token
later with:
This copies the current OIDC access token and expiry from the active gateway login. This requires an active named gateway that was registered for OIDC. If the stored gateway access token is expired and a refresh token is available, the CLI refreshes it before storing the provider credential. It does not store the OIDC refresh token in the provider.
--from-existing uses profile-backed discovery. The requested --type must
name an imported provider profile with a discovery section. If no matching
profile exists, the CLI returns an error instead of falling back to legacy
discovery.
Create a provider whose profile requires no static credentials without a credential source:
Provider creation rejects profileless types. For a custom GitLab deployment, import a profile with the deployment’s endpoints and then create an instance using that profile ID. Existing profileless provider records remain usable, but OpenShell does not create new ones.
Update a custom provider profile after exporting it, editing its endpoints,
binaries, or credential metadata, and preserving the exported resource_version:
Import remains create-only and fails if the profile ID already exists. Use
profile update <id> for existing profiles. Interceptor-managed
profiles are read-only. The target ID must match the profile ID in the file. Update accepts
one file at a time and rejects stale resource versions. Updated profile policy
applies to all provider instances of that type on the next sandbox config sync.
Delete one or more custom provider profiles by ID:
When a multi-profile delete fails for one entry, the CLI reports that profile’s failure and continues with the remaining IDs. The command exits with an error after it attempts every requested deletion if any entry failed.
Static credentials require an imported provider profile. Profiles
normally define at least one endpoint. An endpointless profile requires an
explicit credential_binding.provider on a sandbox policy endpoint. OpenShell
does not activate static credentials from a profileless provider because it
cannot determine which credential definition applies.
Manage Providers
List, inspect, update, and delete providers from the active gateway.
List all providers:
Use -o json or -o yaml for machine-readable output:
Structured list output is an envelope with providers and
next_page_token fields. Each provider includes metadata (id, name,
type), credential key names, config key names, labels, creation timestamp,
resource version, and credential expiration times. Only credential and config
keys are exposed, never values, preventing accidental credential leakage in
logs or output. Pass the returned token to --page-token to continue. For
details on how credentials are injected into sandboxes, refer to
Credential Injection.
Inspect a provider:
Update a provider’s credentials:
To wait until attached sandboxes apply the updated credentials, add --wait:
The update records which sandboxes are attached before saving the new credentials. Its result includes a change ID and outcome for each of those sandboxes. Sandboxes attached later are outside this wait. The timeout applies to the whole group; if any selected sandbox fails or times out, the command exits with an error and still reports each sandbox’s outcome. When no sandboxes are attached, it reports the saved change and an empty target list.
Credential refresh status tells you whether OpenShell obtained credentials. Provider readiness tells you whether the sandbox applied the credentials, policy, and environment for new processes. It does not test access to a backend model or cancel requests already sent upstream.
After a static credential update completes, launch a new client process to use the updated reference. An existing process keeps its revision-scoped reference; readiness does not make that old reference resolve the new value. Acknowledged detach revokes retained references and removes them from environments for future launches.
Set or clear a credential expiry timestamp:
Use 0 as the timestamp to clear expiry for a credential key.
Credential Refresh
Provider refresh stores non-injectable refresh material separately from the provider’s current credential values. The gateway can mint OAuth2 refresh-token tokens, OAuth2 client credentials tokens, Google service account JWT tokens, and AWS STS temporary credentials, then write the current access token back to the provider record for sandbox injection.
Configure refresh metadata for one injectable credential key:
Pass secret material with --secret-material-env KEY[=ENVVAR] (ENVVAR
defaults to KEY): the CLI reads the value from its own environment, so the
secret never appears in the host process table the way an expanded
--material KEY="$VALUE" argument would, and KEY is automatically marked
secret. Keep non-secret material on --material; --secret-material-key KEY
still marks a key supplied through --material as secret.
Check refresh status:
Delete refresh metadata for a credential:
Force a gateway-managed refresh for one credential:
AWS STS
The gateway calls sts:AssumeRole and writes three short-lived credentials
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) to the
provider record atomically.
The aws and aws-s3 profiles declare AWS_SECRET_ACCESS_KEY and
AWS_SESSION_TOKEN as additional_outputs of the AWS_ACCESS_KEY_ID refresh,
so all three credentials are gateway-minted. Create the provider with
--runtime-credentials — no placeholder credential is needed.
The gateway resolves its own AWS credentials using the default credential chain (instance role, IRSA, ECS task role, environment variables). For gateways not running on AWS, provide explicit IAM keys via refresh material:
Pass the long-lived secret with --secret-material-env so the CLI reads it
from its own environment instead of expanding it into a process argument,
where it would be visible in the host process table.
For temporary source credentials (AWS SSO or a prior AssumeRole), also pass a
session token with --secret-material-env aws_session_token=AWS_SESSION_TOKEN.
It requires the aws_access_key_id and aws_secret_access_key pair.
Use the generic aws profile type for multi-service access and scope endpoints
via sandbox network policy. Use aws-s3 for S3-specific endpoint rules.
The proxy re-signs requests using SigV4 before forwarding to AWS. Both curl and Python boto3 are supported.
External refresh systems should continue to push new current credentials through
openshell provider update. The --credential-expires-at option works for
static credentials, externally refreshed credentials, and gateway-managed
refresh strategies.
Delete a provider:
Delete multiple providers by listing their names in one command:
When a multi-provider delete fails for one entry, the CLI reports that provider’s failure and continues with the remaining names. The command exits with an error after it attempts every requested deletion if any entry failed.
Attach Providers to Sandboxes
Pass one or more --provider flags when creating a sandbox:
Each --provider flag attaches one provider. The sandbox receives eligible
credentials from every attached provider as placeholders at runtime. Each
static credential resolves only for endpoints in that provider’s profile, or
for explicitly bound sandbox policy endpoints when the profile is endpointless.
Profile-managed providers also contribute provider-generated network policy
entries. Endpoint binding independently limits where each static credential can
be resolved.
Use --provider to attach providers when creating a sandbox. To change the
providers attached to a running sandbox, use openshell sandbox provider attach
and openshell sandbox provider detach. See
Profiles for details.
Auto-Discovery Shortcut
Name a provider with --provider. If no provider by that name exists and the
name matches an imported profile ID, the CLI creates one from local profile
discovery, so you do not need to create it separately:
This finds your ANTHROPIC_API_KEY, creates a claude-code provider, attaches
it to the sandbox, and launches Claude Code. Add --auto-providers to skip the
confirmation prompt, or --no-auto-providers to skip creation entirely.
A provider is attached only when you name it. OpenShell does not derive one from
the trailing command: a profile’s binaries list authorizes a binary to reach
that profile’s endpoints, which is not a statement that running the binary asks
for the provider. A sandbox with no providers is a normal, fully supported
state.
How Credential Injection Works
The agent process inside the sandbox never sees real credential values. At startup, OpenShell replaces each credential with an opaque placeholder token in the agent’s environment. When the agent sends an HTTP request containing a placeholder, the proxy resolves it immediately before forwarding the request.
Static credential resolution has two independent authorization boundaries:
- Network policy must allow the calling binary and request destination.
- The credential binding must include the request host, port, and path. Profile
endpoints provide the binding by default. An endpointless profile can use a
sandbox policy endpoint that names the attached provider instance through
credential_binding.provider.
Both checks must pass. A provider profile endpoint does not grant network access unless provider policy composition or the sandbox’s own policy allows the request. A plain sandbox policy endpoint does not grant credential use unless the profile already covers it or the endpoint explicitly binds an endpointless provider.
Every static credential declared by a provider receives the complete endpoint set from that provider’s profile, or the explicitly bound sandbox policy endpoints for an endpointless profile.
Credential resolution requires the proxy to handle the request as HTTP. Raw
tls: skip and non-HTTP tunnels remain opaque and do not support credential
rewrite. Refer to Profiles
for endpoint matching and migration guidance.
Supported injection locations
The proxy resolves credential placeholders in the following parts of an HTTP request:
The proxy does not rewrite cookies, response content, unsupported request bodies, or WebSocket binary frames.
Fail-closed behavior
If policy allows a request but the credential binding does not include the
request endpoint, the proxy rejects the request with HTTP 403 and the
credential_endpoint_mismatch reason. It emits a denied activity event and a
security finding without recording the secret, placeholder, environment key, or
query string.
Unknown, malformed, expired, or otherwise unresolved placeholders also fail closed instead of being forwarded to the upstream service.
Inspect an Endpoint Binding
Export the profile used by a provider to inspect its credential boundary:
For the GitHub example profile, GITHUB_TOKEN and GH_TOKEN can resolve for
the profile’s api.github.com:443 and github.com:443 endpoints. Even if a
sandbox policy allows uploads.example.com:443, sending either placeholder
there returns credential_endpoint_mismatch.
For another service, define the credential in its own provider profile. Put stable endpoints in the profile, or leave the profile endpointless and bind each concrete provider instance from sandbox policy. Refer to Profiles for the profile workflow and schema.
Available Provider Types
The provider types available to --type are the IDs of the profiles you
imported. List them:
The repository’s
providers/ directory
ships example profiles for GitHub, PyPI, and the major inference and agent
providers. Each file’s header states the credential environment variables it
declares, the binaries it authorizes, and the endpoints it grants. Read it,
adjust the binary paths for your image, and import your copy.
ANTHROPIC_API_KEY is an API key from console.anthropic.com, not a subscription token. Subscription users must generate a separate API key from the Anthropic Console.
Inference Provider Access
Attach an inference provider to each sandbox that needs it and configure the workload to call the provider’s native endpoint. The workload, not OpenShell, selects the model and request timeout.
An OpenAI-compatible protocol does not make the openai profile safe for an
arbitrary host. Baseten, Bitdeer, Groq, Ollama, LM Studio, self-hosted NIM, and
other alternate endpoints need their own profile declaring the actual host,
port, credential, and allowed binaries. See
Inference for complete examples
and migration guidance.
Next Steps
Explore related topics:
- To manage workspace access for providers, refer to Workspaces.
- To control what the agent can access, refer to Policies.
- To use the default workload image, refer to Sandboxes.
- To view the complete field reference for the policy YAML, refer to the Policy Schema Reference.