AMR (Agent Mandate Registry) について
AMRは、本人に代わって行動するAIエージェントの権限委任を記録・検証するオープンソースのMCPサーバーです。署名付きアクショントークンとハッシュチェーン監査ログを備え、ローカルで動作します。
主な機能
- 01エージェント権限の登録と検証
- 02範囲確認付き署名アクショントークン
- 03ハッシュチェーンによる操作記録
- 04ロール別のツールプロファイル
- 05権限の取り消しと監査証明
活用シーン
- 01エージェントの権限と制限を記録
- 02実行前にアクショントークンを検証
- 03エージェントの操作記録を確認・異議申し立て
- 04監督用の権限証拠を提示
MCP 対応
権限委任、トークン、操作記録、監査のツールをMCPクライアントに公開します。ツールプロファイルにより、委任者、エージェント、受領者の機能を分離します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx mandatiaAMR_DB_PATHAbsolute path of the SQLite registry file (default: amr_mandates.db in the client's current directory)AMR_SIGNING_KEY_PATHシークレットAbsolute path of the registry's Ed25519 private key, created on first use; keep it out of version controlAMR_PUBLIC_KEY_PATHシークレットAbsolute path of the registry's public key fileローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
17掲載時のツール一覧 · 3 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| scope | string | はい | |
| agent_id | string | はい | |
| currency | string | いいえ | |
| metadata | any | いいえ | |
| signed_at | any | いいえ | |
| max_amount | any | いいえ | |
| period_days | any | いいえ | |
| principal_id | string | はい | |
| risk_classes | any | いいえ | |
| amount_actions | any | いいえ | |
| duration_hours | number | はい | |
| allowed_actions | any | いいえ | |
| forbidden_actions | any | いいえ | |
| parent_mandate_id | any | いいえ | |
| period_max_amount | any | いいえ | |
| delegation_allowed | boolean | いいえ | |
| legal_basis_article | string | はい | |
| principal_signature | any | いいえ | |
| max_delegation_depth | any | いいえ | |
| legal_basis_regulation | string | はい | |
| legal_basis_jurisdiction | string | いいえ |
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
エージェント委任登録簿(AMR)
AI エージェントのための法的委任レイヤーです。
AMR は、本人に代わって AI エージェントが行動することを認める法的委任を登録、検証、監査するオープンソースの MCP サーバーです。誰がどのエージェントに何を、いつまで行う権限を与えたのかを、暗号技術によって連鎖した監査証跡として提供します。これは、EU AI Act Article 26 に基づく導入事業者の人間による監督および記録保持の義務を裏付ける証拠となるもので、eIDAS 2.0 の電子委任を想定しています。AMR は技術ツールであり、それ自体がシステムの法令遵守を保証するものではありません。
エージェント向けクイックスタート
このセクションは、AI エージェント(Claude Code、Cursor、任意の MCP クライアント)が、アカウントもメールアドレスも問い合わせ相手も必要とせず、AMR をインストールして最初の検証済み委任を自力で完了できるように書かれています。すべての処理はお使いのマシン上で実行されます。AMR はネットワークに接続しません(オプトイン方式の例外が2つあり、どちらもデフォルトでは無効です。オペレーターが AMR_ISSUE_TOKEN を設定した場合の report_issue と、オペレーターが AMR_DID_WEB_RESOLVE=1 を設定した場合の did:web キー確認です)。
1. サーバーを起動します(uv が必要です)。
uvx mandatia
PyPI パッケージ名は mandatia ですが、Python モジュールと amr コマンドの名前はそのままです。uvx amr は別の無関係なプロジェクトをインストールするため、使用しないでください。代わりにリポジトリの最新コードを実行するには、次のようにします。
uvx --from git+https://github.com/JC7333/amr amr
AMR は MCP Python SDK のバージョン1とバージョン2で動作します(mcp>=1.2,<3)。バージョンの追加指定は必要ありません。
または、リポジトリをクローンして uv sync && uv run amr を実行します。
2. MCP クライアントに登録します。
Claude Code:
claude mcp add amr -- uvx mandatia
Cursor(.cursor/mcp.json)や、mcpServers オブジェクトを読み込むその他のクライアント:
{
"mcpServers": {
"amr": {
"command": "uvx",
"args": ["mandatia"],
"env": {
"AMR_DB_PATH": "/absolute/path/amr_mandates.db",
"AMR_SIGNING_KEY_PATH": "/absolute/path/amr_signing_key.pem",
"AMR_PUBLIC_KEY_PATH": "/absolute/path/amr_signing_key.pub"
}
}
}
}
代わりにリポジトリのコードを実行する場合、引数は
["--from", "git+https://github.com/JC7333/amr", "amr"] です。
3つのパスを設定してください。デフォルトでは、AMR はクライアントのカレントディレクトリにデータベースと署名鍵を書き込みます。.pem 秘密鍵はバージョン管理の対象外にしてください。
3. 最初の検証済み委任を完了します。 エージェントが使う順にツールを示します。
create_mandate:誰が何を許可するかを登録します(principal_id、agent_id、scope、legal_basis_regulation、legal_basis_article、duration_hours。範囲を定めるにはallowed_actions/forbidden_actionsを追加します。この制約を適用するのはissue_action_tokenのみです)。verify_mandate(agent_id, action):エージェントに有効な委任がある場合、authorized: trueを返します。actionが範囲内かどうかは確認しません。確認するのはissue_action_tokenです。log_action(mandate_id, action):ハッシュチェーンで連結されたジャーナルにエントリーを追加します。issue_mandate_attestation+get_registry_public_key:第三者がpython -m amr.verify_attestationを使ってオフラインで確認できる署名済み文書を発行します。revoke_mandate(mandate_id, reason):停止ボタンです。以後、verify_mandateはauthorized: falseを返します。すでに発行されたトークンと証明書は、有効期限が切れるまで有効です。ただし、受信側がcheck_action_tokenでトークンを再確認する場合は除きます。get_proof(mandate_id):監査用の完全な一式(委任、アクション、整合性)を取得します。エージェントがすでに行うべきでないことを実行していた場合は、contest_action(mandate_id, action_id, reason, response_days)でその行為に異議があることを記録し、list_action_contestsでオペレーターが設定した期限を確認できます。report_issue(title, description, version, context):AMR 自体の問題を報告します。AMR_ISSUE_TOKENが設定されていない場合、ネットワーク接続は行わず、問題報告を作成するための事前入力済みリンクを返します。設定されている場合は、GitHub に問題を登録します。詳しくはdocs/report-issue-spec.mdを参照してください。
同じ手順を実行でき、テストスイートで検証されるコードは
examples/quickstart_agent.py にあります。
git clone https://github.com/JC7333/amr.git && cd amr && uv sync
uv run python examples/quickstart_agent.py # prints every step, ends with "OK"
エージェント向けの機械可読な概要は、AGENTS.md と llms.txt を参照してください。
問題を報告するには、report_issue を呼び出すか、
https://github.com/JC7333/amr/issues で問題を登録してください(実際の委任内容や個人データは決して記載しないでください)。
なぜ AMR なのか?
最新の AI エージェントインフラストラクチャでは多くの懸念事項が扱われていますが、法的な権限付与のレイヤーが欠けています。
| 懸念事項 | 既存のツール | AMR |
|---|---|---|
| インフラストラクチャとオーケストレーション | ✅ LangChain、AutoGen、CrewAI | — |
| セキュリティとサンドボックス化 | ✅ Docker、RBAC、ネットワークポリシー | — |
| 権限とアクセス制御 | ✅ OAuth、IAM、API キー | — |
| オブザーバビリティとトレーシング | ✅ OpenTelemetry、Langfuse | — |
| 法的な権限付与と説明責任 | ❌ 対象外 | ✅ AMR |
EU AI Act 第26条(Regulation (EU) 2024/1689)は、高リスク AI システムの導入者に対し、人間による監督を割り当て、システムが生成するログを、導入者が管理できる範囲で、少なくとも6か月間保持することを義務付けています(第26条第6項)。附属書IIIのシステムには2027年12月2日から、附属書Iのシステムには2028年8月2日から適用されます(Regulation (EU) 2026/1744)。第26条に違反した場合、1,500万ユーロまたは全世界の年間売上高の3%のいずれか高い方が上限の罰金を科される可能性があります(第99条第4項。中小企業およびスタートアップの場合は、いずれか低い方が適用されます(第99条第6項))。AMR は、誰がエージェントに何をいつまで許可したか、そしてエージェントが何を行ったかを、監督の根拠として信頼できる改ざん検知可能な形式で記録します。AMR はシステム独自のログを補完するものであり、それに取って代わるものではありません。
構造的なハードストップによる強制
AMR は権限付与を記録するだけではなく、それを強制します。エージェントのランタイムは、アクションを実行する前に AMR から署名済みアクショントークンを取得する必要があります。有効で、期限切れでも取り消し済みでもない権限付与が、その特定のエージェントによるその特定のアクションを許可している場合に限り、トークンが発行されます。権限付与なし → トークンなし → アクションなし。
トークンは Ed25519(EdDSA)で署名された JWS(RFC 7515)であり、jti クレームと issued_tokens 監査テーブルによってリプレイを防止し、許可する正確なアクションハッシュとスコープダイジェストを含みます。利用側は AMR の公開鍵を使用してオフラインで検証し、aud、exp、amr_action_hash を必ず確認しなければなりません。
実行範囲の強制と委任の制御
権限付与には構造化された実行範囲を設定できます。具体的には、エージェントが要求できるアクションタイプ(allowed_actions)、決して要求できないアクションタイプ(forbidden_actions。こちらは常に優先され、サブタイプにも適用されます。たとえば agent.create を禁止すると agent.create.batch も禁止されます)、委任の可否(delegation_allowed)、および任意の金額上限(currency を伴う max_amount。amount_actions に適用)です。これにより、トークン発行者は権限付与の有無だけでなく、要求されたアクションを実行範囲と照合します。
allowed_actionsの範囲外のアクションタイプ、またはforbidden_actionsに一致するアクションタイプには、トークンが発行されません(reason: "action_out_of_scope"。detailと、拒否した委任指示を示すrefused_byが含まれます)。- サブ委任指示(
parent_mandate_id)が作成されるのは、親が有効で、委任を許可し、現在委任を行うエージェントに付与されている場合に限られます。サブ委任指示は親の許可されたアクションと上限の範囲内にとどまり、親の禁止事項を継承し、親より長く有効であってはなりません。 - サブ委任指示の下で発行されるすべてのトークンで、委任指示のチェーン全体が再確認されます。親を失効(
revoke_mandate)させるか、有効期限切れにすると、その下にあるすべてのサブ委任指示でトークンが発行されなくなります。 - 任意の累積上限(ローリング期間
period_days日間におけるperiod_max_amount。同じcurrencyとamount_actionsを適用)により、その期間内に委任指示およびその下にあるすべてのサブ委任指示の下で発行されたトークンの金額合計が制限されます。金額を伴うアクション(amount_actionsで指定されたもの、空の場合はすべてのアクション、およびamountを宣言するアクション)では、エージェントが高額な購入を小口に分割したり、サブエージェント経由で同じ予算を再度使ったりすることはできません(detail: "period_amount_above_limit:<max> <CUR>/<days>d"。予算を使い切った委任指示がrefused_byに示されます)。トークンは、使用されたかどうかにかかわらず、発行された時点でカウントされます。拒否されたトークンはカウントされません。サブ委任指示自身の上限は、親の上限を超えてはなりません。親の上限はサブ委任指示の適用範囲にコピーされません(ただし、発行時にはサブ委任指示にも適用されます)。適用される上限をすべて確認するには、get_proofとアテステーションと同様に、チェーン全体を確認してください。アクションごとの上限を持つ親の下に上限を設定するサブ委任指示では、両方のamount_actionsの和集合が適用されます(いずれか一方が空のリストの場合、すべてのアクションが対象です)。 - 任意のリスククラス(
risk_classes)を使うと、何が懸かっているかに応じて、トークンを使用可能な期間を制限できます。各クラスでは、アクションタイプ(forbidden_actionsと同様にサブタイプを含めて指定)と、1~86400 のmax_token_secondsを指定します。例:{"name": "irreversible", "actions": ["invoice.pay"], "max_token_seconds": 30}。そのクラスに該当するアクションのトークンは、その期間を超えて使用できません。委任指示と委任チェーン上のすべての親委任指示において、最短の期間が適用されるため、サブ委任指示で期間を短縮することはできますが、延長することはできません。サブ委任指示は親のクラスを継承し(自身の適用範囲に表示されます)、同じクラス名を再利用できるのは、max_token_secondsが親と同じかそれより短い場合に限られます(それ以外はlimit_exceeds_parent)。一致したクラス名は、amr_risk_classesとしてトークンに封印されます。クラスによってトークンの有効期間がAMR_TOKEN_LIFETIME_SECONDSを超えることはありません。クラスのない委任指示では、ハッシュとトークンは完全にそのまま維持されます。クラスには"registry_check": trueを設定することもできます。この場合、そのクラスのトークンにはamr_registry_check: trueが付与され、実行時に受信側がcheck_action_tokenで再確認するため、その間に発生した失効が反映されます。サブ委任指示はこのフラグを継承し、無効にすることはできません。この設定のないクラスは、形式とハッシュが完全にそのまま維持されます。
例:サブエージェントを決して作成しないよう指示されたアシスタントエージェント。
create_mandate(..., allowed_actions=["report.*"], forbidden_actions=["agent.create"])
issue_action_token(..., action_type="agent.create")
→ {"denied": true, "reason": "action_out_of_scope", "detail": "forbidden:agent.create"}
周辺境界のないルート委任は、これまでどおり機能します(フリーテキストのスコープ、存在確認と有効性確認のみで、ハッシュも同じです)。累積上限のない周辺境界は、正規形がそのまま維持されるため、ハッシュ、周辺境界ダイジェスト、プリンシパル署名に変更はありません。スキーマ v7 で追加されるのは token_amounts テーブルのみです。累積上限の制限事項:スキーマ v7 より前に発行されたトークンには金額が記録されていないため、カウントされません(古い AMR は、上限付きのブランチでは不明な周辺境界フィールドを拒否するため、トークンを発行できません)。上限が適用されるのは、1 つの委任とそのブランチであり、同じプリンシパルのすべての委任ではありません。サブ委任については、意図的に互換性を破る変更が 2 つあります。新しいサブ委任には委任を許可する親が必要になったため、フリーテキストの親は委任できなくなりました。また、v1.1 より前に作成されたものも含め、サブ委任下のトークンには、すべての親が有効かつ期限切れでないことが必要になりました。
デプロイルール。 エージェントが独自の委任を登録できない場合に限り、これらの制御は有効です。
create_mandateとregister_principal_keyはプリンシパル側のツールです。プリンシパル(またはそのバックオフィス)には公開し、管理対象のエージェントには決して公開しないでください。create_mandateを呼び出せるエージェントは、キーなしで任意のプリンシパルの新しいルート委任を自ら発行できます。また、register_principal_keyを呼び出せるエージェントは、まだキーを登録していないプリンシパルを名乗ることができます。各プリンシパルがキーを登録すれば、プリンシパル署名(以下を参照)によって最初の問題は解消されます。キーを検証済みの身元に紐付ける機能は、ロードマップに記載されています。
プリンシパル署名:プリンシパルが委任に署名します
プリンシパルは、自身の Ed25519 公開鍵を 1 回登録できます(register_principal_key)。以後、レジストリはプリンシパルが署名した委任のみを、そのプリンシパル名義で受け付けます。prepare_mandate_signature は署名する正確なバイト列を返し、create_mandate は principal_signature と signed_at を受け取ります。署名は委任の chain_hash に封印され、同じレジストリ内では 2 回使用できません。また、公開鍵と署名対象のバイト列とともに Proof Pack に保存されるため、誰でもオフラインで再検証できます。すべての未署名の委任を拒否するには、AMR_REQUIRE_PRINCIPAL_SIGNATURE=true を設定します。
有効な署名によって証明されるのは、その委任が principal_id に対して最初に登録されたキーで署名されたことです。通常の principal_id では、レジストリはキー登録者を確認しないため(最初の登録が優先されます)、オンボーディング時に各プリンシパルのキーを、そのプリンシパル自身のチャネルを通じて登録してください。組織は代わりに did:web:<its domain> 識別子を使用できます。この場合、ドメインが https://<domain>/.well-known/did.json でキーを公開しているときに限り、そのキーが受け付けられます。また、そのドキュメントの SHA-256 がキーとともに封印されます(ネットワークアクセスはオプトイン、AMR_DID_WEB_RESOLVE=1)。これは登録時点でのドメイン管理権を証明するものであり、適格な署名を証明するものではありません。did:web プリンシパルに依存する利用者は、Proof Pack、アテステーション、または保険会社向けドシエで did_web_unverified: false を確認する必要があります。
動作の変更(did:web キー): デフォルト設定では、did:web: 識別子のキー登録は「最初の登録が優先」ではなく、did_web_resolution_disabled で拒否されるようになりました。すでに登録済みのキーは引き続き有効で、did_web_unverified として報告されます。非 ASCII の類似文字で記述された scheme:method: プレフィックスは、principal_id_lookalike で拒否されます。キーを持たないプリンシパルの委任は、これまでどおり(同じハッシュで、結果に "principal_signature": null が追加されます)動作します。キー登録前に作成された委任も引き続き有効です。既知の制限を含め、docs/principal-signature-spec.md を参照してください。
詳しい仕様については、docs/token-issuance-spec.md を参照してください。
業界テンプレート
テンプレートは、特定の種類のエージェント向けにすぐ使える、バージョン管理された権限境界です。各アクションタイプの意味を平易な言葉で説明するカタログも備えています。最初のテンプレートである agent-sante-rgpd は、医療機関のアシスタントエージェントを対象としています。診療記録の閲覧、予約の管理、人間が送信するための書簡や患者へのメッセージの下書き、上限額内での備品の発注は許可されます。一方、処方、診断、診療記録の変更やエクスポート、患者への直接連絡、サブエージェントの作成は一切許可されません。
from amr.templates import get_template
template = get_template("agent-sante-rgpd")
await create_mandate(..., **template.create_mandate_kwargs())
委任には、メタデータとして template_id、template_version、template_digest が記録されます。このメタデータはラベルであり、チェーンハッシュには封入されません。封印されるのは権限境界であり、トークン発行者がこれを適用します。テンプレートが補完するのは既存の create_mandate 引数のみです。既存の委任とそのハッシュは変更されません。現時点では Python API として提供されており、テンプレートを一覧表示する MCP ツールはまだありません。すべての権限境界と同様、このテンプレートが有効なのは、エージェント自身が create_mandate を呼び出せない場合に限られます(上記のデプロイルールを参照)。詳しくは docs/templates/agent-sante-rgpd.md をご覧ください。
機関(委員会、理事会)がエージェントを承認した場合、委任にその決定を記録できます(organ_decision:機関、役職、日付、任意の参照情報、指定された人物または役割)。医療テンプレートはこれを受け入れ、create_mandate はチェーンハッシュに封入します(許可アクションのリストが限定されたルート委任のみ)。また、verify_mandate と get_proof もこれを返します。この情報がない委任のハッシュは一切変更されません。
第三者検証:受領者は委任だけを確認
エージェントは、署名済みの委任証明(issue_mandate_attestation)を、受領者(販売者、病院、保険会社など)に提示できます。受領者は、レジストリの公開鍵を一度取得しておけば(get_registry_public_key)、アカウントもレジストリへの接続も不要で、オフラインで証明のみを検証できます。証明には、委任の存在、委任者(本人が署名したかどうか、および include_principal_payload を指定した場合は受領者が署名を自ら再検証できること)、エージェント、権限範囲と構造化された権限境界、有効期限、さらに証明の発行時に委任とそのすべての上位委任が有効だったことが記載されます。
python -m amr.verify_attestation attestation.jws --public-key registry.pub --audience seller:acme
# registry.pub: the PEM (or the JSON) returned by get_registry_public_key
# {"valid": true, "reason": "ok", "attestation": {"principal_id": "...", "perimeter": {...}, ...}}
証明で確認できないこと:委任が「現在も」有効であることです。証明の有効期間は最大でも AMR_ATTESTATION_LIFETIME_SECONDS(デフォルトは15分)で、委任または親委任の有効期限を超えることはありません。発行後に行われた失効がオフラインの受領者に反映されるのは、証明の有効期限が切れた後です。証明は所持者が提示できる文書です。受領者は、agent_id に記載されたエージェントとやり取りしていることを確認する必要があります。特定の受領者宛てにするには audience を渡します。include_principal_payload が設定されていない限り、委任の metadata は開示されません(設定されている場合は署名対象のバイト列に含まれます)。レジストリは自らのデータベースを信頼します。ファイルを保護してください。既存の委任とそのハッシュは変更されません。発行記録は、新しい追記専用テーブル issued_attestations に保存されます(スキーマ v5)。詳しくは docs/mandate-attestation-spec.md をご覧ください。
パブリックレジストリ:アカウント不要のオンライン検証
AMR は各オペレーターの隣で stdio 経由で動作するため、ほかの人が照会することはできません。パブリックレジストリは、独立した読み取り専用の検証ポイントです。オペレーターがレジストリの署名済みスナップショットをエクスポートし、小規模な WSGI アプリケーション(標準ライブラリのみ)がそれを提供します。受信者はアカウントを作成せず、ブラウザー(HTML)またはスクリプト(JSON)から、委任識別子を確認するか、証明書を貼り付けて検証できます。
python -m amr.public_registry export --out amr_public_registry.jws # read-only, signed EdDSA
python -m amr.public_registry serve --export amr_public_registry.jws --public-key registry.pub
curl http://127.0.0.1:8080/mandates/<mandate-id>
# {"status": "active" | "revoked" | "expired" | "cut_by_parent" | ..., "verification_ms": 0.2, ...}
スナップショットには、委任ごとにエージェント、本人の SHA-256 参照値(識別子そのものは平文で保存されません)、対象範囲、日付、記録されたステータス、取消日、チェーンハッシュが含まれます。一方、対象範囲の文章、法的根拠、メタデータ、取消理由は含まれません。アプリケーションは、提供前にピン留めされたレジストリキーを使ってスナップショットを検証します。また、受信者が自分で検証できるよう、/snapshot で生データを提供します(JSON の回答を信頼することは、アプリケーションの運用者を信頼することを意味します)。
書き込み経路はなく、ログを保持せず、クライアントのアドレスを読み取ることもありません。すべての結果にスナップショットの日付と検証にかかった時間が表示されます。制限事項:スナップショット作成後に行われた取消は、次回のエクスポートまで反映されません。古いスナップショットからの回答を拒否するには、AMR_PUBLIC_SNAPSHOT_MAX_AGE_SECONDS を設定してください。デプロイとドメインの設定はオペレーターが行います。既存の委任とそのハッシュは変更されません。スキーマの変更もありません。docs/public-registry-spec.md を参照してください。
ビジョン:レジストリから実行強制へ
AMR は委任レジストリとして始まりました。委任の保存、検証、監査を行います。これは必要ですが、それだけでは不十分です。
問題は、委任の確認が任意の呼び出しだと、エージェントがそれを省略してしまうことです。実環境への導入から数週間で、システムは助言的なコンプライアンスへと形骸化します。
AMR は現在、構造的な実行強制を提供します。実行許可(issue_action_token)を発行するレイヤーです。有効な委任がなければ、許可はなく、アクションも実行できません。誰かが確認を推奨するからではなく、アーキテクチャ上、回避できないため、システムは委任なしでは動作しません。
| レイヤー | 機能 | ステータス |
|---|---|---|
| レジストリ | 委任の保存、検証、監査。SHA-256 チェーン。MCP ネイティブ。 | ✅ 提供中 |
| 実行強制 | 委任を必須とする実行許可(issue_action_token、check_action_token)。委任がなければアクションもありません。 | ✅ 提供中 |
| エコシステム | AMR はアクションの前に許可します。認証プロキシは、アクションの実行中に何が起きたかを証明します。 | 現在も互換性あり |
オープンソースのレジストリは引き続き無料です。実行強制レイヤーが商用製品です。
クイックスタート
git clone https://github.com/JC7333/amr.git
cd amr
uv sync
uv run amr
Claude Desktop との連携
Claude Desktop の設定ファイルに AMR を追加します。
場所: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"amr": {
"command": "uv",
"args": ["--directory", "C:\\dev\\amr", "run", "amr"]
}
}
}
Claude Desktop を再起動します。すべての AMR ツールをすぐに利用できるようになります。
ツール
create_mandate
AI エージェントが本人の代理で行動することを許可する、新しい法的委任を登録します。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
principal_id | str | マンデートを付与するプリンシパル。例:"user:audric" |
agent_id | str | 認可を受けるエージェント。例:"agent:korvex-advisor-v1" |
scope | str | エージェントに認可される操作 |
legal_basis_regulation | str | 規制または契約。例:"EU AI Act Art.26" |
legal_basis_article | str | 具体的な条項。例:"Art.26(1)(a)" |
duration_hours | float | 期間(時間単位、最大8760=1年) |
legal_basis_jurisdiction | str | 管轄区域コード(デフォルトは"EU") |
parent_mandate_id | str | null | 委任チェーンにおける親マンデートのUUID(親は委任を許可している必要があります) |
metadata | dict | 注釈用の任意の文字列キーと値のペア |
allowed_actions | list[str] | null | エージェントが要求できるアクションの種類:"invoice.pay"、"invoice.*"、または"*" |
forbidden_actions | list[str] | null | 許可されないアクションの種類(allowed_actionsより優先されます)。例:["agent.create"] |
delegation_allowed | bool | エージェントがサブマンデートを付与できるかどうか(デフォルトはfalse) |
max_delegation_depth | int | null | delegation_allowedを指定した場合、マンデート配下に作成できるサブマンデートの階層数。1~16(1=エージェントは委任できますが、そのサブエージェントは委任できません)。より深いサブマンデートはdelegation_depth_exceededで拒否されます。すべての祖先の上限がチェックされます。指定しない場合、このマンデートによる上限はありません。設定されている場合のみ、封印された境界に追加されるため、既存のマンデートのハッシュは変わりません。この上限はマンデートとともに封印され、その配下にサブマンデートを作成するたびにチェックされます(サブマンデートで宣言できる階層数は、祖先の残りの上限を超えられません)。トークン発行時には再チェックされず、親を宣言したチェーンにのみ適用されます。エージェントが別のルートを作成するのを防ぐのは、プリンシパルの署名です。このキーを含む境界は、古いAMRバージョンでは読み取れません。 |
max_amount | str | null | アクションごとの上限額(小数文字列)。例:"500" |
currency | str | max_amountのISO 4217コード(デフォルトは"EUR") |
amount_actions | list[str] | null | 上限額内のamountを必ず含める必要があるアクション(空の場合はすべて) |
period_max_amount | str | null | このマンデートとすべてのサブマンデートに適用される、period_days期間内の累積上限額(小数文字列)。例:"2000" |
period_days | int | null | period_max_amountのローリング期間(日数)。1~366日(period_max_amountを指定する場合は必須)。例:30 |
risk_classes | list[dict] | null | {name, actions, max_token_seconds, registry_check?}クラス。ここおよびすべてのサブマンデートで、対象アクションのトークン有効期間を制限します。registry_check: trueを指定すると、受信側にcheck_action_tokenで再チェックするよう求めます。例:[{"name": "irreversible", "actions": ["invoice.pay"], "max_token_seconds": 30, "registry_check": true}] |
principal_signature | str | null | prepare_mandate_signatureペイロードに対するプリンシパルのbase64url Ed25519署名(プリンシパルのキーが登録済みの場合は必須) |
signed_at | str | null | 署名済みペイロードに含めるタイムゾーン付きISO 8601タイムスタンプ(レジストリの時刻から15分以内) |
戻り値:
{
"status": "created",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"principal_id": "user:audric",
"agent_id": "agent:korvex-advisor-v1",
"scope": "Compare and recommend financial products to retail clients",
"perimeter": null,
"parent_mandate_id": null,
"principal_signature": null,
"expires_at": "2026-05-13T20:00:00+00:00",
"chain_hash": "a3f5c2d1e8b9..."
}
perimeterには、構造化された境界が指定されている場合、その値が格納されます(chain_hashに封印されます)。境界および委任に関するエラーは、安定したコードを含む{"error": "...", "code": "..."}を返します:perimeter_invalid、parent_mandate_not_found、parent_mandate_<status>、parent_mandate_expired、delegation_not_allowed、delegator_mismatch、sub_mandate_requires_perimeter、perimeter_exceeds_parent、limit_exceeds_parent、expires_after_parent。親より上のチェーンが不正な場合は、parent_mandate_<status>、parent_mandate_expired、またはdelegation_chain_too_deep(16階層を超過)を返します。
署名済み委任状の principal_signature は {"key_id", "signed_at"} です。署名エラー:principal_signature_required、principal_signature_incomplete、principal_key_not_registered、signed_at_invalid、principal_signature_stale、principal_signature_invalid、principal_signature_replayed。
register_principal_key
プリンシパルの Ed25519 公開鍵を、所持証明とともに一度だけ登録します。
| パラメーター | 型 | 説明 |
|---|---|---|
principal_id | str | プリンシパル。例:"user:audric" |
public_key | str | 生の 32 バイト公開鍵(base64url) |
proof_signature | str | {"context":"amr.principal_key.v1","principal_id":...,"public_key":...} の署名(正規化 JSON) |
{"status": "registered", "principal_id", "key_id", "registered_at", "chain_hash", "domain_proof"} を返します。domain_proof は、did:web:<domain> プリンシパルの場合を除き null です。この場合、鍵は https://<domain>/.well-known/did.json に記載されている場合のみ受け付けられます(AMR_DID_WEB_RESOLVE=1 が必要です)。domain_proof には did_document_url、did_document_sha256、verified_at が格納されます。docs/principal-signature-spec.md のセクション 1 bis を参照してください。
prepare_mandate_signature
create_mandate と同じ引数(任意の signed_at を追加。デフォルトは現在時刻)を受け取ります。書き込みは行わず、プリンシパルが create_mandate を呼び出す前に署名する正確なバイト列を {"payload", "payload_b64url", "signed_at"} として返します。
prepare_mandate_pdf
prepare_mandate_signature と同じ引数を受け取ります。書き込みは行わず、プリンシパルが読み、独自の署名ツール(たとえば PAdES 署名)で署名するための委任状を PDF として返します:{"pdf_base64", "filename", "pdf_sha256", "attachment_name", "payload_sha256", "payload", "payload_b64url", "signed_at"}。PDF には prepare_mandate_signature の正確なペイロードが添付ファイル amr-mandate.json として含まれ、すべてのページに SHA-256 が印字されます。同じ引数と signed_at を指定すると、常に同じ PDF が生成されます。レジストリはこの PDF に署名せず、このバージョンでは PDF に施された署名も検証しません。委任状は引き続き、同じペイロードに対するプリンシパルの Ed25519 署名によって受け付けられます。この署名の signed_at は、レジストリの時計から AMR_PRINCIPAL_SIGNATURE_MAX_AGE_SECONDS(デフォルトは 900 秒)以内である必要があります。この時間内に生成、署名、登録を行ってください(docs/principal-signature-spec.md のセクション 2 bis を参照)。
verify_mandate
AI エージェントに現在有効で、期限切れでない委任状があるかを確認します(サブ委任状の場合は、その上位にあるすべての委任状も有効で期限切れでない必要があります)。アクションが委任範囲に含まれるかは確認しません。確認するのは issue_action_token です。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
agent_id | str | 確認するエージェント。例:"agent:korvex-advisor-v1" |
action | str | エージェントが実行しようとしているアクション |
context | str | 監査ログ用の任意のコンテキスト |
戻り値:
{
"authorized": true,
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"reason": "Active mandate found",
"scope": "Compare and recommend financial products to retail clients",
"perimeter": null,
"parent_mandate_id": null,
"expires_at": "2026-05-13T20:00:00+00:00"
}
log_action
有効な委任状のもとでエージェントのアクションを記録します。前のアクションと暗号学的に連鎖します。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | アクションの実行に使用した委任状の UUID |
action | str | 実行したアクションの説明 |
evidence | str | 任意の参照情報または証拠。例:"email:msg_abc123" |
result | str | 任意の結果。例:"Delivered" |
戻り値:
{
"status": "logged",
"action_id": "7f3e9b2a-...",
"mandate_id": "550e8400-...",
"action": "Generated investment recommendation for Product X",
"chain_hash": "c8d7e6f5..."
}
委任状は有効で、取り消されておらず、期限切れであってはなりません。サブ委任状の場合は、その上位にあるすべての委任状も同じ条件を満たす必要があります。親委任状を取り消すか、期限切れにすると、その配下のブランチ全体でログ記録が停止します。その場合、拒否理由と連鎖を途切れさせた委任状が次のように示されます:{"error": "...", "reason": "parent_mandate_revoked", "refused_by": "<parent id>"}(ほかに parent_mandate_expired、parent_mandate_<status>、parent_mandate_not_found、delegation_chain_too_deep があります)。
revoke_mandate
プリンシパルの停止ボタンです。プリンシパルが示した理由とともに、委任の最終的な取り消しを記録します。追記のみで、mandate_revocations に連鎖する行と、revoked 委任イベントを追加します。委任の行は変更されず、そのハッシュも変わりません。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | 取り消す委任の UUID |
reason | str | 記録される取り消し理由(1~500 文字) |
principal_signature | str | null | 取り消しペイロードの Ed25519 署名(プリンシパルに登録済みのキーがある場合は必須) |
signed_at | str | null | ペイロードに設定される signed_at |
委任を取り消せるのは、その委任自身のプリンシパルのみです(サブ委任の場合は、それを委任したエージェントです)。署名ポリシーは create_mandate と同じです。署名する正確なバイト列を生成するには、prepare_revocation_signature(mandate_id, reason, signed_at=None) を使用します。
呼び出しが返った時点での効果: issue_action_token と issue_mandate_attestation は、その委任(mandate_status_revoked)およびその配下のすべてのサブ委任(parent_mandate_revoked)を拒否します。verify_mandate はその委任を返さなくなり、その配下にサブ委任を作成できなくなります。log_action はその委任と配下のすべてのサブ委任を拒否し、get_proof と export_insurer_dossier は取り消しを報告します。発行済みトークンを取り消すことはできず、exp までは有効です。レスポンスにはその数と最も遅い有効期限が示されます。ただし、受信側がアクションを実行する際に check_action_token でトークンを再確認する場合は除きます(下記を参照)。オフラインで確認する受信側に対しては、発行済みの委任アテステーションも exp まで(デフォルトでは 15 分)有効です。レスポンスには、委任とそのサブ委任についても、その数と最も遅い有効期限が示されます。
戻り値:
{
"status": "revoked",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"principal_id": "org:clinic",
"reason": "agent exceeded its order limit",
"revoked_at": "2026-10-23T20:30:01.123456+00:00",
"principal_signature": null,
"chain_hash": "a3f1...",
"outstanding_tokens": {"still_valid": 1, "last_expires_at": "2026-10-23T20:34:12+00:00"},
"outstanding_attestations": {"still_valid": 0, "last_expires_at": null}
}
トークンの有効期間は最大でも AMR_TOKEN_LIFETIME_SECONDS(デフォルトでは 300 秒)であり、委任または委任チェーン上のいずれかの上位委任の有効期限を超えることはありません。また、そのチェーンでアクションタイプに適用される最短のリスククラス(risk_classes)の有効期限も超えません。呼び出し元の lifetime_override_seconds で短縮することはできますが、延長することはできません。デフォルトより長いトークンを要求していた呼び出し元には、デフォルトの有効期間が適用されるようになるため、これは破壊的変更です。取り消し後に発行済みトークンが引き続き有効な期間は、チェーンの深さにかかわらず、最大でもこの有効期間です。docs/revocation-spec.md を参照してください。
contest_action
エージェントがすでに行動し、本人がその行動に異議を唱えています。委任を取り消せば、その後の行動は停止します。contest_action は、log_action で記録された過去の行動のうち、どの行動に、いつ、なぜ、誰が異議を唱えたかを記録します。追記専用です。action_contests に連鎖する行が追加され(行動ごとに1件。取り消しや編集はできません)、action_contested 委任イベントが記録されます。行動ログ、委任、およびすでに記録されたすべてのハッシュは変更されません。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | 行動が記録された委任の UUID |
action_id | str | log_action が返す action_id |
reason | str | 行動に異議を唱える理由(1~500文字) |
response_days | int | respond_by までの日数(1~365)。オペレーターが選択します |
contested_by | str | null | 異議を唱える本人。デフォルト:委任の本人 |
principal_signature | str | null | 異議申し立てペイロードの Ed25519 署名(異議を唱える本人に登録済みの鍵がある場合は必須) |
signed_at | str | null | ペイロードに設定する signed_at |
contested_by には、委任の本人、または委任チェーン上でその委任より上位にある任意の委任の本人を指定できます(組織がサブエージェントの行動に異議を唱える場合)。これらの委任のステータスは問いません。署名ポリシーは create_mandate および revoke_mandate と同じです。prepare_contest_signature を使ってバイト列を作成してください(同じ引数に加えて signed_at=None)。
respond_by = contested_at + response_days はオペレーターが独自に設定する期限です。たとえば、指示された内容を保持または使用する前に顧問が設けた猶予期間を過ぎると、その内容を受け入れたと解釈される可能性があります。AMR は法的な期限を算出せず、法的な期限についていかなる主張もしません。 異議申し立てによって行動が取り消されたり、委任が取り消されたりすることはありません。委任を取り消すには revoke_mandate を呼び出してください。
戻り値:
{
"status": "contested",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"action_id": "0b6f7c1e-3d0a-4c55-9a43-5d1f1f0e2a10",
"action_chain_hash": "9c2e...",
"contested_by": "org:clinic",
"reason": "order placed above the agreed quantity",
"response_days": 14,
"contested_at": "2026-11-01T21:30:00+00:00",
"reminder": {"respond_by": "2026-11-15T21:30:00+00:00", "days_left": 14, "deadline_passed": false},
"principal_signature": null,
"chain_hash": "5be0..."
}
エラー(code):invalid_input、mandate_not_found、action_not_found(行動が別の委任に属する場合も含む)、contester_not_in_chain、action_already_contested、および revoke_mandate の本人署名関連のコード。
リマインダー: list_action_contests(mandate_id=None, contested_by=None, due_within_days=None)(読み取り専用。mandate_id、contested_by、または両方を指定)は、respond_by が最も近い順に異議申し立てを返します。各項目には reminder.days_left(期限経過後は負の値)と reminder.deadline_passed が含まれます。たとえば due_within_days=3 を指定して毎朝呼び出すなど、定期的に実行してください。get_proof は、action_contests にある委任の異議申し立てを一覧表示し、chain_integrity.contests_intact でそれらを再検証します。docs/action-contest-spec.md を参照してください。
check_action_token
エージェントのアクションを受け取る側は、取り消せない手順を実行する直前に、レジストリでトークンを再確認します。トークンに amr_registry_check: true(リスククラスに registry_check が指定されている場合)が含まれているときは必須です。どのトークンでも実行できます。
読み取り専用です。
| パラメーター | 型 | 説明 |
|---|---|---|
token | str | issue_action_token が返した JWS |
audience | str | 呼び出し元を示します。トークンの aud と一致する必要があります |
expected_action_hash | str | null | これから実行する正規化されたアクションの SHA-256。amr_action_hash と一致する必要があります |
max_token_age_seconds | int | null | 独自に設定する、より厳しい上限(1~86400)。それより前に発行されたトークンは拒否します。有効期限 exp が延長されることはありません |
署名(EdDSA のみ、このレジストリの鍵を使用)、iss、aud、exp、nbf、トークンがレジストリによって発行されたものであることを検証し、その後、委任とその上位にあるすべての委任が引き続き有効で、取り消されておらず、期限切れでないことを検証します。
{"valid": true, "reason": "ok", "jti": "...", "mandate_id": "...", "agent_id": "agent:billing",
"action_type": "invoice.pay", "registry_check_required": true,
"expires_at": "2026-10-29T21:30:30+00:00", "checked_at": "2026-10-29T21:30:12.400000+00:00"}
{"valid": false, "reason": "mandate_status_revoked", "jti": "...", "mandate_id": "...",
"checked_at": "2026-10-29T21:30:14.100000+00:00"}
レジストリはデータベースを読み取り専用で開き、確認のために何も書き込みません。また、応答には署名が付与されないため、誰かが確認したことの証明にはなりません。レジストリには独自の経路で問い合わせてください。トークンの保持者であるエージェントが中継した確認結果は決して受け入れないでください。registry_check を持つ委任が作成されると、それより古い AMR バージョンではその境界を読み取れず、フェイルクローズします。docs/token-issuance-spec.md の「実行時のレジストリ確認」を参照してください。
get_proof
すべてのアクションと暗号学的なチェーン検証を含む、委任の完全な監査バンドルである Proof Pack を生成します。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | 証明する委任の UUID |
format | str | 出力形式(現在は "json") |
戻り値:
{
"proof_pack_version": "0.1.0",
"generated_at": "2026-04-13T18:00:00+00:00",
"mandate": { "...": "full mandate details" },
"delegation_chain": {"broken": false, "reason": null, "refused_by": null},
"actions": [ "...list of all logged actions..." ],
"events": [],
"action_contests": [],
"chain_integrity": {
"actions_chain_valid": true,
"principal_signature_valid": null,
"revocation_signature_valid": null,
"contests_intact": true,
"total_actions": 5,
"total_events": 0
},
"compliance_notes": {
"ai_act_art26": "This Proof Pack documents the mandate chain for AI Act Art.26 compliance.",
"retention": "Logs must be retained for minimum 6 months per AI Act Art.26(6)."
}
}
mandate.principal_signature には、委任者の署名、公開鍵、鍵の所持証明、署名対象のバイト列(または null)が格納されます。principal_signature_valid は、それらを保存されている委任と照合して再確認します。署名が一致しない場合、または委任の作成時に委任者が鍵を持っていたにもかかわらず署名がない場合は false です。その時点で委任者が鍵を持っていなかった委任では null です。
revoke_mandate の実行後、mandate.status は "revoked" となります(保存値は mandate.stored_status に保持されます)。mandate.revocation には revoked_at、reason、取り消しに対する委任者の署名(または null)、チェーンハッシュが格納されます。revocation_signature_valid は、その署名を委任者の鍵と照合して再確認します(確認対象がない場合は null)。
delegation_chain は、サブ委任の上位にあるチェーンが引き続き有効かどうかを示します。
委任の上位にあるものが取り消し済み、期限切れ、非アクティブ、または見つからない場合は、{"broken": true, "reason": "parent_mandate_revoked", "refused_by": "<parent id>"} となります(サブ委任自体の mandate.status は変わりません。チェーンの切断はその上位で発生します)。
それ以外の場合、およびルート委任の場合は常に、{"broken": false, "reason": null, "refused_by": null} となります。
issue_mandate_attestation
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | 証明する委任の UUID |
agent_id | str | 委任のエージェントと一致する必要があります |
audience | str | null | 宛先となる受信者(任意) |
lifetime_seconds | int | null | 有効期間を短くする場合に指定します(設定済みの上限を超えることはありません) |
include_principal_payload | bool | 委任者の署名と署名対象のバイト列も含めます(metadata が開示されます)。既定値は false です |
{"attestation", "jti", "issued_at", "expires_at", "key_id", "issuer"}、または {"denied": true, "reason", "mandate_id"} を返します。後者の例は mandate_not_found、agent_mismatch、mandate_status_<status>、mandate_status_revoked、mandate_expired、parent_mandate_<status>、parent_mandate_revoked、principal_signature_invalid です。親が原因の場合は refused_by も含まれます(一覧は docs/mandate-attestation-spec.md を参照)。
get_registry_public_key
パラメーターはありません。{"issuer", "key_id", "algorithm": "EdDSA", "public_key_pem", "public_key_jwk"} を返します。受信側がアテステーションをオフラインで検証するために必要な情報です。
export_insurer_dossier
ある期間における1つのマンデートの署名付きドシエをエクスポートします。AI エージェントについて保険会社や監査人が求める資料です。読み取り専用で、レジストリ内の事実のみを使用します。
パラメーター:
| パラメーター | 型 | 説明 |
|---|---|---|
mandate_id | str | マンデートの UUID |
period_start | str | null | ISO 8601 形式の開始日時(タイムゾーンのない値は UTC として扱います。日付のみの値は受け付けません)。デフォルトはマンデートの作成日時です |
period_end | str | null | ISO 8601 形式の終了日時(タイムゾーンのない値は UTC として扱います。日付のみの値は受け付けません)。デフォルトは現在日時です |
format | str | "json"(デフォルト)、または印刷可能なページも取得する場合は "html" |
ドシエの内容: マンデート(本人、エージェント、スコープ、申告された法的根拠、日付)、その適用範囲(許可および禁止されたアクションの種類、委任権、金額の上限)、生成時点で有効かどうか、および無効な理由(mandate_revoked、mandate_expired、parent_mandate_revoked などの上位のマンデートでの連鎖切れ)、各サブマンデートの深さ、適用範囲、有効状態、および期間中に記録されたアクション数(マンデートが打ち切られると、そのブランチ全体も打ち切られます)、期間中に当該マンデートのエージェント自身が記録したアクション、マンデートとそのサブマンデートの期間中のステータスイベントとアクショントークン、整合性チェック(アクションログのチェーン、本人の署名、最後のチェーンハッシュ)、およびドシエの制限事項を記載した固定リスト(例:拒否されたトークン要求は記録されないため、ドシエに記載されるのは発行済みトークンであり、ブロックされたアクションではありません)。
戻り値:
{
"dossier": { "dossier_version": "1.0", "period": {}, "mandate": {}, "status": {},
"integrity": {}, "sub_mandates": [], "events": [], "actions": [],
"tokens": [], "limits": [] },
"dossier_sha256": "hex SHA-256 of the canonical dossier",
"signature": { "jws": "...", "algorithm": "EdDSA", "key_id": "...",
"public_key_pem": "..." },
"html": "only when format is \"html\""
}
署名は JWS(RFC 7515、EdDSA/Ed25519。アクショントークンと同じレジストリキー)で、そのペイロードはドシエの正規化された JSON です。オフラインで検証するには、次のようにします。
from amr.proof.insurer_dossier import verify_dossier
dossier = verify_dossier(jws, registry_public_key_pem) # raises if anything is off
エクスポートによって署名キーが作成されることはありません。キーがないレジストリではエラーが返されます。レジストリの公開キーは別経路で取得してください。エクスポート内の public_key_pem は便宜上のものであり、自身のキーを持つドシエだけでは、誰が署名したかを証明できません。HTML ページは自己完結型の印刷用ビューで(外部リソースはありません。ブラウザーから PDF に印刷できます)、ドシエの SHA-256 とキー ID を表示します。証明となるのは JSON の署名のみです。docs/insurer-dossier-spec.md を参照してください。
仕組み
┌─────────────────────────────────────────────────────────────────────┐
│ PRINCIPAL │
│ (user:audric, org:acme-corp) │
└──────────────────────────┬──────────────────────────────────────────┘
│ create_mandate()
▼
┌─────────────────────────────────────────────────────────────────────┐
│ MANDATE (SHA-256 chained) │
│ id · principal · agent · scope · legal_basis · expires_at │
│ chain_hash = SHA256(mandate_data + prev_hash) │
└──────────────────────────┬──────────────────────────────────────────┘
│ verify_mandate() → authorized: true
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AGENT │
│ (agent:korvex-advisor-v1) │
└──────────────────────────┬──────────────────────────────────────────┘
│ log_action() × N
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ACTION LOG (append-only, SHA-256 chained) │
│ action_1 ──hash──▶ action_2 ──hash──▶ action_3 ──hash──▶ ... │
│ Each action links to the previous via chain_hash │
└──────────────────────────┬──────────────────────────────────────────┘
│ get_proof()
▼
┌─────────────────────────────────────────────────────────────────────┐
│ PROOF PACK (JSON) │
│ mandate + actions + chain_integrity + compliance_notes │
│ Ready for regulatory audit, eIDAS submission, or archival │
└─────────────────────────────────────────────────────────────────────┘
セキュリティ
-
Pydantic v2 による検証 — すべてのツール入力は、データベースにアクセスする前に検証されます。不明なフィールドは拒否されます(
extra="forbid")。期間、文字列の長さ、UUID 形式はモデル層で強制されます。 -
パラメーター化 SQL のみを使用 — すべてのデータベースクエリーでは
?プレースホルダーを使用します。SQL 内での文字列補間や f 文字列は使用しません。各コミットでruffの S608 ルールにより強制されます。 -
追記専用テーブル —
mandatesテーブルとaction_logsテーブルがUPDATEまたはDELETEされることはありません。監査証跡は設計上、不変です。ステータスの変更には別のmandate_eventsテーブルを使用します。 -
SHA-256 暗号チェーン — 各マンデートと各アクションログエントリーは、git 形式の SHA-256 ハッシュによって直前のものと連結されます。改ざんがあると、それ以降のすべてのハッシュが無効になり、証跡から改ざんを検知できます。
-
stdio トランスポートのみ — AMR は stdio 経由でローカル MCP サーバーとして動作します。リスニングポート、外部からのネットワーク接続、ツールからの外部 HTTP 通信はありません。ただし、オプトインの例外が1つあります。オペレーターが
AMR_ISSUE_TOKENを設定した場合に限り、report_issueが GitHub API に HTTPS リクエストを1回送信します。攻撃対象領域は最小限です。
規制上の背景
| 規制 | AMR との関連性 |
|---|---|
| EU AI Act Art.26 | 高リスク AI システムの導入者は、指示に従ってシステムを使用し、人間による監視を割り当て、システムが生成するログを保持する必要があります。AMR は、監視の証拠として、各エージェントの背後にある委任とそのアクションを記録します。2027 年 12 月 2 日(Annex III のシステム)および 2028 年 8 月 2 日(Annex I のシステム)から適用されます。Regulation (EU) 2026/1744。 |
| EU AI Act Art.26(6) | 高リスクシステムが生成するログは、少なくとも 6 か月間保持する必要があります。AMR の追記専用 SQLite データベースと Proof Pack のエクスポートは、この要件を満たすのに役立ちます。 |
| eIDAS 2.0 | 自然人または法人に代わって行動する AI エージェントへの電子的な委任です。AMR の委任チェーンは、eIDAS の電子的委任の信頼フレームワークに対応しています。 |
| 罰金 | 第 26 条への不遵守には、1,500 万ユーロまたは全世界の年間売上高の 3%のいずれか高い方の罰金が科される可能性があります(Art. 99(4)。中小企業およびスタートアップの場合は、Art. 99(6) に基づき、いずれか低い方)。 |
ロードマップ
| 状況 | 機能 |
|---|---|
| リリース済み | 委任レジストリ · SHA-256 チェーン · Proof Pack JSON · 構造化された権限範囲 · 下位委任と委任チェーン · 取り消し · 係争中のアクション · 署名付きアクショントークン(強制適用)と実行時のチェック · オフライン委任証明 · 署名付き保険会社向け資料(JSON および印刷可能な HTML) · 委任者の署名と did:web キー · 読み取り専用の公開レジストリ · セクターテンプレート(医療) · MCP SDK v1 および v2 · PyPI パッケージ mandatia |
| 予定 | PDF Proof Pack のエクスポート · MCP クライアント向けリモートトランスポート · PostgreSQL バックエンド · マルチテナント対応 · MCP と並行する REST API · eIDAS 2.0 適格電子署名 · 国境を越えた委任の承認 · Webhook 通知 · ダッシュボードとアラート |
開発
# Install all dependencies including dev extras
uv sync --all-extras
# Run the full test suite
uv run pytest -v
# Run with short traceback on failure
uv run pytest -v --tb=short
# Lint and security check (src + tests)
uv run ruff check src/ tests/
# Auto-fix safe issues
uv run ruff check --fix src/ tests/
# Start the MCP server (stdio — normal to wait for input)
uv run amr
プロジェクト構成
src/amr/
├── config.py # Settings via pydantic-settings (env prefix: AMR_)
├── server.py # MCP server entrypoint (stdio transport; mcp 1.x or 2.x)
├── models/mandate.py # Pydantic models: MandateCreate, Mandate, ActionLog
├── crypto/chain.py # compute_hash() and verify_chain() — stdlib only
├── db/engine.py # init_db(), get_db(), get_last_mandate_hash()
├── tools/
│ ├── create_mandate.py
│ ├── prepare_mandate_pdf.py # the mandate as a PDF the principal signs itself
│ ├── verify_mandate.py
│ ├── log_action.py
│ ├── get_proof.py
│ ├── check_action_token.py # receiver re-checks a token when it acts
│ ├── issue_mandate_attestation.py # attestation + registry public key
│ ├── revoke_mandate.py
│ ├── contest_action.py # contested acts and their response deadline (reminder)
│ ├── report_issue.py # network call, opt-in (AMR_ISSUE_TOKEN)
│ └── export_insurer_dossier.py
├── attestation.py # offline attestation verifier (no DB, no network)
├── did_web.py # did:web key check, network opt-in (AMR_DID_WEB_RESOLVE)
├── mandate_pdf.py # deterministic mandate PDF, payload attached (stdlib only)
├── verify_attestation.py # python -m amr.verify_attestation
├── proof/insurer_dossier.py # Signed insurer dossier: canonical form, JWS, print view
└── templates/ # Sector mandate templates (agent-sante-rgpd)
tests/
├── conftest.py # Isolated temp DB fixture (autouse)
└── test_*.py # One file per tool or feature (`uv run pytest -q`)
環境変数
| 変数 | デフォルト値 | 説明 |
|---|---|---|
AMR_DB_PATH | amr_mandates.db | SQLite データベースファイルへのパス |
AMR_LOG_LEVEL | INFO | ログの詳細度 |
AMR_SERVER_NAME | Agent Mandate Registry | MCP サーバーの表示名 |
AMR_REQUIRE_PRINCIPAL_SIGNATURE | false | 委任者が署名していないすべての委任を拒否します |
AMR_PRINCIPAL_SIGNATURE_MAX_AGE_SECONDS | 900 | signed_at とレジストリの時計の間に許容される時間差 |
AMR_ISSUE_TOKEN | 未設定 | report_issue が自ら Issue を作成できるようにする GitHub トークン(細かな権限設定、Issues: write、単一リポジトリ)。プロセス環境からのみ読み込まれ、.env からは読み込まれません。未設定の場合、ネットワーク呼び出しは行われません |
AMR_DID_WEB_RESOLVE | 未設定 | 1 を設定すると、register_principal_key が did:web 委任者の DID ドキュメントを読み込みます(そのドメインへの HTTPS GET を 1 回実行)。プロセス環境からのみ読み込まれ、.env からは読み込まれません。未設定の場合、did:web キーは拒否されます |
AMR_ISSUE_REPOSITORY | JC7333/amr | report_issue が Issue を作成するリポジトリ(owner/name) |
AMR_ATTESTATION_LIFETIME_SECONDS | 900 | 委任証明の最長有効期間 |
AMR_PUBLIC_EXPORT_PATH | amr_public_registry.jws | python -m amr.public_registry export が書き込み、そのアプリで提供される署名付きスナップショット |
AMR_PUBLIC_KEY_PATH | amr_signing_key.pub | レジストリの公開鍵。公開レジストリアプリはこの鍵を固定してスナップショットを検証します |
AMR_PUBLIC_SNAPSHOT_MAX_AGE_SECONDS | 未設定 | 公開レジストリ:この経過時間を超えた場合、状態ではなく snapshot_too_old を返します |
ライセンス
Apache License 2.0 — 条項の全文については、LICENSE をご覧ください。
商用製品で自由に使用できます。EU AI Act のオープンソースに関する規定と互換性があります。
⚠️ 免責事項: AMR は技術インフラストラクチャツールです。法的助言を構成するものではありません。EU AI Act、eIDAS 2.0、その他の規制への準拠は、引き続き運用者の責任です。具体的な規制上の義務については、資格を有する法律顧問にご相談ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。