本文へ移動

セキュリティ

もてなすように、守る。

IDプロバイダーの価値は、テナント間の壁の確かさと、シークレットの扱いの丁寧さで決まります。ここでは、Usher Identityがどのように作られているかをご紹介します。説明するのはソフトウェアの動作であり、いかなる認定の取得も主張するものではありません。

アーキテクチャ

別々のドメイン、別々のネットワーク。

Usher Identity自身のページと各顧客の発行者は、それぞれ異なる登録可能ドメインに置かれています。データベースはインターネットに到達できないネットワーク上にあり、外に出る唯一の道は、行き先を確認するプロキシです。

  • CaddyがすべてのホストのTLSを終端し、Usher Identity自身のサービスだけが設定できるヘッダーを取り除きます。
  • 認証層はホストで区別しながら、すべての環境に応答します。あるホスト向けにキャッシュしたものを、別のホストに返すことはありません。
  • 各サービスは専用のユーザーとしてValkeyに接続し、自分のキーにしかアクセスできません。デフォルトユーザーはありません。
  • トークンやコードを含むSQL文が、その値ごとデータベースのログに書き込まれることはありません。

インターネット

ユーザー、あなたのアプリ、あなたのサーバー

エッジ

Caddy:TLS、HSTS、内部ヘッダーの除去

usheridentity.com

サイトとConsole

usheridentity.com, console.usheridentity.com

API

api.usheridentity.com

*.usherid.com

認証層

すべての環境の発行者とLobby

データネットワーク · 外部への経路なし

Postgres

環境ごとに1つのスキーマ

Valkey

各サービスは自分のキーだけにアクセス

唯一の出口

エグレスプロキシ

顧客が指定したすべてのURLに

ディスカバリ、JWKS、ログアウト

公開アドレスのみ

Usher Identityの各層。テナントドメインはプラットフォームとは異なる登録可能ドメインのため、テナントのページがConsoleと同一サイトになることはありません。

分離

重要なものは、何も共有しない。

プロジェクトの各環境には、専用のPostgresスキーマ、専用の署名鍵、そして専用のデータキーで封印された専用のシークレットがあります。発行者はテナントドメイン上のホストで、Cookieはホスト限定のため、ブラウザーがある環境のCookieを別の環境に送ることはありません。

usheridentity.com

サイト、Usher Identity Console、Usher Identityアカウント

*.usherid.com

環境ごとに1つの発行者を、別のドメインに

環境

ユーザー、セッション、トークンは、この環境のために作られたスキーマに保存されます。クエリはそのスキーマに対して実行され、テナント列を持つ共有テーブルが使われることはありません。

Acmeの本番環境にある封印済みのGoogleクライアントシークレットを、Northwindの本番環境にコピーする。

保存時の暗号化

あるべき場所に結び付いた、エンベロープ暗号化。

Usher Identityに預けたシークレットは、ひとつの環境に属するデータキーを使ってAES-256-GCMで封印されます。データキー自体も、データベースの外に保管された、バージョン管理されたマスターキーでラップされます。

環境ごとのデータキー
ある環境のデータキーが漏えいしても、別の環境のデータキーについては何もわかりません。
AADによる結び付け
すべての暗号文に環境と用途が結び付けられているため、値を別の行や別のテナントに移すことはできません。
バージョン管理された鍵
封印された値には、それぞれ作成時の鍵のバージョンが記録されるため、鍵をローテーションし、古い値をラップし直せます。
認証付き暗号
GCMのタグにより、改ざんされた値は別の内容に復号されるのではなく、開くことに失敗します。
  1. マスターキー

    データベースの外に保管、バージョン管理

  2. データキー(環境ごとに1つ)

    マスターキーでラップ

  3. シークレット

    データキーを使いAES-256-GCMで封印

u1.<key version>.<iv>.<ciphertext + tag>

aad = u1 | version | environment | purpose

封印された値は、その認証データに環境と用途を記しています。ほかの場所にコピーしても、開くことはできません。

取り組み

細部まで、丁寧に。

  • パスワード(使う場合)

    OWASPが推奨するコスト(19 MiB、2パス)でArgon2idを使ってハッシュ化し、同時に実行する数に上限を設けているため、大量のサインインでサービスが停止することはありません。新しいパスワードは、Have I Been PwnedのRange APIで既知の漏えいと照合されます。このAPIが受け取るのは、パスワードのハッシュの短い先頭部分だけです。最小文字数はデフォルトで12文字です。

  • 再利用されうるものは保存しない

    クライアントシークレット、トークン、マジックリンクのトークン、メールで届くコードは、ハッシュ化して保存されます。バックアップコードは暗号化されます。認可コードの有効期間は5分で、メールで届くコードは3回まで試せます。

  • すべての扉にレート制限

    サインイン、新規登録、メールで届くコード、マジックリンク、パスワードのリセット、2段階認証の確認には、それぞれ個別の制限があります。たとえば、パスワードでのサインインは1分間に10回、メールで届くコードは10分間に5回までです。

  • 厳格なContent-Security-Policy

    Lobbyのページには毎回新しいnonceと、それを軸にしたポリシーが付与されます。実行されるのはnonceを持つこのオリジンのスクリプトだけで、フォームの送信先は同一オリジンに限られ、ほかのサイトがページをフレームに埋め込むことはできません。

  • 信頼できる監査ログ

    ワークスペース、プロジェクト、環境への変更は追記専用のログに書き込まれ、各エントリーは直前のエントリーとハッシュチェーンでつながっています。そのため、編集されたエントリーや欠けたエントリーがあれば、すぐにわかります。

  • 顧客のURLのためのエグレスプロキシ

    顧客から指定されたアドレスへのUsher Identityのリクエスト(OIDCディスカバリ、JWKS、バックチャネルログアウト)は、すべてひとつのプロキシを経由して外に出ます。プロキシは名前解決を一度だけ行い、プライベート、ループバック、リンクローカル、クラウドメタデータのアドレスを拒否したうえで、確認したアドレスに接続します。そのため、DNSリバインディングによって顧客のURLを内部のURLに変えることはできません。

  • 二度と割り当てられないハンドル

    本番環境のハンドルは、その発行者のホスト名の最初のラベルです。Consoleは招待制で、フィッシングとして報告されたLobbyは停止されます。また、一度使われたハンドルが再び割り当てられることはありません。古いアプリが、まだそのトークンを信頼しているかもしれないからです。

  • 終わらせたいときに終わるセッション

    Usher Identityはキャッシュされたコピーを信頼せず、リクエストのたびに自身のセッションを確認します。そのため、終了したセッションはすぐに無効になります。アクセストークンの有効期間は短く(デフォルトで10分)、APIからイントロスペクションできます。

責任ある開示

何か見つけましたか?まずはお知らせください。

Usher Identityにセキュリティ上の問題を見つけたと思ったら、ぜひお知らせください。修正に向けて、一緒に取り組みます。

security@usheridentity.com
  • 見つけた内容、場所、再現手順。
  • あなたの理解の範囲で、その問題を使って何ができるか。
  • 連絡先と、謝辞にお名前を掲載してよいかどうか。

テストはご自身が所有する環境だけで行い、他人のデータにはアクセスしないでください。また、問題を公表する前に、修正のための妥当な猶予をいただけますようお願いします。Usher Identityのサインインになりすましたページを報告するには、不正利用の報告をご覧ください。