Add service account support #55

Open
opened 2026-01-03 23:47:02 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-01-03 23:47:02 +00:00 (Migrated from github.com)

User Story

As a DevOps engineer, I want to use service accounts with qctl in CI/CD pipelines so I can automate deployments without interactive authentication.

Design

Command Interface

# Create service account token (via web UI or API)
# Token provided as environment variable or file

# Authenticate with service account
export QCTL_SERVICE_TOKEN=eyJhbGc...
qctl auth status

# Or via file
qctl auth login --service-account --token-file /path/to/token.json

# Or via environment
QCTL_TOKEN_FILE=/path/to/token.json qctl qrun publish

Service Account Token Format

{
  "type": "service_account",
  "account_id": "sa-abc123",
  "account_name": "ci-deployer",
  "organization": "acme-corp",
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2025-01-15T00:00:00Z",
  "scopes": ["qctl:deploy", "qctl:read"]
}

Authentication Priority

1. QCTL_SERVICE_TOKEN environment variable (raw JWT)
2. QCTL_TOKEN_FILE environment variable (path to token file)
3. --token-file CLI argument
4. Interactive login tokens (from keychain)

CI/CD Examples

# GitHub Actions
- name: Deploy to production
  env:
    QCTL_SERVICE_TOKEN: ${{ secrets.QCTL_TOKEN }}
  run: |
    qctl qrun publish --env prod

# GitLab CI
deploy:
  script:
    - qctl auth login --service-account --token-file $QCTL_TOKEN_FILE
    - qctl qrun publish --env prod

Files to Create/Modify

File Action Purpose
qctl-core/src/main/java/io/qrun/qctl/core/auth/ServiceAccountAuth.java Create SA authentication
qctl-core/src/main/java/io/qrun/qctl/core/auth/TokenResolver.java Create Token resolution chain
qctl-core/src/main/java/io/qrun/qctl/core/auth/model/ServiceAccount.java Create SA model
qctl-core/src/main/java/io/qrun/qctl/core/auth/TokenManager.java Modify Add SA support
qctl-core/src/main/java/io/qrun/qctl/core/auth/LoginCommand.java Modify Add --service-account

Implementation Tasks

  • Create ServiceAccountAuth for SA token handling
  • Create TokenResolver with priority chain
  • Support QCTL_SERVICE_TOKEN environment variable
  • Support QCTL_TOKEN_FILE environment variable
  • Add --service-account and --token-file to login command
  • Parse and validate service account JSON format
  • Verify JWT signature and expiration
  • Extract scopes and validate permissions
  • Integrate with TokenManager for consistent auth API
  • Add clear error messages for CI/CD debugging
  • Document CI/CD configuration patterns
  • Write unit tests for TokenResolver
  • Write unit tests for ServiceAccountAuth

Acceptance Criteria

  • QCTL_SERVICE_TOKEN env var authenticates automatically
  • QCTL_TOKEN_FILE env var reads token from file
  • --token-file flag works with login command
  • Token expiration is checked and reported
  • Scope validation prevents unauthorized operations
  • qctl auth status shows service account info
  • Clear error messages in non-interactive mode
  • Works in GitHub Actions, GitLab CI, Jenkins
## User Story As a DevOps engineer, I want to use service accounts with qctl in CI/CD pipelines so I can automate deployments without interactive authentication. ## Design ### Command Interface ```bash # Create service account token (via web UI or API) # Token provided as environment variable or file # Authenticate with service account export QCTL_SERVICE_TOKEN=eyJhbGc... qctl auth status # Or via file qctl auth login --service-account --token-file /path/to/token.json # Or via environment QCTL_TOKEN_FILE=/path/to/token.json qctl qrun publish ``` ### Service Account Token Format ```json { "type": "service_account", "account_id": "sa-abc123", "account_name": "ci-deployer", "organization": "acme-corp", "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "expires_at": "2025-01-15T00:00:00Z", "scopes": ["qctl:deploy", "qctl:read"] } ``` ### Authentication Priority ``` 1. QCTL_SERVICE_TOKEN environment variable (raw JWT) 2. QCTL_TOKEN_FILE environment variable (path to token file) 3. --token-file CLI argument 4. Interactive login tokens (from keychain) ``` ### CI/CD Examples ```yaml # GitHub Actions - name: Deploy to production env: QCTL_SERVICE_TOKEN: ${{ secrets.QCTL_TOKEN }} run: | qctl qrun publish --env prod # GitLab CI deploy: script: - qctl auth login --service-account --token-file $QCTL_TOKEN_FILE - qctl qrun publish --env prod ``` ## Files to Create/Modify | File | Action | Purpose | |------|--------|---------| | `qctl-core/src/main/java/io/qrun/qctl/core/auth/ServiceAccountAuth.java` | Create | SA authentication | | `qctl-core/src/main/java/io/qrun/qctl/core/auth/TokenResolver.java` | Create | Token resolution chain | | `qctl-core/src/main/java/io/qrun/qctl/core/auth/model/ServiceAccount.java` | Create | SA model | | `qctl-core/src/main/java/io/qrun/qctl/core/auth/TokenManager.java` | Modify | Add SA support | | `qctl-core/src/main/java/io/qrun/qctl/core/auth/LoginCommand.java` | Modify | Add --service-account | ## Implementation Tasks - [ ] Create ServiceAccountAuth for SA token handling - [ ] Create TokenResolver with priority chain - [ ] Support QCTL_SERVICE_TOKEN environment variable - [ ] Support QCTL_TOKEN_FILE environment variable - [ ] Add --service-account and --token-file to login command - [ ] Parse and validate service account JSON format - [ ] Verify JWT signature and expiration - [ ] Extract scopes and validate permissions - [ ] Integrate with TokenManager for consistent auth API - [ ] Add clear error messages for CI/CD debugging - [ ] Document CI/CD configuration patterns - [ ] Write unit tests for TokenResolver - [ ] Write unit tests for ServiceAccountAuth ## Acceptance Criteria - [ ] QCTL_SERVICE_TOKEN env var authenticates automatically - [ ] QCTL_TOKEN_FILE env var reads token from file - [ ] --token-file flag works with login command - [ ] Token expiration is checked and reported - [ ] Scope validation prevents unauthorized operations - [ ] `qctl auth status` shows service account info - [ ] Clear error messages in non-interactive mode - [ ] Works in GitHub Actions, GitLab CI, Jenkins
Sign in to join this conversation.