Claude Code on your Claude subscription
Run Claude Code in a cloud sandbox on your Claude Pro or Max plan. Model usage counts against your Claude plan; Tangle bills only the sandbox’s compute.
1. Create a token
On your machine, with Claude Code installed:
claude setup-tokenIt opens a browser to sign in to your Claude account and prints a long-lived
OAuth token that starts with sk-ant-oat. Treat it like a password.
2. Store it as a secret
Store the token once as an account secret. Secrets are encrypted at rest, and no API returns their values.
export CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-..."
tangle secret create CLAUDE_TOKEN --value-stdin <<< "$CLAUDE_CODE_OAUTH_TOKEN"Or from TypeScript:
await client.secrets.create("CLAUDE_TOKEN", process.env.CLAUDE_CODE_OAUTH_TOKEN!);3. Start the agent
import { Sandbox } from "@tangle-network/sandbox";
const client = new Sandbox({
apiKey: process.env.TANGLE_API_KEY!,
baseUrl: "https://sandbox.tangle.tools",
});
const agent = await client.create({
name: "claude-on-my-plan",
backend: {
type: "claude-code",
model: {
cliAuth: { account: "me", secretEnv: "CLAUDE_TOKEN", format: "token" },
},
},
secrets: ["CLAUDE_TOKEN"],
git: { url: "https://github.com/your-org/your-repo" },
idleTimeoutSeconds: 900,
});
await agent.waitFor("running");
const result = await agent.prompt("Summarize this repository in five bullets.", {
sessionId: "main",
});
if (!result.success) throw new Error(result.error);
console.log(result.response);From a terminal, the same agent is one command:
tangle sandbox create --name claude-on-my-plan --backend claude-code \
--cli-auth CLAUDE_TOKEN --git-url https://github.com/your-org/your-repo
tangle agent prompt <sandbox-id> "Summarize this repository in five bullets." \
--session main --streamThree fields do the work:
| Field | Meaning |
|---|---|
backend.type: "claude-code" | Run the Claude Code harness. Always set it; the default harness is OpenCode, which does not take a Claude token. |
backend.cliAuth | Which secret holds the credential. format: "token" means the secret is the raw setup-token value. account is your own label for it. |
secrets: ["CLAUDE_TOKEN"] | Grants this sandbox that secret. The create request is refused if cliAuth names a secret you did not grant. |
Do not inject the token as a plain environment variable such as
CLAUDE_CODE_OAUTH_TOKEN. Without cliAuth, the platform configures Claude
Code to use a Tangle model key and the harness ignores the variable.
In a workflow
A workflow’s agent.run runs on the same secret when its profile declares
the source. Store the token under the name CLAUDE_TOKEN as above, then set
model.metadata.credentialSource: subscription on a claude-code profile:
- id: review
agent.run:
profile:
harness: claude-code
model:
default: anthropic/claude-sonnet-5-5
metadata: { credentialSource: subscription }
prompt: { instructions: ["Review the change."] }
prompt: "Review the last commit."The run creates its sandbox with backend.cliAuth and CLAUDE_TOKEN in
secrets, and mints no Router key, so the Router bills nothing for it. A run
whose account stored no CLAUDE_TOKEN fails with No stored secret named CLAUDE_TOKEN. The profile cannot run in a worker or as topology: inference,
which only the Router serves.
Rotate or revoke
A secret name cannot be overwritten. To rotate, delete it and store the new token under the same name; sandboxes created afterwards use the new value.
claude setup-token
tangle secret delete CLAUDE_TOKEN --force
tangle secret create CLAUDE_TOKEN --value-stdin <<< "$CLAUDE_CODE_OAUTH_TOKEN"To cut access everywhere at once, revoke the token in your Claude account settings.
From HTTP
Any language can start the same agent. On the wire, credential fields sit
under backend.model. The body names the secret; the token never appears in
it.
curl -X POST https://sandbox.tangle.tools/v1/sandboxes \
-H "Authorization: Bearer $TANGLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "claude-on-my-plan",
"backend": {
"type": "claude-code",
"model": {
"cliAuth": { "account": "me", "secretEnv": "CLAUDE_TOKEN", "format": "token" }
}
},
"secrets": ["CLAUDE_TOKEN"]
}'Troubleshooting
| Result | Cause | Fix |
|---|---|---|
401 OAuth access token is invalid | The token expired, was revoked, or was pasted with extra characters. | Run claude setup-token again and rotate the secret. |
400 Native authentication secret CLAUDE_TOKEN must be listed in secrets | cliAuth.secretEnv is not in secrets. | Add the secret name to secrets. |
cliAuth cannot be combined with API credentials, baseUrl, or inline authFiles | cliAuth was set together with apiKey, apiKeyEnv, baseUrl, or authFiles. | Use one credential per backend. |
A 401 from Anthropic proves the token reached Claude Code inside the
sandbox: the remaining problem is the token itself.
Related
- Start a cloud agent: streaming, sessions, and spin-down.
- Agent profiles: instructions and tools for the agent.
- Network egress rules: keep the agent to the hosts it needs.