CLI

The oidc.pub CLI is a single binary for everything you do from the command line:

  • Authenticate and manage services on oidc.pub
  • Sync openid-configuration and JWKS from your own issuer
  • Run a local OIDC issuer for development and testing

It also serves as the sync worker for Docker and Kubernetes deployments — see the Sync Worker documentation.

Installation

The CLI requires Node.js 22+ or Docker.

npx oidc.pub --help

Try it locally with dev issuer

You don't need a real OIDC issuer to try oidc.pub. The CLI ships with a built-in dev issuer that generates an RSA keypair, serves the discovery endpoints locally, and mints signed JWTs — all auto-synced to your oidc.pub service on startup.

1. Create a service

npx oidc.pub login
npx oidc.pub service create --name "Demo"
# • Service created: Demo
#   Subdomain: demo-7xk2

2. Run the dev issuer

Pass --service to derive the issuer URL and sync the discovery document on startup:

npx oidc.pub dev issuer --service demo-7xk2
# • Local issuer running on http://localhost:9229
# • Synced openid-configuration and JWKS to https://demo-7xk2.oidc.pub

Leave it running. The issuer URL embedded in tokens is https://demo-7xk2.oidc.pub, so any verifier that trusts that issuer can validate the tokens you mint.

3. Mint a token

In a second terminal, request a signed JWT:

TOKEN=$(curl -s http://localhost:9229/token | jq -r .access_token)

Or mint a token with custom claims:

TOKEN=$(curl -s -X POST http://localhost:9229/token \
  -H "Content-Type: application/json" \
  -d '{"sub": "ci-bot", "aud": "my-api"}' | jq -r .access_token)

4. Verify against the public JWKS

The discovery document and JWKS are now served by oidc.pub. Inspect them with curl:

curl -s https://demo-7xk2.oidc.pub/.well-known/openid-configuration | jq .
curl -s https://demo-7xk2.oidc.pub/.well-known/jwks.json | jq .

Then verify the token signature using the public JWKS:

npm install jose
node --input-type=module --eval "
import { jwtVerify, createRemoteJWKSet } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://demo-7xk2.oidc.pub/.well-known/jwks.json'));
const { payload } = await jwtVerify(process.argv[1], jwks);
console.log('Token is valid. Claims:', payload);
" "$TOKEN"

Any OIDC-aware relying party — Vault, GitHub Actions, AWS STS, GCP Workload Identity Federation — configured to trust https://demo-7xk2.oidc.pub will now accept these tokens.

Sync from your own issuer

Once you have a real OIDC issuer (Vault, GitLab, a Kubernetes API server, your own service), point oidc.pub at it with service sync:

npx oidc.pub service sync \
  --service demo-7xk2 \
  --source-url https://your-issuer.internal \
  --once

Drop --once to keep syncing on an interval. For long-running deployments inside Docker or Kubernetes, use the same binary as a container — see the Sync Worker documentation.

Authentication

login

Authenticate via browser-based OAuth. Opens your browser, completes the login flow, and stores a session token locally.

FlagDescriptionDefault
--oidcpub-url <url>oidc.pub base URLhttps://oidc.pub
--profile <name>Credential profiledefault
--provider <name>OAuth providergithub

whoami

Display the currently logged-in user and session status.

logout

Remove stored credentials for the current profile.

Services

service create

Create a new service on oidc.pub. Requires authentication via login or the OIDCPUB_API_KEY environment variable.

FlagDescriptionRequired
--name <name>Human-readable service nameyes
--subdomain <sub>Custom subdomain (paid tiers only)no
--description <desc>Service descriptionno

service sync

Sync OIDC discovery configuration from a source issuer to oidc.pub. Same engine as the sync worker container.

FlagDescriptionDefault
--service <subdomain>Target service subdomain (required)
--source-url <url>OIDC issuer URL to sync from
--api-key <key>API key or JWT (alternative to login)
--onceSync once and exitfalse
--interval <seconds>Seconds between syncs300

Service accounts

Service accounts provide programmatic access to manage your services. Commands are available under service-account (aliased to sa). Available on the Team plan and above.

service-account create

Create a service account. A static policy returns a one-time bearer token (printed to stdout); store it immediately, it is never shown again.

FlagDescriptionDefault
--name <name>Service account name (required)
--services <list>Comma-separated subdomains the account may act on. Use * for all.*
--ip-allowlist <list>Comma-separated IPs/CIDRs to restrict the token
--policy-file <path>JSON policy document; overrides --services for full control (e.g. OIDC policies)
npx oidc.pub service-account create --name "CI/CD Pipeline" --services "*"

The policy file is validated against https://oidc.pub/schemas/service-account-policy.v1.json. Reference the URL via $schema for editor autocomplete.

service-account list

List your service accounts.

service-account delete <id>

Permanently delete a service account. Any token it issued stops working immediately.

service-account regenerate-token <id>

Regenerate the token for a static service account. The previous token is invalidated atomically; the new token is printed to stdout.

Local development

dev issuer

Run a local OIDC issuer with an in-memory RSA keypair. Serves discovery and JWKS endpoints and mints signed JWTs. With --service, the discovery document and JWKS are pushed to your oidc.pub service on startup.

FlagDescriptionDefault
--service <subdomain>Target oidc.pub service to sync to
--url <url>Issuer URL embedded in tokens and discoveryderived from --service
--port <port>Local HTTP port9229
--subject <sub>Default sub claimtest-user
--audience <aud>Default aud claim
--claims <json>Extra claims as a JSON object

Endpoints served by the local issuer:

PathPurpose
GET /.well-known/openid-configurationOIDC discovery document
GET /.well-known/jwks.jsonPublic JWKS
GET /tokenMint a JWT with default claims
POST /tokenMint a JWT with claims from the JSON body

Profiles

Switch between accounts or environments with --profile. Each profile has its own session token and base URL.

npx oidc.pub login --profile staging --oidcpub-url https://staging.oidc.pub
npx oidc.pub service create --profile staging --name "Test Service"

The default profile is default.

Credential storage

Credentials are stored in ~/.config/oidcpub/credentials.json (respects XDG_CONFIG_HOME). The file is created with mode 0600. Session tokens expire after 36 hours.

Legacy Docker sync mode

The latest image is backward compatible with existing sync worker deployments. When OIDCPUB_SERVICE_ID is set and no subcommand is given, the container runs in legacy sync mode automatically. Existing Docker and Kubernetes deployments continue to work without changes after updating the image reference.