Keycloak Integration for Nginx via auth_request
Restricts access to Nginx sites by requiring users to authenticate with their Keycloak account. Only users with a specific role (configurable per service) are granted access.
- Create a new
OpenID Connect
client in Keycloak - Enable
Client authentication
- Create Redirect URIs for your services (e.g.
https://<DOMAIN>/_auth/callback
, seeAUTH_CALLBACK
environment variable) - Copy secret from
Credentials
tab - Go to
Client scopes
→CLIENT_ID-dedicated
and add a predefinedclient roles
mapper:- Set
Client ID
to the id of your client - Set
Token Claim Name
toroles
- Disable
Add to access token
- Enable
Add to userinfo
- Save
- Set
- Create client roles for your services
- Update your
ISSUER
url - Set
CLIENT_ID
to your client id andCLIENT_SECRET
to your client secret - (optional) Change
AUTH_CALLBACK
to a different path it the default conflicts with one of your services - (optional) Adjust
SESSION_ALLOWED_TTL
andSESSION_FORBIDDEN_TTL
- Make sure your nginx includes the
ngx_http_auth_request_module
:nginx -V |& grep http_auth_request_module
- Create an internal
location
block in your server:location .auth { internal; proxy_pass http://CONTAINER_HOST:CONTAINER_PORT/auth?role=SERVICE_ROLE_NAME; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Request-Uri $scheme://$host$request_uri; }
- Add the following to any
location
block you want to control access to:auth_request .auth; auth_request_set $auth_redirect $upstream_http_x_auth_redirect; auth_request_set $auth_cookie $upstream_http_x_auth_cookie; error_page 401 =307 $auth_redirect; add_header Set-Cookie $auth_cookie always;
On a NixOS system you can import the nginx-keycloak.nixosModules.nginx-keycloak
module and
configure it like this:
{
services.nginx-keycloak = {
enable = true;
settings = {
host = "127.0.0.1";
port = 8000;
client_id = "nginx";
client_secret_file = "/run/secrets/nginx-keycloak/client_secret";
keycloak_base_url = "https://id.domain.de/realms/main/";
};
};
}
Now you can use the following configuration to restrict access to nginx locations:
{
services.nginx.virtualHosts."my-service.domain.de" = {
locations."/" = {
return = "200 'Hello World!'";
extraConfig = nginx-keycloak.lib.auth_config ".auth";
};
locations.".auth" = nginx-keycloak.lib.auth_location {
host = "http://127.0.0.1:8000";
role = "my-service";
};
};
}