Skip to content

Commit 7498a03

Browse files
committed
better docs
1 parent 0ce6acf commit 7498a03

File tree

5 files changed

+156
-110
lines changed

5 files changed

+156
-110
lines changed

docs/en/operations/external-authenticators/tokens.md

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,34 @@ ClickHouse users can be authenticated using tokens. This works in two ways:
1313

1414
Although not all tokens are JWTs, under the hood both ways are treated as the same authentication method to maintain better compatibility.
1515

16-
## Token Processors
16+
# Token Processors
1717

18-
To use token-based authentication, add `token_processors` section to `config.xml` and define at least one token processor in it. Its contents are different for different token processing workflows (JWT and opaque (generic) tokens).
18+
## Configuration
19+
To use token-based authentication, add `token_processors` section to `config.xml` and define at least one token processor in it.
20+
Its contents are different for different token processor types.
1921

20-
### Common configuration parameters
21-
In addition to specific parameters (see below), there are also parameters that can be applied to a token processor of any type:
22-
- `cache_lifetime` -- maximum lifetime of cached token (in seconds). Optional, default: 3600.
22+
**Common parameters**
23+
- `type` -- type of token processor. Supported values: "JWT", "Azure", "OpenID". Mandatory. Case-insensitive.
24+
- `token_cache_lifetime` -- maximum lifetime of cached token (in seconds). Optional, default: 3600.
2325
- `username_claim` -- name of claim (field) that will be treated as ClickHouse username. Optional, default: "sub".
2426
- `groups_claim` -- Name of claim (field) that contains list of groups user belongs to. This claim will be looked up in the token itself (in case token is a valid JWT, e.g. in Keycloak) or in response from `/userinfo`. Optional, default: "groups".
2527

26-
### JWT (JSON Web Token)
28+
For each type, there are additional specific parameters.
29+
If some parameters that are not required for current processor type are specified, they are ignored.
30+
If there are conflicting parameters (e.g `algo` is specified together with `jwks_uri`), an exception will be thrown.
2731

28-
JWT itself is a source of information about user. It can be decoded locally, and its integrity can be verified using token issuer's (public) key.
32+
## JWT (JSON Web Token)
2933

