andrewmusselman opened a new pull request, #922:
URL: https://github.com/apache/tooling-trusted-releases/pull/922

   # Invalidate SSH keys when user account is disabled
   
   Fixes #737 
   
   ## Problem
   
   When an LDAP account is banned or deleted, the user's SSH keys remain valid. 
The SSH authentication flow in `atr/ssh.py` validates key existence and 
expiration but does not check account status. Additionally, workflow SSH keys 
(20-minute TTL) have no mechanism for immediate revocation before expiry.
   
   ## Solution
   
   Three layers of defense:
   
   1. **LDAP check during SSH authentication** (new) — `begin_auth()` rejects 
banned/deleted users before loading keys; `validate_public_key()` rejects 
banned/deleted users before accepting workflow keys
   2. **`revoked` flag on workflow SSH keys** (new) — allows immediate 
invalidation of in-flight workflow keys before their 20-minute TTL expires
   3. **Admin revocation page** (new) — allows admins to delete all persistent 
SSH keys and revoke all workflow keys for a user instantly
   
   ## Changes
   
   ### New files
   - `atr/admin/templates/revoke-user-ssh-keys.html` — admin page template with 
two tables (persistent keys, workflow keys)
   - `migrations/versions/0062_2026.03.19_ef59ffaf.py` — Alembic migration 
adding `revoked` column to `workflowsshkey`
   - `tests/e2e/admin/test_revoke_ssh_keys.py` — 8 e2e tests (page rendering, 
form validation, revocation flow, nav link)
   
   ### Modified files
   - `atr/ssh.py` — adds LDAP account status check in `begin_auth()` and 
`validate_public_key()`, checks `revoked` flag on workflow keys
   - `atr/models/sql.py` — adds `revoked: bool` field to `WorkflowSSHKey`
   - `atr/storage/writers/ssh.py` — adds `FoundationAdmin` class with 
`revoke_all_user_keys()`
   - `atr/storage/__init__.py` — wires `ssh` into `WriteAsFoundationAdmin`
   - `atr/admin/__init__.py` — adds `RevokeUserSSHKeysForm`, GET/POST route 
handlers
   - `atr/templates/includes/topnav.html` — adds "Revoke user SSH keys" nav 
link under Admin
   - `atr/docs/authentication-security.md` — documents SSH key security 
properties and implementation references
   - `atr/docs/authorization-security.md` — documents SSH admin revocation 
access control
   - `tests/e2e/admin/helpers.py` — adds `REVOKE_SSH_KEYS_PATH` constant
   - `tests/e2e/admin/conftest.py` — adds `page_revoke_ssh_keys` fixture
   
   ## Design decisions
   
   - **Persistent keys deleted, workflow keys marked revoked**: Persistent keys 
have no TTL — deleting them is clean. Workflow keys have a 20-minute TTL; 
marking them `revoked=True` preserves an audit trail of what was in flight when 
revocation happened.
   - **LDAP failure = auth rejected**: If LDAP is unreachable during SSH auth, 
authentication fails closed. SSH write access can modify releases, so 
availability is less critical than preventing banned users from authenticating.
   - **Separate page from PAT revocation**: Keeps each admin page focused on 
one credential type. Same form pattern (REVOKE confirmation, PRG redirect, 
audit logged).
   - **Migration applies automatically**: `db.init_database()` runs `alembic 
upgrade head` on server startup, so no manual migration step is needed.
   
   ## Testing
   
   - `make e2e` — 103 passed, 9 errors (pre-existing failures in 
`e2e/announce/test_get.py`, unrelated to this change)
   - `make unit` — 356 passed, 13 skipped
   
   ---
   
   ## Rebase confirmation details (optional but encouraged)
   
   ```
   $ git fetch upstream main
   From github.com:apache/tooling-trusted-releases
    * branch              main       -> FETCH_HEAD
   $ git rebase upstream/main
   Current branch ssh-invalidate-737 is up to date.
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to