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 Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.
Use Codex (CLI + AppServer) as the full agent provider — planning, tool orchestration, native compaction, MCP tools, session resume — in place of the Claude Agent SDK. ChatGPT subscription or OPENAI_API_KEY. Per-group via agent_provider. 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 Discord bot channel integration via Chat SDK.
Add Emacs as a channel. Opens an interactive chat buffer and org-mode integration so you can talk to NanoClaw from within Emacs (Doom, Spacemacs, or vanilla). Local HTTP bridge — no bot token or external service needed.
Add Google Calendar as an MCP tool (list calendars, list/search/create events, free/busy queries) using OneCLI-managed OAuth. Multi-calendar and multi-account supported. Mirrors /add-gmail-tool's stub pattern — no raw credentials ever reach the container; OneCLI injects real tokens at request time.
Add Google Chat channel integration via Chat SDK.