Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help


id: ADR-017 title: 受信認証は、認可の前に正規のプリンシパルを解決する date: 2026-08-14 status: 提案中 relates-to:

  • ADR-010
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7141
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8289
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8290
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8076
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7142
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6996
  • https://github.com/zeroclaw-labs/zeroclaw/pull/8063
  • https://github.com/zeroclaw-labs/zeroclaw/pull/8272
  • crates/zeroclaw-api/src/principal.rs
  • crates/zeroclaw-api/src/grants.rs
  • crates/zeroclaw-runtime/src/security/auth_provider.rs
  • crates/zeroclaw-runtime/src/security/principal_resolver.rs
  • crates/zeroclaw-runtime/src/rpc/dispatch.rs
  • crates/zeroclaw-runtime/src/rpc/wss.rs
  • crates/zeroclaw-memory/src/sqlite_permissions.rs

ADR-017: 認可の前に、受信認証で正規のプリンシパルを解決する

コンテキスト

ZeroClawには、外部のアクターがデーモンに到達する方法がいくつかあります。ローカルRPC、リモートWSS、Webゲートウェイ、CLIおよびZerocodeクライアント、チャネル、そして将来のエージェント間パスです。承認済みのRFC #7141 以前は、これらの経路が「誰が行動しているのか?」と「そのアクターは何をしてよいのか?」という問いに対して、一元的に強制される共通の答えを持っていませんでした。

TLS とリコネクト用トークンだけでは不十分です。TLS は接続を保護できても、接続してきたクライアントが ZeroClaw の権限を持つことを証明するものではありません。また、既存の tui_id / tui_sig の仕組みはリコネクトの継続性を担保するものであり、独立した身元証明ではありません。リモートの WSS クライアント、ブラウザユーザー、ローカルプロセス、チャンネル送信者、サービスクライアントはいずれも、特権的なランタイム処理を開始する前に、同一の認可モデルに収束させる必要があります。

リスクは一つのルートで認証が欠けていることだけではありません。より大きなリスクは、並行して存在するセキュリティ機構です。ネイティブのペアリングトークン、ピア認証情報、SSH鍵、パスワード、OIDCのsubject、チャネルの送信者、サービス認証情報がそれぞれ独自のユーザーID、ロール体系、所有者キー、フォールバック動作を持ち込むことになります。そうなると、あるプロバイダーのadminクレーム、一つのローカルユーザー名、あるいは使い回されたsubject文字列が、別の機構が依存しているポリシーを意図せず迂回してしまう可能性があります。

承認済みのRFC #7141により、アーキテクチャの方向性が決定されました。同RFCでは、プロバイダーが認証情報を検証すること、共有リゾルバーが検証済みのIDを正規の ZeroClaw プリンシパルおよびパーミッションプロファイルの付与へマッピングすること、そしてランタイムサーフェスは認証情報を自ら再解釈するのではなく、解決済みのプリンシパルを利用することを求めています。実装の順序は #8289 で管理され、セッション、メモリ、送信者ごとの認可に関する詳細な作業は #8290 で追跡されています。本ADRは、ロールアウトが完了したとは主張せず、恒久的な決定事項を記録するものです。

決定

受信アイデンティティを検証、解決、適用の各段階に分割する

Inbound authentication(受信認証)は3つの独立した段階で構成されています:

  1. AuthProvider は1つの認証情報を検証し、プロバイダーの出所情報、subject、actor の種別、claims またはローカルのロスター紐付け、有効期限、再検証メタデータを含む認証済みの identity を返します。
  2. One shared ZeroClaw リゾルバーが、その認証済みIDを正規の PrincipalId と現在の権限プロファイルの付与内容にマッピングします。
  3. Dispatch、gatewayハンドラー、セッション、メモリ、ツール、設定、その他の特権ランタイムサーフェスは、解決されたプリンシパルと付与された権限を強制します。

Rust 実装では内部で型を統合してもよいが、権限の境界は分離されたままである。プロバイダーはアイデンティティを検証する。プロバイダーは ZeroClaw のランタイム権限付与を発行せず、IdP のロールを権限として解釈し直すこともなく、共有リゾルバーを迂回することもない。

正規のプリンシパルを使用し、文字列の偶然の一致によって衝突しないようにする

