This is an older version of Search Guard. Switch to Latest version
Integrating with OpenID providers
Content
Search Guard can integrate with identity providers (IdP) that are compatible with the OpenID standard. This will allow for:
- Automatic configuration
- You just need to point Search Guard to the metadata of your IdP, and Search Guard will use that data for configuration
- Automatic key fetching
- Search Guard will retrieve the public key for validating the JSON web tokens automatically from the JWKS endpoint of your IdP. There is no need to configure keys or shared secrets in
sg_config.yml
.
- Search Guard will retrieve the public key for validating the JSON web tokens automatically from the JWKS endpoint of your IdP. There is no need to configure keys or shared secrets in
- Key rollover
- You can change the keys used for signing the JWTs directly in your IdP. If Search Guard detects an unknown key, it tries to retrieve it from the IdP, transparent to the user.
- Kibana Single Sign On
Configuring OpenID integration
To integrate with an OpenID IdP, set up an authentication domain and choose openid
as HTTP authentication type. Since JSON web tokens already contain all required information to verify the request, challenge
can be set to false
and authentication_backend
to noop
.
Minimal configuration:
openid_auth_domain:
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: openid
challenge: false
config:
subject_key: preferred_username
roles_key: roles
openid_connect_url: https://keycloak.example.com:8080/auth/realms/master/.well-known/openid-configuration
authentication_backend:
type: noop
Configuration parameters:
Name | Description |
---|---|
openid_connect_url | The URL of your IdP where Search Guard can find the OpenID metadata/configuration settings. This URL differs between IdPs, please refer to your IdP configuration. Mandatory. |
jwt_header | The HTTP header which stores the token. This is typically the Authorization header with the Bearer schema: Authorization: Bearer <token> . Optional. The default is Authorization . |
jwt_url_parameter | If the token is not transmitted in the HTTP header, but as an URL parameter, define the name of this parameter here. Optional. |
subject_key | The key in the JSON payload that stores the user’s name. If not defined, the subject registered claim is used. Most IdP providers use the preferred_username claim. Optional. |
roles_key | The key in the JSON payload that stores the user’s roles. The value of this key must be a comma-separated list of roles. Mandatory only if you want to use roles in the JWT. |
subject_pattern | A regular expression that defines the structure of an expected user name. You can use capturing groups to use only a certain part of the subject supplied by the JWT as the Search Guard user name. If the pattern does not match, login will fail. See below for details. Optional, defaults to no pattern. |
proxy | If the IdP is only reachable via an HTTP proxy, you can use the proxy option to define the URI of the proxy. Optional, defaults to no proxy. |
OpenID connect URL
OpenID specifies various endpoints for integration purposes. The most important endpoint is the well-known
configuration endpoint: It lists endpoints and other configuration options relevant to Search Guard.
The URL differs between IdPs, but it usually ends in /.well-known/openid-configuration
. Keycloak example:
http(s)://<server>:<port>/auth/realms/<realm>/.well-known/openid-configuration
The main information that Search Guard needs is the jwks_uri
. This URI specifies where the IdP’s public key(s) in JWKS format can be found. Example:
jwks_uri: "https://keycloak.example.com:8080/auth/realms/master/protocol/openid-connect/certs"
{
keys:[
{
kid:"V-diposfUJIk5jDBFi_QRouiVinG5PowskcSWy5EuCo",
kty:"RSA",
alg:"RS256",
use:"sig",
n:"rI8aUrAcI_auAdF10KUopDOmEFa4qlUUaNoTER90XXWADtKne6VsYoD3ZnHGFXvPkRAQLM5d65ScBzWungcbLwZGWtWf5T2NzQj0wDyquMRwwIAsFDFtAZWkXRfXeXrFY0irYUS9rIJDafyMRvBbSz1FwWG7RTQkILkwiC4B8W1KdS5d9EZ8JPhrXvPMvW509g0GhLlkBSbPBeRSUlAS2Kk6nY5i3m6fi1H9CP3Y_X-TzOjOTsxQA_1pdP5uubXPUh5YfJihXcgewO9XXiqGDuQn6wZ3hrF6HTlhNWGcSyQPKh1gEcmXWQlRENZMvYET-BuJEE7eKyM5vRhjNoYR3w",
e:"AQAB"
}
]
}
You can find more information about the endpoint for your IdP here:
Fetching public keys: The key id
When an IdP generates and signs a JSON web token, it must add the id of the key to the header part of the JWT. Example:
{
"alg": "RS256",
"typ": "JWT",
"kid": "V-diposfUJIk5jDBFi_QRouiVinG5PowskcSWy5EuCo"
}
As per OpenID specification, the kid
(“key id”) is mandatory. Token verification will not work if an IdP fails to add the kid
field to the JWT.
If Search Guard receives a JWT with an unknown kid
, it will visit the IdP’s jwks_uri
and retrieve all currently available valid keys. These keys will be used and cached until a refresh is triggered by retrieving another unknown key id.
Key rollover and multiple public keys
Search Guard is capable of maintaining multiple valid public keys at once. Since the OpenID specification does not allow for a validity period of public keys, a key is deemed valid until it has been removed from the list of valid keys in your IdP, and until the list of valid keys has been refreshed.
If you want to roll over a key in your IdP, it is good practice to:
- Create a new key pair in your IdP, and give the new key a higher priority than the currently used key
- Your IdP will use this new key over the old key
- Upon first appearance of the new
kid
in a JWT, Search Guard will refresh the key list- At this point, both the old key and the new key are valid
- Tokens signed with the old key are also still valid
- The old key can be removed from your IdP when the last JWT signed with this key has timed out
If you have to immediately change your public key, because the currently used key has been comprised, you can also delete the old key first and then create a new one. In this case, all JWTs signed with the old key will become invalid immediately.
Using only certain sections of a JWT subject claim as user name
In some cases, the subject claim in a JWT might be more complex than needed or wanted. For example, a JWT subject claim could be specified as an email address like [email protected]
. The subject_pattern
option gives you the possibility to only use the local part (i.e., exampleuser
) as the user name inside Search Guard.
With subject_pattern
you specify a regular expression that defines the structure of an expected user name. You can then use capturing groups (i.e., sections enclosed in round parentheses; (...)
) to use only a certain part of the subject supplied by the JWT as the Search Guard user name.
For example:
jwt_auth_domain:
http_enabled: true
order: 0
http_authenticator:
type: openid
challenge: false
config:
subject_pattern: "^(.+)@example\.com$"
In this example, (.+)
is the capturing group, i.e., at least one character. This group must be followed by the string @example.com
, which must be present, but will not be part of the resulting user name in Search Guard. If you try to login with a subject that does not match this pattern (e.g. foo@bar
), login will fail.
You can use all the pattern features which the Java Pattern
class supports. See the official documentation for details.
Keep in mind that all capturing groups are used for constructing the user name. If you need grouping only because you want to apply a pattern quantifier or operator, you should use non-capturing groups: (?:...)
.
Example for using capturing groups and non-capturing groups:
subject_pattern: "^(.+)@example\.(?:com|org)$"
In this example, the group around com
and org
is required to use the alternative operator |
. But it must be non-capturing, because otherwise it would show up in the user name.
You can however also use several capturing groups if you want to use these groups for the user name:
subject_pattern: "^(.+)@example\.com|(.+)@foo\.bar$"
TLS settings
In order to prevent man-in-the-middle attacks and other attack scenarios you should secure the connection between Search Guard and your IdP with TLS.
Enabling TLS
Use the following parameters to enable TLS for connecting to your IdP:
config:
openid_connect_idp:
enable_ssl: <true|false>
verify_hostnames: <true|false>
Name | Description |
---|---|
enable_ssl | Whether to use a custom TLS configuration. Defaults to false which indicates that the certificate specified in the configuration searchguard.ssl.transport.pemtrustedcas_filepath is used. |
verify_hostnames | Whether to verify the hostnames of the IdP’s TLS certificate or not. Default: true |
Certificate validation
To validate the TLS certificate of your IdP, configure either the path to the IdP’s root CA or the root certificates content like:
config:
openid_connect_idp:
enable_ssl: true
pemtrustedcas_filepath: /path/to/trusted_cas.pem
or
config:
openid_connect_idp:
enable_ssl: true
pemtrustedcas_content: |-
MIID/jCCAuagAwIBAgIBATANBgkqhkiG9w0BAQUFADCBjzETMBEGCgmSJomT8ixk
ARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1w
bGUgQ29tIEluYy4xITAfBgNVBAsMGEV4YW1wbGUgQ29tIEluYy4gUm9vdCBDQTEh
...
Name | Description |
---|---|
pemtrustedcas_filepath | Absolute path to the PEM file containing the root CA(s) of your IdP |
pemtrustedcas_content | The root CA content of your IdP. Cannot be used when pemtrustedcas_filepath is set. |
TLS client authentication
To use TLS client authentication, configure the PEM certificate and private key Search Guard should send for TLS client authentication, or its contents like:
config:
openid_connect_idp:
enable_ssl: true
pemkey_filepath: /path/to/private.key.pem
pemkey_password: private_key_password
pemcert_filepath: /path/to/certificate.pem
or
config:
openid_connect_idp:
enable_ssl: true
pemkey_content: |-
MIID2jCCAsKgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBlTETMBEGCgmSJomT8ixk
ARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1w
bGUgQ29tIEluYy4xJDAiBgNVBAsMG0V4YW1wbGUgQ29tIEluYy4gU2lnbmluZyBD
...
pemkey_password: private_key_password
pemcert_content: |-
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHRZwzwGlP2FvL
oEzNeDu2XnOF+ram7rWPT6fxI+JJr3SDz1mSzixTeHq82P5A7RLdMULfQFMfQPfr
WXgB4qfisuDSt+CPocZRfUqqhGlMG2l8LgJMr58tn0AHvauvNTeiGlyXy0ShxHbD
...
Name | Description |
---|---|
enable_ssl_client_auth | Whether to send the client certificate to the IdP server or not. Default: false |
pemcert_filepath | Absolute path to the the client certificate. |
pemcert_content | The content of the client certificate. Cannot be used when pemcert_filepath is set. |
pemkey_filepath | Absolute path to the file containing the private key of the client certificate. |
pemkey_content | The content of the private key of your client certificate. Cannot be used when pemkey_filepath is set. |
pemkey_password | The password of your private key, if any. |
Enabled ciphers and protocols
You can limit the allowed ciphers and TLS protocols by using the following keys:
Name | Description |
---|---|
enabled_ssl_ciphers | Array, enabled TLS cipher suites. Only Java format is supported. |
enabled_ssl_protocols | Array, enabled TLS protocols. Only Java format is supported. |
Expert: DOS protection
In theory it is possible to DOS attack an OpenID based infrastructure by sending tokens with randomly generated, non-existing key ids at a high frequency. In order to mitigate this, Search Guard will only allow a maximum number of new key ids in a certain time frame. If more unknown key ids are receievd, Search Guard will return a HTTP status code 503 (Service not available) and refuse to query the IdP. By defaut, Search Guard does not allow for more than 10 unknown key ids in a time window of 10 seconds. You can control these settings by the following configuration keys:
Name | Description |
---|---|
refresh_rate_limit_count | The maximum number of unknown key ids in the time window. Default: 10 |
refresh_rate_limit_time_window_ms | The time window to use when checking the maximum number of unknown key ids, in milliseconds. Default: 10000 |
Kibana Single Sign On
The Kibana Plugin has OpenID support built in since version 14. Please refer to the Kibana OpenID configuration for details.
Additional resources