Skip to content

Authentication ​

PocketCI supports two mutually exclusive authentication strategies: Basic Auth and OAuth. You cannot enable both simultaneously.

If neither is configured, the server runs in open-access mode — all endpoints are accessible without credentials.

Basic Auth ​

The simplest option. Set a username and password on the server:

bash
pocketci server \
  --basic-auth-username admin \
  --basic-auth-password secret123
Flag / Env VarDescription
--basic-auth-usernameUsername (env: CI_BASIC_AUTH_USERNAME)
--basic-auth-passwordPassword (env: CI_BASIC_AUTH_PASSWORD)

CLI commands embed credentials in the server URL:

bash
pocketci pipeline set my-pipeline.ts \
  --server http://admin:secret123@localhost:8080

Limitation: Basic auth does not support pipeline-level RBAC expressions. RBAC requires OAuth so that user attributes (email, organizations, groups) can be evaluated. See Authorization (RBAC) for details.

OAuth ​

OAuth delegates authentication to an external identity provider (GitHub, GitLab, or Microsoft). Users log in via browser redirect; CLI tools use a device-flow login.

Supported Providers ​

ProviderClient ID FlagClient Secret FlagExtra Flags
GitHub--oauth-github-client-id--oauth-github-client-secret—
GitLab--oauth-gitlab-client-id--oauth-gitlab-client-secret--oauth-gitlab-url (for self-hosted)
Microsoft--oauth-microsoft-client-id--oauth-microsoft-client-secret--oauth-microsoft-tenant

Both client ID and client secret must be set to enable a provider. You can enable multiple providers simultaneously — users choose at the login screen.

Required Flags ​

FlagDescription
--oauth-session-secretSecret key for encrypting session cookies and signing JWT tokens. Use a strong random string (32+ characters).
--oauth-callback-urlFull public URL for OAuth callbacks (e.g., https://ci.example.com).

Provider Callback URLs ​

The --oauth-callback-url flag is your server's base URL (no trailing path). PocketCI automatically appends the provider-specific callback path. When registering your OAuth application with each provider, use the corresponding full callback URL:

ProviderCallback URL to register
GitHubhttps://ci.example.com/auth/github/callback
GitLabhttps://ci.example.com/auth/gitlab/callback
Microsofthttps://ci.example.com/auth/microsoftonline/callback

Replace https://ci.example.com with your actual --oauth-callback-url value.

Example ​

bash
pocketci server \
  --oauth-github-client-id GITHUB_CLIENT_ID \
  --oauth-github-client-secret GITHUB_CLIENT_SECRET \
  --oauth-session-secret "$(openssl rand -hex 32)" \
  --oauth-callback-url https://ci.example.com

All OAuth flags have corresponding environment variables prefixed with CI_:

bash
export CI_OAUTH_GITHUB_CLIENT_ID=...
export CI_OAUTH_GITHUB_CLIENT_SECRET=...
export CI_OAUTH_SESSION_SECRET="$(openssl rand -hex 32)"
export CI_OAUTH_CALLBACK_URL=https://ci.example.com

pocketci server

GitHub Organization Enrichment ​

When using the GitHub provider, PocketCI automatically fetches the authenticated user's organization memberships via the GitHub API. These are available in RBAC expressions as the Organizations field.

GitLab Self-Hosted ​

Point GitLab to your instance with --oauth-gitlab-url:

bash
pocketci server \
  --oauth-gitlab-client-id ... \
  --oauth-gitlab-client-secret ... \
  --oauth-gitlab-url https://gitlab.company.com \
  --oauth-session-secret ... \
  --oauth-callback-url https://ci.example.com

JWT Tokens ​

When OAuth is enabled, PocketCI issues JWT tokens (HS256) for CLI and API authentication. Tokens contain:

ClaimJWT FieldDescription
SubjectsubUser ID from the provider
EmailemailUser's email address
NamenameDisplay name
Nicknamenick_nameProvider username
ProviderproviderOAuth provider name
IssuerissAlways pocketci
Issued AtiatToken creation timestamp
Expires AtexpToken expiry (30 days)

Tokens are signed with the --oauth-session-secret key using HMAC-SHA256.

Using Tokens ​

Pass tokens via the Authorization header:

bash
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/pipelines

Or via environment variable for CLI commands:

bash
export CI_AUTH_TOKEN=<token>
pocketci pipeline run my-pipeline -s http://localhost:8080

CLI Login ​

The pocketci login command authenticates via a browser-based device flow:

bash
pocketci login -s https://ci.example.com

This opens a browser, completes OAuth, and saves the token to ~/.pocketci/auth.config. Subsequent CLI commands automatically use the saved token for that server.

Auth Config File ​

Tokens are stored in ~/.pocketci/auth.config (JSON, 0600 permissions):

json
{
  "servers": {
    "https://ci.example.com": {
      "token": "eyJhbGciOiJIUzI1NiIs..."
    }
  }
}

Override the config file location:

bash
pocketci login -s https://ci.example.com -c /path/to/auth.config
# or
export CI_AUTH_CONFIG=/path/to/auth.config

Token Resolution Order ​

CLI commands resolve auth tokens in this order:

  1. --auth-token flag / CI_AUTH_TOKEN env var (highest priority)
  2. Config file lookup by server URL (~/.pocketci/auth.config)
  3. Basic auth credentials embedded in the server URL

Auth Error Messages ​

When a server requires authentication, CLI commands return a helpful message:

authentication required: server https://ci.example.com returned 401 Unauthorized

Please log in first:
  ci login -s https://ci.example.com

Or provide a token directly:
  export CI_AUTH_TOKEN=<token>

MCP Clients ​

MCP clients (VS Code, Claude, etc.) authenticate with the same mechanisms as the REST API. With OAuth enabled, use a Bearer token:

jsonc
// .vscode/mcp.json
{
  "servers": {
    "ci": {
      "url": "https://ci.example.com/mcp",
      "type": "http",
      "headers": {
        "Authorization": "Bearer ${input:ciToken}"
      }
    }
  },
  "inputs": [
    {
      "id": "ciToken",
      "type": "promptString",
      "description": "PocketCI auth token (from: pocketci login)",
      "password": true
    }
  ]
}

With basic auth, use the Basic scheme instead:

jsonc
{
  "servers": {
    "ci": {
      "url": "http://localhost:8080/mcp",
      "type": "http",
      "headers": {
        "Authorization": "Basic ${input:ciBasicAuth}"
      }
    }
  }
}