authy-cli 0.7.0

CLI secrets store & dispatch for AI agents — encrypted vault, scoped policies, run-only tokens, and audit logging
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# Authy

**Secrets Store & Dispatch for AI Agents**

Your agents need API keys. They don't need the keys to the kingdom.

Encrypted vault. Scoped policies. Short-lived tokens. Full audit trail. Single binary, no server, no accounts.

[Get Started](#quick-start) · [View on GitHub](https://github.com/eric8810/authy) · [Read the Docs](#documentation)

---

## The Problem

AI agents run with your secrets — but today's tools give you no control over what they can see.

- **Claude Code** reads `.env` files silently. Infostealer malware targets these files.
- **OpenClaw** stores API keys in plaintext JSON. Over 30,000 instances found exposed online.
- **MCP servers** require secrets hardcoded in config files that get committed to repos.
- **CI/CD pipelines** inject secrets as env vars with no scoping — every step sees everything.

Existing secrets tools don't solve the agent problem:

| Tool | Limitation |
|------|------------|
| **pass/gopass** | No scoped access — GPG key = full access to everything |
| **HashiCorp Vault** | Requires running a server; overkill for local and CI use |
| **1Password CLI** | Proprietary, requires an account |
| **SOPS** | File encryption only, not a runtime dispatch tool |

---

## How Authy Works

```
Admin (TUI or CLI)          Agent
      │                       │
      ├─ store secrets ───►   │
      ├─ create policy ───►   │
      ├─ create token ────►   │
      │                       ├─ authy run --scope X -- agent
      │                       │    ├─ decrypt vault
      │                       │    ├─ filter by policy
      │                       │    ├─ inject as env vars
      │                       │    └─ spawn child process
      │                       │
      └─ audit show ──────►   └─ every access logged
```

1. **Store** secrets in an encrypted vault (never in shell history, config files, or process args)
2. **Scope** access with glob-based allow/deny policies per agent
3. **Dispatch** secrets into child processes as environment variables
4. **Audit** every access with a tamper-evident HMAC-chained log

---

## Features

| Feature | Description |
|---------|-------------|
| **Library API** | Use as a Rust crate — `AuthyClient` for programmatic vault access; `cargo add authy --no-default-features` |
| **Language SDKs** | Use Authy natively in Python, TypeScript, or Go — thin CLI wrappers with zero deps and typed errors |
| **Encrypted Vault** | `age`-encrypted single file; passphrase or X25519 keyfile auth |
| **Scoped Policies** | Glob-based allow/deny rules; deny overrides allow; default deny |
| **Run-Only Mode** | Restrict agents to subprocess injection only — `get`, `env`, `export` blocked |
| **Session Tokens** | Short-lived, HMAC-validated, run-only capable; `authy_v1.` prefix for leak detection |
| **Subprocess Injection** | `authy run` injects secrets as env vars into the child process only |
| **Config File Resolution** | `authy resolve` replaces `<authy:key>` placeholders in any config file |
| **Vault Rekey** | `authy rekey` re-encrypts the vault with new credentials; switch between passphrase and keyfile |
| **JSON Output** | `--json` on all read commands; structured errors to stderr |
| **Audit Log** | Append-only JSONL with HMAC chain; actor, timestamp, outcome on every access |
| **Admin TUI** | Full-screen terminal UI for secrets, policies, sessions, and audit — nothing touches shell history |
| **Headless Mode** | CI/CD friendly; non-interactive with fail-fast; keyfile + token auth |
| **Import from Anywhere** | Migrate from .env, 1Password, pass, SOPS, or HashiCorp Vault in one command |
| **MCP Server** | `authy serve --mcp` exposes vault tools over stdio JSON-RPC 2.0 for AI agent platforms |

---

## Quick Start

### Install

**npm (recommended)**

```bash
npm install -g authy-cli
# or: npx authy-cli --help
```

**Install script**

```bash
# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/eric8810/authy/main/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/eric8810/authy/main/install.ps1 | iex
```

**From source**

```bash
git clone https://github.com/eric8810/authy.git
cd authy && cargo build --release
cp target/release/authy /usr/local/bin/
```

### Initialize

```bash
authy init --generate-keyfile ~/.authy/keys/master.key
```

### Manage Secrets (TUI)

```bash
# Using keyfile (no prompt)
authy admin --keyfile ~/.authy/keys/master.key

# Using passphrase (interactive prompt)
authy admin
```

The TUI will prompt for your passphrase if no keyfile is provided. It provides masked input fields for storing secrets, a policy editor with live testing, session token management, and a scrollable audit log with HMAC verification. Press `?` for key bindings.

### Manage Secrets (CLI)

**推荐:使用 TUI(最直观安全)**

```bash
authy admin --keyfile ~/.authy/keys/master.key
# 或使用 passphrase 启动
authy admin
# 在 TUI 中选择 Secrets → Add,输入密钥名和值(输入被掩码保护)
```

**或使用命令行:**

```bash
# 通过提示输入(安全 - 不会进入 shell history)
authy store anthropic-api-key
# 输入密钥值后按 Ctrl+D

# 或从文件管道输入
authy store anthropic-api-key < ~/.secrets/anthropic-key

authy list
```

### Create a Policy and Launch an Agent

```bash
# Define what the agent can see — run-only means it can never read values directly
authy policy create claude-code \
  --allow "anthropic-*" \
  --allow "github-*" \
  --deny "prod-*" \
  --run-only

# Launch with scoped secrets injected
authy run --scope claude-code --uppercase --replace-dash _ -- claude
# Claude Code sees ANTHROPIC_API_KEY and GITHUB_TOKEN — nothing else
# authy get / authy env / authy export are blocked
```

---

## Use Cases

### Library API (Rust Crate)

```rust
use authy::api::AuthyClient;

// Authenticate and access the vault programmatically
let client = AuthyClient::from_env()?; // reads AUTHY_KEYFILE or AUTHY_PASSPHRASE
client.store("api-key", "sk-secret-value", false)?;
let value = client.get("api-key")?;
let names = client.list(None)?;
client.rotate("api-key", "sk-new-value")?;
```

```bash
# Add to your Rust project (no CLI deps)
cargo add authy --no-default-features
```

### Language SDKs (Python, TypeScript, Go)

Thin CLI wrappers with zero native dependencies. Each SDK shells out to `authy --json`.

**Python**

```bash
pip install authy-secrets
```

```python
from authy_secrets import Authy

client = Authy()
value = client.get("db-url")
client.store("api-key", "sk-secret-value")
names = client.list(scope="backend")
```

**TypeScript**

```bash
npm install authy-secrets
```

```typescript
import { Authy } from "authy-secrets";

const client = new Authy();
const value = await client.get("db-url");
await client.store("api-key", "sk-secret-value");
const names = await client.list({ scope: "backend" });
```

**Go**

```bash
go get github.com/eric8810/authy-go
```

```go
client, _ := authy.New()
value, _ := client.Get(ctx, "db-url")
client.Store(ctx, "api-key", "sk-secret-value")
names, _ := client.List(ctx, authy.WithScope("backend"))
```

### Migrate Your Secrets

```bash
# From .env files
authy import .env

# From 1Password
authy import --from 1password --vault Engineering

# From pass (password-store)
authy import --from pass

# From SOPS encrypted files
authy import --from sops secrets.enc.yaml

# From HashiCorp Vault
authy import --from vault --path secret/myapp
```

All sources support `--dry-run`, `--force`, `--prefix`, and `--keep-names`.

### Config File Templates

```bash
# Template with placeholders (safe to commit)
cat config.yaml.tpl
# host: <authy:db-host>
# port: <authy:db-port>
# api_key: <authy:api-key>

# Resolve at deploy time
authy resolve config.yaml.tpl --scope deploy --output config.yaml
```

### AI Agents

```bash
# Claude Code — run-only policy, secrets injected, agent can't read them
authy policy create claude-code --allow "anthropic-*" --allow "github-*" --run-only
authy run --scope claude-code --uppercase --replace-dash _ -- claude

# OpenClaw — replaces plaintext ~/.openclaw/openclaw.json
authy policy create openclaw --allow "anthropic-*" --allow "discord-*" --run-only
authy run --scope openclaw --uppercase --replace-dash _ -- openclaw

# Any agent that reads env vars
authy run --scope my-agent --uppercase -- ./my-agent.sh
```

### MCP Servers

Keep secrets out of `.mcp.json` using environment variable expansion:

```json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}
```

Launch Claude Code with `authy run` so `${GITHUB_TOKEN}` resolves from the vault.

For MCP servers that need secrets in args (like Postgres), use wrapper scripts:

```json
{
  "mcpServers": {
    "postgres": {
      "command": "authy",
      "args": ["run", "--scope", "claude-db", "--", "bash", "~/.authy/mcp-postgres.sh"]
    }
  }
}
```

### Project Config + Shell Hook

Drop `.authy.toml` in your project root for automatic activation:

```toml
# .authy.toml
[authy]
scope = "claude-code"
keyfile = "~/.authy/keys/master.key"
uppercase = true
replace_dash = "_"
aliases = ["claude", "aider"]
```

```bash
# Add to ~/.bashrc or ~/.zshrc (one-time)
eval "$(authy hook bash)"
```

Now `cd` into the project and type `claude` — secrets are injected automatically.

### Shell Alias (Manual)

Or generate aliases explicitly:

```bash
eval "$(authy alias --from-project)"
# Or: eval "$(authy alias claude-code claude aider)"
```

### CI/CD

```yaml
- name: Deploy
  env:
    AUTHY_KEYFILE: ${{ secrets.AUTHY_KEYFILE }}
  run: authy run --scope ci-deploy --uppercase --replace-dash _ -- ./deploy.sh
```

### Team Sharing

```bash
# Admin creates a run-only, time-limited token
authy session create --scope dev --ttl 8h --label "alice-dev" --run-only

# Developer uses the token — can inject secrets, cannot read values
export AUTHY_TOKEN="authy_v1.eyJ..."
export AUTHY_KEYFILE=~/.authy/keys/master.key
authy run --scope dev --uppercase -- npm run dev

# Revoke instantly if compromised
authy session revoke-all
```

### Docker

```bash
docker run \
  -v ~/.authy:/root/.authy:ro \
  -e AUTHY_KEYFILE=/root/.authy/keys/master.key \
  --entrypoint authy \
  my-agent-image \
  run --scope my-agent --uppercase --replace-dash _ -- agent-binary
```

[AI Agent Integration Guide](AI_AGENT_GUIDE.md) — Full integration docs for Claude Code, OpenClaw, MCP servers, and more.

---

## Core Commands

| Command | Description |
|---------|-------------|
| `authy init` | Initialize vault with passphrase or keyfile |
| `authy admin` | Launch interactive TUI |
| `authy store <name>` | Store a secret (reads from stdin) |
| `authy get <name>` | Retrieve a secret value (blocked in run-only mode) |
| `authy list [--json]` | List secret names (allowed in run-only mode) |
| `authy remove <name>` | Delete a secret |
| `authy rotate <name>` | Update a secret value |
| `authy run [--scope <s>] -- <cmd>` | Run command with scoped secrets injected |
| `authy resolve <file>` | Resolve `<authy:key>` placeholders in config files |
| `authy rekey` | Re-encrypt vault with new credentials |
| `authy env [--scope <s>]` | Output secrets as env vars (blocked in run-only mode) |
| `authy import <file>` | Import from .env file |
| `authy import --from <source>` | Import from 1Password, pass, SOPS, or Vault |
| `authy serve --mcp` | Start MCP server (stdio JSON-RPC 2.0) |
| `authy export --format <f>` | Export secrets (blocked in run-only mode) |
| `authy policy create <name> [--run-only]` | Create an access policy |
| `authy policy test --scope <s> <name>` | Test if a policy allows access |
| `authy session create --scope <s> [--run-only]` | Create a scoped, time-limited token |
| `authy session revoke <id>` | Revoke a session token |
| `authy audit show [--json]` | View audit log |
| `authy project-info` | Show .authy.toml project config |
| `authy alias` | Generate shell aliases for tools |
| `authy hook <shell>` | Output shell hook code for auto-activation |
| `authy audit verify` | Verify audit log integrity |

---

## Comparison

| | Authy | pass | Vault | 1Password CLI |
|---|:---:|:---:|:---:|:---:|
| Single binary | Y | Y | N | Y |
| No server required | Y | Y | N | Y |
| No account required | Y | Y | Y | N |
| Open source | Y | Y | Y | N |
| Scoped policies | Y | N | Y | Y |
| Run-only mode | Y | N | N | N |
| Short-lived tokens | Y | N | Y | Y |
| Subprocess injection | Y | N | N | Y |
| JSON output | Y | N | Y | Y |
| Tamper-evident audit | Y | N | Y | Y |
| Language SDKs | Y | N | Y | Y |
| MCP server | Y | N | N | N |
| Built for agents | Y | N | N | N |

---

## Security

- **Encryption**`age` with X25519 (keyfile) or scrypt (passphrase); single encrypted vault file
- **Secret hygiene** — Never in shell history, process argv, or parent env; zeroized on drop
- **Access control** — Policies inside the encrypted vault; deny overrides allow; default deny
- **Run-only enforcement** — Agents can only inject secrets via subprocess; direct value access blocked
- **Token model** — HMAC-SHA256 with constant-time comparison; only the HMAC is stored, not the token
- **Audit trail** — HMAC-chained JSONL; actor identity, timestamp, operation, outcome on every entry
- **Revocation** — Instant token revocation; `authy_v1.` prefix for automated leak scanning

---

## Documentation

- [README]README.md — Quick start and command reference
- [Architecture]ARCHITECTURE.md — System design and data flow
- [AI Agent Guide]AI_AGENT_GUIDE.md — Claude Code, OpenClaw, MCP servers, CI/CD, Docker

---

Built with Rust. Secured with age.