🔐 技術調査 - OneCLI
目次

🔐 技術調査 - OneCLI

概要

OneCLI は、AI エージェントが API キーなどの機密情報を直接保持せずに外部サービスへアクセスするための、オープンソースのクレデンシャル Vault です。エージェントと外部 API の間に透過的な HTTP ゲートウェイとして介在し、認証情報の一元管理・注入・監査を担います。

この記事は、AI エージェントのセキュリティ設計に関心がある開発者・インフラエンジニアを対象としています。OneCLI のアーキテクチャ・データモデル・構築方法・運用を網羅的に解説します。

項目 内容
種別 オープンソースソフトウェア
リポジトリ onecli/onecli
公式サイト onecli.sh
主要言語 TypeScript / Rust
スター数 717(2026-03-17 時点)

特徴

セキュリティ

項目 内容
ゼロトラスト設計 エージェントはプレースホルダーキー(FAKE_KEY)のみ保有。実キーに到達できない構造
AES-256-GCM 暗号化 {iv_b64}:{authTag_b64}:{ciphertext_b64} 形式で保存。リクエスト時のみメモリ内で復号
MITM CA 証明書 ECDSA P-256 / SHA-256 で自己署名 CA を自動生成。ホストごとにリーフ証明書(有効期間 24 時間)を動的生成
スコープ付きトークン 各エージェントに aoc_ プレフィックスの独立したアクセストークンを付与
監査ログ ゲートウェイの tracing ログで全 CONNECT/MITM リクエストを記録

アーキテクチャ

