Open
Conversation
Implement CLI OIDC authentication that enables command-line tools to
authenticate users through an OpenID Connect provider using a browser-based
flow with state-based token polling.
Key features:
- CLI initiates auth via /api/admin/cli-login, user completes flow in browser
- CLI polls /api/admin/cli-token to retrieve JWT after successful auth
- No local HTTP server required on CLI side (unlike GitHub CLI approach)
- Supports both single-instance (in-memory) and clustered (PostgreSQL) deployments
New components:
- CliAuthDatastore: pluggable storage abstraction with factory pattern
- InMemoryCliAuthStorage: thread-safe storage with automatic cleanup
- PostgresCliAuthStorage: database-backed storage for load-balanced setups
- PendingCliAuth/CompletedCliAuth models with configurable TTLs
Security measures:
- CSRF protection via state parameter (cli: prefix passed through OIDC)
- PKCE support for public clients
- Rate limiting: 60 polls/minute per state
- Single-use tokens deleted after claim
- Short TTLs: 5min pending, 2min completed
API endpoints:
- GET /api/admin/cli-login?state={state} - initiate CLI auth flow
- GET /api/admin/cli-token?state={state} - poll for token (200/202/404/410/429)
Configuration:
- IZANAMI_CLI_AUTH_STORAGE: "in-memory" (default) or "postgresql"
Frontend:
- Enhanced login page to detect CLI auth and show completion message
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The OIDC browser-flow tests were failing because callOpenIdCallback2 was not sending the state parameter in the callback request. The LoginController requires both code and state for CSRF validation in browser flow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request: CLI Authentication via OpenID Connect
Summary
This PR adds support for CLI OIDC authentication, enabling command-line tools (like the Izanami Go CLI -> https://github.com/webskin/izanami-go-cli/releases) to authenticate users through an OpenID Connect provider using a browser-based flow with state-based token polling.
Motivation
CLI tools need a secure way to authenticate users via OIDC without requiring:
This implementation uses a polling-based approach where the CLI opens a browser for authentication and polls the server for the resulting token.
Changes
New Files:
CliAuthDatastore.scalaInMemoryCliAuthStorage.scalaPostgresCliAuthStorage.scalaCliAuthentication.scalaPendingCliAuthandCompletedCliAuthwith configurable TTLsV22__create_cli_auth_table.sqlModified Files:
LoginController.scalacliOpenIdConnectandcliTokenPollendpointsErrors.scalalogin.tsxapplication.confIZANAMI_CLI_AUTH_STORAGEconfigurationNew API Endpoints
/api/admin/cli-login?state={state}/api/admin/cli-token?state={state}Token Polling Responses:
200 OK- Authentication complete, returns JWT token202 Accepted- Authentication pending, keep polling404 Not Found- Invalid or unknown state410 Gone- Token expired (already claimed or TTL exceeded)429 Too Many Requests- Rate limited, includesRetry-AfterheaderAuthentication Flow
Security Features
cli:prefixConfiguration
IZANAMI_CLI_AUTH_STORAGEin-memory,postgresqlin-memoryTesting
LoginAPISpectests for CLI OIDC endpointsCLI Usage (izanami-go-cli)
Breaking Changes
None. This is a purely additive feature.
Checklist