OpenClaw EnterpriseDOCSGitHub

Set up and operate Credential Proxy

Credential Proxy lets an Agent use an approved credential through an enforcing transport without putting provider material in the Agent's configuration. OCC controls access to the execution; the selected Driver enforces the request and credential delivery. For prepared GitHub access, Token Service also maintains the short-lived credential. The setup and verification depend on the selected delivery profile. The architecture walkthrough shows what a child process can request and what it can read in the response.

Use matching OpenShell 0.1.6 components and mandatory pre-credential middleware for repository enrollment. A rollout or source registration alone does not establish enforcement. Missing request hooks are refused before credential release. Older or unqualified compositions can return 409 REPOSITORY_GIT_SENDER_UNQUALIFIED; do not broaden a ref-limited grant to bypass that error. The Credential Proxy reference describes the delivery contracts.

Choose the path before changing an installation

Intended use Requirement and limit
Protected static inference The bundled OpenShell Driver refuses new protected sources, live adoption and new revisions. Existing admitted revisions retain recovery and original-owner cleanup. Other Drivers require qualified whole-execution enforcement; see protected static inference.
Prepared GitHub App access Worker Token Service prepares credentials; OCC authorizes scope and lifetime; Credential Proxy installs and fences delivery. Protected delivery requires a qualified sender.
Native prepared Git A separate explicit Kubernetes/dedicated Codex path without Sandbox or Credential Proxy; it does not provide OpenShell isolation. See native Git.

For a packaged Driver, select its Sandbox and Credential Proxy capabilities from the same registration. The Driver selection guide shows the Installation settings and profile requirements. Selection establishes which implementation OCC loads; qualification establishes what the installed sender actually enforces.

Use the upgrade procedure for an existing installation, including when a Gateway source or its owner must remain.

Prepare enforcement, trust, and custody

For a reviewed development candidate, follow local candidate image selection, including all three immutable OpenShell images, their source commit, and matching charts. New local protected static-inference launches are retired. The launcher rejects OCC_DEVELOPMENT_PROTECTED_EGRESS=1 and any presence of OCC_DEVELOPMENT_OPENSHELL_HOST_GATEWAY_IP before effects, including with Kubernetes/OpenShell. Unset, empty or 0 protected-egress selections retain ordinary Gateway authentication. See the retirement notice.

The following bundled static authority configuration preserves existing admitted revisions and their authorization, withdrawal and cleanup. It does not re-enable new protected sources, live adoption or new revisions. For protected static inference, the Installation selects the same Driver ID in backend[].drivers.credential_proxy and drivers.credential_proxy. A bundled OpenShell authority selection has this shape:

yaml
drivers:  credential_proxy:    id: openshell-egress    configuration:      middlewareName: oce-authority      authorityScope: execution      authority:        host: 0.0.0.0        port: 9444        certificatePath: /etc/openclaw/egress/tls/tls.crt        privateKeyPath: /etc/openclaw/egress/tls/tls.key        issuerPublicKeyPath: /etc/openclaw/egress/issuer/issuer.pub        issuer: openshell-gateway:openshell-gateway        audience: oce-egress        keyId: current

This is a fragment, not a complete Installation. Match issuer, audience, key ID, and middleware name to the configured peers. Keep the OpenShell Backend and Sandbox configuration. A packaged Driver instead takes configuration through its Sandbox selection; its matching Credential Proxy selection has an empty configuration. Either kind can add requestCapacity to size OCC's in-memory request bounds; see request-time capacity.

The API owns the static authority listener. Development binds only to loopback. Production needs a reachable host and a certificate covering the Service DNS name. With Helm, use host: 0.0.0.0 (or ::) and the egressAuthority.port value. Startup and the upgrade check refuse another host or port, a disabled egressAuthority, or file paths other than the chart mounts shown above, with CHART_LISTENER_MISMATCH. The Backend requires HTTPS with bearer-file or mutual TLS authentication. Register oce-authority under [[openshell.supervisor.middleware]] with its HTTPS grpc_endpoint, audience, tls_ca_cert_path, and max_payload_bytes = 4194304. Both peers must support openshell.supervisor-middleware.http-credential-access.v1 and all five capabilities required by connected qualification. Verify the Agent's WSS server trust separately from the controller's Backend mTLS; an administrator client Secret must never be projected into the Agent. See trust prerequisites.

