PAM with pam_nauthilus
pam_nauthilus is a PAM module from contrib/pam_nauthilus that authenticates users via the Nauthilus IdP Device Authorization flow (RFC 8628).
It presents a verification URL and user code to the user and polls the OIDC token endpoint until the flow is approved, denied, or timed out.
What It Is
- Implementation: pure C shared library (
pam_nauthilus.so) - Intended use: PAM stacks (for example
sshd,login) - IdP requirements: OIDC Device Authorization Grant enabled for the configured client
Build Requirements
- C compiler (
gccorclang) - PAM headers:
libpam-dev(Debian/Ubuntu) orpam-devel(RHEL/Fedora) - libcurl headers:
libcurl4-openssl-devorlibcurl-devel - OpenSSL headers:
libssl-devoropenssl-devel - cJSON headers:
libcjson-devorcjson-devel pkg-config
Build and Install
Build:
make build
Install:
sudo make install LIBDIR=/lib/security
Notes:
- Some systems use
/usr/lib/securityor/usr/lib64/security. - The module file name is
pam_nauthilus.so.
PAM Configuration Example
Example /etc/pam.d/sshd line:
auth required pam_nauthilus.so \
issuer=https://idp.example.com \
client_id=ssh \
client_secret=REDACTED \
scope=openid \
user_claim=preferred_username \
timeout=5m \
request_timeout=10s
If multiple scopes are needed in PAM config, encode spaces (for example scope=openid%20profile).
Module Options (Complete)
| Option | Required | Default | Description |
|---|---|---|---|
issuer | yes* | none | Base IdP URL, e.g. https://idp.example.com |
device_endpoint | no | ${issuer}/oidc/device | Device authorization endpoint override |
token_endpoint | no | ${issuer}/oidc/token | Token endpoint override |
userinfo_endpoint | no | ${issuer}/oidc/userinfo | UserInfo endpoint override |
jwks_endpoint | no | ${issuer}/oidc/jwks | JWKS endpoint override |
introspection_endpoint | no | ${issuer}/oidc/introspect | Introspection endpoint override |
client_id | yes | none | OIDC client ID |
client_secret | yes | none | OIDC client secret |
scope | no | openid | Requested scope list |
user_claim | no | preferred_username | Claim used to match PAM username |
timeout | no | 5m | Overall flow timeout |
request_timeout | no | 10s | Per-request HTTP timeout |
ca_file | no | none | Additional PEM CA bundle |
tls_server_name | no | none | TLS SNI override |
allow_http | no | false | Allow http:// endpoints (testing only) |
* issuer is required unless all endpoint overrides are set explicitly.
Required Nauthilus IdP Configuration
Minimal OIDC section for this PAM flow:
idp:
oidc:
enabled: true
issuer: "https://idp.example.com"
signing_keys:
- id: "main"
key_file: "/etc/nauthilus/oidc.key"
active: true
device_code_expiry: 10m
device_code_polling_interval: 5
device_code_user_code_length: 8
clients:
- name: "SSH"
client_id: "ssh"
client_secret: "REDACTED"
grant_types:
- urn:ietf:params:oauth:grant-type:device_code
token_endpoint_auth_method: "client_secret_basic"
scopes:
- openid
- profile
- email