canonical / canonical/authd

Enforce authd account locks and detected IdP disablement in PAM account management

Open
#1,888 0 comments 1 reaction 0 assignees View on GitHub
jira
Dominant language
Go
Stars
308
Forks
41
Avg merge
2d 4h
Merged PRs (30d)
58

Description

### Summary

SSH public-key authentication is performed by `sshd` rather than through PAM's `auth` stack. However, when `UsePAM yes` is enabled, OpenSSH still runs the PAM account stack through `pam_acct_mgmt()` after authentication succeeds.

authd currently exposes `pam_sm_acct_mgmt`, but `pamModule.AcctMgmt` returns `PAM_IGNORE`. As a result, SSH public-key logins bypass:

- Accounts locked with `authctl user lock`
- Users previously detected as disabled by the identity provider
- Devices previously detected as disabled by the identity provider

These states are recorded locally by authd. This gap is documented in #1878.

### Expected behavior

For an authd-managed user, the PAM account phase should deny the login when:

- The user is marked `locked` in authd's local database.
- The broker has previously determined that the user's identity-provider account is disabled and stored `UserIsDisabled: true`.
- The broker has previously determined that the device is disabled by the identity provider and stored `DeviceIsDisabled: true`.

The denial must happen before `sshd` sends the final authentication-success response.

Local Unix users and users unknown to authd should continue through the remaining PAM account stack by returning `PAM_IGNORE`.

### Implementation notes

- Replace the no-op `pamModule.AcctMgmt` implementation.
- Have the PAM module query authd rather than reading broker `token.json` files directly.
- Add an authd-side account-check operation that:
- Checks the local account lock state.
- Resolves the user's configured broker.
- Asks the broker for the previously detected user/device disabled state.
- Preserve provider-ID-aware user lookup so an identity-provider username change does not lose a local account lock.
- Return an appropriate PAM denial status and log the reason without exposing unnecessary account details.

A live identity-provider check is not required for the initial implementation. Previously detected user and device disablement should be enforced; live revocation checks and their offline behavior can be addressed separately.

Contributor guide

Open the contributing guide

Research direction

Start at pamModule.AcctMgmt and trace the authd account-check boundary and broker state lookup described in the issue. Done means authd-managed locked or previously disabled users and devices are denied before SSH reports success, while local or unknown users still return PAM_IGNORE; verify this with the relevant PAM account-management tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, linux
Domain
authentication, backend, operating-systems, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
56/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.