OpenID Connect (OIDC) Integration for nginx via auth_request
Find a file
defelo-renovate[bot] 021c6ac138
chore(deps): update rust crate tempfile to 3.20.0 (#12)
Co-authored-by: defelo-renovate[bot] <186864790+defelo-renovate[bot]@users.noreply.github.com>
2025-05-11 21:14:23 +00:00
.github/workflows Merge pull request #5 from Defelo/renovate/determinatesystems-nix-installer-action-17.x 2025-04-24 13:41:59 +02:00
nix fix: set systemd service type to exec 2025-05-06 20:51:26 +02:00
src init 2025-04-16 20:56:23 +02:00
.envrc init 2025-04-16 20:56:23 +02:00
.gitattributes init 2025-04-16 20:56:23 +02:00
.gitignore init 2025-04-16 20:56:23 +02:00
Cargo.lock chore(deps): update rust crate tempfile to 3.20.0 (#12) 2025-05-11 21:14:23 +00:00
Cargo.nix chore(deps): update rust crate tempfile to 3.20.0 (#12) 2025-05-11 21:14:23 +00:00
Cargo.toml chore(deps): update rust crate tempfile to 3.20.0 (#12) 2025-05-11 21:14:23 +00:00
config.yml init 2025-04-16 20:56:23 +02:00
flake.lock init 2025-04-16 20:56:23 +02:00
flake.nix chore: add ci 2025-04-16 20:56:23 +02:00
LICENSE.md init 2025-04-16 20:56:23 +02:00
nixos-options.md init 2025-04-16 20:56:23 +02:00
README.md init 2025-04-16 20:56:23 +02:00
renovate.json chore: add renovate 2025-04-16 20:56:24 +02:00
treefmt.nix chore: add renovate 2025-04-16 20:56:24 +02:00

nginx-oidc

OpenID Connect (OIDC) Integration for nginx via auth_request

nginx-oidc enables single sign-on (SSO) via any OIDC provider (e.g. Kanidm, Authentik or Keycloak) for any nginx site using the auth_request module. It is primarily designed to run on NixOS, but should also work on any other Linux distribution.

Features

  • Stateless, easy to set up
  • Supports public and confidential OIDC clients
  • Enforces Proof Key for Code Exchange (PKCE)
  • Optional role-based access control
  • Bind session to user's ip address
  • Send headers containing information about the authenticated user to the proxied service using proxy_set_header
  • NixOS module

NixOS Module Documentation

See nixos-options.md

Setup Instructions (NixOS)

  1. Add this repository as an input to your flake.nix:
    {
      inputs.nginx-oidc.url = "github:Defelo/nginx-oidc";
    }
    
  2. Add the module to your NixOS configuration:
    {
      imports = [nginx-oidc.nixosModules.default];
    }
    

Server

The nginx-oidc server only needs to be reachable by nginx. It is recommended to run both nginx and nginx-oidc on the same host and let nginx-oidc listen on a unix socket (configured automatically by the NixOS module if not explicitly changed).

  1. Enable the nginx-oidc server by setting services.nginx.oidc.enable = true;.
  2. (recommended) Generate a random cookie secret file (e.g. using head -c 64 /dev/urandom) and set services.nginx.oidc.settings.cookie_secret_path to the absolute path of this file. If this option is not set, a random secret is generated on each start, invalidating any previously issued auth/session cookies.
  3. Configure your OIDC client(s) via the services.nginx.oidc.settings.clients option. You need to specify at least the issuer URL. The client_id defaults to the client name (attribute name). If you want to configure a confidential client, you need to specify the client_secret_path. Omit this option in case of a public client.

Nginx Integration

Make sure your nginx is compiled with the --with-http_auth_request_module configure flag to include the ngx_http_auth_request_module. On NixOS this flag is already set.

  1. Enable nginx-oidc for all locations you want to restrict by setting services.nginx.virtualHosts.<name>.locations.<name>.oidc.enable = true;
  2. Set the clientName option to the name of the client configured in the nginx-oidc server you want to use. Defaults to the name of the virtual host if unset.
  3. (optional) Set the role option to allow access to only users with a specific role.
  4. If you set up the nginx-oidc server on a different host (not recommended), you need to set the nginxOidcUrl option accordingly.

How it works

  1. When a user tries to access a restricted location, nginx sends an HTTP request to <nginx-oidc>/auth/<client> which includes the session cookie (if set).
  2. If the session cookie is valid and the user is authorized to access this location, nginx-oidc returns a 200 OK and access is granted. Otherwise a 401 Unauthorized is returned including a signed and encrypted auth cookie which contains the URL the user tried to access and the OAuth2 state and an X-Auth-Redirect header which nginx then translates into a redirect to the auth URL of the OIDC provider.
  3. After logging in to the OIDC provider the user is redirected to the callback location on the same virtualHost as the restricted location which is proxied to <nginx-oidc>/callback/<client>. nginx-oidc then completes the OIDC flow by exchanging the authorization code for an access token and fetches the user's information from the OIDC provider. A signed and encrypted session cookie is set and the user is redirected back to the URL they originally came from.
  4. If the session cookie has expired, nginx-oidc tries to refetch the user's information using the access/refresh tokens. If this fails, the user is redirected to the OIDC provider to reauthenticate.