OpenClaw EnterpriseDOCSGitHub

Credential source withdrawal

Use this reference to revoke a credential source from an Agent's running version without a redeploy.

Withdraw a source from an Agent

Withdrawal revokes a source from an Agent's selected version while the version keeps running. Send POST /namespaces/:namespaceId/agents/:agentId/credential-sources/:credentialSourceId/withdraw. The caller needs agent:operate, and the selected version must have been saved with that source, as its Harness authentication or in credentialSources. The request returns 202 with the withdrawal in state pending. A saved version with the source that is not yet selected gets its own withdrawal, so it never attaches the source. A withdrawn Harness source fails that deployment with CREDENTIAL_WITHDRAWN; otherwise it becomes selected without the source, and the read below then returns its withdrawal. An earlier version that still runs because the selected version's deployment has not finished replacing it gets its own withdrawal too. A replay returns the same withdrawal and makes the caller its requestedBy. It queues another attempt only if none is queued or running; a queued attempt runs at once.

The worker detaches the source from the version's Sandbox and records revoked only after the gateway confirms that the version's placeholders no longer resolve, even in running processes. Requests already forwarded upstream are not undone. Read the state with GET /namespaces/:namespaceId/agents/:agentId/credential-sources/:credentialSourceId/withdrawal, which requires agent:read. It returns requestedBy, the principal whose agent:operate the worker rechecks, reason with lastAttemptAt for the worker's latest attempt, and withdrawalInProgress, which is true while an attempt is queued or running. A pending withdrawal with reason CREDENTIAL_WITHDRAWAL_PENDING is waiting for the gateway; a Sandbox without a running process never confirms revocation. AUTHORIZATION_DENIED or ACTOR_REVOKED means the requester lost agent:operate; another operator can send the withdraw request again to retry it on their own authority. CREDENTIAL_WITHDRAWAL_MISCONFIGURED or CREDENTIAL_WITHDRAWAL_OWNERSHIP_CONFLICT means Compute cannot reach the version's Sandbox as configured, or found an object it does not own; the attempt fails without retries, even with maintenance. Correct the cause, then send the request again. CREDENTIAL_WITHDRAWAL_REQUIRES_RUNTIME_RETIREMENT means Compute cannot remove the source from that version's running policy. It also fails without retries. A Credential Proxy that reduces policy in place does so only for the selected version, so another version's withdrawal, such as one for a later version that failed or is still deploying, ends with this reason. The withdrawal stays pending, so that version cannot use the source, and the read can report it with that version's revisionId and withdrawalInProgress: false. The next deployment that succeeds retires every earlier version, including that one, and the read then stops reporting it. If that version's own deployment selects it instead, the deployment queues one more attempt as it completes, so its policy is reduced without a new request. If that deployment selects it but fails before completing, send the request again.

The worker retries an unconfirmed withdrawal a few times with backoff (OCC_WORKER_MAX_ATTEMPTS; by default about 12 seconds). If those attempts run out because the gateway is unreachable or has not confirmed revocation (or the last attempt outlived its worker's claim, after a worker restart or a hung gateway call), and Compute has no maintenance (the Kubernetes Compute Driver has none), the worker queues another series 30 seconds later, then after 1, 2 and 4 minutes, then every 5 minutes, 15 series in all (about an hour). Meanwhile the read shows pending, the latest reason, and withdrawalInProgress: true, and the source still resolves in the Sandbox. The first series the gateway confirms records revoked, with no replay needed. A withdraw request sent while a series waits queues nothing more; the series runs at once, on the caller's authority.

When the last series fails, or every withdrawal left on the version is denied to its requester, the withdrawal stays pending with withdrawalInProgress: false. Nothing retries it on its own unless the version has maintenance (see below). Send the withdraw request again to queue another attempt, with its own series.

A withdrawn source never re-attaches to that version. If its Sandbox is recreated, a withdrawn source is left out and the version keeps running without it, unless harnessAuth names it. If a Sandbox create that started before the withdrawal finishes after it, the next deployment or maintenance pass detaches the source again. A withdrawn Harness source instead fails provisioning with CREDENTIAL_WITHDRAWN, and maintenance of the version stops preparing it. While any withdrawal is pending, each maintenance pass queues another attempt if none is outstanding. Maintenance does not recheck grants on withdrawn sources, which never attach again, so removing one cannot stop it. After model-source withdrawal, maintenance never prepares the version again. It continues recovering pending tool withdrawals even when the model source is already revoked, and stops only when every withdrawal is revoked. Redeploy to resume Compute repair.

For externally managed Codex OAuth, restarting the same OpenShell Sandbox after withdrawal keeps the Harness process alive but unready, with AUTHENTICATION_FAILED at the login phase. It does not start Codex or use cached authentication. A restart cannot restore the withdrawn binding; deploy a new version to resume model execution.

Withdrawals of different sources on one version share one worker attempt, but each is authorized by its own requestedBy. A requester who lost agent:operate leaves only their withdrawal pending with AUTHORIZATION_DENIED; the others are still revoked.

The version still references the source, so the source cannot be deleted until a redeploy replaces the version. Redeploy the Agent with a replacement source or another authentication method.

Search documentation