With Helm, enable egressAuthority, set its port, tlsSecretName (tls.crt, tls.key), and issuerSecretName (public.pem). Its clients must select the actual Gateway and trusted supervisor namespaces and Pod labels. Allow those peers to reach the authority and resolve DNS. Keep upstream access constrained to the selected endpoints. The Gateway signing private key stays with the Gateway; the authority receives its public key. All phases of an exchange must reach the same authority process; replicated shared exchange state is unavailable.

For prepared GitHub access, use the separate protected repository configuration. Only the worker receives the App signing key and persistent custody key. Do not copy either into Agent configuration. The request-phase worker service and its TLS port are separate from the static API authority above. A missing key, unqualified sender, or unavailable trust path is a stop condition, not a reason to use an ambient token.

Enable Google Workspace requests from a dedicated worker

OCE binds the selected Google source to its host, path, OAuth scopes and plugin release when deploying the Agent. For each request, the OpenShell supervisor sends the HTTP details and deployed binding to a shared guard in the execution cluster. The guard checks the release’s operation map locally. OpenShell substitutes the bearer after approval. Redeploy to apply a new plugin selection. Public Discovery uses no credential.

Set the source’s config.binary to /usr/local/lib/oce/plugins/google/bin/gog when the installation allows other executables. The checks also cover gog helpers.

Install the guard once for the OpenShell Gateway. Use the execution cluster’s Helm context and the same digest-pinned OCE controller image that deploys the map.

sh
helm upgrade --install oce-plugin-guard deploy/helm/openclaw-plugin-request-guard \  --namespace openshell-system --values guard-values.yaml --set-string image="$OCE_IMAGE"

In guard-values.yaml, set tlsSecretName for the guard Service DNS name, issuerSecretName for the Gateway’s verification key (public.pem), and issuer and keyId to match the Gateway. Set clients to the Gateway and supervisor namespace and Pod selectors, as illustrated in the chart values. Allow both peers to reach the Service. The guard reads its keys at startup. Roll its Pods after rotating a Secret in place and update the Gateway’s trusted CA if it changes. Register the guard on the Gateway:

toml
[[openshell.supervisor.middleware]]name = "oce-plugin-requests"grpc_endpoint = "https://openclaw-enterprise-plugin-request-guard.openshell-system.svc.cluster.local:9445"audience = "urn:openshell:extension:middleware:oce-plugin-requests"tls_ca_cert_path = "/etc/openshell/certs/oce-egress-ca.pem"max_payload_bytes = 4194304timeout = "2s"

Restart the Gateway to load the registration. Set drivers.sandbox.configuration.gateway.managedPluginMiddleware to the same grpc_endpoint. Select the account, save, and deploy. If the guard is unreachable, the supervisor denies guarded requests before sending them upstream.