30-
This key can exist in three ways:
31-
* ##### Static key:
34+
JWT itself is a source of information about user.
35+
It is decoded locally and its integrity is verified using either static key or JWKS (JSON Web Key Set), either local or remote.
36+
37+
`algo`, `static_jwks`/`static_jwks_file` and `jwks_uri` are defining different JWT processing workflows, and they cannot be specified together.
38+
### JWT with static key:
3239
```xml
3340
<clickhouse>
3441
<token_processors>
3542
<my_static_key_validator>
43+
<type>jwt</type>
3644
<algo>HS256</algo>
3745
<static_key>my_static_secret</static_key>
3846
</my_static_key_validator>
@@ -49,25 +57,28 @@ This key can exist in three ways:
4957
| HS512 | RS512 | ES512 | PS512 | |
5058
| | | ES256K | | |
5159
Also supports None (though not recommended).
60+
`claims` - A string containing a JSON object that should be contained in the token payload. If this parameter is defined, token without corresponding payload will be considered invalid. Optional.
5261
- `static_key` - key for symmetric algorithms. Mandatory for `HS*` family algorithms.
5362
- `static_key_in_base64` - indicates if the `static_key` key is base64-encoded. Optional, default: `False`.
5463
- `public_key` - public key for asymmetric algorithms. Mandatory except for `HS*` family algorithms and `None`.
5564
- `private_key` - private key for asymmetric algorithms. Optional.
5665
- `public_key_password` - public key password. Optional.
5766
- `private_key_password` - private key password. Optional.
5867

59-
* ##### Static JWKS
68+
### JWT with static JWKS
6069
```xml
6170
<clickhouse>
6271
<token_processors>
6372
<my_static_jwks_validator>
73+
<type>jwt</type>
6474
<static_jwks>{"keys": [{"kty": "RSA", "alg": "RS256", "kid": "mykid", "n": "_public_key_mod_", "e": "AQAB"}]}</static_jwks>
6575
</my_static_jwks_validator>
6676
</token_processors>
6777
</clickhouse>
6878
```
6979

70-
#### Parameters:
80+
**Parameters:**
81+
7182
- `static_jwks` - content of JWKS in JSON
7283
- `static_jwks_file` - path to a file with JWKS
7384
- `claims` - A string containing a JSON object that should be contained in the token payload. If this parameter is defined, token without corresponding payload will be considered invalid. Optional.
@@ -81,63 +92,85 @@ Only one of `static_jwks` or `static_jwks_file` keys must be present in one veri
8192
Only RS* family algorithms are supported!
8293
:::
8394

84-
* ##### Remote JWKS
95+
### JWT with remote JWKS
8596
```xml
8697
<clickhouse>
8798
<token_processors>
8899
<basic_auth_server>
100+
<type>jwt</type>
89101
<jwks_uri>http://localhost:8000/.well-known/jwks.json</jwks_uri>
90-
<jwks_refresh_timeout>300000</jwks_refresh_timeout>
102+
<jwks_cache_lifetime>3600</jwks_cache_lifetime>
91103
</basic_auth_server>
92104
</token_processors>
93105
</clickhouse>
94106
```
95107

96-
#### Parameters:
108+
**Parameters:**
97109

98110
- `uri` - JWKS endpoint. Mandatory.
99-
- `jwks_refresh_timeout` - Period for resend request for refreshing JWKS. Optional, default: 300000.
111+
- `jwks_cache_lifetime` - Period for resend request for refreshing JWKS. Optional, default: 3600.
100112
- `claims` - A string containing a JSON object that should be contained in the token payload. If this parameter is defined, token without corresponding payload will be considered invalid. Optional.
101113
- `verifier_leeway` - Clock skew tolerance (seconds). Useful for handling small differences in system clocks between ClickHouse and the token issuer. Optional.
102114

103115

104-
### Opaque tokens
116+
## Processors with external providers
117+
118+
Some tokens cannot be decoded and validated locally. External service is needed in this case. "Azure" and "OpenID" (a generic type) are supported now.
105119

106-
To define a token processor, add `token_processors` section to `config.xml`. Example:
120+
### Azure
107121
```xml
108122
<clickhouse>
109123
<token_processors>
110-
<azuure>
111-
<provider>openid</provider>
112-
<cache_lifetime>600</cache_lifetime>
113-
<username_claim>sub</username_claim>
114-
<groups_claim>groups</groups_claim>
115-
</azuure>
124+
<azure_processor>
125+
<type>azure</type>
126+
</azure_processor>
116127
</token_processors>
117128
</clickhouse>
118129
```
119130

120-
:::note
121-
Different providers have different sets of parameters.
122-
:::
131+
No additional parameters are required.
123132

124-
**Parameters**
133+
### OpenID
134+
```xml
135+
<clickhouse>
136+
<token_processors>
137+
<oid_processor_1>
138+
<type>openid</type>
139+
<configuration_endpoint>url/.well-known/openid-configuration</configuration_endpoint>
140+
<verifier_leeway>60</verifier_leeway>
141+
<jwks_cache_lifetime>3600</jwks_cache_lifetime>
142+
</oid_processor_1>
143+
<oid_processor_2>
144+
<type>openid</type>
145+
<userinfo_endpoint>url/userinfo</userinfo_endpoint>
146+
<token_introspection_endpoint>url/tokeninfo</token_introspection_endpoint>
147+
<jwks_uri>url/.well-known/jwks.json</jwks_uri>
148+
<verifier_leeway>60</verifier_leeway>
149+
<jwks_cache_lifetime>3600</jwks_cache_lifetime>
150+
</oid_processor_2>
151+
</token_processors>
152+
</clickhouse>
153+
```
125154

126-
- `provider` -- name of identity provider. Mandatory, case-insensitive. Supported options: "Google", "Azure", "OpenID".
127-
- `configuration_endpoint` -- URI of `.well-known/openid-configuration`. Optional parameter, used only for OpenID providers.
128-
- `userinfo_endpoint` -- URI of userinfo endpoint. Optional parameter. Optional parameter, used only for OpenID providers.
129-
- `token_introspection_endpoint` -- URI of token introspection endpoint. Optional parameter. Optional parameter, used only for OpenID providers.
130-
131155
:::note
132-
Either `configuration_endpoint` or both `userinfo_endpoint` and `token_introspection_endpoint` shall be set. If none of them are set or all three are set, this is an invalid configuration that will not be parsed.
156+
Either `configuration_endpoint` or both `userinfo_endpoint` and `token_introspection_endpoint` (and, optionally, `jwks_uri`) shall be set. If none of them are set or all three are set, this is an invalid configuration that will not be parsed.
133157
:::
134158

159+
**Parameters:**
160+
161+
- `configuration_endpoint` - URI of OpenID configuration (often ends with `.well-known/openid-configuration`);
162+
- `userinfo_endpoint` - URI of endpoint that returns user information in exchange for a valid token;
163+
- `token_introspection_endpoint` - URI of token introspection endpoint (returns information about a valid token);
164+
- `jwks_uri` - URI of OpenID configuration (often ends with `.well-known/jwks.json`)
165+
- `jwks_cache_lifetime` - Period for resend request for refreshing JWKS. Optional, default: 3600.
166+
- `verifier_leeway` - Clock skew tolerance (seconds). Useful for handling small differences in system clocks between ClickHouse and the token issuer. Optional, default: 60
135167

168+
Sometimes a token is a valid JWT. In that case token will be decoded and validated locally if configuration endpoint returns JWKS URI (or `jwks_uri` is specified alongside `userinfo_endpoint` and `token_introspection_endpoint`).
136169

137170
### Tokens cache
138-
To reduce number of requests to IdP, tokens are cached internally for no longer then `cache_lifetime` seconds.
139-
If token expires sooner than `cache_lifetime`, then cache entry for this token will only be valid while token is valid.
140-
If token lifetime is longer than `cache_lifetime`, cache entry for this token will be valid for `cache_lifetime`.
171+
To reduce number of requests to IdP, tokens are cached internally for no longer then `token_cache_lifetime` seconds.
172+
If token expires sooner than `token_cache_lifetime`, then cache entry for this token will only be valid while token is valid.
173+
If token lifetime is longer than `token_cache_lifetime`, cache entry for this token will be valid for `token_cache_lifetime`.
141174

142175
## Enabling token authentication for a user in `users.xml` {#enabling-jwt-auth-in-users-xml}
143176

@@ -181,17 +214,7 @@ JWT authentication cannot be used together with any other authentication method.
181214

182215
## Enabling token authentication using SQL {#enabling-jwt-auth-using-sql}
183216

184-
When [SQL-driven Access Control and Account Management](/docs/en/guides/sre/user-management/index.md#access-control) is enabled in ClickHouse, users identified by JWT authentication can also be created using SQL statements.
185-
186-
```sql
187-
CREATE USER my_user IDENTIFIED WITH jwt CLAIMS '{"resource_access":{"account": {"roles": ["view-profile"]}}}'
188-
```
189-
190-
Or without additional JWT payload checks:
191-
192-
```sql
193-
CREATE USER my_user IDENTIFIED WITH jwt
194-
```
217+
Users with "JWT" authentication type cannot be created using SQL now.
195218

196219
## Identity Provider as an External User Directory {#idp-external-user-directory}
197220

src/Access/Common/JWKSProvider.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jwt::jwks<jwt::traits::kazuho_picojson> JWKSClient::getJWKS()
1919
std::shared_lock lock(mutex);
2020

2121
auto now = std::chrono::high_resolution_clock::now();
22-
auto diff = std::chrono::duration<double, std::milli>(now - last_request_send).count();
22+
auto diff = std::chrono::duration<double>(now - last_request_send).count();
2323

24-
if (diff < refresh_ms) {
24+
if (diff < refresh_timeout) {
2525
jwt::jwks <jwt::traits::kazuho_picojson> result(cached_jwks);
2626
return result;
2727
}

src/Access/Common/JWKSProvider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class IJWKSProvider
2323
class JWKSClient : public IJWKSProvider
2424
{
2525
public:
26-
explicit JWKSClient(const String & uri, const size_t refresh_ms_): refresh_ms(refresh_ms_), jwks_uri(uri) {}
26+
explicit JWKSClient(const String & uri, const size_t refresh_ms_): refresh_timeout(refresh_ms_), jwks_uri(uri) {}
2727

2828
~JWKSClient() override = default;
2929
JWKSClient(const JWKSClient &) = delete;
@@ -34,7 +34,7 @@ class JWKSClient : public IJWKSProvider
3434
jwt::jwks<jwt::traits::kazuho_picojson> getJWKS() override;
3535

3636
private:
37-
size_t refresh_ms;
37+
size_t refresh_timeout;
3838
Poco::URI jwks_uri;
3939

4040
std::shared_mutex mutex;

0 commit comments

Comments
 (0)