use-native-credential-proxy
# ClaudeWave: use-native-credential-proxy The use-native-credential-proxy skill enables NanoClaw to authenticate with Anthropic using credentials stored directly in .env files instead of the OneCLI agent vault. Enable this skill when you prefer simple environment-based credential management without the OneCLI gateway infrastructure, accepting that credentials are passed directly into container environment variables rather than injected per request through a secure vault system.
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/use-native-credential-proxy && cp -r /tmp/use-native-credential-proxy/.claude/skills/use-native-credential-proxy ~/.claude/skills/use-native-credential-proxySKILL.md
# Use Native Credential Proxy
This skill adds a **native, `.env`-based credential path** for the container agent — an explicit opt-out of the OneCLI gateway. With it enabled, NanoClaw reads the Anthropic credential straight from `.env` and threads it into the container as standard environment variables, which the Claude Agent SDK reads natively. No OneCLI vault, no HTTPS proxy, no certificates.
> **Credential-home inversion — read this first.** NanoClaw's default is that credentials live in the OneCLI agent vault and are injected per request, never threaded into the container via `-e`. This skill deliberately inverts that: the credential lives in `.env` on the host and is passed into the container's environment. That inversion is the *entire point* of this skill (simple `.env` credentials without OneCLI). Use it only if you accept that tradeoff; everywhere else in NanoClaw, env-threaded credentials are an anti-pattern.
The skill is **additive**: it ships its proxy logic and tests in this folder, copies them into `src/`, and makes a single one-line reach-in at the container-spawn seam (gated by an env flag). It does not remove or rewrite the OneCLI gateway — when the flag is unset, the gateway path is exactly as it was, and the native proxy is a no-op.
## How it works
- `src/native-credential-proxy.ts` exports `nativeCredentialEnvArgs()`. It reads `ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN` (and optional `ANTHROPIC_BASE_URL`) from `.env` via core's `readEnvFile`, and returns the Docker `-e VAR=value` arguments.
- All gating lives inside that function: it returns an empty array unless `NANOCLAW_NATIVE_CREDENTIALS=true`. So the reach-in in core is a single unconditional `args.push(...nativeCredentialEnvArgs())`.
- The seam is `buildContainerArgs` in `src/container-runner.ts`, right after the `TZ` env line — the same place container env vars are assembled, just before the OneCLI gateway is applied. With the flag on, the direct credential env vars take precedence in the container; with it off, nothing changes.
## Phase 1: Pre-flight
### Check if already applied
```bash
test -f src/native-credential-proxy.ts && grep -q 'nativeCredentialEnvArgs' src/container-runner.ts && echo applied || echo not-applied
```
If it prints `applied`, the native proxy is already wired — skip to Phase 3 (Configure).
### Confirm the seam exists
```bash
grep -n "args.push('-e', \`TZ=" src/container-runner.ts
```
This should print the `TZ` env line inside `buildContainerArgs`. If it does not, the file has drifted — read `buildContainerArgs` in `src/container-runner.ts` and find the spot where container `-e` env vars are first pushed; the reach-in goes there.
## Phase 2: Apply code changes
### Copy the skill's source and tests into `src/`
```bash
S=.claude/skills/use-native-credential-proxy
cp $S/native-credential-proxy.ts src/native-credential-proxy.ts
cp $S/native-credential-proxy.test.ts src/native-credential-proxy.test.ts
cp $S/native-credential-proxy-wiring.test.ts src/native-credential-proxy-wiring.test.ts
```
`native-credential-proxy.test.ts` is the behavior test (it drives `nativeCredentialEnvArgs()` against a real `.env` read through core's `readEnvFile`). `native-credential-proxy-wiring.test.ts` asserts the one-line reach-in is present in `buildContainerArgs`.
### Import the proxy in `src/container-runner.ts`
Add this import alongside the other local imports (e.g. right after the `./container-config.js` import):
```ts
import { nativeCredentialEnvArgs } from './native-credential-proxy.js';
```
### Make the one-line reach-in
In `buildContainerArgs`, find the `TZ` env line and add the call right after it:
```ts
args.push('-e', `TZ=${TIMEZONE}`);
args.push(...nativeCredentialEnvArgs());
```
That is the only edit to core. `native-credential-proxy-wiring.test.ts` asserts this `args.push(...nativeCredentialEnvArgs())` call exists inside `buildContainerArgs` — delete the reach-in and it goes red.
### Add the env flag stub to `.env.example`
Append to `.env.example`:
```bash
# Native credential proxy (.claude/skills/use-native-credential-proxy)
# Opt out of the OneCLI gateway and supply Anthropic credentials from .env.
# When true, the credential below is injected into the container env directly.
# NANOCLAW_NATIVE_CREDENTIALS=true
# One of the following is required when the flag is true:
# ANTHROPIC_API_KEY=
# CLAUDE_CODE_OAUTH_TOKEN=
# Optional custom endpoint:
# ANTHROPIC_BASE_URL=https://api.anthropic.com
```
### Validate
```bash
pnpm run build
pnpm exec vitest run src/native-credential-proxy.test.ts src/native-credential-proxy-wiring.test.ts
```
The build must be clean and both tests must pass. The build leg confirms the proxy's import of core's `readEnvFile` still resolves; the behavior test confirms the `.env` → `-e` injection; the wiring test confirms the reach-in into `buildContainerArgs` is in place.
## Phase 3: Configure credentials
Ask the user (multiple choice): do they want to use their **Claude subscription** (Pro/Max) or an **Anthropic API key**?
1. **Claude subscription (Pro/Max)** — uses an existing Claude Pro or Max subscription. They run `claude setup-token` in another terminal to mint a token.
2. **Anthropic API key** — pay-per-use API key from console.anthropic.com.
### Subscription path
Tell the user to run `claude setup-token` in another terminal and copy the token it outputs. Do NOT collect the token in chat.
Once they have it, add it to `.env` along with the opt-out flag:
```bash
grep -q '^NANOCLAW_NATIVE_CREDENTIALS=' .env && sed -i.bak 's/^NANOCLAW_NATIVE_CREDENTIALS=.*/NANOCLAW_NATIVE_CREDENTIALS=true/' .env && rm -f .env.bak || echo 'NANOCLAW_NATIVE_CREDENTIALS=true' >> .env
echo 'CLAUDE_CODE_OAUTH_TOKEN=<token>' >> .env
```
`ANTHROPIC_AUTH_TOKEN` is also accepted as an alternative to `CLAUDE_CODE_OAUTH_TOKEN`.
### API key path
Tell the user to get an API key from https://console.anthropic.com/setAdd local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when agents need to read attached Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, or text-based PDF files without uploading them to a hosted parser.
Add Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.
Add clidash — a zero-dependency, read-only web dashboard that derives its tabs and tables at runtime from any CLI that lists resources as JSON. Ships pre-wired for NanoClaw's ncl CLI (agent groups, sessions, channels, users, roles), plus message-activity charts, a log tail, and a read-only file viewer for group skills/CLAUDE.md/profiles.
Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or instead of Claude. ChatGPT subscription or OpenAI API key, vault-only via OneCLI. Per-group via `ncl groups config update --provider codex`. Distinct from using OpenAI as an MCP tool (where Claude remains the planner).
Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.
Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.
Add Dial channel integration — a real phone number for SMS and AI voice calls via the Dial platform (getdial.ai). Native adapter — no Chat SDK bridge.
Add another phone number to an existing Dial channel — a second (or third) public line for the agent, so one NanoClaw install answers SMS and AI voice calls on multiple numbers. Use when Dial is already installed and the operator wants an additional number (e.g. a personal line plus a support line). Requires the Dial channel to already be installed (see /add-dial).