-
Epic
-
Resolution: Unresolved
-
Undefined
-
None
-
None
-
None
-
[Backend] API & logic for OAuth token lifecycle
-
Product / Portfolio Work
-
False
-
-
False
-
Not Selected
-
To Do
-
PROJQUAY-10436 - (Phase 1) Programmatic OAuth Token Provisioning for Automation
-
Epic Goal
Implement the backend logic, API endpoints, and authentication layer required to support programmatic OAuth token creation without UI interaction.
This includes schema updates for multiple tokens per application and zero-touch bootstrap authentication for scenarios where no existing token is available.
Why is this important?
This is the foundational work that enables fully automated Quay deployments. Without these API endpoints and authentication mechanisms, users cannot:
- Bootstrap Quay access without UI interaction
- Implement GitOps workflows for Quay configuration
- Rotate credentials programmatically in CI/CD pipelines
Scenarios
- Zero-touch deployment: A platform engineer deploys Quay via operator and uses their LDAP service account credentials to create an initial API token via curl, without ever accessing the UI.
- CI/CD bootstrap: A Jenkins pipeline authenticates using superuser Basic Auth to create a short-lived token for a specific build job.
- Security response: An admin uses the DELETE endpoint to revoke a specific compromised token without affecting other tokens.
Acceptance Criteria
- Schema:
- Database supports one-to-many relationship (App -> Tokens)
- Stores: name, created_by, expires_at, last_used, and scopes
- API - Create (POST):
- POST /api/v1/organization/{orgname}/application/{client_id}/tokens
- Accepts: name (required), expiration (optional), scopes (optional)
- Returns the token secret once in the response
- Supports both standard and zero-touch bootstrap authentication
- API - List (GET):
- GET /api/v1/organization/{orgname}/application/{client_id}/tokens
- Returns a list of all tokens (legacy & new) with metadata
- Exclude the token secret from the response
- Supports standard authentication only
- API - Revoke (GET):
- DELETE /api/v1/organization/{orgname}/application/{client_id}/tokens/{token_id}
- Immediately invalidates the specific token
- Returns 204 No Content
- Supports standard authentication only
- Standard Authentication (OAuth Token / Session Cookie)
- Endpoints accept session cookie (UI-driven)
- Endpoints accept OAuth Bearer Token (automation with existing token)
- Requires "Organization Admin" permission
- Zero-Touch Bootstrap Authentication (for initial token creation, when `FEATURE_PROGRAMMATIC_BOOTSTRAP=true`):
- Endpoints accepts HTTP Basic Auth for superusers
- Endpoints accepts LDAP service account credentials (if LDAP is configured and user matches
- LDAP_SUPERUSER_FILTER)
- Endpoint accepts OIDC service principal (if OIDC is configured)
- Note: Zero-touch bootstrap authentication is only available on the POST (create) endpoint, not GET or DELETE.
- Feature Flag
- `FEATURE_PROGRAMMATIC_BOOTSTRAP`: Enables zero-touch bootstrap authentication
(default value: `false`) - When `false`, only standard authentication (OAuth/Session) is accepted
- Feature flag documented in config schema
- `FEATURE_PROGRAMMATIC_BOOTSTRAP`: Enables zero-touch bootstrap authentication
- Enforcement:
- Authentication logic rejects expired tokens
- Authentication logic rejects revoked tokens
- Token scopes are enforced on API operations
- Rate Limit:
- Endpoints inherit existing nginx `/api/` rate limits
- No additional rate-limiting implementation required
- Document that `FEATURE_RATE_LIMITS: true` is recommended for production
- Audit Logging
- Log all zero-touch bootstrap authentication attempts (success and failure)
- Include authentication method in audit trail (Basic Auth, LDAP, OIDC)
- Log token creation events: `api_token.created`
- Log token revocation events: `api_token.revoked`
- CI
- Unit tests for all API endpoints
- Integration tests for zero-touch bootstrap authentication
- Tests for feature flag behavior
- Release Technical Enablement - Provide necessary release enablement details and documents.
Dependencies (internal and external)
- Internal:
- Database schema migration? (Do we need migration? if so, would that require downtime/lock?)
- Existing OAuth infrastructure (extending, not replacing)
Previous Work (Optional):
- Existing `OAuth` Tables (–> we are not replacing anything but extending)
- Existing `OAuthApplication` and `OAuthAccessToken` models
- Existing `create_user_access_token()` function in `data/model/oauth.py`
- Existing `/api/v1/user/initialize` endpoint pattern
- Existing `LDAP_SUPERUSER_FILTER` configuration
Open questions:
- Is there a hard limit on the number of active tokens allowed per Application to prevent abuse?
- Do we need pagination for the GET endpoint if a user has 100+ tokens?
Done Checklist
- CI - CI is running, tests are automated and merged.
- Release Enablement <link to Feature Enablement Presentation>
- DEV - Upstream code and tests merged: <link to meaningful PR or GitHub Issue>
- DEV - Upstream documentation merged: <link to meaningful PR or GitHub Issue>
- DEV - Downstream build attached to advisory: <link to errata>
- QE - Test plans in Polarion: <link or reference to Polarion>
- QE - Automated tests merged: <link or reference to automated tests>
- DOC - Downstream documentation merged: <link to meaningful PR>
Reference
For the full collaborative design spec, background history, and detailed edge cases, please see:
- the original shared document: PROJQUAY-9755: Granular lifecycle management for OAuth 2 application tokens
- RFE-4345: Provisioning Quay API tokens programmatically
- RFE-8731: API tokens for bootstrapping and automating Quay deployments
- is triggered by
-
RFE-4345 Provisioning Quay API tokens programmatically
-
- Refinement
-