kych-oauth2-gateway.1.rst (8713B)
1 kych-oauth2-gateway(1) 2 ###################### 3 4 .. only:: html 5 6 Name 7 ==== 8 9 **kych-oauth2-gateway** - OAuth 2.0 gateway for SWIYU credential verification 10 11 12 Synopsis 13 ======== 14 15 **kych-oauth2-gateway** 16 [**-c** *FILE*] 17 [**-L** *LEVEL*] 18 [**-v**] 19 20 **kych-oauth2-gateway** 21 [**-h** | **-V**] 22 23 24 Description 25 =========== 26 27 **kych-oauth2-gateway** is an HTTP server that lets an OAuth 2.0 client - 28 typically a GNU Taler exchange performing KYC - obtain identity attributes 29 from the Swiss SWIYU e-ID trust infrastructure. 30 31 Towards the client it speaks a plain OAuth 2.0 authorization code flow. 32 Towards the SWIYU verifier it speaks OpenID for Verifiable Presentations 33 (OID4VP): it builds a presentation definition, has the user's SWIYU wallet 34 present an SD-JWT verifiable credential against it, and hands the disclosed 35 claims back to the client. The OAuth 2.0 *scope* of the authorization request 36 names the credential claims to disclose, which is what makes the disclosure 37 selective: a client that only needs proof of majority requests the scope 38 ``age_over_18``, and learns nothing else. 39 40 The gateway does not verify credentials itself and holds no signing keys. All 41 cryptographic verification happens in the SWIYU verifier that kych.conf(5) 42 points each client at; the gateway keeps the session state, mints the OAuth 43 2.0 codes and tokens, and stores the wallet's response until the client 44 collects it. 45 46 Its options are as follows: 47 48 **-c** *FILE* \| **--config=**\ *FILE* 49 Read the configuration from *FILE*. Without it the standard search path 50 applies, ending at ``/etc/kych/kych.conf``. See kych.conf(5). 51 52 **-L** *LEVEL* \| **--log=**\ *LEVEL* 53 Set the logging verbosity. Accepted values are ``ERROR``, ``WARN``, 54 ``INFO``, ``DEBUG`` and ``TRACE``, or the numbers 1 to 5; case is ignored. 55 Defaults to ``INFO``. An unrecognised value is refused before the server 56 starts. 57 58 .. note:: 59 60 At ``DEBUG`` the log includes the generated nonces, authorization codes 61 and the full request bodies exchanged with the verifier. Such logs 62 contain both secrets and personal data. 63 64 **-v** \| **--verbose** 65 Also log what the libraries have to say. Without it, messages from 66 ``sqlx``, ``axum``, ``hyper``, ``h2``, ``reqwest``, ``rustls`` and ``mio`` 67 are dropped whatever **-L** says, which is what keeps ``DEBUG`` readable. 68 69 **-h** \| **--help** 70 Print short help on options and exit. 71 72 **-V** \| **--version** 73 Print version information and exit. 74 75 Each line of the log carries a timestamp with the machine's UTC offset, the 76 level, the source and, for anything logged while handling a request, a random 77 ten-character identifier of that request in parentheses - which is how the 78 several lines belonging to one verification can be told apart under load. 79 Under systemd the timestamp is omitted, since the journal records its own. 80 81 82 Endpoints 83 ========= 84 85 The server exposes the following HTTP endpoints. The REST API is specified in 86 detail in the KyCH OAuth2 Gateway RESTful API documentation; the summary here 87 is limited to what an administrator needs in order to place the service 88 behind a reverse proxy. 89 90 ``GET /config`` 91 Public. Reports the credential type, format, algorithms and the complete 92 set of claims a client may request, as configured by ``VC_TYPE``, 93 ``VC_FORMAT``, ``VC_ALGORITHMS`` and ``VC_CLAIMS``. 94 95 ``POST /setup/{client_id}`` 96 Authenticated with the client secret as an HTTP bearer token. Opens a 97 verification session and returns its *nonce*, the unguessable part of the 98 authorization URL handed to the user. The session expires after 15 minutes. 99 100 ``GET /authorize/{nonce}`` 101 Entered by the user's browser. Takes the OAuth 2.0 parameters 102 *response_type* (which must be ``code``), *client_id*, *redirect_uri*, 103 *state* and *scope* as query arguments, creates the verification at the 104 SWIYU verifier and returns the wallet's verification URL. With an *Accept* 105 header naming ``text/html`` the reply is a page showing a QR code and a 106 wallet deep link; otherwise it is JSON. 107 108 The *redirect_uri* must appear in the client's registered allowlist, and 109 every claim in *scope* must be permitted, or the request is refused. 110 Re-entering the URL replays the existing verification instead of starting a 111 second one. 112 113 ``POST /notification`` 114 Unauthenticated webhook, called by the SWIYU verifier when a wallet has 115 responded. The gateway then fetches the result from the verifier, stores 116 the disclosed credential and mints the authorization code. It answers 117 ``200 OK`` in all cases, including every failure, so that the verifier does 118 not retry; problems are visible only in the log. 119 120 ``GET /status/{verification_id}`` 121 Polled by the browser during verification, authorised by the OAuth 2.0 122 *state* value as a query argument. Reports ``pending``, ``authorized``, 123 ``verified``, ``completed``, ``failed`` or ``expired``. 124 125 ``GET /finalize/{verification_id}`` 126 Also authorised by *state*. Redirects the browser back to the client's 127 *redirect_uri* with the authorization code, once the session is verified. 128 129 ``POST /token`` 130 The OAuth 2.0 token endpoint, form-encoded, authenticated with *client_id* 131 and *client_secret*. Exchanges the authorization code for a bearer token 132 valid for one hour. The code is single-use, and the *redirect_uri* must 133 match the one used at authorization time. 134 135 ``GET /info`` 136 Authenticated with the bearer token from ``/token``. Returns the disclosed 137 credential as JSON. 138 139 140 Environment 141 =========== 142 143 ``LISTEN_FDS``, ``LISTEN_PID`` 144 Read when ``SERVE = systemd``: the listening socket is taken from the 145 service manager instead of being bound. Ignored otherwise. 146 147 ``JOURNAL_STREAM`` 148 Set by systemd. Its presence suppresses the timestamp on each log line, 149 because the journal already records one. 150 151 ``XDG_CONFIG_HOME``, ``HOME`` 152 Searched for a configuration file when **-c** is not given, and expanded in 153 options that name a path. ``$PATH`` is searched for the 154 ``kych-oauth2-gateway`` binary itself, to derive ``$PREFIX`` and the other 155 variables of the ``[paths]`` section. 156 157 ``PGHOST``, ``PGPORT``, ``PGUSER``, ``PGPASSWORD``, ``PGDATABASE``, ``PGSSLMODE`` 158 Supply defaults for any part that the ``DATABASE`` connection string leaves 159 out. Note that ``~/.pgpass`` is *not* consulted when ``DATABASE`` is given 160 in URI form, which it normally is. 161 162 163 Files 164 ===== 165 166 ``/etc/kych/kych.conf`` 167 Configuration file, as installed by the Debian package, and the last of the 168 four locations searched when **-c** is not given. See kych.conf(5). 169 170 ``/usr/share/kych/config.d/`` 171 Read before the configuration file itself, so that packaged defaults can be 172 overridden rather than edited. 173 174 ``./js/`` 175 The QR code helper served under the ``/js`` URL prefix is read from a path 176 *relative to the working directory* of the process, not from an installed 177 location. Start the server from the directory that holds ``js/`` - the 178 packaged systemd unit uses ``/usr/share/kych`` - or the authorization page 179 will render without its QR code. 180 181 ``/run/kych/kych.sock`` 182 Listening socket of the packaged service: created by the server itself per 183 ``UNIXPATH`` with the shipped ``SERVE = unix``, or by ``kych.socket`` with 184 ``SERVE = systemd``. 185 186 187 Security 188 ======== 189 190 The server speaks plain HTTP and never terminates TLS; run it behind a 191 reverse proxy. It performs no privilege separation, so run it as an 192 unprivileged user. 193 194 Access control differs per endpoint, and none of it is a substitute for a 195 proxy that restricts who may reach what. In particular ``/notification`` 196 accepts unauthenticated requests and should be reachable only from the 197 verifier's address, while ``/status`` and ``/finalize`` are protected merely 198 by knowledge of the OAuth 2.0 *state* value. 199 200 201 Exit Status 202 =========== 203 204 On ``SIGINT`` or ``SIGTERM`` the server stops accepting connections, lets the 205 requests it is already handling finish, and exits zero. It exits non-zero 206 before serving any request if the configuration cannot be read or is 207 incomplete (for instance if ``SERVE = unix`` without a ``UNIXPATH``), if the 208 database is unreachable, or if the listening socket cannot be bound. 209 210 211 Examples 212 ======== 213 214 Start the server with a configuration file: 215 216 .. code-block:: shell 217 218 $ kych-oauth2-gateway -c /etc/kych/kych.conf 219 220 Start the server with debug logging enabled: 221 222 .. code-block:: shell 223 224 $ kych-oauth2-gateway -c /etc/kych/kych.conf -L DEBUG 225 226 227 See Also 228 ======== 229 230 kych-client-management(1), kych.conf(5). 231 232 The KyCH operator manual, https://docs.taler.net/taler-kych-manual.html, and 233 the REST API specification, https://docs.taler.net/core/api-kych.html. 234 235 236 Bugs 237 ==== 238 239 Report bugs by using https://bugs.taler.net/ or by sending electronic 240 mail to <taler@gnu.org>.