]> begriffs open source - ai-pg/blob - full-docs/txt/oauth-validator-design.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / oauth-validator-design.txt
1
2 50.1. Safely Designing a Validator Module #
3
4    50.1.1. Validator Responsibilities
5    50.1.2. General Coding Guidelines
6    50.1.3. Authorizing Users (Usermap Delegation)
7
8 Warning
9
10    Read and understand the entirety of this section before implementing a
11    validator module. A malfunctioning validator is potentially worse than
12    no authentication at all, both because of the false sense of security
13    it provides, and because it may contribute to attacks against other
14    pieces of an OAuth ecosystem.
15
16 50.1.1. Validator Responsibilities #
17
18    Although different modules may take very different approaches to token
19    validation, implementations generally need to perform three separate
20    actions:
21
22    Validate the Token
23           The validator must first ensure that the presented token is in
24           fact a valid Bearer token for use in client authentication. The
25           correct way to do this depends on the provider, but it generally
26           involves either cryptographic operations to prove that the token
27           was created by a trusted party (offline validation), or the
28           presentation of the token to that trusted party so that it can
29           perform validation for you (online validation).
30
31           Online validation, usually implemented via OAuth Token
32           Introspection, requires fewer steps of a validator module and
33           allows central revocation of a token in the event that it is
34           stolen or misissued. However, it does require the module to make
35           at least one network call per authentication attempt (all of
36           which must complete within the configured
37           authentication_timeout). Additionally, your provider may not
38           provide introspection endpoints for use by external resource
39           servers.
40
41           Offline validation is much more involved, typically requiring a
42           validator to maintain a list of trusted signing keys for a
43           provider and then check the token's cryptographic signature
44           along with its contents. Implementations must follow the
45           provider's instructions to the letter, including any
46           verification of issuer ("where is this token from?"), audience
47           ("who is this token for?"), and validity period ("when can this
48           token be used?"). Since there is no communication between the
49           module and the provider, tokens cannot be centrally revoked
50           using this method; offline validator implementations may wish to
51           place restrictions on the maximum length of a token's validity
52           period.
53
54           If the token cannot be validated, the module should immediately
55           fail. Further authentication/authorization is pointless if the
56           bearer token wasn't issued by a trusted party.
57
58    Authorize the Client
59           Next the validator must ensure that the end user has given the
60           client permission to access the server on their behalf. This
61           generally involves checking the scopes that have been assigned
62           to the token, to make sure that they cover database access for
63           the current HBA parameters.
64
65           The purpose of this step is to prevent an OAuth client from
66           obtaining a token under false pretenses. If the validator
67           requires all tokens to carry scopes that cover database access,
68           the provider should then loudly prompt the user to grant that
69           access during the flow. This gives them the opportunity to
70           reject the request if the client isn't supposed to be using
71           their credentials to connect to databases.
72
73           While it is possible to establish client authorization without
74           explicit scopes by using out-of-band knowledge of the deployed
75           architecture, doing so removes the user from the loop, which
76           prevents them from catching deployment mistakes and allows any
77           such mistakes to be exploited silently. Access to the database
78           must be tightly restricted to only trusted clients ^[17] if
79           users are not prompted for additional scopes.
80
81           Even if authorization fails, a module may choose to continue to
82           pull authentication information from the token for use in
83           auditing and debugging.
84
85    Authenticate the End User
86           Finally, the validator should determine a user identifier for
87           the token, either by asking the provider for this information or
88           by extracting it from the token itself, and return that
89           identifier to the server (which will then make a final
90           authorization decision using the HBA configuration). This
91           identifier will be available within the session via system_user
92           and recorded in the server logs if log_connections is enabled.
93
94           Different providers may record a variety of different
95           authentication information for an end user, typically referred
96           to as claims. Providers usually document which of these claims
97           are trustworthy enough to use for authorization decisions and
98           which are not. (For instance, it would probably not be wise to
99           use an end user's full name as the identifier for
100           authentication, since many providers allow users to change their
101           display names arbitrarily.) Ultimately, the choice of which
102           claim (or combination of claims) to use comes down to the
103           provider implementation and application requirements.
104
105           Note that anonymous/pseudonymous login is possible as well, by
106           enabling usermap delegation; see Section 50.1.3.
107
108 50.1.2. General Coding Guidelines #
109
110    Developers should keep the following in mind when implementing token
111    validation:
112
113    Token Confidentiality
114           Modules should not write tokens, or pieces of tokens, into the
115           server log. This is true even if the module considers the token
116           invalid; an attacker who confuses a client into communicating
117           with the wrong provider should not be able to retrieve that
118           (otherwise valid) token from the disk.
119
120           Implementations that send tokens over the network (for example,
121           to perform online token validation with a provider) must
122           authenticate the peer and ensure that strong transport security
123           is in use.
124
125    Logging
126           Modules may use the same logging facilities as standard
127           extensions; however, the rules for emitting log entries to the
128           client are subtly different during the authentication phase of
129           the connection. Generally speaking, modules should log
130           verification problems at the COMMERROR level and return
131           normally, instead of using ERROR/FATAL to unwind the stack, to
132           avoid leaking information to unauthenticated clients.
133
134    Interruptibility
135           Modules must remain interruptible by signals so that the server
136           can correctly handle authentication timeouts and shutdown
137           signals from pg_ctl. For example, blocking calls on sockets
138           should generally be replaced with code that handles both socket
139           events and interrupts without races (see WaitLatchOrSocket(),
140           WaitEventSetWait(), et al), and long-running loops should
141           periodically call CHECK_FOR_INTERRUPTS(). Failure to follow this
142           guidance may result in unresponsive backend sessions.
143
144    Testing
145           The breadth of testing an OAuth system is well beyond the scope
146           of this documentation, but at minimum, negative testing should
147           be considered mandatory. It's trivial to design a module that
148           lets authorized users in; the whole point of the system is to
149           keep unauthorized users out.
150
151    Documentation
152           Validator implementations should document the contents and
153           format of the authenticated ID that is reported to the server
154           for each end user, since DBAs may need to use this information
155           to construct pg_ident maps. (For instance, is it an email
156           address? an organizational ID number? a UUID?) They should also
157           document whether or not it is safe to use the module in
158           delegate_ident_mapping=1 mode, and what additional configuration
159           is required in order to do so.
160
161 50.1.3. Authorizing Users (Usermap Delegation) #
162
163    The standard deliverable of a validation module is the user identifier,
164    which the server will then compare to any configured pg_ident.conf
165    mappings and determine whether the end user is authorized to connect.
166    However, OAuth is itself an authorization framework, and tokens may
167    carry information about user privileges. For example, a token may be
168    associated with the organizational groups that a user belongs to, or
169    list the roles that a user may assume, and duplicating that knowledge
170    into local usermaps for every server may not be desirable.
171
172    To bypass username mapping entirely, and have the validator module
173    assume the additional responsibility of authorizing user connections,
174    the HBA may be configured with delegate_ident_mapping. The module may
175    then use token scopes or an equivalent method to decide whether the
176    user is allowed to connect under their desired role. The user
177    identifier will still be recorded by the server, but it plays no part
178    in determining whether to continue the connection.
179
180    Using this scheme, authentication itself is optional. As long as the
181    module reports that the connection is authorized, login will continue
182    even if there is no recorded user identifier at all. This makes it
183    possible to implement anonymous or pseudonymous access to the database,
184    where the third-party provider performs all necessary authentication
185    but does not provide any user-identifying information to the server.
186    (Some providers may create an anonymized ID number that can be recorded
187    instead, for later auditing.)
188
189    Usermap delegation provides the most architectural flexibility, but it
190    turns the validator module into a single point of failure for
191    connection authorization. Use with caution.
192
193    ^[17] That is, "trusted" in the sense that the OAuth client and the
194    PostgreSQL server are controlled by the same entity. Notably, the
195    Device Authorization client flow supported by libpq does not usually
196    meet this bar, since it's designed for use by public/untrusted clients.