Closed12
Shared Signals and Events についてのメモ
SSE
- Transmitters と Receivers 間での非同期コミュニケーションをいい感じにするための API
- Transmitters と Receivers 間のやりとりは stream で行う
- stream における興味のある subject を追加したり削除したりできる
- subject の定義はなんかいい感じにできるらしい
- subject は stream に含まれるかどうかの同意ができる
- イベントの送受信は IETF standard protocols をベースにしたプッシュ/プルが使える
- stream のイベントのフォーマットは SETs // TODO
CAEP
- SAML とか OIDC みたいなフェデレーションのプロトコルはユーザーのログイン時にアクセスの有効性を検証する
- これによって確立されたセッションは長時間持続する
- 持続している間ユーザの属性が変わることがある
- これによって確立されたセッションは長時間持続する
- ログイン時に検証した情報だけに依存してるとよくない
- 属性の変更をやり取りする標準が WG に提案された
- CAEP はステータスの変更を表現する標準
- security event token(SET)で表現される CAEP イベントは、SSE Framework を使った Transmitters によって送信される
- receiver が CAEP event を受け取ったら、セキュリティの対策をしたり、ユーザーのセキュリティアクセスとかプライバシーに対してどうすんのか動的に調整する
- CAEP にはこんなイベントがある
- Session Revoked
- Token Claims Change
- Credential Change
- Assurance Level Change
- Device Compliance Change
CAEP が最初に投稿された Google のブログ
具体的なユースケースがあるのでイメージが付きやすいかも
RISC
- ユーザーは 1 つのメールアドレスを複数サービスに使うので、攻撃者はサービスをまたいだ複数のアカウントをターゲットにする
- SNS のパスワードリカバリーが email に依存してて、写真共有サービスへのアクセスが SNS に依存してる、みたいな連携がある
- これを攻撃者が利用してアカウントの乗っ取りが連鎖することがある
- RISC はこういう攻撃のセキュリティアラートを送受信する標準
- RISC にはこんなイベントがある
- Account Credential Change Required
- Account Purged/Disabled/Enabled
- Identifier Changed/Recycled
- Credential Compromise
- Recovery Activated/Information Changed
SSE Framework を説明する OpenID のブログ
- OpenID RISC と Google 提案の CAEP はどっちも非同期のストリームでイベントをどうこうするやつだったので、RISC とか CAEP とかに関わらないイベントのストリームを管理する標準として SSE がでてきた
- Receiver のエンドポイントに push するか、Receiver が polilng することで SET のやり取りをする
- Receiver と Transmitter 間の認可は OAuth
- 顧客がイベントをストリームに流すことを同意してないのに Transmitter が Receiver にイベントを流す、みたいなことが起きるとまずい
- Receiver に認可を渡すのに OAuth を使う
- Subject という概念がある
- あるストリームでは指定された Subject のイベントだけが通知される
- ユーザーの Subject を追加したら、そのユーザーに関するイベントが通知される
- 例えばユーザーが退会した、とか
- セッションの Subject を追加したら、そのセッションに関するイベントが通知される
- 例えばそのセッションが切られた、とか
- Implementer’s Draft として採用された
SSE Framework を説明する Cisco のページ
各 API を実際にどう叩くのかイメージが解説されてる
- receiver が transmitter の /.well-known/sse-configuration を叩いて SSE の設定を取得
- jwk のエンドポイントとか event の配信方法とか、イベント取得の設定用エンドポイントとかが返ってくる
- receiver が 1 で取得した設定の configuration_endpoint に設定を送る
- どういう方法で event を配信するか(poll/push)とか、どういうイベントがほしいかとか
- Bearer トークンで認可
- polling につかうエンドポイントが返ってくる
- subject を追加するために 1 で取得した add_subject_endpoint を叩く
- ユーザー A のイベントの通知よろしく!みたいな感じ
- receiver が verification_endpoint を叩くとテスト用のイベントが通知される
- receiver が config を設定したときに払い出された polling 用のエンドポイント(delivery.endpoint_uri)を叩くと、配信されたイベントが SETS の形式で取得できる
- 認可するかどうかの決定を動的なデータ(デバイスの位置、IP の位置、デバイスやアプリの状態、ユーザーの権限)を元に行いたいことが増えてきた
- サービスにログインした状態で国を移動したあと、サービス側が与える権限を変更する
- デバイスに変なアプリが入ってるのを検知したら VPN を切断する
- IP が変わったら権限を再評価
- ユーザーに付与された権限をアプリに通知
- なんだけど、動的な認可は難しい
- いまは認証時にだけ認可の決定をするのがふつう
- CAEP はユーザーセッションの属性を独立した組織がコントロールするのを可能にする認可へアクセスするための新しいアプローチ
- pub-sub モデル
- アプリ/IdP はセッションの更新情報を通知する
- IdP は認可の決定やユーザー属性位の publisher であり、VPN server や SaaS アプリからの client IP をサブスクライブする
- VPN server や SaaS アプリは IdP による認可の決定をサブスクライブし、VPN server や SaaS アプリはセッション内の client IP の publisher となる
- つまり複数の publisher がいて、複数のsubscriber がいる可能性がある
- Interacting with CAEP
- デバイス/アプリが RP によるサービスにリクエストを送る(デバイスからサービスを利用する)
- 認証されたユーザーのセッションが生存している間何回も起こる
- 以前のアクセスとなんか変化があったら(IP 変わったとか)、RP は update context を publish する(非同期)
- メッセージにこのセッションに関する更新を受信するかどうかを含めることができる
- subscriber は IdP のようなポリシーサーバーを含めることができる
- ポリシーサービスがセッションに影響のある変更を受け取ったら、このセッションの subscriber すべてに更新情報を処理して publish(非同期)
- なにか問題があって修復が必要な場合、RP はデバイスやアプリにどういった問題があってどうすればいいか(例えば再ログインを求めるとか?)を通知
- デバイス/アプリが RP によるサービスにリクエストを送る(デバイスからサービスを利用する)
- ユースケース
- ファイル共有サービスのユーザーが外国に行った場合、CAEP でどうするか
- サービスのプロバイダーがユーザーの IP 位置情報が変わったことをイベントで publish
- 以前のサービスプロバイダーによるアクセス許可の認可でそのセッションに関心をもった IdP はユーザーの IP 情報が変わったことをイベントで受け取る
- ユーザーのアクセス権を再評価し、そのユーザーがログインしているすべてのセッションについてユーザーの新しい属性を publish する
- 属性にはサービスプロバイダー固有の認可の決定を含む
- このセッションに関心のあるすべてのサービスプロバイダーはユーザーの新しい属性を取得する
- 属性にはそのユーザーにアクセス権をもたせたままにするかどうか決定できるようなものを含む
- サービスプロバイダーはそのユーザーの特定のリソースへの権限を無効化する
- ファイル共有サービスのユーザーが外国に行った場合、CAEP でどうするか
- 人気のアプリで脆弱性が見つかった
- ポリシーサーバーが脆弱性評価に対する全てのユーザーのアクセス許可を再評価
- アプリ利用してるユーザーの全てのセッションに対して terminate を publish
- サービス提供者はイベントを受け取ってセッションを切る
- 認証済みユーザーが怪しいアプリをダウンロードしたり怪しいサイトを訪れた
- endpoint security service が怪しい挙動を観測したら、デバイスのすべてのセッションを invalidate するイベントを publish
- セッションを subscribe しているサービスはユーザーに再認証を要求
GoogleIdentityPlatform の RISC
SSE Framework
Absract
- SSE は協力している同士の間でイベントやシグナルを共有できるようにする
- 複数のアプリケーションが RISC とか CAEP できるようにする
2. Subject Principals
- SSE Framework を利用して送信者に送信され受信者に受信されるイベントについてのエンティティを Subject Principal という
- Subject Principal は SSE の送信者、受信者によって管理される
- これらは送信者、受信者が管理する人間、機械、デバイス、テナント、組織だったりする(それ以外でもありうる)
3. Subject Members in SSE Events
- SSE Event における Subject 型のメンバーは任意のクレーム名をもてる
- 各メンバーは 1 つだけの Subject Principal を参照しないといけない
- Subject には simple subject と complex subject がある
3.1. Simple Subject Members
- Simple Subject Member はクレーム名と値をもつ
- 値は https://datatracker.ietf.org/doc/html/draft-ietf-secevent-subject-identifiers で定義されてる Subject Identifier
3.2. Complex Subject Members
- Complex Subject Members は 1 つ以上の Simple Subject Members で構成される JSON
- user とか device とか session とかが定義されてる
- Complex Subject のメンバーは同じ Subject Principal の属性を表してないとダメ
- Complex Subject は 1 つだけの Subject Principal を参照しないといけない
3.3. Subject Identifiers in SSE Events
- Subject Identifier はフォーマットがある
- https://openid.net/specs/openid-sse-framework-1_0-ID1.html#subject-ids-in-sse
-
https://datatracker.ietf.org/doc/html/draft-ietf-secevent-subject-identifiers だったり、https://openid.net/specs/openid-sse-framework-1_0-ID1.html#additional-subject-id-formats で定義されてるやつだったり
- 後者は JWT ID とか SAML Assertion ID とかある
- 仕様の範囲外で拡張してもいい
3.5. Receiver Subject Processing
- 受信者はなるべく SSE event の Subject の全メンバーを処理しないとダメ
- 送信者はメタデータで特定のメンバーを Critical と定義できる
- 受信者が Critical なメンバーを処理できない場合、その Subject を含むイベントを全部破棄しないといけない
4. Event Properties
- 追加のメンバーが events claim に含まれる
- いくつかのメンバーは必須で、event types specs で定義されてるように指定される
- 送信者は event types spec に指定されてない追加のメンバーを含めたい場合、そのメンバー名は URI にしないとダメ
5. Example SETs that conform to the SSE framework
SETs の例
6. Transmitter Configuration Discovery
- 受信者が送信者の情報を得るためのディスカバリが定義されてる
6.1. Transmitter Configuration Metadata
- フィールドが色々定義されてる
- 送信者の identifier / jwk の URI / どう配信するか / 設定用のエンドポイント / ステータスエンドポイント / サブジェクト追加、削除のエンドポイント / 検証用エンドポイント / critical 扱いする(受信者が処理しないといけない) subject member
6.2. Obtaining Transmitter Configuration Information
- /.well-known/sse-configuration から JSON で配信すること
6.2.1. Transmitter Configuration Request
- 送信者は これを GET で配信する
- issuer が複数いる場合
GET /.well-known/sse-configuration/issuer1
みたいにする
6.2.2. Transmitter Configuration Response
6.2.3. Transmitter Configuration Validation
7. Management API for SET Event Streams
- 送信者が提供し受信者が実行する、Event stream の設定とステータスの更新、subject の追加と削除、verification のための API を定義する
- 送信者がこれらを実装するかどうかは OPTIONAL
7.1. Event Stream Management
- Configuration Endpoint
- Status Endpoint
- Add Subject Endpoint
- Remove Subject Endpoint
- Verification Endpoint
7.1.1. Stream Status
- Status Endpoint への GET でステータスが取得できる
- どのストリームのステータスをみるかどうかを指定する subject をパラメーターに持ち、status フィールドで enabled / paused / disabled のいずれかを返す
- enabled ならストリームでイベントを送信する
- paused ならイベントを送ってはならない
- それらのイベントは enabled になったタイミングで送るべき
- 同じ Subject Principal に影響のある連続したイベントを持っていた場合、送信されるイベントの順番は生成順である必要がある
- もしくは、同じ Subject Principal に影響のある最後のイベントだけを送らなければならない
- disabled だったらイベントを通史しないし、保持もしない
- Status Endpoint への POST でステータスが更新できる
- status で更新後のステータスを指定
- subject で対象を指定
7.1.2. Stream Configuration
- Stream Configuration は JSON
- 送信者、受信者の Identifier、送信者がサポートしてるイベント、受信者が要求するイベント、実際に配信されるイベント、どうやって送るか、verification request を出すのに開けなければいけないインターバル、Subject Identifier Format のフォーマット
7.1.2.1. Reading a Stream’s Configuration
- 受信者は GET で stream の configuration を取得できる
7.1.2.2. Updating a Stream’s Configuration
- 受信者は GET で stream の configuration を更新できる
7.1.2.3. Removing a Stream Configuration
- 受信者は DELETE で stream の configuration を削除できる
7.1.3. Subjects
- 受信者は送信者に、ある Subject についてのイベントを受信したいかどうかを Subject の追加や削除によって伝えることができる
- Add Subject Endpoint で Subject を追加できる
- Remove Subject Endpoint で Subject を削除できる
7.1.4. Verification
- Stream を流れるイベントがめちゃめちゃ少ない場合がある
- この場合 Receiver が受信についての検証をするのがたいへん
- Verification Event が使える
- Verification Event の属性は定義されてる
- https://openid.net/specs/openid-sse-framework-1_0-ID1.html#verification-event
- Verification Endpoint への POST で verification event が送られる
7.1.5. Stream Updated Event
- 送信者は受信者のリクエストがなくても Subject に関するステータスを変えられる
- その場合、ステータスが変わったことをイベントで通知する
8. Authorization
- 受信者が送信者に API コールする際の認可は OAuth 2.0 のアクセストークンをつかうべき
- 受信者は Client Credential Grant か、ほかの適切なやり方でトークンを取得する
9. Security Considerations
- 送信者による Subject の追加要求に対するレスポンスで Subject についての情報が漏れるかも
- 常に 204 返す、とかでもいい
- SET には PII を含むことがあるので、個人情報漏洩のパスにならないようにする
- 受信者による Subject の追加はあくまで受信者の意志として扱う
- 追加リクエストがきたからといって送信者は全部送る必要はない
- 9.3. Malicious Subject Removal
- よくわからん
10. Privacy Considerations
SET
Abstract
- SET(Security Event Token) はデータ構造
- subject についての issuer 目線での事実を説明したもの
- 例えば subject のトークンが発行されたとか、無効化されただとか
- security と identity 関連のイベントを表現することを意図している
- SET は JWT であり、署名または暗号化できる
- HTTP で発信される
1. Introduction and Overview
- SETs は他の目的にも利用できるが、仕様では identity と個人情報に関する security/privacy に関する項目のみの話になる
- subject は永続的なもの(ユーザーアカウントとか)とテンポラリなもの(セッションとか)がある
- subject の状態変化は UA やセキュリティサブシステムなどによってトリガーされるが、イベントの生成の原因となったアクションに対してイベントの発行と送信はバックチャンネルで非同期で行う
- SET の受信者は SET を受信し、検証し、処理したあと自身の独自のアクションを行う
- 個人の識別子が別の security subject に関連づいている(メールアドレスが他人に紐付いてるとか)を通知された時、SET の受信者は旧ユーザーのリソースに対して新しいユーザーがアクセスできないようにしてもいいし、なんもしなくてもいい
- SET を送ったらそれに対して受信者はなんかしがちだけど、送信者が受信者になにかすることを求めるものではない
1.2. Definitions
- SET Issuer が SETs を作って SET recipients のサービスに送る人
- SET recipient が受け取る人
- 使用によっては receiver といわれる
- Subject は SET で通知されるイベントや状態変化が起きた対象
- princpal / web resource / IP アドレスとか SET の issuer みたいなエンティティ
- このユーザー退会したよ、なら Subject=ユーザー、このサービス情報漏えいしたよ、なら Subject=サービス、このセッション漏洩したよ、なら Subject=セッション、みたいな感じだと思う
- princpal / web resource / IP アドレスとか SET の issuer みたいなエンティティ
- Event Identifier
- SET における events claim の値の、メンバー名
- URI じゃないとダメ
- Event Payload
- SET における events claim の値の、値
- Profiling Specification
- イベントごとの仕様?
2. The Security Event Token (SET)
- JWT のトップレベルの claim を SET "envelope" という
- いくつかの envelope はすべての SET に存在するが、特定の SET profile 固有のもある
- この仕様で定義される envelope claims は SET の検証と SET に含まれるイベントデータについての情報を提供するのに利用される
- event claim は security subject について説明する event identifier と イベント固有のデータを持つ
- events claim は 1 つ以上のメンバーを持つ JSON オブジェクトじゃないとダメ
- events の各メンバーは name/value ペアの JSON オブジェクト
- メンバー名は URI で、event identifier
- 対応する値は event payload
- payload がないようなイベントは空の JSON オブジェクト {} になる
- メンバー名は URI で、event identifier
2.1. Illustrative Examples
- なんかいろいろ例が載っている
- SCIM でパスワードリセットした場合とか OIDC で同意を得たとか
2.2. Core SET Claims
- iss
- SET の発行元
- iat
- jti
- aud
- 1 つ以上の audience
- 多分 recipient のことでいいと思う
- sub
- SET の対象
- トークンが revoke されたイベントならトークンの identifier
- SET の対象
- exp
- events
- event statements の set
- 発生したイベントの種類とイベントのメタデータが入ってる
- ログアウトしたよ、とかパスワードリセットしたよ、みたいな
- txn
- 関連のある JWT が複数発行される場合紐付けに使えるらしい
- toe
- イベント発生日時
2.3. Explicit Typing of SETs
- JOSE Header の typ は secevent+jwt になる
2.4. Security Event Token Construction
- ふつうに JWT として組み立てようねくらいの感じに見える
3. Requirements for SET Profiles
- SET の設計時に守らないといけないやつ的な?
4. Preventing Confusion between SETs and Other JWTs
- JWT って理解できない claim を無視しないといけないので、SET を SET 以外の文脈で使われてまずいことになる、みたいのがあるので防ぐためにどうこう
- ID トークンがくるところに SET を送られたときにどう気づくかとか、アクセストークンについてはどうかとかそういうの
5. Security Considerations
5.2. Delivery
- この仕様では SET をどう配信するかは定義しない
SET の push
Abstract
- どうやって HTTP POST をつかって SET を recipient に送るかを定義する
- recipient のエンドポイントに POST する
- SET は body で送られる
1. Introduction and Overview
2. SET Delivery
- Transmitter が送った SET に対して Recipient が解釈できなかったりするとエラーレスポンスを返す
- recipient がすべき検証
- SET パースできるか
- issuer が正しいとか署名検証できるとか
- audience が想定してるやつか
- recipient がその SET の受信を望んでいること
2.1. Transmitting a SET
- SET の送信のため、Transmitter は Recipient のエンドポイントに POST する
- 失敗したら recipient はエラーコードを返す
SET の poll
Abstract
- recipient が HTTP POST を使ってポーリングすることで SET をどう配送するかの仕様
2.2. Polling HTTP Request
- recipient はポーリングのパラメーターに使う JSON を組み立てる
- maxEvents
- 一発で受信する数
- returnImmediately
- レスポンスをすぐ返すか
- false だとロングポーリングになる
- レスポンスをすぐ返すか
- ack
- 受信済み SET のjti のリスト
- これが指定されると transmitter は SET を保持しなくて良くなる
- setErrors
- 処理できなかった SET の jti とエラー内容の組み合わせ
- maxEvents
2.3. Polling HTTP Response
- sets
- SETs
- メンバー名が jti になる
- moreAvailable
- ack してないやつがまだあるか
2.4. Poll Request
2.5. Poll Response
RISC
- Risk Incident Sharing and Coordination を 実装するのに必要な SSE Framework を元にしたイベントタイプとコンテントを定義する
- event type is https://schemas.openid.net/secevent/risc/event-type/
- types
-
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required
- subject がクレデンシャルの変更を要求された
-
https://schemas.openid.net/secevent/risc/event-type/account-purged
- subject が永久削除された
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
- subject が disable になった
- 今後 enabled になるかも
- subject が disable になった
- https://schemas.openid.net/secevent/risc/event-type/account-enabled
-
https://schemas.openid.net/secevent/risc/event-type/identifier-changed
- 識別子が変わった
- メールアドレス変わったよとか
- 識別子が変わった
-
https://schemas.openid.net/secevent/risc/event-type/identifier-recycled
- 識別子が別のユーザーに使い回された
-
https://schemas.openid.net/secevent/risc/event-type/credential-compromise
- クレデンシャルが漏洩しちゃった
- エンドユーザーは RISC イベントの送信を opt-in/out できるべき
- それようのイベントも定義されている
-
https://schemas.openid.net/secevent/risc/event-type/opt-in
- opt in した
-
https://schemas.openid.net/secevent/risc/event-type/opt-out-initiated
- opt out を要求した
-
https://schemas.openid.net/secevent/risc/event-type/opt-out-cancelled
- opt out をキャンセルした
-
https://schemas.openid.net/secevent/risc/event-type/opt-out-effective
- opt out された
-
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required
-
https://schemas.openid.net/secevent/risc/event-type/recovery-activated
- リカバリーによってアクティベートされた
-
https://schemas.openid.net/secevent/risc/event-type/recovery-information-changed
- リカバリ情報が変わった
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
- セッションが破棄された
- これはもう deprecated
- CAEP の session-revoked をつかってね
CAEP
- SSE Framework の Continuous Access Evaluation Profile を定義
- CAEP には CAEP 固有の claim が定義されてる
- event_timestamp
- イベントの発生時刻
- SET の toe とは違う?
- initiating_entity
- イベントのトリガーになったエンティティ
- user のアクションがきっかけなのか?ポリシーの評価がきっかけなのか?みたいな
- イベントのトリガーになったエンティティ
- reason_admin
- 管理用メッセージ
- ローカライズできる
- ロギング、監視用
- 管理用メッセージ
- reason_user
- エンドユーザーに見せるユーザーフレンドリーなメッセージ
- event_timestamp
- イベントについて
- event type=https://schemas.openid.net/secevent/caep/event-type/
- イベントいろいろ
-
https://schemas.openid.net/secevent/caep/event-type/session-revoked
- セッションが破棄された
-
https://schemas.openid.net/secevent/caep/event-type/token-claims-change
- トークンの claim が変わった
- claims に変わった claim を指定
-
https://schemas.openid.net/secevent/caep/event-type/credential-change
- クレデンシャルが作られた、変わった、破棄された、削除された
- 例えばパスワードが変わったとかリセットされたとか
- FIDO 端末が enrollment されたとか
- どういうクレデンシャルがどうなったか、みたいのがフィールドでわかるようになってる
-
https://schemas.openid.net/secevent/caep/event-type/assurance-level-change
- aal が変わった
- サービス A にパスワードでログインしたあとサービス B に MFA して AAL2 で認証されたときとかに通知される
-
https://schemas.openid.net/secevent/caep/event-type/device-compliance-change
- デバイスのコンプライアンスのステータスが変わった
- サンプルだと信頼できない場所にデバイスが移動した、みたいなケースになってる
- デバイスのコンプライアンスのステータスが変わった
-
https://schemas.openid.net/secevent/caep/event-type/session-revoked
雑なまとめ
SSE Framework
- サービス間(例えば IdP と RP 間)で非同期でイベントのやりとりしたいことがある
- どうイベントを通知するかとか、どの Subject(例えばユーザー)についてのイベントを受信したいかとかを Transmitter の API で設定できる
- IdP が transmitter で RP が receiver だとすると、RP が IdP に polling の形式でイベントストリームを作って、そのストリームでユーザー A、B、C の情報を受信したい、みたいなリクエストができる
- どうイベントを送信するか、はここでは定義されてない
- イベントは SET でやりとりする
SET
- JWT のデータ構造
- 署名、暗号化できる
- security と identity 関連のイベントを表現することを意図している
- Subject に対して何が起きたのか?を表現
- events claim にイベントの詳細が入ってくる
- ここのフォーマットは RISC とか CAEP で定義される
どう送信するか
- poll
- https://datatracker.ietf.org/doc/html/draft-ietf-secevent-http-poll
- 定期的に receiver が transmitter にリクエスト
- push
- https://datatracker.ietf.org/doc/html/draft-ietf-secevent-http-push-10
- receiver のエンドポイントに transmitter がリクエスト
RISC/CAEP
- どっちも SET のイベントの定義
- ここで定義されてるフォーマットで SET の events claim の各項目が決まる
- RISC と CAEP の切り分けはよくわかんなかった
- なんとなくイレギュラーっぽいものが RISC になってる気はする
このスクラップは2022/08/13にクローズされました