Replay-safe authentication middleware for autonomous AI agents
Project description
AgentPass
Replay-safe authentication middleware for autonomous AI agents.
Ed25519 署名済み JWT を使い、AIエージェント間(M2M)の認証をサードパーティサーバー不要で実現します。
Agent ──[AgentPass JWT]──▶ Merchant API
▲ Ed25519 署名 + aud 固定 + jti 使い捨て
What AgentPass Solves
| 問題 | AgentPass の対策 |
|---|---|
| リプレイ攻撃 | jti クレームで各トークンを使い捨て。傍受されたトークンを再送しても即拒否 |
| なりすまし | Ed25519 署名でトークンを発行元エージェントの鍵ペアに紐付け。偽造不可 |
| APIキー共有 | エージェントごとに独立した鍵ペア。1つの鍵が漏洩しても他に影響なし |
3-Minute Quick Demo
pip install agentpass-ai cryptography PyJWT
Note: Install package:
agentpass-ai/ Import package:agentpass
# quickdemo.py — python quickdemo.py
from agentpass import issue_token, verify_token, TokenRequest, generate_keypair
ENDPOINT = "https://api.example.com/v1/query"
# エージェントと検証側が同じ鍵ペアを共有するデモ。
# 本番: エージェントが事前に公開鍵を加盟店へ登録する。
private_key, public_key = generate_keypair()
token = issue_token(
TokenRequest(
agent_id="agent-demo-001",
destination_url=ENDPOINT,
amount_requested=0.001,
purpose="data query",
),
private_key,
).token
claims = verify_token(token, public_key, ENDPOINT)
print(f"✓ Verified agent={claims.agent_id} amount={claims.amount} {claims.currency}")
print(f" token={token[:52]}...")
Expected output:
✓ Verified agent=agent-demo-001 amount=0.001 JPY
token=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWIi...
ASGI Middleware Setup
FastAPI / Starlette への組み込みは3ファイルで完了します。
1. インストール
pip install agentpass-ai fastapi uvicorn cryptography PyJWT httpx
Note: Install package:
agentpass-ai/ Import package:agentpass
2. 加盟店サーバー (merchant.py)
from fastapi import FastAPI
from starlette.requests import Request
from agentpass import AuthorizationMiddleware, AnomalyDetector
app = FastAPI()
app.add_middleware(
AuthorizationMiddleware,
anomaly_detector=AnomalyDetector(), # リプレイ攻撃検知
)
@app.get("/v1/pay")
async def pay(request: Request):
claims = request.state.agent_claims # 検証済みクレームが自動バインド
return {
"agent_id": claims.agent_id,
"amount": claims.amount,
"currency": claims.currency,
}
3. agentpass.json を公開する
{
"agentpass_version": "1.0.0",
"merchant_id": "550e8400-e29b-41d4-a716-446655440000",
"public_key": "a1b2c3d4...",
"pricing": [
{ "endpoint": "/v1/pay", "price_per_token": 0.001 }
]
}
https://api.merchant.com/.well-known/agentpass.json で配信します。public_key はエージェントが事前登録した Ed25519 公開鍵(hex)を設定してください。
4. エージェント (agent.py)
from agentpass import issue_token, TokenRequest, generate_keypair
import httpx
# 実際はセキュアストレージから秘密鍵を読み込む
private_key, _ = generate_keypair()
req = TokenRequest(
agent_id="agent-7f3a...",
destination_url="https://api.merchant.com/v1/pay",
amount_requested=0.001,
purpose="data access",
)
issued = issue_token(req, private_key)
resp = httpx.get(
"https://api.merchant.com/v1/pay",
headers={"Authorization": f"AgentPass {issued.token}"},
)
print(resp.json()) # {"agent_id": "agent-7f3a...", "amount": 0.001, "currency": "JPY"}
5. 起動
# Terminal 1
uvicorn merchant:app
# Terminal 2
python agent.py
Security Model
| 防衛壁 | 仕組み | 防御する攻撃 |
|---|---|---|
| Ed25519 署名 | トークンをエージェントの秘密鍵で署名。公開鍵は agentpass.json から自律取得 |
偽造・なりすまし |
| 改ざん検知 | JWT 三部構造。1バイトでも変更すれば検証失敗 | 中間者改ざん |
aud 宛先固定 |
完全URLを埋め込み、受信URLと完全一致チェック | トークン横流し |
jti 使い捨て |
AnomalyDetector が JTI を TTL 付きで記録し、再送を即拒否 |
リプレイ攻撃 |
クローラーは SSRF防御(プライベートIPへの解決を即拒否)と 1MBストリーム制限(巨大レスポンスで即切断)を内蔵しています。
Architecture
┌─────────────────────────────────────────────────────┐
│ AgentPass Core │
│ │
│ AuthorizationMiddleware (ASGI) │
│ │ │
│ ├─▶ AgentPassCrawler ├─▶ TTL Cache │
│ │ └─▶ SSRF Protection └─▶ 1MB Limit │
│ │ │
│ ├─▶ TokenVerifier (Ed25519 + aud + exp) │
│ │ │
│ └─▶ AnomalyDetector (jti replay defense) │
│ │
└─────────────────────────────────────────────────────┘
| モジュール | 役割 |
|---|---|
AgentPassCrawler |
agentpass.json の非同期取得・SSRF防御・TTLキャッシュ |
TokenVerifier |
Ed25519署名検証・aud/expチェック・必須クレーム検証 |
AnomalyDetector |
JTIベースのリプレイ攻撃検知・期限切れエントリのGC |
AuthorizationMiddleware |
上記3つを統合するASGIミドルウェア |
Error Reference
| HTTP | error_code |
原因 |
|---|---|---|
| 400 | INVALID_PAYLOAD |
署名不一致 / 必須クレーム欠如 |
| 401 | INVALID_PAYLOAD |
Authorizationヘッダー欠如 / スキーム誤り / JWT不正 |
| 401 | TOKEN_EXPIRED |
JWTの exp 超過 |
| 403 | DESTINATION_MISMATCH |
aud が要求URLと不一致 |
| 403 | REPLAY_ATTACK |
同一JTIのトークンを再送信 |
| 503 | MERCHANT_UNVERIFIED |
agentpass.json の取得失敗 |
Tests
pytest
pytest --cov=src --cov-report=term-missing # カバレッジ付き
263 tests, 0 failed(Python 3.14)
Core(153件)
| ファイル | カバー範囲 | 件数 |
|---|---|---|
tests/test_agentpass_crawler.py |
SSRF防御・1MB制限・TTLキャッシュ・HTTP異常系 | 20 |
tests/test_authorization_middleware.py |
ミドルウェア全経路(正常・異常・JWT検証) | 20 |
tests/test_core_authorization_middleware.py |
Pydanticスキーマ統合・エラーコード体系 | 18 |
tests/test_circuit_breaker.py |
予算・レート制限・スライディングウィンドウ | 22 |
tests/test_token_verifier.py |
Ed25519署名・aud・exp・クレーム検証 | 15 |
tests/test_token_issuer.py |
トークン発行・JTI一意性 | 9 |
tests/test_anomaly_detector.py |
リプレイ検知・GC・時刻制御 | 11 |
tests/test_credit_scorer.py |
信用スコア計算・ペナルティ・境界値 | 22 |
tests/test_agent_signer.py |
AgentID導出・決定論性 | 9 |
tests/e2e/test_agentpass_ecosystem.py |
フルスタック統合(正常系・リプレイ攻撃) | 7 |
Sandbox(110件)— プロトコル境界検証
| ファイル | カバー範囲 | 件数 |
|---|---|---|
tests/sandbox/test_budget_exceeded_returns_402.py |
Budget Control・HTTP 402拒否 | 20 |
tests/sandbox/test_budget_rejection_audit_log.py |
append-only JSONL監査ログ | 16 |
tests/sandbox/test_budget_replay.py |
拒否イベントのreplay検証 | 8 |
tests/sandbox/test_exp005b_jti_collision.py |
JTI衝突・スレッド安全性(N並列→承認1件) | 16 |
tests/sandbox/test_exp006_burst_freeze.py |
バースト検知・一時freeze(HTTP 503) | 22 |
tests/sandbox/test_exp005c_agent_keypair_isolation.py |
エージェント別鍵隔離・signer mismatch拒否 | 28 |
License
MIT License — 商用利用・改変・再配布自由。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agentpass_ai-1.0.0b3.tar.gz.
File metadata
- Download URL: agentpass_ai-1.0.0b3.tar.gz
- Upload date:
- Size: 31.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bd4cc5a798d63d2003f0ba76aadd893b753bf6fa9ff0dcb6667d088d99d7f40
|
|
| MD5 |
7e31b4e5b7470306fc344fd9cafcc597
|
|
| BLAKE2b-256 |
c7945954760f53a60446cb75da39009a5c9a657257dc89ff9027e1a1e50312df
|
File details
Details for the file agentpass_ai-1.0.0b3-py3-none-any.whl.
File metadata
- Download URL: agentpass_ai-1.0.0b3-py3-none-any.whl
- Upload date:
- Size: 21.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fe6050eb18889326e253eee2c9cde0bd88706a5ee05f031c9d1abc98d5084e7
|
|
| MD5 |
b4ba23b2bb86f988fb09c569721dc32f
|
|
| BLAKE2b-256 |
1449dfbfb94451a7f2cc945db6d622eef789ef4d8287b0959ac03c16fc37c597
|