ZeroClaw における principal(プリンシパル)とは、認証が成功した後のアクターを識別する永続的なIDです。principal のIDは、デプロイメント内で一意に曖昧さなく識別されます。

OIDCの人間のIDは、検証済みの発行者(issuer)とsubの組み合わせによって識別され、sub単独では識別されません。プロバイダーのエイリアスは監査出力に表示される場合がありますが、異なる発行者に由来する同一のsub文字列を、同じアクターとして扱えるようにするものではありません。

ローカルのアイデンティティは、明示的なロスター設定を通じてプリンシパルに対応付けられます。異なるローカル認証情報が同じプリンシパルに解決されるのは、設定によってそれらが紐付けられている場合に限ります。ロスターの表示名を変更する際は、安定したプリンシパル識別子を維持するか、所有するセッション、メモリ、承認、監査の各レコードをアトミックに移行しなければなりません。

client_credentials はヒューマンユーザーではなくサービスプリンシパルに解決されます。クレームの名前が似ているという理由で、サービスプリンシパルがブラウザセッション、対話型ユーザーを前提とした仮定、または人間のプライベートなメモリを引き継いではなりません。

ネイティブのペアリングは互換性のための経路として引き続き利用できます。後続の明示的なトークンからプリンシパルへのマッピングが設定されていない限り、共有ペアリングトークンは名前付きの個人ではなく共有オペレーターとして解決されます。

プロバイダーをまたいだ文字列の一致では、アカウントが紐付けられることは決してありません。プロバイダー間のアカウント連携には、明示的な設定と監査可能な移行パスが必要です。

権限プロファイルを、実行時の権限付与で使える唯一の語彙にする

パーミッションプロファイルは、実行時の認可に使われる唯一の語彙です。プロバイダーの生のクレーム、IdP のグループ、ローカルのユーザー名、チャネルの送信者、サービスクライアント名は、共通のリゾルバーによって ZeroClaw のパーミッションプロファイルに対応付けられるまで、いかなる権限も付与しません。

1つのIDが複数の権限プロファイルに対応する場合、初期リゾルバーは明示的な付与を決定的な和集合(ユニオン)で結合します。きめ細かなセレクターは、該当するリソースの付与との積集合(インターセクション)によって合成されます。空のセレクターリストはインスタンスを一切付与せず、広範なアクセスには明示的なワイルドカード、全セレクター、または管理者権限の付与が必要です。

特権を伴うRPC、ゲートウェイ、ツール、設定、セッション、メモリの操作はすべて分類され、デフォルトで拒否されます。分類されないまま追加されたルートやメソッドは、暗黙的に許可されることはありません。管理者アクセスは所有権を消去しません。プリンシパルをまたぐアクセスには明示的な管理者による付与が必要であり、監査イベントが生成されます。

Explicit deny のセマンティクス、プロバイダー固有のポリシー言語、より広範なポリシー管理 API、および異なる優先順位ルールは、それぞれ個別に判断すべき事項です。これらは本 ADR の副次的な効果として生じるものではありません。

認証と許可を、取り消し可能な状態に保ってください

initialize は RPC の認証ハンドシェイクです。認証を完了するために必要な最小限のメソッドのみが、プリンシパルがバインドされる前に実行されます。特権メソッドはすべて、認証されていない呼び出し元を拒否します。

資格情報のルーティングは明示的に行われます。資格情報の形式がプロバイダーを安全に識別できない場合、ハンドシェイクで意図したプロバイダーエイリアスを指定します。不透明なベアラートークンを、すべてのイントロスペクションエンドポイントに送信することはありません。選択された方式またはプロバイダーで失敗しても、共有オペレーターの権限やより広範な権限にフォールバックすることはありません。

確立済みの接続は、無期限の認可スナップショットを保持しません。認可ポリシーの世代が変わった後、次の特権操作の前に、ランタイムは現在の権限プロファイルとクレーム対応付けの設定から実効的な権限を再解決します。プロファイル、対応付け、ロスター項目、プロバイダー、またはペアリングトークンを削除または絞り込んだ場合、その影響は再接続やデーモンの再起動を待つのではなく、文書化された世代または再検証の境界で既存の認可に反映されなければなりません。