For Gmail, configure gmail.googleapis.com, /gmail/v1/users/me/messages and gmail.readonly. At a controlled upstream, verify that listing IDs receives the bearer and fetching an individual message produces no request. To allow more mapped Gmail operations, explicitly configure a subtree such as /gmail/v1/users/me/**. Withdraw the source to stop its use by the running version.

Register, authorize, and deploy an OpenAI static inference source

The bundled OpenShell Driver rejects the source creation, live adoption and deployment operations below with 409 RESOURCE_CONFLICT, including on existing installations. These steps require a separately selected Driver that supports new protected static admission and has qualified static enforcement. For an existing bundled revision, keep its recorded owner and follow the upgrade and withdrawal procedures.

Use the built CLI from the repository root with jq, a ready Namespace, OCC_URL, OCC_NAMESPACE, and a private OCC_SERVICE_KEY_FILE for an authorized operator.

Obtain whole-execution consent before creating the source: protection covers sibling processes in that execution, not another execution of the same Agent. Follow only the openai API-key example in Register the key, then return here. Do not use that page's codex-pat variant for this profile, or follow its copied-key rotation and Agent-deleting cleanup as a live-adoption procedure. Retain SOURCE_ID and the Secret reference.

With Credential Proxy selected, fresh openai registration is already live:

bash
./bin/occ credential-source get "$SOURCE_ID" -o json

Require ownerCapability: credential_gateway, egress.adoption: live and egress.retention: none. Creation reads the versioned Secret without depositing a Gateway copy. The CLI's GATEWAY STATUS ready label does not prove such a copy exists. Keep the Gateway selected: live reads do not transfer ownership. A ready source alone does not prove installed enforcement.

For an existing unreferenced legacy or narrower source, obtain the same consent, then explicitly adopt live reads instead:

bash
cat > source-adoption.json <<'JSON'{"adoption":"live","authorityScope":"execution"}JSON./bin/occ credential-source update "$SOURCE_ID" --file source-adoption.json./bin/occ credential-source get "$SOURCE_ID" -o json

This update requires exact source update and operate on every referenced Secret, advances the source generation, and retains its Gateway owner. It does not remove an old Gateway copy: retention: none describes live reads, not past custody. A bound source cannot take this first cutover.

Follow create the Agent and grant the source for the dedicated Codex Configuration, Agent request, and exact IAM binding. Use an authorized native model ID; keep models.providers.codex.baseUrl at http://127.0.0.1:9. The Agent lists { "sourceId": "$SOURCE_ID" } in credentialSources and names that source in harnessAuth. The creating operator and Agent service principal each need exact source operate; the Agent needs no underlying Secret permission.

bash
./bin/occ agent runtime-credentials provision "$AGENT_ID"DEPLOYMENT_ID="$(./bin/occ agent deploy "$AGENT_ID" -o json | jq -r .id)"./bin/occ agent deployment-status "$AGENT_ID" "$DEPLOYMENT_ID" -o json./bin/occ agent get "$AGENT_ID" -o json./bin/occ agent runtime "$AGENT_ID" -o json

Require the requested revision to succeed, become selected, and have a ready runtime. Protected Compute checks the current installation before releasing the workload. Do not bypass pending or failed admission.

Enroll prepared GitHub access

Follow OpenShell repository enrollment to authorize repositories for a Namespace and select up to 16 on an Agent using github-repository. The worker prepares a token for exactly that selection; GitHub permissions and branch rules still apply. No preview option or OCE branch list is needed. Existing explicit git-write grants retain their ref limits. The walkthrough includes the separate Gateway model source, worker custody, registry and mandatory pre-credential middleware setup.

Verify use, loss, and withdrawal

Use model verification to send a fresh nonce through the actual Agent. Its unauthenticated request must fail and its administrator-authenticated request must return the nonce. That denial tests Gateway authentication; it does not prove Credential Proxy enforcement.

For static inference, verify a valid POST to the configured base URL plus /responses or /chat/completions with the exact admitted model. Attempt the same request with a different model, and a GET to that inference route; both must be refused by enforcement. Use a controlled origin with independent request logs, and record the selected revision, enforcement refusal and no new origin request. A provider error or an unready Harness does not establish that denial.

Save the successful response, then withdraw the exact source through OCC:

bash
./bin/occ agent credential-withdrawal request "$AGENT_ID" "$SOURCE_ID"./bin/occ agent credential-withdrawal get "$AGENT_ID" "$SOURCE_ID" -o json

Inspect the withdrawal state and reason:

An upstream request already sent can finish. Credential Proxy can still withhold a response it has not released; withdrawal cannot recall bytes already released. A withdrawn model source cannot support continued model turns. Restore service with an authorized replacement binding and a new revision; restarting cannot restore withdrawn permission. See withdrawal.

For a git-write grant with an explicit review ref, use the admitted <owner>/<repo>.git path. Verify discovery (GET /<owner>/<repo>.git/info/refs?service=git-upload-pack), fetch (POST /<owner>/<repo>.git/git-upload-pack) and a push to the approved review ref (POST /<owner>/<repo>.git/git-receive-pack). Independently read the written ref. A push to another ref and DELETE on the same Git route must be refused before reaching the origin. For github-repository, push and read back its ref in each selected repository. Verify that the same Agent cannot push to an unselected private repository in the same installation. Ordinary permitted refs remain available within the selected set. For installation-wide access, there is no OCE ref allowlist: GitHub controls membership and permissions. Use an unsupported method such as that DELETE for the OCE negative check; a GitHub 404 outside membership is not an OCE denial. Capture the selected revision and correlated enforcement and origin evidence. The native Git example applies only to its separate composition.

Withdraw repository access

Token expiry, finite grant/session expiry and standing-approval removal are different checks. For standing access, fetch a commit known to be absent locally after the original token expires, without changing the binding. This checks renewal; it cannot extend a finite grant. Then withdraw while the replacement token and session are still valid:

  1. As an Agent administrator, read GET /namespaces/:namespaceId/agents/:agentId/repository-approvals.

  2. Select the approval for the current binding. Send POST /namespaces/:namespaceId/agents/:agentId/repository-approvals/:approvalId/remove with {"expectedGeneration": <that approval's generation>}. This is the approval generation, not the Agent, source or policy generation. Require 204; on a conflict, read current approval state before deciding what to do.

  3. Require a fresh fetch to fail with access_withdrawn before the token/session expires, with no new origin request. An already authorized send may finish.

  4. Clear the binding using the existing Configuration ID:

    bash
    jq -n --arg configuration "$CONFIGURATION_ID" \  '{configurationId: $configuration, repositoryBindings: []}' > repository-withdrawal.json./bin/occ agent update "$AGENT_ID" --file repository-withdrawal.json

Removing the binding before standing approval is rejected. For finite access, there is no standing approval to remove: use the binding-removal step directly and verify fresh denial.

Require a new model reply in the same conversation after Git removal. Continuity requires verified Git-only policy reduction and healthy independent model access; an explicit model withdrawal or IAM refusal queues retirement of that runtime. Unavailable evidence keeps cleanup pending without repeating the reduction or stopping a healthy Agent. Verify continuity on the selected release; readiness alone does not prove it. Static model sources do not renew tokens; existing Gateway refresh sources use their own rotation procedure.

Diagnose before retrying

Observation Action and recovery evidence
Source failed, absent, or missing credentials Read credential-source get and its reason; correct the owning Secret or enrollment. Require a new successful real request, not just ready.
Unavailable authority or lost installation Check peer TLS trust, selected Driver identity, network access, and current runtime. Keep access closed until the current installation is verified.
Prepared material is pending or expired Check the Token Service’s issuer access. An authorized GitHub metadata request can start or join renewal until its deadline. Readiness checks and native Git broker requests still depend on background preparation.
Refresh reports reauthorize Obtain new provider authorization through the source's supported enrollment; do not replay an old refresh token.
Installation or send outcome is unknown Preserve the original operation and custody. Fence the old worker/recipient and reconcile through its owner; do not resend or fabricate success.
Withdrawal remains pending Inspect its reason and withdrawalInProgress; follow the withdrawal recovery procedure. Do not report revocation as complete.

Public deployment status is not a token-custody ledger. If the selected owner cannot establish whether issuance, installation, or retirement completed, stop the transition and retain its recovery state. Do not edit database rows as an operator workaround. For Git reason codes and log correlation, see adapter diagnostics. Detailed enforcement evidence belongs in qualification procedures.

Search documentation