]> begriffs open source - ai-pg/blob - full-docs/txt/libpq-oauth.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / libpq-oauth.txt
1
2 32.20. OAuth Support #
3
4    32.20.1. Authdata Hooks
5    32.20.2. Debugging and Developer Settings
6
7    libpq implements support for the OAuth v2 Device Authorization client
8    flow, documented in RFC 8628, as an optional module. See the
9    installation documentation for information on how to enable support for
10    Device Authorization as a builtin flow.
11
12    When support is enabled and the optional module installed, libpq will
13    use the builtin flow by default if the server requests a bearer token
14    during authentication. This flow can be utilized even if the system
15    running the client application does not have a usable web browser, for
16    example when running a client via SSH.
17
18    The builtin flow will, by default, print a URL to visit and a user code
19    to enter there:
20 $ psql 'dbname=postgres oauth_issuer=https://example.com oauth_client_id=...'
21 Visit https://example.com/device and enter the code: ABCD-EFGH
22
23    (This prompt may be customized.) The user will then log into their
24    OAuth provider, which will ask whether to allow libpq and the server to
25    perform actions on their behalf. It is always a good idea to carefully
26    review the URL and permissions displayed, to ensure they match
27    expectations, before continuing. Permissions should not be given to
28    untrusted third parties.
29
30    Client applications may implement their own flows to customize
31    interaction and integration with applications. See Section 32.20.1 for
32    more information on how add a custom flow to libpq.
33
34    For an OAuth client flow to be usable, the connection string must at
35    minimum contain oauth_issuer and oauth_client_id. (These settings are
36    determined by your organization's OAuth provider.) The builtin flow
37    additionally requires the OAuth authorization server to publish a
38    device authorization endpoint.
39
40 Note
41
42    The builtin Device Authorization flow is not currently supported on
43    Windows. Custom client flows may still be implemented.
44
45 32.20.1. Authdata Hooks #
46
47    The behavior of the OAuth flow may be modified or replaced by a client
48    using the following hook API:
49
50    PQsetAuthDataHook #
51           Sets the PGauthDataHook, overriding libpq's handling of one or
52           more aspects of its OAuth client flow.
53
54 void PQsetAuthDataHook(PQauthDataHook_type hook);
55
56           If hook is NULL, the default handler will be reinstalled.
57           Otherwise, the application passes a pointer to a callback
58           function with the signature:
59
60 int hook_fn(PGauthData type, PGconn *conn, void *data);
61
62           which libpq will call when an action is required of the
63           application. type describes the request being made, conn is the
64           connection handle being authenticated, and data points to
65           request-specific metadata. The contents of this pointer are
66           determined by type; see Section 32.20.1.1 for the supported
67           list.
68
69           Hooks can be chained together to allow cooperative and/or
70           fallback behavior. In general, a hook implementation should
71           examine the incoming type (and, potentially, the request
72           metadata and/or the settings for the particular conn in use) to
73           decide whether or not to handle a specific piece of authdata. If
74           not, it should delegate to the previous hook in the chain
75           (retrievable via PQgetAuthDataHook).
76
77           Success is indicated by returning an integer greater than zero.
78           Returning a negative integer signals an error condition and
79           abandons the connection attempt. (A zero value is reserved for
80           the default implementation.)
81
82    PQgetAuthDataHook #
83           Retrieves the current value of PGauthDataHook.
84
85 PQauthDataHook_type PQgetAuthDataHook(void);
86
87           At initialization time (before the first call to
88           PQsetAuthDataHook), this function will return
89           PQdefaultAuthDataHook.
90
91 32.20.1.1. Hook Types #
92
93    The following PGauthData types and their corresponding data structures
94    are defined:
95
96    PQAUTHDATA_PROMPT_OAUTH_DEVICE #
97           Replaces the default user prompt during the builtin device
98           authorization client flow. data points to an instance of
99           PGpromptOAuthDevice:
100
101 typedef struct _PGpromptOAuthDevice
102 {
103     const char *verification_uri;   /* verification URI to visit */
104     const char *user_code;          /* user code to enter */
105     const char *verification_uri_complete;  /* optional combination of URI and
106                                              * code, or NULL */
107     int         expires_in;         /* seconds until user code expires */
108 } PGpromptOAuthDevice;
109
110           The OAuth Device Authorization flow which can be included in
111           libpq requires the end user to visit a URL with a browser, then
112           enter a code which permits libpq to connect to the server on
113           their behalf. The default prompt simply prints the
114           verification_uri and user_code on standard error. Replacement
115           implementations may display this information using any preferred
116           method, for example with a GUI.
117
118           This callback is only invoked during the builtin device
119           authorization flow. If the application installs a custom OAuth
120           flow, or libpq was not built with support for the builtin flow,
121           this authdata type will not be used.
122
123           If a non-NULL verification_uri_complete is provided, it may
124           optionally be used for non-textual verification (for example, by
125           displaying a QR code). The URL and user code should still be
126           displayed to the end user in this case, because the code will be
127           manually confirmed by the provider, and the URL lets users
128           continue even if they can't use the non-textual method. For more
129           information, see section 3.3.1 in RFC 8628.
130
131    PQAUTHDATA_OAUTH_BEARER_TOKEN #
132           Adds a custom implementation of a flow, replacing the builtin
133           flow if it is installed. The hook should either directly return
134           a Bearer token for the current user/issuer/scope combination, if
135           one is available without blocking, or else set up an
136           asynchronous callback to retrieve one.
137
138           data points to an instance of PGoauthBearerRequest, which should
139           be filled in by the implementation:
140
141 typedef struct PGoauthBearerRequest
142 {
143     /* Hook inputs (constant across all calls) */
144     const char *openid_configuration; /* OIDC discovery URL */
145     const char *scope;                /* required scope(s), or NULL */
146
147     /* Hook outputs */
148
149     /* Callback implementing a custom asynchronous OAuth flow. */
150     PostgresPollingStatusType (*async) (PGconn *conn,
151                                         struct PGoauthBearerRequest *request,
152                                         SOCKTYPE *altsock);
153
154     /* Callback to clean up custom allocations. */
155     void        (*cleanup) (PGconn *conn, struct PGoauthBearerRequest *request);
156
157     char       *token;   /* acquired Bearer token */
158     void       *user;    /* hook-defined allocated data */
159 } PGoauthBearerRequest;
160
161           Two pieces of information are provided to the hook by libpq:
162           openid_configuration contains the URL of an OAuth discovery
163           document describing the authorization server's supported flows,
164           and scope contains a (possibly empty) space-separated list of
165           OAuth scopes which are required to access the server. Either or
166           both may be NULL to indicate that the information was not
167           discoverable. (In this case, implementations may be able to
168           establish the requirements using some other preconfigured
169           knowledge, or they may choose to fail.)
170
171           The final output of the hook is token, which must point to a
172           valid Bearer token for use on the connection. (This token should
173           be issued by the oauth_issuer and hold the requested scopes, or
174           the connection will be rejected by the server's validator
175           module.) The allocated token string must remain valid until
176           libpq is finished connecting; the hook should set a cleanup
177           callback which will be called when libpq no longer requires it.
178
179           If an implementation cannot immediately produce a token during
180           the initial call to the hook, it should set the async callback
181           to handle nonblocking communication with the authorization
182           server. ^[16] This will be called to begin the flow immediately
183           upon return from the hook. When the callback cannot make further
184           progress without blocking, it should return either
185           PGRES_POLLING_READING or PGRES_POLLING_WRITING after setting
186           *pgsocket to the file descriptor that will be marked ready to
187           read/write when progress can be made again. (This descriptor is
188           then provided to the top-level polling loop via PQsocket().)
189           Return PGRES_POLLING_OK after setting token when the flow is
190           complete, or PGRES_POLLING_FAILED to indicate failure.
191
192           Implementations may wish to store additional data for
193           bookkeeping across calls to the async and cleanup callbacks. The
194           user pointer is provided for this purpose; libpq will not touch
195           its contents and the application may use it at its convenience.
196           (Remember to free any allocations during token cleanup.)
197
198 32.20.2. Debugging and Developer Settings #
199
200    A "dangerous debugging mode" may be enabled by setting the environment
201    variable PGOAUTHDEBUG=UNSAFE. This functionality is provided for ease
202    of local development and testing only. It does several things that you
203    will not want a production system to do:
204      * permits the use of unencrypted HTTP during the OAuth provider
205        exchange
206      * allows the system's trusted CA list to be completely replaced using
207        the PGOAUTHCAFILE environment variable
208      * prints HTTP traffic (containing several critical secrets) to
209        standard error during the OAuth flow
210      * permits the use of zero-second retry intervals, which can cause the
211        client to busy-loop and pointlessly consume CPU
212
213 Warning
214
215    Do not share the output of the OAuth flow traffic with third parties.
216    It contains secrets that can be used to attack your clients and
217    servers.
218
219    ^[16] Performing blocking operations during the
220    PQAUTHDATA_OAUTH_BEARER_TOKEN hook callback will interfere with
221    nonblocking connection APIs such as PQconnectPoll and prevent
222    concurrent connections from making progress. Applications which only
223    ever use the synchronous connection primitives, such as PQconnectdb,
224    may synchronously retrieve a token during the hook instead of
225    implementing the async callback, but they will necessarily be limited
226    to one connection at a time.