Catalog PyPI
Back to packageRELEASE DETAILS

1.0.0b3

PyPI

agentpass-ai

Replay-safe authentication middleware for autonomous AI agents

ai-agentsauthenticationjwtm2mmiddlewarereplay-safe
Published18 May 2026
Direct dependencies10
Transitive dependenciesNot calculated

README

Version 1.0.0b3 documentation

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)          │
│                                                      │
└─────────────────────────────────────────────────────┘
モジュール役割
AgentPassCrawleragentpass.json の非同期取得・SSRF防御・TTLキャッシュ
TokenVerifierEd25519署名検証・aud/expチェック・必須クレーム検証
AnomalyDetectorJTIベースのリプレイ攻撃検知・期限切れエントリのGC
AuthorizationMiddleware上記3つを統合するASGIミドルウェア

Error Reference

HTTPerror_code原因
400INVALID_PAYLOAD署名不一致 / 必須クレーム欠如
401INVALID_PAYLOADAuthorizationヘッダー欠如 / スキーム誤り / JWT不正
401TOKEN_EXPIREDJWTの exp 超過
403DESTINATION_MISMATCHaud が要求URLと不一致
403REPLAY_ATTACK同一JTIのトークンを再送信
503MERCHANT_UNVERIFIEDagentpass.json の取得失敗

Tests

pytest
pytest --cov=src --cov-report=term-missing  # カバレッジ付き

263 tests, 0 failed(Python 3.14)

Core(153件)

ファイルカバー範囲件数
tests/test_agentpass_crawler.pySSRF防御・1MB制限・TTLキャッシュ・HTTP異常系20
tests/test_authorization_middleware.pyミドルウェア全経路(正常・異常・JWT検証)20
tests/test_core_authorization_middleware.pyPydanticスキーマ統合・エラーコード体系18
tests/test_circuit_breaker.py予算・レート制限・スライディングウィンドウ22
tests/test_token_verifier.pyEd25519署名・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.pyAgentID導出・決定論性9
tests/e2e/test_agentpass_ecosystem.pyフルスタック統合(正常系・リプレイ攻撃)7

Sandbox(110件)— プロトコル境界検証

ファイルカバー範囲件数
tests/sandbox/test_budget_exceeded_returns_402.pyBudget Control・HTTP 402拒否20
tests/sandbox/test_budget_rejection_audit_log.pyappend-only JSONL監査ログ16
tests/sandbox/test_budget_replay.py拒否イベントのreplay検証8
tests/sandbox/test_exp005b_jti_collision.pyJTI衝突・スレッド安全性(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 — 商用利用・改変・再配布自由。

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 10

Native requirements
10 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
PyJWT
Environment
{
  "extras": "crypto",
  "marker": null,
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
PyJWT[crypto]>=2.10runtime
cryptography
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
cryptography>=44runtime
httpx
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
httpx>=0.28runtime
pydantic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
pydantic>=2.10runtime
fastapi
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.115runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
pytest>=8; extra == "dev"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=0.24; extra == "dev"runtime
pytest-cov
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
pytest-cov; extra == "dev"runtime
respx
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
respx>=0.21; extra == "dev"runtime
anyio
Environment
{
  "extras": "trio",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.13",
  "evaluation": "NOT_EVALUATED"
}
anyio[trio]>=4; extra == "dev"runtime

Distribution files

2 collected
agentpass_ai-1.0.0b3-py3-none-any.whl

bdist_wheel · 21.1 KB · Python py3

Source file
agentpass_ai-1.0.0b3.tar.gz

sdist · 30.92 KB · Python source

Source file

Repository

PENDING
notenkitoclient-cpu/agentpass

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 22:50 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:b48fcadeec57e0d8bbcccba1dc9e70ab25c260cec609dc1a610cf50709a51c35

Other collected versions

View all collected versions →