バージョンごとのドキュメント一覧

50.1. 検証器モジュールを安全に設計する #

<title>Safely Designing a Validator Module</title>

警告

Read and understand the entirety of this section before implementing a validator module. A malfunctioning validator is potentially worse than no authentication at all, both because of the false sense of security it provides, and because it may contribute to attacks against other pieces of an OAuth ecosystem. 検証器モジュールを実装する前にこのセクション全体を読んで理解してください。 機能不全の検証器は、それが提供する誤った安全感と、OAuthエコシステムの他の部分に対する攻撃に寄与する可能性があるため、全くセキュリティがないよりも潜在的に悪いです。

50.1.1. 検証器の役割 #

<title>Validator Responsibilities</title>

Although different modules may take very different approaches to token validation, implementations generally need to perform three separate actions: 異なるモジュールは、トークンバリデーションに対して非常に異なるアプローチをとることがありますが、実装は一般に、3つの別個のアクションを実行する必要があります。

トークンを検証する

The validator must first ensure that the presented token is in fact a valid Bearer token for use in client authentication. The correct way to do this depends on the provider, but it generally involves either cryptographic operations to prove that the token was created by a trusted party (offline validation), or the presentation of the token to that trusted party so that it can perform validation for you (online validation). 検証器は、まず、提示されたトークンが実際にクライアント認証で使用するための有効なベアラトークンであることを確認する必要があります。 これを行う正しい方法はプロバイダに依存しますが、通常は、トークンが信頼できる組織によって作成されたことを証明するための暗号処理(オフラインバリデーション)、またはバリデーションを実行できるようにその信頼できる組織にトークンを提示する(オンラインバリデーション)ことが含まれます。

Online validation, usually implemented via <ulink url="https://datatracker.ietf.org/doc/html/rfc7662">OAuth Token Introspection</ulink>, requires fewer steps of a validator module and allows central revocation of a token in the event that it is stolen or misissued. However, it does require the module to make at least one network call per authentication attempt (all of which must complete within the configured <xref linkend="guc-authentication-timeout"/>). Additionally, your provider may not provide introspection endpoints for use by external resource servers. オンライン検証(通常はOAuthトークンイントロスペクションを介して実装される)では、検証器モジュールの手順が少なくて済み、盗難または誤発行されたイベントのトークンを一元的に失効させることができます。 ただし、モジュールは、認証の試行ごとに少なくとも1つのネットワーク呼び出しを行う必要があります(これらはすべて、設定されたauthentication_timeout内で完了する必要があります)。 また、プロバイダは、外部リソースサーバが使用するイントロスペクションエンドポイントを提供しない場合があります。

Offline validation is much more involved, typically requiring a validator to maintain a list of trusted signing keys for a provider and then check the token's cryptographic signature along with its contents. Implementations must follow the provider's instructions to the letter, including any verification of issuer ("where is this token from?"), audience ("who is this token for?"), and validity period ("when can this token be used?"). Since there is no communication between the module and the provider, tokens cannot be centrally revoked using this method; offline validator implementations may wish to place restrictions on the maximum length of a token's validity period. オフライン検証ははるかに複雑であり、通常検証器はプロバイダのトラステッド署名キーのリストを維持し、チェックはトークンの暗号署名とその内容を維持する必要があります。 実装は、発行者(「このトークンはどこから来たのか?」)、オーディエンス(「このトークンは誰のためのものか?」)、有効性ピリオド(「このトークンはいつ使用できるのか?」)の検証を含む、プロバイダの指示に従わなければなりません。 モジュールとプロバイダの間には通信がないため、このメソッドを使用してトークンを一元的に取り消すことはできません。 オフライン検証器の実装では、トークンの有効性ピリオドの最大長さに制限を設けることができます。

If the token cannot be validated, the module should immediately fail. Further authentication/authorization is pointless if the bearer token wasn't issued by a trusted party. トークンが検証できない場合、モジュールは直ちに失敗します。 ベアラトークンが信頼できる組織によって発行されていない場合、それ以上の認証/認可は無意味です。

