認可(B2C)
まずは少し立ち止まって、アクセス制御について考えてみましょう。アクセス制御の明確な定義が業界で合意されているわけではありませんが、多少時間をかけて検索し、各種ドキュメントを読んでみると、信頼できる情報源のほとんどが、アクセス制御は、認証、認可、同意、およびポリシー適用をすべてまとめた、適切な人物とサービスだけがアプリケーションとAPIにアクセスできるようにする包括的な概念であることに同意していることがわかります。それでは次に、認証、認可、同意、およびポリシー適用の違いについて詳しく見ていきましょう。Auth0テナント(皆さんが利用している認可サーバー)は、通常、認証と同意、それに一部または全部の認可とポリシー適用を引き受けます。加えて、ほとんどの場合、特に文脈に応じたアクセスが必要な場合に、アプリケーションまたはAPI自体がポリシーの主要な適用者になります。
認証(Authentication):プリンシパル(ユーザーまたはアプリケーション)が自己申告している通りの人物または存在かどうかを判断するプロセス。
認可(Authorization):プリンシパルに基づいて、許可されているのは何か、付与されているアクセス許可は何か、および/またはコンテキストに即した一連のアクセス条件を判断するプロセス。
同意(Consent):ユーザー(リソース所有者)が、自身の代わりに実行することを許可するためにアプリケーションに付与したアクセス許可。これは通常、委任された認可の要件になります。ユーザーは、異なるシステムにあるユーザーのデータへのアクセス許可をクライアントに付与する必要があります。
ポリシー適用(Policy Enforcement):アプリケーションまたはAPIのポリシーを適用する行為で、ユーザーの認証情報および/または認可情報に基づいてアクセスを拒否または許可します。
一般的に各種アクセス制御は、(a)情報の保管に責任を負うのは誰か、(b)決定に責任を負うのは誰か、(c)制限の適用に責任を負うのは誰か、を理解しやすいように、3つのカテゴリに分類されます。
1つ目のカテゴリは、アプリケーションまたはAPI全体へのアクセスが許可または拒否される場合です。通常、これを適用するために必要なデータと適用プロセスの両方が、認可サーバーのコンテキストで定義されます。たとえば、ユーザーに紐づけられた
app_metadata
と、Auth0テナントで定義されているRuleを使用する、というようにです。2つ目のカテゴリは、アプリケーションまたはAPIの機能性の、特定のサブセットへのアクセスが許可または拒否される場合です。これを適用するために必要なデータは通常、認可サーバーに保管されます。たとえば、Auth0テナントにあるユーザーの
app_metadata
を使用して、アプリケーションまたはAPI自体で実行される適用プロセスによって行います。このシナリオでは、データは通常、id
またはaccess
トークンで1つ以上のカスタムクレームとして伝達されます。3つ目のカテゴリは、アプリケーションまたはAPIのコンテキスト内でプリンシパル(対象者)が操作できるものに応じてアクセスが許可または拒否される場合です。通常、これを適用するために必要なデータと適用プロセスの両方が、アプリケーションまたはAPIのコンテキストで定義されます。このシナリオでは、
id
またはaccess
トークンで1つ以上のカスタムクレームとして伝えられるデータが、Auth0以外の外部ソースからのデータを伴って、または伴わずに利用されます。
加えて、以上で説明したアクセス制御のカテゴリにはいずれも、Role-based Access Control(RBAC)およびAttribute-based Access Control(ABAC)のメカニズムを適用できます。どのようなユースケースであれ、必要な機能性とワークフローを検討する際には、いくつか考慮すべき点があります。
アプリケーションまたはAPI全体へのアクセスを拒否すべきシナリオはあるか?
サードパーティアプリケーションがアクセスできるAPIを提供するか?
自社(ファーストパーティ)のアプリケーションもAPIにアクセスするか?
アプリケーションがサードパーティAPIを呼び出すか?
アプリケーションおよび/またはAPIはユーザークレームに基づいてアクセス制御を適用すべきか?
Auth0は、特定の条件に基づき、アプリケーションまたはAPIのアクセス制限をサポートしています。特定のシナリオでは、UnauthorizedError
を返すRuleを作成する必要があります。たとえば、ユーザーが誤った時間にアプリケーションまたはAPIへのアクセスを試みたとき(こちらの例を参照)や、ユーザーのapp_metadata
に適切なクレームが含まれていない場合です。OpenID Connect(OIDC)を使ったアプリケーションの場合は、これによって、アクセス認可に使用されるIDトークンの割り当てが妨げられます。同様に、APIの場合、この例で説明されているように、OAuth2アクセストークン(APIの呼び出しに使用)の割り当てが妨げられる可能性があります。
ベストプラクティス
Auth0は、アプリケーションが制限を適用できるように、必要な情報を提供することもできます。アプリケーションレベルの統合では、Auth0を使用すると、カスタムクレームをIDトークンに追加できます。アプリケーションはこれを検証し、ポリシー適用に使用できます。この場合、アプリケーションが適用を判断するのに必要な情報を決める必要があります。アプリケーションではなくAPIで判断する必要がある場合は、おそらくIDトークンの代わりにアクセストークンを使用する必要があります。詳細については、このまま読み進めてください。
APIレベルの統合の場合、Auth0は、カスタムクレームとスコープの再構成を、両方ともアクセストークンのコンテキスト内でサポートしています。この場合も、APIがアクセスを判断するのに必要な情報を決める必要があります。APIは、アクセストークンの内容を検証してこれを適用する必要があります。
ベストプラクティス
カスタムクレームまたはスコープを通じて許可を使用するべきかどうかを決定する際に、スコープの性質と目的を理解する必要があります。読みやすく、トピックについて理解を深めるためのおすすめブログ記事をご覧ください。
アプリケーション統合
このシナリオでは、Auth0テナントが、アプリケーションへのアクセスが認可されていることを示す指標としてトークンを提供します。顧客向けのアプリケーションで一般的に最も利用されている業界標準プロトコル、OpenID Connect(OIDC)を活用するアプリケーションの場合、これはJWTと呼ばれるIDトークンになります。
IDトークンのクレーム
Auth0ではRuleの拡張性を利用して、たとえばユーザーのメタデータコンテンツに基づき、簡単にIDトークンにカスタムクレームを追加することができます。次に、アプリケーションは必要なクレームのIDトークンを検証し、必要に応じて特定の機能性へのアクセスを許可または拒否することができます。Ruleを利用したカスタムクレームの追加プロセスは合理化されているものの、Ruleエンジンには柔軟性があってカスタムコードを書き込むことができるため、意図しない悪影響を与えることもあるので注意してください。この拡張性機能を使用する際は、常に、ルールのベストプラクティスのガイダンスに従って作業することが重要です。
ベストプラクティス
カスタムクレームの追加を検討している場合は、ユーザーのapp_metadata
の一部としてクレームに含める必要のあるアクセス制御データを保管することをお勧めします。まず第一に、これによりデータを取得するために外部のAPIを呼び出す必要がなくなります。外部APIの呼び出しはログインシーケンスのパフォーマンスと拡張性に悪影響を与える可能性があります。第二に、app_metadata
はユーザーによって直接変更「できない」ため、ユーザーが自身のメタデータを変更してアクセス制御の制限を回避することはできません。また、「メタデータのベストプラクティス」のガイダンスもご確認ください。
IDトークンのスコープ
OIDCスコープは、通常、認証中にアプリケーションがユーザーの情報にアクセスするための同意を取得するために使用されます。事前定義された各スコープは、定義された、OIDC仕様で説明されている標準クレームのセットを返します。アプリケーションが要求するスコープは、そのアプリケーションでどのユーザー属性が必要かによって異なります。要求されたスコープがユーザーによって認可されると、クレームはIDトークンで返され、/userinfoエンドポイント経由でも利用できるようになります。
API統合
このシナリオでは、Auth0テナントは、一般的にJWTと呼ばれるOAuth2アクセストークンを提供できます。APIはこれを使用して、特定の当事者へのアクセスを制限できます。加えて、Auth0は、概念的にファーストパーティとサードパーティのアプリケーションと呼ばれる両方をサポートします。
Auth0テナントは認可サーバーとして機能し、ユーザー(リソース所有者)の同意を得て、一般的にJWTと呼ばれるアクセストークンをアプリケーション(クライアント)に提供するために使用できます。これにより、リソース所有者の代理として、リソースサーバーにホストされている保護されたリソースにアクセスできるようになります。発行されたアクセストークンは通常、APIに送信されるHTTP認可ヘッダーでBearerトークンとして渡されます。
単一のAPIであっても、論理的に関連するマイクロサービスAPI一式であっても、Auth0が提供するアクセストークンを活用してサービスへのアクセスを保護できます。これをAuth0 Dashboardで、またはAuth0 Management APIを通じてセットアップするのは比較的簡単ですが、さまざまなアプリケーションのシナリオとAPIのレイアウトを確認して、システムに最適なアーキテクチャを判断することが重要です。
OAuth2は、特にサードパーティのアクセスを念頭に置いて設計されています。たとえば、ユーザー(リソース所有者)が、ユーザーのデータを提供するサービス(リソースサーバー)と同じOrganizationに属していないアプリケーション(クライアント)を使用する場合などです。このようなケースで、アプリケーションがユーザーの所有するデータにアクセスする必要がある場合、ユーザーはそのデータが存在するOrganizationにリダイレクトされ、そのOrganizationがユーザーを認証してから、ユーザーに対して、アプリケーションにデータへのアクセス許可を与えるように求めます。アクセス許可を求めるこのプロンプトは同意の提供と呼ばれ、サードパーティアプリケーションのサポート提供の大きな部分を占めます。サードパーティアプリケーションを統合する予定がある場合は、Auth0がユーザーの同意を求めるプロンプトを処理するように、早い段階でサードパーティとしてマークすることが重要です。
一方、自社でアプリケーション、ユーザーデータ、およびデータへのアクセスに使用するAPIを所有している場合は、すべてのインタラクションがファーストパーティで行われるため、通常、同意が必要になることはありません。ファーストパーティアプリケーションのみを作成する場合は、リソースサービスの定義の一環としてユーザーの同意をスキップできるようにすることで、不要な同意画面がユーザーに表示されないようにすることができます。
また、追加の機能性が提供されており、明示的なユーザーの同意を得ることができない(つまり、同意を提供できる認証済みのユーザーがいない)ユーザーに関連するデータがある場合もあります。このシナリオでは、クライアント資格情報の付与が有効なアプリケーションのリストを定義することができます。
アクセストークンのクレーム
IDトークンの場合と同様に、Auth0のRule拡張性を利用して、カスタムクレームをアクセストークンに追加できます。その後、APIは必要なクレームのアクセストークンを検証し、必要に応じて特定の機能性へのアクセスを許可または拒否することができます。
ベストプラクティス
カスタムクレームの追加を検討している場合は、ユーザーのapp_metadata
の一部としてクレームに含める必要のあるアクセス制御データを保管することをお勧めします。まず第一に、これによりデータを取得するために外部のAPIを呼び出す必要がなくなります。外部APIの呼び出しはパフォーマンスと拡張性に悪影響を与える可能性があります。第二に、app_metadata
はユーザーによって直接変更「できない」ため、ユーザーが自身のメタデータを変更してアクセス制御の制限を回避することはできません。また、「メタデータのベストプラクティス」のガイダンスもご確認ください。
アクセストークンのスコープ
OAuth2スコープは通常、APIがユーザーに代わって実行できるアクションを決定できるメカニズムとして使用されます。スコープはAPIごとに追加でき、Auth0 Dashboardで、またはAuth0 Management APIを通じて特定のアクセス許可を定義します。また、スコープはAuth0の拡張性を介して操作することもできます(この例のように、Rule経由など)。アプリケーションがAPIにアクセスするために要求するスコープは、アプリケーションが使用するためにユーザーがアクセス許可を与える必要がある機能性に応じて選ぶ必要があります。要求されたスコープが認可されると、アクセストークンで返され、そのAPIによって検証できるようになります。良い例が、ログインにソーシャルプロバイダーを使用しているアプリケーションにログインする場面です。ソーシャルプロバイダーのAPIは、ユーザーが自分に代わってアプリケーションにアイテムを投稿させるかどうかをアプリケーションが指定することを求めます。これによって、ユーザーはこの要求を許可または拒否できます。この例は、ユーザーがアプリケーションにアクセス許可を委任する方法を示しています。ユーザーロールに基づいてアクセスを制限するAPIとは異なり、別の方法で処理する必要があります。
ベストプラクティス
Auth0の拡張性を通じて完全にアクセストークンスコープを操作できる能力を持っているとしても、セキュリティのベストプラクティスとして、消去するのは認可されていないスコープのみにし、要求されていないスコープの追加は避けるべきです。
スコープは、ユーザーのアクセス許可を適用する方法としてよく使用されますが、この方法で使用すると問題が発生する状況もあります。そのため、スコープは本来の目的(つまり、アプリケーションへのアクセス許可の委任)に使用し、ロールベースまたはその他のアクセス制御のシナリオにはカスタムクレームを使用することをお勧めします。
Fine-grained Authorization(FGA)
Fine Grained Authorizationを使用すると、以下の事項に基づいて特定のリソースまたはオブジェクトへのアクセスを個々のユーザーに付与できます。
editor
やeditor
など、Organization内でのユーザーの役割ユーザーまたはオブジェクトの属性(ユーザーの
manager
やオブジェクトのmarketing
など)ユーザーとオブジェクト間の関係(親フォルダーに対して表示アクセス権を持つユーザーは、その子フォルダーに対する表示アクセス権も持つなど)
FGAを使用すると、認可モデルを作成して、ユーザーのアクセス権を決定するために必要な関係性を判断できます。
Role Based Access Control(RBAC)
Auth0では、すぐに使えるRole Based Access Control(RBAC)がサポートされます。RBACとは、Organization内でのロールに基づいてユーザーにアクセス許可を割り当てることを指します。エラーが発生しにくく、管理しやすい方法なので、アクセス制御がシンプルになります。
マシンツーマシン(M2M)アプリケーション
APIを呼び出すために、ユーザー対話型セッションのないアプリケーションでアクセストークンを取得する必要があるシナリオは少なくありません。このようなシナリオでは、ユーザーではなくクライアントを認証しなければならず、OAuth 2では、これを簡単に達成できるクライアント資格情報付与タイプを提供しています。これが必要な一般的な例:
APIと通信する必要があるcronジョブまたはその他のサービス(たとえば、毎日レポートを生成して管理者にメールで送信する必要がある場合)。
特権アクセスをサポートする個別のAPI(たとえば、APIがユーザーの目に直接触れることがなく、バックエンドでのみ稼働する場合)。
一部のAPIレイヤーがユーザーの関与なしに、またはユーザートークンの有効期限が切れた後に、他のAPIレイヤーと通信する必要がある、特定のマイクロサービスアーキテクチャ。
ユーザーが認証される前に(Auth0テナントのルールまたはカスタムDBスクリプトから)呼び出される必要がある、権限付きのAPI
ベストプラクティス
今までは特別な「サービスアカウント」を作成することでこのようなケースに対応してきました。つまり、非対話的なユースケースに対応するサービスのために構成されたユーザー名とパスワードを持つユーザーのことです。さまざまな理由から、このアプローチは現在は推奨されていません。最新のベストプラクティスは、OAuth 2.0クライアント資格情報付与を使用することです。
プロジェクト計画ガイド
当社では、PDF形式の計画ガイダンスを提供しています。ダウンロードして、推奨される戦略の詳細を参照してください。
B2C IAM Project Planning Guide