
AIエージェントのためのクレデンシャル分離。エージェントは実際のAPIキーを一切見ることがありません - 構造的保証であり、ポリシーではありません。
AIエージェントのためのクレデンシャルファイアウォール。
この冒頭の主張は構造的なものであり、ポリシーではありません。エージェントはプレースホルダートークンを受け取り、実際のAPIキーは決して受け取りません。実際のキーは、wardnプロキシ内部からアップストリームAPIに至る一つのネットワークシームのみを通過し、エージェントに到達する前にレスポンスから除去されます。ログ、環境、LLMコンテキストウィンドウ、スクラッチファイル、シェル履歴にはプレースホルダーのみが保持されます。```text agent process OPENAI_KEY=wdn_placeholder_a1b2c3d4e5f6g7h8 (useless) agent logs Authorization: Bearer wdn_placeholder_a1b2... (useless) LLM context wdn_placeholder_a1b2c3d4e5f6g7h8 (useless) wardn proxy injects the real key in-flight, single seam (deleted on response) ~/.vibeguard/vault.enc AES-256-GCM(Argon2id(passphrase)) (encrypted at rest)
これは負荷に耐える主張であり、現在のエージェント侵害、プロンプトインジェクション、ログの窃取、スキルの外部流出に対して防御可能です。
詳細については [docs/THREAT-MODEL.md](https://github.com/rohansx/wardn/blob/main/docs/THREAT-MODEL.md) をご覧ください。カバーされている範囲とされていない範囲の正直な内訳が書かれています。より強力な「ホストが侵害されても何も漏洩しない」という主張が達成可能になるティアも含まれています。
保管庫自体(保存時に暗号化、パスフレーズ由来の鍵)は実際のコンポーネントであり、ファイアウォールを単一のマシンで実行できる理由です。今後の [docs/HOSTED-TIER.md](https://github.com/rohansx/wardn/blob/main/docs/HOSTED-TIER.md) ティアでは、さらにプロキシを機密コンピューティングエンクレーブでラップするため、完全に侵害されたVPSでも鍵を読み取ることはできません。
[](https://crates.io/crates/wardn)
[](LICENSE)
## 問題点
現在のすべてのAIエージェントフレームワークは、APIキーを環境変数や `.env` ファイルに保存しています。侵害されたエージェント、悪意のあるスキル、コモディティスティーラー、またはLLMログから `Authorization: Bearer sk-...` を外部流出させるプロンプトインジェクションによって、あなたの認証情報が完全に取得されます。```
~/.env → OPENAI_KEY=sk-proj-real-key # plaintext, readable by anyone
agent context → "Use OPENAI_KEY=sk-proj-real-key" # leaked into LLM context window
agent logs → Authorization: Bearer sk-proj-... # sitting in log files
wardnはエージェントに無価値なプレースホルダ文字列を渡し、到達可能なすべての表面から実際のキーを削除します。実際のキーはネットワーク層(単一の継ぎ目)で注入され、エージェントに到達する前にレスポンスから除去されます。``` agent environment → OPENAI_KEY=wdn_placeholder_a1b2c3d4e5f6g7h8 (useless) wardn vault → OPENAI_KEY=sk-proj-real-key (encrypted at rest) upstream request → Authorization: Bearer sk-proj-real-key (network transit only) upstream response → ...real keys stripped, placeholders returned... (re-injected on the way back) agent logs → Authorization: Bearer wdn_placeholder_a1b2... (useless) LLM context window → wdn_placeholder_a1b2c3d4e5f6g7h8 (useless)
## アーキテクチャ```mermaid
flowchart TB
subgraph Agent["AI Agent Process"]
A1["Agent Code"]
A2["ENV: OPENAI_KEY=wdn_placeholder_a1b2..."]
end
subgraph Wardn["wardn daemon · localhost:7777"]
direction TB
P["HTTP Proxy"]
MCP["MCP Server\n(stdio)"]
subgraph Pipeline["Request Pipeline"]
direction LR
S1["Identify\nAgent"] --> S2["Resolve\nPlaceholder"] --> S3["Check\nAuth"] --> S4["Rate\nLimit"] --> S5["Inject\nReal Key"]
end
subgraph ResponsePipeline["Response Pipeline"]
direction RL
R1["Strip Real\nKeys"] --> R2["Replace with\nPlaceholders"]
end
subgraph Vault["Encrypted Vault"]
V1["AES-256-GCM"]
V2["Argon2id KDF"]
V3["Placeholder Map\nper agent × credential"]
end
end
subgraph External["External APIs"]
E1["api.openai.com"]
E2["api.anthropic.com"]
E3["..."]
end
A1 -- "placeholder token\nin headers/body" --> P
A1 -. "MCP: get_credential_ref\nlist_credentials\ncheck_rate_limit" .-> MCP
MCP -. "placeholder token\n(never real keys)" .-> A1
P --> Pipeline
Pipeline --> External
External --> ResponsePipeline
ResponsePipeline -- "response with\nplaceholders only" --> A1
Pipeline <--> Vault
ResponsePipeline <--> Vault
style Agent fill:#1a1a2e,stroke:#e94560,color:#fff
style Wardn fill:#0f3460,stroke:#16213e,color:#fff
style Pipeline fill:#16213e,stroke:#e94560,color:#fff
style ResponsePipeline fill:#16213e,stroke:#e94560,color:#fff
style Vault fill:#1a1a2e,stroke:#00d2ff,color:#fff
style External fill:#0a0a0a,stroke:#533483,color:#fff
Agent sends request with placeholder in Authorization header │ ▼ ┌─────────────────────────┐ │ wardn proxy │ │ localhost:7777 │ │ │ │ 1. Identify agent │ │ 2. Resolve placeholder │ │ 3. Check authorization │ │ 4. Check rate limit │ │ 5. Inject real key │ │ 6. Forward request │ │ 7. Strip key from resp │ │ 8. Return to agent │ └─────────────────────────┘ │ ▼ External API (only place real key exists in transit)
## Demo
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/12823/1fa6109ffd855ec98c173c5edd2d7ee77f6b0c918a3cdecb1ea5fbfe8326161d.gif" alt="wardn デモ" width="800">
</p>
## 信頼レベル(正直に)
| 階層 | 場所 | 保証内容 |
|---|---|---|
| **セルフホスト(現在)** | あなたのラップトップ、VPS、CI | 保存時暗号化されたボールト、エージェントに対するファイアウォールの主張。ホスト上のrootからの防御は**行いません**。 |
| **ホステッド(近日対応予定)** | wardn管理またはBYOクラウド | 機密コンピューティングエンクレーブ(Nitro / SEV-SNP)+ リモートアテステーション + プロキシへの暗号化フロー。本当の「host compromise leaks nothing」という主張。 |
セルフホスト階層は現在の主要な主張であり、今日提供されています。ホステッド階層は厳格なアップグレードパスです。費用と運用の複雑さがかかり、その設計は[docs/HOSTED-TIER.md](https://github.com/rohansx/wardn/blob/main/docs/HOSTED-TIER.md)にあります。カバーされるものとされないものの正直な完全な目録:
👉 **[docs/THREAT-MODEL.md](https://github.com/rohansx/wardn/blob/main/docs/THREAT-MODEL.md)** — カバー/非カバーの表、「no software vault eliminates host compromise」を明確に指摘し、アップグレードパスも記載。
## Install```bash
# Prebuilt binary (Linux/macOS, amd64/arm64), checksum-verified
curl -sSf https://raw.githubusercontent.com/rohansx/wardn/main/install.sh | sh
# or from crates.io
cargo install wardn
# or Homebrew, once the tap is published (see Formula/wardn.rb)
brew install rohansx/wardn/wardn
wardn vault create wardn vault set OPENAI_KEY wardn vault set ANTHROPIC_KEY
wardn setup claude-code
以上です。Claude Code は、環境から実際のキーを読み取る代わりに、wardn の MCP サーバーを使用してプレースホルダートークンを取得するようになりました。
### その後の流れ
1. Claude Code が `get_credential_ref` を呼び出す → `wdn_placeholder_a1b2...`(実際のキーではない)を取得
2. エージェントがプレースホルダーを含むリクエストを wardn プロキシ経由で送信
3. プロキシがプレースホルダーを実際のキーに置き換え、API に転送
4. レスポンスがエージェントに返される前に、プロキシが実際のキーを削除
実際のキーがエージェントのメモリ、ログ、LLM コンテキストウィンドウに入ることはありません。
## ローカルダッシュボード
デーモンが起動したら(`wardn serve`、または `wardn run` で起動)、ブラウザで
**http://127.0.0.1:7777/ui** を開いてください。読み取り専用、ローカルのみのビューです。
- **認証情報 (Credentials)** — 保存されたすべての認証情報とその ACL(許可されたエージェント、
許可されたドメイン、レート制限 + 予算バッジ)を表示。
- **最近のアクティビティ (Recent Activity)** — 直近 50 件のプロキシイベントを表示。メソッド、ドメイン、
パス、ステータス、エージェント、リクエスト ID、記録されたコスト(`request_completed`、
`credential_injected`、`rate_limit`、`budget_exceeded`、`loop_detected`、
`request_error`)を含む。
- **予算 (Budgets)** — 各認証情報の設定済み予算(最大、使用済み、
残り、期間、モード)を、50% / 80% を超えると警告 → 不良に変わる進捗バー付きで表示。
2 秒ごとに自動ポーリングされます。変更用のエンドポイントはありません。ダッシュボードから操作する唯一の方法は API そのもの(`/api/summary`、`/api/credentials`、`/api/audit?limit=N`、`/api/budgets`)です。```bash
# Static, anonymous, never sees real keys
curl http://127.0.0.1:7777/api/summary | jq
wardn vault get OPENAI_KEY
wardn vault list
wardn serve
wardn serve --mcp --agent my-agent
## CLIリファレンス