クライアントの認可

Next the validator must ensure that the end user has given the client permission to access the server on their behalf. This generally involves checking the scopes that have been assigned to the token, to make sure that they cover database access for the current HBA parameters. 次に検証器は、エンドユーザが、彼らに代わってサーバによるクライアントアクセスの許可を与えていることを確認しなければなりません。 これには通常、現在のHBAパラメータによるデータベースアクセスをカバーしていることを確認するために、トークンにアサインされたスコープをチェックすることが含まれます。

The purpose of this step is to prevent an OAuth client from obtaining a token under false pretenses. If the validator requires all tokens to carry scopes that cover database access, the provider should then loudly prompt the user to grant that access during the flow. This gives them the opportunity to reject the request if the client isn't supposed to be using their credentials to connect to databases. このステップの目的は、OAuthクライアントが虚偽の理由でトークンを取得するのを防ぐことです。 検証器がすべてのトークンにデータベースアクセスを可能にする内容を伴うことを要求する場合、処理中にプロバイダはユーザにアクセス許可を明示的に求める必要があります。 これにより、クライアントが資格情報を使用してデータベースに接続することになっていない場合に、リクエストを拒否する機会が与えられます。

While it is possible to establish client authorization without explicit scopes by using out-of-band knowledge of the deployed architecture, doing so removes the user from the loop, which prevents them from catching deployment mistakes and allows any such mistakes to be exploited silently. Access to the database must be tightly restricted to only trusted clients デプロイされたアーキテクチャに関する外部から得た知識を用いることで、明示的なスコープを用いずにクライアント認可を確立することも可能ですが、そうするとユーザを処理の中から排除し、設定の誤りに気が付かなくなることになり、その誤りが気が付かないうちに悪用されることになります。 もしユーザが追加のスコープの入力を求められない場合は、データベースへのアクセスは信頼できるユーザ [17] if users are not prompted for additional scopes. にのみしっかりと制限されなければなりません。

Even if authorization fails, a module may choose to continue to pull authentication information from the token for use in auditing and debugging. 認可が失敗した場合でも、モジュールは、監査およびデバッグで使用するために、トークンから認証情報を引き続き取得し続けることを選択できます。

エンドユーザを認証する

Finally, the validator should determine a user identifier for the token, either by asking the provider for this information or by extracting it from the token itself, and return that identifier to the server (which will then make a final authorization decision using the HBA configuration). This identifier will be available within the session via <link linkend="functions-info-session-table"><function>system_user</function></link> and recorded in the server logs if <xref linkend="guc-log-connections"/> is enabled. 最後に、検証器は、プロバイダにこの情報を要求するか、トークン自身からこの情報を抽出することによって、識別子をサーバに返します(サーバはHBA設定を使用して最終的な認可を決定します)。 log_connectionsが有効になっている場合、この識別子はsystem_userを介してセッション内で使用可能になり、サーバログに記録されます。