項目 内容
透過的プロキシ注入 HTTP CONNECT をインターセプトし、MITM 方式で実認証情報を注入
パターンマッチング ホスト(完全一致 + *. ワイルドカード)とパス(完全一致 + /prefix/*)でルーティング
デュアルサービス構成 Next.js 製 Web ダッシュボード(ポート 10254)+ Rust 製ゲートウェイ(ポート 10255)
柔軟なストレージ 組み込み PGlite または外部 PostgreSQL を選択可能
2 種類の認証モード シングルユーザーモード(デフォルト)と Google OAuth(チーム利用)

DX

項目 内容
ワンコマンドデプロイ Docker Compose 1 コマンドで起動可能
フレームワーク非依存 HTTPS_PROXY 環境変数と CA 証明書の配布のみで任意のフレームワークと連携

構造

システムコンテキスト図

管理操作 HTTP リクエスト 認証情報注入済みリクエスト 暗号化キー管理 データ永続化 開発者 AI エージェント OneCLI 外部 API KMS データベース
要素名 説明
開発者 ダッシュボード経由で認証情報とエージェントを管理するオペレーター
AI エージェント OneCLI プロキシ経由で外部 API を呼び出すクライアント
OneCLI 認証情報を安全に保管し、エージェントのリクエストに注入するクレデンシャル Vault
外部 API エージェントが呼び出す対象の外部サービス
KMS ローカルまたはクラウド上のキー管理サービス
データベース ユーザー・エージェント・暗号化済みシークレットを永続化するストレージ

コンテナ図

OneCLI ブラウザ操作 HTTP リクエスト 認証情報注入済みリクエスト 暗号化キー取得 データ読み書き 認証情報解決 API 認証情報解決リクエスト 開発者 AI エージェント 外部 API KMS データベース Web ダッシュボード Rust ゲートウェイ
要素名 説明
Web ダッシュボード Next.js 製の管理 UI + API サーバー。ポート 10254 で動作。シークレット・エージェント管理と認証情報解決 API を提供
Rust ゲートウェイ Tokio・Hyper 製の HTTP プロキシ。ポート 10255 で動作。エージェントのリクエストをインターセプトして認証情報を注入
KMS ローカルまたは OneCLI Cloud 上のキー管理サービス。シークレットの暗号化キーを管理
データベース PGlite(組み込み)または PostgreSQL(外部)。ユーザー・エージェント・シークレットを格納

コンポーネント図

Web_Dashboard Rust_Gateway Database_Layer ログイン シークレット-エージェント管理 aoc_ ヘッダ付きリクエスト 認証情報注入済みリクエスト AI エージェント 外部 API 開発者 認証システム ダッシュボード UI resolve-credentials API サーバーアクション Prisma ORM 共有 UI コンポーネント HTTP リクエストハンドラ ホスト-パス パターンマッチャ 認証情報インジェクタ MITM CA 証明書マネージャ User モデル Agent モデル Secret モデル
要素名 説明
認証システム NextAuth ベースのユーザー認証モジュール
ダッシュボード UI shadcn/ui を使用した管理画面。シークレットとエージェントを管理
resolve-credentials API ゲートウェイからの認証情報解決リクエストを処理する Next.js API エンドポイント
サーバーアクション Next.js サーバーアクション。データ操作をサーバーサイドで実行
Prisma ORM データベースアクセス層。スキーマ定義とマイグレーションを管理
共有 UI コンポーネント packages/ui に配置された再利用可能な shadcn/ui コンポーネント群
HTTP リクエストハンドラ Tokio・Hyper でエージェントからの HTTP リクエストを受け付けるモジュール
ホスト-パス パターンマッチャ リクエストの host と path を Secret の hostPattern・pathPattern と照合するモジュール
認証情報インジェクタ プレースホルダー値を復号済みの実認証情報に置換するモジュール
MITM CA 証明書マネージャ HTTPS インターセプション用の CA 証明書を生成・管理する rustls モジュール
User モデル ユーザー情報を格納する Prisma モデル
Agent モデル エージェント情報と aoc_ プレフィックス付きアクセストークンを格納する Prisma モデル
Secret モデル name・hostPattern・pathPattern・headerName・valueFormat・encryptedValue を持つ Prisma モデル

プロキシリクエストフロー

HTTP CONNECT トークン検証 true false リーフ証明書で TLS パターンマッチ AES-256-GCM 復号 HTTPS バイトコピー エージェント ゲートウェイ intercept? MITM - TLS 終端 TCP トンネル リクエスト復号 シークレット解決 ヘッダー注入 外部 API
要素名 説明
HTTP CONNECT エージェントが Proxy-Authorization: Basic base64("x:{aoc_token}") を付与して送信
intercept シークレットが存在するホストは MITM、存在しないホストは TCP パススルー
MITM - TLS 終端 CA 署名のリーフ証明書(有効期間 24 時間、DashMap キャッシュ)でエージェント側 TLS を終端
パターンマッチ ホスト(完全一致 + *. ワイルドカード)とパス(* / /prefix/* / 完全一致)で照合
ヘッダー注入 injectionConfig に基づきプレースホルダーを実キーに置換。ホップバイホップヘッダーは除外

パターンマッチングルール

ホストパターン

パターン マッチする例 マッチしない例
api.anthropic.com api.anthropic.com other.anthropic.com
*.anthropic.com api.anthropic.comsub.anthropic.com anthropic.com

パスパターン

パターン マッチする例 マッチしない例
* すべてのパス なし
/v1/* /v1/messages/v1//v1 /v2/messages
/v1/messages /v1/messages(完全一致のみ) /v1/messages/
null(未設定) すべてのパス なし

データ

概念モデル

User resolve-credentials Agent Secret
要素名 説明
User システムへのアクセス主体。シングルユーザーモードでは自動生成、OAuth モードでは Google ログインで作成
Agent プロキシに接続するクライアント。アクセストークンで認証
Secret 暗号化された API クレデンシャル。ホスト・パスのパターンに基づき対象リクエストへ注入
resolve-credentials Agent がプロキシ経由でリクエストを送信する際に、Secret を解決・復号して注入する処理

情報モデル

User + id: String + email: String + name: String + authMode: String Agent + id: String + userId: String + name: String + accessToken: String Secret + id: String + userId: String + name: String + type: String + encryptedValue: String + hostPattern: String + pathPattern: String + injectionConfig: JSON owns 1 0..* owns 1 0..*
要素名 説明
User.id ユーザーの一意識別子
User.email OAuth モードでのログインに使用するメールアドレス
User.authMode 認証モード。local / oauth / cloud のいずれか
Agent.accessToken プロキシ認証に使用するトークン。aoc_ プレフィックス付き
Agent.userId 所有ユーザーへの外部キー
Secret.type クレデンシャルの種別。anthropic または generic
Secret.encryptedValue AES-256-GCM で暗号化されたクレデンシャル値
Secret.hostPattern マッチ対象ホストのグロブパターン(例: api.anthropic.com*.example.com
Secret.pathPattern マッチ対象パスのグロブパターン(省略時は全パスにマッチ)
Secret.injectionConfig 注入設定。headerNamevalueFormat(例: Bearer {value})を持つ JSON。type = "anthropic" の場合は null

injectionConfig の詳細

type = "generic" の場合のみ使用する JSON フィールドです。

type InjectionConfig = {
  headerName: string;   // 必須: 注入先の HTTP ヘッダー名
  valueFormat: string;  // 省略時は "{value}" がデフォルト
};
ユースケース headerName valueFormat
OpenAI API Key authorization Bearer {value}
カスタムヘッダー x-custom-api-key {value}
Slack Bot Token authorization Bearer {value}
Basic 認証 authorization Basic {value}

type = "anthropic" の場合、トークン種別に応じて自動決定されます。

トークン形式 注入先ヘッダー
sk-ant-oat...(OAuth トークン) Authorization: Bearer {value}x-api-key を削除)
その他(通常 API キー) x-api-key: {value}Authorization を削除)

暗号化ライフサイクル

フェーズ 内容
生成 crypto.randomBytes(32).toString('base64') で 32 バイトキーを生成
保存 SECRET_ENCRYPTION_KEY 環境変数または /app/data/secret-encryption-key ファイルに格納
暗号化形式 {iv_b64}:{authTag_b64}:{ciphertext_b64}(IV: 12 バイト、Auth Tag: 16 バイト)
復号 ゲートウェイが CONNECT 解決時にオンデマンドで復号。メモリ内のみで保持し、ディスクへの書き込みは行わない
ローテーション 自動ローテーション機構は未実装。キー変更時は既存シークレットの再暗号化が必要
消失時 全シークレットが復号不能(不可逆)

構築方法

前提条件

方式 必要なツール
Docker(推奨) Docker Engine 20.10 以上
ローカル開発 mise、Rust 1.75 以上、Node.js 22、pnpm 9.0.0

ポート 10254(ダッシュボード)と 10255(ゲートウェイ)を開放してください。

Docker Compose での起動

git clone https://github.com/onecli/onecli.git
cd onecli
docker compose -f docker/docker-compose.yml up
  • PostgreSQL コンテナと OneCLI アプリコンテナを同時に起動
  • 初回起動時に暗号化キーと PGlite データベースを自動生成

Docker 単体での起動

docker run --pull always \
  -p 10254:10254 \
  -p 10255:10255 \
  -v onecli-data:/app/data \
  ghcr.io/onecli/onecli

組み込み PGlite を使用するため、外部 DB は不要です。

ローカル開発環境の構築

git clone https://github.com/onecli/onecli.git
cd onecli
mise install          # Node.js、pnpm などを自動インストール
pnpm install
cp .env.example .env
pnpm db:generate      # Prisma クライアント生成
pnpm db:up            # PostgreSQL を Docker で起動
pnpm db:migrate       # マイグレーション実行
pnpm dev              # Web + Gateway を同時起動

環境変数の設定

.env.example をコピーして .env を編集してください。

変数名 説明 デフォルト
DATABASE_URL PostgreSQL 接続文字列 PGlite(組み込み)
SECRET_ENCRYPTION_KEY AES-256-GCM 暗号化キー(32 バイト Base64) 初回起動時に自動生成
NEXTAUTH_SECRET OAuth 認証有効化フラグ 未設定(単一ユーザーモード)
GOOGLE_CLIENT_ID Google OAuth クライアント ID
GOOGLE_CLIENT_SECRET Google OAuth クライアントシークレット
AUTH_MODE local(開発用)または oauth local
NEXT_PUBLIC_GATEWAY_URL クライアントからのゲートウェイ URL http://localhost:10255

暗号化キーの生成コマンドは以下のとおりです。

node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

開発用コマンド一覧

コマンド 説明
pnpm dev Web + Gateway を開発モードで起動
pnpm dev:web Web のみ起動
pnpm build 本番ビルド
pnpm check Lint + 型チェック + フォーマット
pnpm db:up PostgreSQL を Docker で起動
pnpm db:down PostgreSQL を停止
pnpm db:generate Prisma クライアント生成
pnpm db:migrate マイグレーション実行
pnpm db:studio Prisma Studio を起動

利用方法

エージェントの作成

  1. ダッシュボード(http://localhost:10254)にアクセス
  2. 「Agents」タブから「New Agent」を作成
  3. 生成されたアクセストークン(aoc_ プレフィックス)を保存

シークレットの登録

  1. ダッシュボードの「Secrets」タブで API キーを登録
  2. ホストパターン(例:api.anthropic.com)とパスパターン(例:/v1/*)を指定
  3. 注入するヘッダー名(例:x-api-key)と実際の API キー値を設定

エージェントからのリクエスト送信

エージェントはゲートウェイをプロキシとして使用します。

curl -x http://localhost:10255 \
  -H "Proxy-Authorization: aoc_YOUR_TOKEN" \
  -H "x-api-key: FAKE_KEY" \
  https://api.anthropic.com/v1/messages \
  -d '{"model": "claude-3-5-sonnet-latest", ...}'
  • Proxy-Authorization にエージェントトークンを指定
  • x-api-key にはプレースホルダー(FAKE_KEY など任意の値)を指定
  • ゲートウェイがホスト・パスパターンを照合し、実際の API キーを自動注入

SDK・フレームワークからの利用

HTTPS_PROXY 環境変数と CA 証明書を設定するだけで、コード変更なしに利用できます。

# CA 証明書のダウンロード(初回のみ)
curl http://localhost:10254/api/gateway/ca -o /tmp/onecli-gateway-ca.pem

# 環境変数の設定
export HTTPS_PROXY=http://x:aoc_YOUR_TOKEN@localhost:10255
export HTTP_PROXY=http://x:aoc_YOUR_TOKEN@localhost:10255
export NODE_EXTRA_CA_CERTS=/tmp/onecli-gateway-ca.pem

Python(openai SDK)の例

import os
import openai
import httpx

os.environ["REQUESTS_CA_BUNDLE"] = "/tmp/onecli-gateway-ca.pem"

client = openai.OpenAI(
    api_key="FAKE_KEY",
    http_client=httpx.Client(
        proxies={"https://": "http://x:aoc_YOUR_TOKEN@localhost:10255"},
    ),
)

LangChain からの利用

import os
from langchain_anthropic import ChatAnthropic

os.environ["HTTPS_PROXY"] = "http://x:aoc_YOUR_TOKEN@localhost:10255"
os.environ["REQUESTS_CA_BUNDLE"] = "/tmp/onecli-gateway-ca.pem"
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-placeholder"

llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
response = llm.invoke("Hello!")

n8n からの利用

# docker-compose.yml の n8n サービスに追加
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    environment:
      - HTTPS_PROXY=http://x:aoc_YOUR_TOKEN@onecli:10255
      - NODE_EXTRA_CA_CERTS=/tmp/onecli-gateway-ca.pem
      - NODE_USE_ENV_PROXY=1
      - ANTHROPIC_API_KEY=sk-ant-placeholder
    volumes:
      - /tmp/onecli-gateway-ca.pem:/tmp/onecli-gateway-ca.pem:ro

Dify からの利用

# Dify の docker-compose.override.yml
services:
  api:
    environment:
      - HTTPS_PROXY=http://x:aoc_YOUR_TOKEN@onecli:10255
      - REQUESTS_CA_BUNDLE=/tmp/onecli-gateway-ca.pem
      - ANTHROPIC_API_KEY=sk-ant-placeholder
    volumes:
      - /tmp/onecli-gateway-ca.pem:/tmp/onecli-gateway-ca.pem:ro

対応フレームワーク一覧

フレームワーク 連携方式
Claude Code 環境変数(HTTPS_PROXY
OpenHands Docker 環境変数
n8n Docker 環境変数 / Node.js SDK
Dify Docker 環境変数
任意の HTTP クライアント HTTPS_PROXY 対応であれば動作

Node.js SDK

import { OneCLI } from "@onecli-sh/sdk";

const onecli = new OneCLI({
  url: "http://localhost:10254",
  apiKey: "oc_your_api_key",
});

// Docker 引数にプロキシ設定を自動注入
const args = ["run", "-i", "--rm", "n8nio/n8n"];
await onecli.applyContainerConfig(args);

ポート構成

ポート サービス 用途
10254 Next.js ダッシュボード UI、API、認証管理
10255 Rust ゲートウェイ クレデンシャル注入プロキシ

運用

デプロイメント

Docker(本番推奨)

単一コンテナにダッシュボード・ゲートウェイ・ストレージを内包しています。初回起動時に暗号化キー・データベース・CA 証明書を自動生成します。

docker run -d \
  -p 10254:10254 \
  -p 10255:10255 \
  -v onecli-data:/app/data \
  ghcr.io/onecli/onecli

クラウドデプロイ

  • 外部 PostgreSQL を DATABASE_URL で指定
  • PROXY_SECRET は AWS Secrets Manager 等の外部シークレットマネージャーに格納

起動シーケンス

entrypoint.sh が以下の順で初期化を実行します。

  1. /app/data/proxy-secret(32 バイト乱数 hex)を生成
  2. PGlite データベースを /app/data/pglite/ に初期化(外部 DB 未指定の場合)
  3. SECRET_ENCRYPTION_KEY を生成・保存
  4. runtime-config.json に認証モードを書き込み
  5. プロキシサービス(10255 番ポート)を起動
  6. Web サービス(10254 番ポート)を起動

ヘルスチェック

エンドポイント サービス 確認コマンド
GET /api/health Web ダッシュボード curl http://localhost:10254/api/health
GET /healthz Rust ゲートウェイ curl http://localhost:10255/healthz

Docker ヘルスチェックは両エンドポイントを 30 秒ごとに検証します。

データ永続化

/app/data ボリュームに以下を格納します。

パス 内容
/app/data/pglite/ 組み込みデータベースファイル
/app/data/proxy-secret プロキシ認証シークレット(消失で復旧不可)
/app/data/secret-encryption-key AES 暗号化キー(消失で全シークレット消失)
CA 証明書 MITM 傍受用 CA 証明書

ボリューム削除時にすべてのデータが永久消失するため、定期バックアップが必要です。

監査ログ

OSS 版ではデータベースへの監査ログテーブルは存在しません。ゲートウェイの tracing クレートによる標準出力ログで記録されます。

# ログの確認
docker logs onecli --follow

# 主要なログイベント
# CONNECT リクエスト
# INFO onecli_gateway::gateway: CONNECT peer=172.17.0.2:54321 host=api.anthropic.com:443 mode=mitm rule_count=1

# MITM フォワードリクエスト
# INFO onecli_gateway::gateway: MITM method=POST url=https://api.anthropic.com:443/v1/messages status=200 injections_applied=1

# トンネル終了
# INFO onecli_gateway::gateway: tunnel closed host=api.github.com:443 client_to_server=1024 server_to_client=2048

ログレベルは RUST_LOG 環境変数で制御します。

docker run ... -e RUST_LOG=debug ghcr.io/onecli/onecli

ダッシュボード操作

ダッシュボード(http://localhost:10254)のナビゲーション構成は以下のとおりです。

画面 主な機能
Overview エージェント数・シークレット数の統計カード、User API Key(oc_ プレフィックス)の表示・コピー
Agents エージェント一覧、作成(名前入力 → aoc_ トークン自動生成)、トークン再生成、削除
Secrets シークレット一覧、作成(タイプ・値・ホスト/パスパターン・注入設定)、更新、削除
Settings プロフィール設定、User API Key の管理

認証モード

シングルユーザーモード(デフォルト)

  • NEXTAUTH_SECRET 未設定時に有効
  • ログイン不要で全シークレットがデフォルトユーザーに帰属
  • 開発・個人用途向け

OAuth モード(チーム利用)

  • NEXTAUTH_SECRETGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET の全設定が必要
  • Google 認証によるマルチユーザー対応
  • ユーザーごとにシークレットを分離

ベストプラクティス

セキュリティ

  • エージェントには実際の API キーを渡さず、プレースホルダーキーを使用
# エージェントはダミーキーを設定する
OPENAI_API_KEY=FAKE_KEY
# プロキシが本物のキーに置換して転送する
  • エージェントトークン(aoc_ プレフィックス)は厳重に管理
  • SECRET_ENCRYPTION_KEY は環境変数インジェクション経由で設定し、コードにハードコードしない
  • 秘密情報を含む .env ファイルは .gitignore に追加

暗号化キー管理

  • SECRET_ENCRYPTION_KEY の変更は全シークレットの消失を招くため、ローテーション手順を事前に策定
  • クラウド環境では AWS Secrets Manager 等に格納してオーケストレーターから注入

アクセス制御

  • 現状はユーザー単位でシークレットを管理(エージェント単位の制限は未実装)
  • エージェントトークンは漏洩時に即時失効できる体制を整備
  • グロブパターンでホスト・パスを絞り込み、意図しないシークレット注入を防止

スケーリング

  • マルチインスタンス構成では外部 PostgreSQL を使用
  • ゲートウェイとダッシュボードを分離デプロイする場合、それぞれのポートを個別に公開

トラブルシューティング

起動時エラー

エラーコード 原因 対処法
oauth-misconfigured NEXTAUTH_SECRET 設定済みだが Google OAuth 資格情報が未設定 3 変数すべて設定するか、NEXTAUTH_SECRET を削除
missing-encryption-key SECRET_ENCRYPTION_KEY が未設定 openssl rand -hex 32 | base64 で生成して設定

ポート競合

10254・10255 番ポートが使用中の場合は PORT / PROXY_PORT 環境変数で変更してください。

docker run -d \
  -e PORT=8080 \
  -e PROXY_PORT=8081 \
  -p 8080:8080 \
  -p 8081:8081 \
  -v onecli-data:/app/data \
  ghcr.io/onecli/onecli

データベース接続エラー

  • DATABASE_URL のフォーマットを確認
  • 開発環境では pnpm db:up で PostgreSQL コンテナを起動
  • PGlite のパーミッションエラーは /app/data ディレクトリの権限を確認

エージェント接続失敗

  • プロキシの Proxy-Authorization ヘッダーにエージェントトークンが正しく設定されているか確認
  • ゲートウェイ(10255 番ポート)への疎通を確認
curl http://localhost:10255/healthz
  • シークレットのホスト・パスパターンがリクエスト先と一致しているか確認

ログ確認

docker logs <container_id>

初期化シーケンス・シークレット生成・サービス起動メッセージを確認してください。

資格情報注入の検証

# ダミーキーでプロキシ経由リクエストを送信し、本物のキーが注入されるか確認する
curl -x http://localhost:10255 \
  -H "Proxy-Authorization: Bearer aoc_YOUR_TOKEN" \
  https://api.target-service.com/endpoint

まとめ

OneCLI は、AI エージェントに API キーを直接渡さず、透過的な HTTP プロキシ経由でクレデンシャルを注入するゼロトラスト設計のクレデンシャル Vault です。Docker 1 コマンドでデプロイでき、HTTPS_PROXY 環境変数の設定だけで LangChain・n8n・Dify・Claude Code など任意のフレームワークと連携できます。

類似ツールとの主な違いを整理すると以下のとおりです。

観点 OneCLI Infisical / HashiCorp Vault
主な対象 AI エージェント アプリケーション全般
注入方式 HTTP プロキシ(MITM) SDK / サイドカー / CLI
コード変更 不要(HTTPS_PROXY のみ) SDK 統合が必要
セットアップ Docker 1 コマンド クラスタ構築が必要(Vault)
スコープ クレデンシャル注入に特化 シークレット管理全般

AI エージェントへのクレデンシャル管理を手軽に始めたい場合、OneCLI は有力な選択肢です。

この記事が少しでも参考になった、あるいは改善点などがあれば、ぜひリアクションやコメント、SNS でのシェアをいただけると励みになります!

参考リンク