既存の接続に対する認証情報の有効期限切れとプロバイダー側の失効は、プロバイダーが実際に保証できる範囲内で適用されます。正規の Principal、所有権記録、ログ、監査記録は引き続き機密情報を含みません。ライブの再検証にベアラー資格情報または同等のシークレットハンドルが必要な場合、プロバイダーは、サポートされているシークレットストレージの境界を通じて、プロバイダーが所有し接続単位にスコープされた再検証コンテキストに、その最小限の資格情報のみを保持します。通常のランタイムコンシューマーはこれを読み取ることができず、切断、認証情報の有効期限切れ、プロバイダーの削除、または失効時に破棄されます。

OIDCトークンの用途は明示的に定める。ブラウザでの認可コード+PKCEでは、IDトークンを認証イベントの証拠として検証し、ZeroClawセッションを確立する。APIおよびRPCのベアラー経路は、ZeroClaw向けに発行されたアクセストークンのみを受け入れる。Device Authorization Grantはブラウザを使えない人間のクライアント向けであり、client_credentialsはサービスプリンシパル向けである。オフラインのJWT検証は、トークンの有効期限と設定された最大認証有効期間によって制限される。より迅速な失効が必要なデプロイメントでは、イントロスペクション、バックチャネル失効、またはその他のライブな権威を使用しなければならない。

セッションおよびメモリのストレージ境界で、プリンシパルの所有権を強制する

認証済みのすべてのセッションは、正規のプリンシパルによって所有されます。セッションの検索、承認、アタッチ、再開、変更、削除の各操作は、成功する前に所有者が一致している必要があります。不明、競合、または所有者が未設定のレガシーレコードは、文書化された移行処理によって shared-operator プリンシパルに対応付けられない限り、スコープ付きプリンシパルに対してフェイルクローズ(失敗扱い)となります。

プライベートメモリは、プリンシパルとエージェントの組み合わせをキーとして管理され、明示的な管理者による付与で許可されない限り、そのプリンシパルにのみ表示されます。共有エージェントメモリは別のスコープであり、有効化され付与された場合にのみ表示されます。

プリンシパルの所有権は追加のストレージ次元であり、agent、session、namespace、tenant の各次元を置き換えるものではありません。プライベートメモリの読み取り、書き込み、upsert、削除では、アトミックなストレージ述語にプリンシパルの所有権を含めます。事前チェックの後により広範な変更を行う方法や、読み取りの後に事後フィルタリングを行う方法では不十分です。

Internally initiated work must not choose an owner by accident. Scheduled, SOP-initiated, or other non-interactive runs that write owned session or memory state need an explicit principal rule before the first implementation slice depends on a default.

Keep provider and transport implementations separate from authorization authority

Translation:

プロバイダーおよびトランスポートの実装を、認可の権限から分離しておく

すべての受信インターフェースは同じプリンシパルおよびパーミッションプロファイルのモデルを利用しますが、トランスポートの実装まで同じである必要はありません。ローカルRPCはピア資格情報を使用してもよく、リモートWSSはネイティブのペアリングまたはOIDCを使用してもよく、Webゲートウェイはルーター境界で認証を行い、CLIまたはZerocodeクライアントはプロバイダーに適したログインフローを提供します。

ネイティブのペアリングとローカルのピア認証情報は、最初の強制適用ロールアウトにおいて必須の互換性パスです。これにより、リモートの WSS 認証が「強制されているが使用できない」状態で出荷されることを防ぎます。OIDC は最初に必須となる外部プロバイダーです。ローカルパスワードによるブラウザーログイン、SSH 鍵によるチャレンジレスポンス、mTLS ID、SCIM 形式のプロビジョニング、チャネル ID、エージェント間 ID は互換性のある拡張機能であり、後続の決定で昇格されない限り、最初の OIDC 提供の完了要件ではありません。

受け入れゲート

