Providers v2
Providers v2 turns providers from credential records into profile-backed access bundles. A provider profile describes the credentials, endpoints, binaries, policy rules, and refresh behavior for a provider type. A provider instance stores the concrete credential and config values for one gateway.
Use Providers v2 when you want provider-owned policy rules to travel with provider credentials. For example, a GitHub provider can describe both GITHUB_TOKEN and the GitHub API endpoints that a sandbox needs, so users do not have to copy the same network policy into every sandbox.
Why Providers v2 Exists
Provider credentials and network policy were previously configured through separate workflows. A user could create a GitHub provider that stored GITHUB_TOKEN, but the sandbox still needed a separate policy that allowed api.github.com, selected the right binaries, and configured REST enforcement.
Providers v2 keeps those pieces together:
Enable Providers v2
Provider profile policy composition is controlled by the gateway-level providers_v2_enabled setting. Enable it on the active gateway:
When the setting is disabled or unset, providers keep the existing credential-only behavior. Sandboxes still receive provider credential placeholders, but attached provider profiles do not add network policy entries to the effective policy.
To disable provider profile policy composition, delete the setting:
The feature flag controls provider-derived policy layers. It does not change the current credential injection model. OpenShell still injects placeholder environment variables into sandbox processes and resolves those placeholders in outbound HTTP traffic.
Available Features
Providers v2 currently includes these user-facing features:
- Built-in provider profiles stored in the
providers/directory of the GitHub repository. openshell provider list-profileswith table, YAML, and JSON output.openshell provider profile export,import,lint, anddeletefor custom profiles.- Provider instances created from built-in or imported profile IDs with
openshell provider create --type <id>. - Just-in-time effective policy composition from sandbox policy plus attached provider profiles.
- Runtime sandbox provider lifecycle commands under
openshell sandbox provider list|attach|detach. - Credential refresh configuration with
openshell provider refresh status|configure|rotate|delete. - Credential expiry metadata with
openshell provider update --credential-expires-at; values accept Unix epoch milliseconds or ISO/RFC3339 timestamps.
Roadmap
The following Providers v2 design items are not part of the current behavior:
Use Inference Routing for the current inference.local model.
Provider Profiles
A provider profile defines a provider type. It contains metadata, credential declarations, endpoint policy, binary policy, inference metadata, and optional credential refresh metadata.
List available profiles:
Export a built-in profile as YAML:
Lint a profile before importing it:
Import one profile file:
Import all non-recursive *.yaml, *.yml, and *.json files from a directory:
Custom profile IDs must use lowercase kebab-case with a-z, 0-9, and -. Built-in profile IDs and legacy provider aliases are reserved. Built-in profiles are read-only, and OpenShell rejects deleting a custom profile while a sandbox-attached provider uses it.
Category Enum
The category field controls how openshell provider list-profiles groups profiles. Use one of these canonical YAML values:
Profile Schema
Provider profile YAML and JSON use this shape. Treat this as a field map, not a profile to import verbatim. The endpoint and rule fields mirror the network policy schema used under network_policies. Refer to Policy Schema Reference for field semantics.
Profile Sections
id, display_name, and description identify the profile. id is the value passed to openshell provider create --type.
category groups profiles in openshell provider list-profiles. Use one of the values in the category enum.
credentials declares the credential names, environment variables, auth metadata, and optional refresh metadata for the provider type. The current runtime still exposes configured credential keys as placeholder environment variables and resolves placeholders in outbound HTTP requests.
endpoints contains the same endpoint object shape as sandbox network policy. A profile can use access presets, protocol-specific allow rules, deny rules, WebSocket credential rewriting, request body credential rewriting, GraphQL fields, and SSRF IP allowlists.
binaries contains the executable paths allowed to reach the profile endpoints when the profile contributes policy to a sandbox.
inference_capable marks profiles that are intended to participate in inference workflows. It does not currently mount or configure inference.local.
Refresh Metadata
Credential refresh metadata belongs to one credential declaration. The profile defines allowed defaults, such as token URL, scopes, refresh lead time, maximum lifetime, and required material keys. The provider instance stores the actual refresh material.
Profile YAML can declare these refresh strategies:
openshell provider refresh configure accepts only gateway-mintable strategies: oauth2-refresh-token, oauth2-client-credentials, and google-service-account-jwt. Use openshell provider update for static and external refresh patterns.
Gateway-managed refresh strategies use these material keys:
OpenShell keeps token endpoints profile-owned. Refresh material cannot override token_url or token_uri during refresh configuration.
Provider Instances
A provider instance stores concrete credentials and config for a profile type. Built-in profile IDs and imported custom profile IDs are accepted by --type.
Create a GitHub provider from the built-in github profile:
Create a provider from local credentials discovered by the provider implementation:
Create a provider from an imported custom profile:
Inspect the provider:
Update provider credentials:
Set or clear credential expiry metadata:
Use an ISO/RFC3339 timestamp or Unix epoch milliseconds. Use 0 as the timestamp to clear expiry for a credential key.
OpenShell skips expired provider credentials when it builds a sandbox provider environment. Running sandboxes also reject expired retained credential generations during placeholder resolution, so stale placeholders fail closed instead of forwarding unresolved or expired credential material.
Configure Credential Refresh
Refresh configuration is stored separately from the current injectable credential value. The gateway refresh worker reads refresh state, mints a new short-lived token for supported strategies, writes the token back to the provider record, and updates credential expiry metadata.
For a complete Microsoft Graph OAuth2 refresh-token walkthrough, see Refresh Microsoft Graph Credentials with Providers v2.
The profile YAML strategy values use underscores, while the CLI --strategy values use kebab-case:
Create the provider instance first:
Configure OAuth2 client credentials refresh:
Configure OAuth2 refresh-token refresh:
Configure Google service account JWT refresh:
--secret-material-key takes the name of a --material key, not the secret value. For example, use --material client_secret="$MS_CLIENT_SECRET" with --secret-material-key client_secret. The key should match a material entry so OpenShell can record that material field as sensitive when it stores refresh state. The gateway uses the material values to mint future access tokens, but only the --credential-key value, such as MS_GRAPH_ACCESS_TOKEN, becomes the injectable provider credential. If a refresh response rotates an OAuth refresh token, OpenShell stores the new refresh_token material and marks refresh_token as secret automatically.
Use --credential-expires-at when the current provider credential already has a known expiry timestamp. For refresh-managed keys, the value can be Unix epoch milliseconds or an ISO/RFC3339 timestamp such as 2026-01-01T00:00:00Z or 2026-01-01T01:00:00+01:00. OpenShell stores that value as epoch milliseconds in both refresh state and provider credential metadata. Later gateway-managed refreshes replace it with the minted token expiry.
Force a refresh immediately:
Check refresh status:
The status table reports operational state without printing token values or refresh material:
When no refresh configuration exists, the CLI distinguishes whole-provider checks from credential-specific checks:
Delete refresh state for one credential:
Deleting refresh state clears the provider credential expiry only when that expiry came from the deleted refresh state. If you later set a different expiry manually with openshell provider update --credential-expires-at, OpenShell preserves the manual value.
Refresh Logs
The gateway emits secret-safe refresh logs during each worker sweep. Use these logs to check which credentials the gateway is watching, when the next refresh is due, and whether a credential is already refreshed.
The sweep line summarizes how many credential refresh records the worker inspected. The watch line shows the provider, credential key, strategy, refresh status, expiry time, next refresh time, and whether refresh is due or manually requested. It does not include access-token values or refresh material.
Refresh updates the provider record. Sandboxes receive the updated credential through the same placeholder environment and proxy rewrite path as other provider credentials.
Launch Sandboxes with Providers
Attach providers when creating a sandbox with repeated --provider flags:
When providers_v2_enabled=true, each attached provider with a matching profile contributes a provider policy layer to the sandbox effective policy. When the setting is disabled, the sandbox receives provider credentials but not provider-derived policy entries.
List providers attached to a sandbox:
The list output includes provider name, provider type, credential key count, and config key count.
Policy Composition
OpenShell stores sandbox-authored policy and provider attachments separately. When a sandbox asks for its effective policy, the gateway composes the current sandbox policy with provider policy layers just in time.
For example, the built-in GitHub profile contains these endpoints and binaries:
If a sandbox attaches a provider named work-github, the effective policy includes a generated provider rule:
Inspect the effective policy:
Composition follows these rules:
- Provider policy entries use reserved
_provider_*keys derived from provider instance names. - Provider policy entries are derived data. OpenShell does not persist them back into the sandbox-authored policy.
- If a user-authored rule already uses the same key, OpenShell keeps the user rule and adds a numeric suffix to the provider rule.
- Provider and user rules are concatenated. Overlapping endpoints remain separate rules.
- A gateway global policy override suppresses provider-derived policy layers.
Attach and Detach Providers
Attach an existing provider to a running sandbox:
Detach a provider:
Attach and detach are idempotent. Attach validates that the provider exists before mutating the sandbox, and provider deletion fails while the provider is attached to any sandbox.
Runtime Limitations
Provider attach and detach update the persisted sandbox provider list. Running sandboxes poll for provider environment revisions and effective policy changes.
The policy effect applies to future effective policy reads after the sandbox observes the update. The credential environment effect applies only to new process launches after the update is observed, such as later SSH, exec, or SFTP sessions.
Already-running processes keep the environment they started with. OpenShell does not mutate a live process environment after provider attach, detach, or credential update. If a long-running process needs a newly attached provider credential placeholder, restart that process or launch a new process after the sandbox has observed the provider update.
Detaching a provider removes its provider policy layer from future effective policy reads and removes its credential placeholders from future process environments. It does not remove environment variables from already-running processes.
OpenShell rejects provider updates and refresh configuration when they would make two providers attached to the same sandbox expose the same active credential environment key. Use provider-specific credential names when one sandbox needs multiple providers with overlapping upstream concepts.
Next Steps
- Use Providers for the current provider command reference.
- Use Customize Sandbox Policies to apply user-authored policy rules.
- Use Policy Schema Reference for endpoint and L7 rule field details.