Keycloak

Integration with Keycloak as an Auth provider

The gm-jwt-keycloak filter validates incoming requests against Keycloakarrow-up-right and generates an internal Grey Matter jwt tokenarrow-up-right.

Filter Configuration Options

Required Parameters

Name

Type

Example

Description

clientSecret

string

"40fcc8c9-0067-402e-95ac-a5aac213be8a"

Client secret from keycloak. See keycloak documentationarrow-up-right

clientID

string

"edge"

Name of the client created in Keycloak

endpoint

string

Full Keycloak URL

authnHeaderName

string

"access_token"

Name of header used for validating incoming and passing outgoing authentication tokens.

authzheaderName

string

"user_info"

Name of header used for validating incoming and passing outgoing authorization tokens

realm

string

"greymatter"

Name of the realm to be used in Keycloak

jwtPrivateKeyPath

string

"./certs/private_key.pem"

Private jwt key for Greymatter signing and validation

jwks

stringified JSON

"{"keys":[{"crv":"P-521","kid":"1","kty":"EC","x":"AStrIEK2lPMCEPCiOA-vhIx65kwGL1tCYXGNmhIAFJU8BrGlPO8WYm3aUcmCXNJD76wYL3oh9Wu5d7iJifAdZhbg","y":"AehFcEyvkz0-8MvMGQSUfw5GVdYQTaWSRiOIiGVjK2FJCcl7n70CCIlNKpK3c2LNJu2BzrQmh7y21Ug7jvSafbQI"}]}"

Public JSON web key sets for internal validation of tokens

sharedJwtKeycloakSecret

string

"password123"

User-created synthetic password for logging in users to Keycloak

Additional Parameters

Name
Type
Default
Description

useTls

bool

false

Should the filter use certs in connecting to key cloak?

certPath

string

"./certs/server.crt"

Certificate path

keyPath

string

"./certs/server.key"

Keyfile path

caPath

string

"./certs/intermediate.crt"

Certificate authority or intermediate certificate path

insecureSkipVerify

bool

false

Should calls to keycloak require hostname verification in certs?

timeoutMs

int

1000ms

Timeout in milliseconds for the connection between gm-proxy and gm-jwt-keycloak service. Set to a negative number to disable timeouts completely, though this is not advised as it can cause an infinite hang in the sidecar.

maxRetries

int

0

Number of retries after failed connection between gm-proxy and keycloak

retryDelayMs

int

0

Amount of time in milliseconds between each unsuccessful retry

cacheLimit

int

100

Maximum number of tokens held in cache. If negative, caching is disabled, must be > 0 to enable caching

cachedTokenExp

int

10m

Time in minutes to hold tokens in the cache. If negative, caching is disabled, must be > 0 to enable caching

writeBody

bool

false

Should tokens be written to the response body instead of headers?

fetchFullToken

bool

false

Should the full token be fetched from Keycloak's /userinfo endpoint instead of logging in the client from the /token endpoint?

authenticateOnly

bool

false

If true, filter will only validate incoming tokens and will not reach out to keycloak to create new tokens

Setting Up PKI Users

In addition to using Keycloak as an OIDC provider for the mesh, the jwt.keycloak filter can also generate JWT tokens for users entering the mesh with certificates. To do this, the following must be configured:

Retrieve an admin-cli client token to make API changes in keycloak. An example of retrieving this with curl could be:

Find a user's email in the certificate, predicated by cn=. For example, a user with the certificate metadata "CN=bob.smith@greymatter.io,OU=,O=,L=,ST=,C=" will have the email bob.smith@greymatter.io.

Generate a user's synthetic password using a user's username (e.g. bob.smith) and sharedJwtKeycloakSecret that you have entered and configured in the filter. The algorithm we use for computing the synthetic password is sha256(sharedJwtKeycloakSecret + username). For example, in golang this would be:

Create a json file user.json and enter in the information from above:

Make an API request to Keycloak's users API to create the user using the access_token generated above:

The user is now successfully initialized in Keycloak and will be able to be logged in via PKI from the keycloak filter.

Flow Chart

Last updated

Was this helpful?