Different providers may record a variety of different authentication information for an end user, typically referred to as <emphasis>claims</emphasis>. Providers usually document which of these claims are trustworthy enough to use for authorization decisions and which are not. (For instance, it would probably not be wise to use an end user's full name as the identifier for authentication, since many providers allow users to change their display names arbitrarily.) Ultimately, the choice of which claim (or combination of claims) to use comes down to the provider implementation and application requirements. 様々なプロバイダが、あるエンドユーザの様々な認証情報を記録する場合があります、通常は要求(claims)と呼ばれます。 プロバイダは通常、これらの要求のうち、許可決定に使用できるほど信頼できるものと信頼できないものを記録します。 (たとえば、多くのプロバイダでは、ユーザがディスプレイ名を任意に変更できるので、エンドユーザのフルネームを認証の識別子として使用することは賢明ではありません。) 結局のところ、どの要求(または要求の組合せ)を使用するかの選択は、プロバイダの実装とアプリケーションの要件に依存します。

Note that anonymous/pseudonymous login is possible as well, by enabling usermap delegation; see <xref linkend="oauth-validator-design-usermap-delegation"/>. ユーザマップ委任を有効にすることで、匿名/仮名のログインも可能であることに注意してください。50.1.3を参照してください。

50.1.2. 一般的なコーディングガイドライン #

<title>General Coding Guidelines</title>

Developers should keep the following in mind when implementing token validation: 開発者は、トークンバリデーションを実装する際に、次の点に留意する必要があります。

トークンの機密性

Modules should not write tokens, or pieces of tokens, into the server log. This is true even if the module considers the token invalid; an attacker who confuses a client into communicating with the wrong provider should not be able to retrieve that (otherwise valid) token from the disk. モジュールは、サーバログにトークンまたはトークンの断片を書き込むべきではありません。 モジュールがトークンを無効だと見なしたとしても、これは当てはまります。クライアントを混乱させて間違ったプロバイダと通信させようとする攻撃者が、ディスクから(そうでなければ有効な)トークンを取得できるべきではありません。

Implementations that send tokens over the network (for example, to perform online token validation with a provider) must authenticate the peer and ensure that strong transport security is in use. (例えば、プロバイダとオンライントークンバリデーションを行うために)ネットワークを介してトークンを送信する実装は、ピアを認証し、強力なトランスポートセキュリティが使用されていることを確認する必要があります。

ログ書き込み

Modules may use the same <link linkend="error-message-reporting">logging facilities</link> as standard extensions; however, the rules for emitting log entries to the client are subtly different during the authentication phase of the connection. Generally speaking, modules should log verification problems at the <symbol>COMMERROR</symbol> level and return normally, instead of using <symbol>ERROR</symbol>/<symbol>FATAL</symbol> to unwind the stack, to avoid leaking information to unauthenticated clients. モジュールは、標準の拡張機能と同様に、同じロギングファシリティを使用できます。ただし、コネクションの認証フェーズ中にクライアントへログエントリを出力する際のルールは、微妙に異なります。 一般的に、認証されていないクライアントへの情報の漏洩を回避するために、ERROR/FATALを使用してスタックを巻き戻すのではなく、検証上の問題をCOMMERRORレベルでログに記録し、正常に終了する方が適切です。

Interruptibility

Modules must remain interruptible by signals so that the server can correctly handle authentication timeouts and shutdown signals from <application>pg_ctl</application>. For example, blocking calls on sockets should generally be replaced with code that handles both socket events and interrupts without races (see <function>WaitLatchOrSocket()</function>, <function>WaitEventSetWait()</function>, et al), and long-running loops should periodically call <function>CHECK_FOR_INTERRUPTS()</function>. Failure to follow this guidance may result in unresponsive backend sessions. モジュールは、サーバが正しく認証タイムアウトとpg_ctlからのシャットダウンシグナルを処理できるように、シグナルによる割り込みが可能でなければなりません。 たとえば、ソケット上のブロッキング呼び出しは、一般的にソケットイベントと割り込みの両方を競合せずに処理するコードに置き換えるべきで(WaitLatchOrSocket()WaitEventSetWait()、などを参照してください)、長時間実行されるループはCHECK_FOR_INTERRUPTS()定期的に呼び出しする必要があります。 このガイダンスに従わないと、バックエンドセッションが応答しなくなる可能性があります。

テスト

The breadth of testing an OAuth system is well beyond the scope of this documentation, but at minimum, negative testing should be considered mandatory. It's trivial to design a module that lets authorized users in; the whole point of the system is to keep unauthorized users out. OAuthシステムのテストの幅は、この文書のスコープをはるかに超えていますが、少なくともネガティブテストは必須であると考えるべきです。 許可されたユーザをログインさせるモジュールを設計するのは簡単です。 システムの全体的なポイントは、許可されていないユーザを締め出すことです。

文書化

Validator implementations should document the contents and format of the authenticated ID that is reported to the server for each end user, since DBAs may need to use this information to construct pg_ident maps. (For instance, is it an email address? an organizational ID number? a UUID?) They should also document whether or not it is safe to use the module in <symbol>delegate_ident_mapping=1</symbol> mode, and what additional configuration is required in order to do so. DBAがpg_identマップを作成するためにこの情報を使用する必要があるかもしれないので、実装はサーバに報告される各ユーザの認証されたIDの内容と形式を文書化する必要があります。 (たとえば、それはメールアドレスか?組織ID番号か?UUIDか?) また、モジュールをdelegate_ident_mapping=1モードで使用するのが安全かどうか、そしてそうするための追加の設定は何かも文書化するのが良いでしょう。

50.1.3. ユーザの認可(ユーザマップ移譲) #

<title>Authorizing Users (Usermap Delegation)</title>

The standard deliverable of a validation module is the user identifier, which the server will then compare to any configured <link linkend="auth-username-maps"><filename>pg_ident.conf</filename> mappings</link> and determine whether the end user is authorized to connect. However, OAuth is itself an authorization framework, and tokens may carry information about user privileges. For example, a token may be associated with the organizational groups that a user belongs to, or list the roles that a user may assume, and duplicating that knowledge into local usermaps for every server may not be desirable. 検証モジュールの標準的な成果物はユーザ識別子であり、サーバは設定されたpg_ident.confマッピングと比較して、エンドユーザが接続を認可されているかどうかを判断します。 ただし、OAuthは自分自身で認可フレームワークであり、トークンはユーザ特権に関する情報を運ぶ場合があります。 たとえば、トークンはユーザが属する組織グループに関連付けられたり、ユーザが引き受ける役割をリストに関連付けられたりすることがあり、その情報をすべてのサーバのローカルユーザマップに複製することは望ましくない場合があります。

To bypass username mapping entirely, and have the validator module assume the additional responsibility of authorizing user connections, the HBA may be configured with <xref linkend="auth-oauth-delegate-ident-mapping"/>. The module may then use token scopes or an equivalent method to decide whether the user is allowed to connect under their desired role. The user identifier will still be recorded by the server, but it plays no part in determining whether to continue the connection. ユーザ名マッピングをバイパスし、検証器モジュールにユーザ接続を許可する追加の責任を負わせるには、HBAをdelegate_ident_mappingで構成します。 モジュールは、トークンスコープまたは同等のメソッドを使用して、ユーザが目的のロールの下で接続できるかどうかを決定します。 ユーザ識別子はサーバによって記録されますが、コネクションを継続するかどうかを決定する際には関係ありません。

Using this scheme, authentication itself is optional. As long as the module reports that the connection is authorized, login will continue even if there is no recorded user identifier at all. This makes it possible to implement anonymous or pseudonymous access to the database, where the third-party provider performs all necessary authentication but does not provide any user-identifying information to the server. (Some providers may create an anonymized ID number that can be recorded instead, for later auditing.) この方式を使用すると、認証自体はオプショナルになります。 モジュールがコネクションが許可されていることを報告する限り、ユーザ識別子がまったく記録されていなくてもログインは続行されます。 これにより、データベースに匿名または仮名のアクセスを実装することが可能になります。 この場合、サードパーティプロバイダは必要な認証をすべて実行しますが、ユーザを識別する情報をサーバに提供しません。 (プロバイダによっては、後で監査するために、代わりに記録できる匿名化されたID番号を作成する場合があります。)

Usermap delegation provides the most architectural flexibility, but it turns the validator module into a single point of failure for connection authorization. Use with caution. ユーザマップ委任は、最も柔軟なアーキテクチャを提供しますが、検証器モジュールをコネクション認可の単一障害点にしてしまいます。 注意して使用してください。



[17] That is, "trusted" in the sense that the OAuth client and the <productname>PostgreSQL</productname> server are controlled by the same entity. Notably, the Device Authorization client flow supported by libpq does not usually meet this bar, since it's designed for use by public/untrusted clients. つまり、OAuthクライアントとPostgreSQLサーバが同じエンティティによって制御されているという意味での「信頼できる」です。 特に、libpqによってサポートされているデバイス認証クライアントフローは、パブリック/信頼できないクライアントによって使用されるように設計されているため、通常はこの基準を満たしません。