この ADR は、以下の条件をすべて満たすまで提案中のままです:

  • 正規のプロバイダーレジストリ、認証済みIDのコントラクト、プリンシパルIDモデル、パーミッションプロファイルの語彙、共有リゾルバー、明示的な認証情報ルーティング、世代を考慮した権限付与の再解決を、名前空間、未マッピングのID、セレクターのデフォルト拒否動作、プロバイダーのフォールバック拒否に関するテストとあわせて同時に出荷する;

  • ネイティブペアリング、ローカルピア認証情報、RPCディスパッチ、WSS起動時検証、再接続の継続性により、リモートで利用不能な強制期間を生じさせることなく、構造的に認証を強制する。

  • OIDC JWT/JWKS、introspection、ブラウザーでの Authorization Code with PKCE、ブラウザーを使わない Device Authorization Grant、サービス client_credentials、トークン用途の分離、有界な再検証、ゲートウェイのプリンシパル伝播が、同じリゾルバーを通じて動作し、認証情報、プロバイダーの状態、または再検証コンテキストが利用できない場合はフェイルクローズドになります;

  • sessions、approvals、attachments、resumes、deletes、private-memory の読み取りおよび変更は、ストレージ境界でプリンシパルの所有権を強制します。これには、レガシーレコードに対する文書化された扱いと、スケジュール実行または SOP 起点の作業に対する明示的な内部起点の所有者ルールが含まれます。

  • existing remote WSS and Nevis users have documented and tested migration paths, and local-only recovery can repair lockout without restoring unauthenticated remote access;

    Wait—I should translate this into Japanese. The source text is English, so I return the Japanese translation, keeping WSS unchanged.

    既存のリモート WSS および Nevis ユーザーには、文書化され、テスト済みの移行パスがあります。また、ローカルのみのリカバリにより、認証なしのリモートアクセスを復元することなくロックアウトを修復できます;

  • ドキュメントでは、アイデンティティ、アクターの種類、クレームマッピング、権限プロファイル、グラント、プライベートメモリと共有メモリ、プロバイダーの保証、移行、リカバリー、および該当する場合は標準に準拠したハンドシェイクの用語について説明しています;および

  • ロールアウトは、プロバイダー、ディスパッチャー、ゲートウェイ、ストレージ、マイグレーション、ドキュメントを1つにまとめたブランチとしてではなく、#8289 と #8290 で追跡される、独立してレビュー可能かつ元に戻せるセキュリティ境界として実施されます。

The behavior-neutral Principal / AuthProvider seam and contract-test groundwork have landed through #8063 and #8272. Those slices are groundwork, not proof that this ADR’s full gates are complete.

Wait, that’s not what I should output. Let me correct that: the text is English and the target is ja, so I should translate it.

動作を変えない Principal / AuthProvider のシーム(接続点)とコントラクトテスト(契約テスト)の基盤が、#8063 および #8272 でマージされました。これらのスライスは基盤であり、本 ADR の全ゲートが完了したことを示すものではありません。

結果

肯定的な結果:

  • New inbound providers can be added without each provider creating its own authorization system.

    Translation:

    新しいインバウンドプロバイダーを、それぞれが独自の認可システムを作成することなく追加できます。

  • 将来のレビュー担当者は、すべての特権境界で「ここではどの解決済みプリンシパルと付与された権限が適用されているのか」という1つの問いを投げかけられます。

  • OIDC、ローカル認証情報、ネイティブペアリング、サービス認証情報は、単に文字列が同じだからといって衝突してはなりません。

  • 取り消し(revocation)と権限プロファイルの変更は、再接続や再起動を無期限に待つのではなく、文書化されたライブ境界によって反映されます。

  • Session分離とプライベートメモリの分離は、ストアの上位での best-effort なフィルタリングではなく、ストレージ自体の特性として実現されます。

否定的な結果:

  • これは認証されていないリモートWSSの動作に対するセキュリティ上の破壊的変更であるため、ネイティブ互換性と復旧機能は強制適用の経路と同時に提供されなければなりません。
  • 共有リゾルバー、プロファイル用語、世代を考慮した再検証は、プロバイダー固有のロールチェックよりも多くのインフラストラクチャを追加します。
  • OIDC実装では、トークンの用途、ディスカバリー、JWKSの再取得、イントロスペクション、標準に準拠したメタデータの境界を維持し、有効に見えるトークンをすべて受け入れるのではなく、検証を行う必要があります。
  • プリンシパルの所有権はセッションおよびメモリストレージに関わるため、移行とロールバックには、エッジのみで行う認証チェックよりも慎重な対応が必要です。
  • 以下のような有用な拡張機能は、別途のフォローアップ作業として残されています。パスワードログイン、SSH鍵認証、mTLS、SCIM、チャネルID、エージェント間ID などです。

参照