Skip to Content
OIDC Provider

OIDC Authentication

Creddy implements OpenID Connect (OIDC), allowing agents to authenticate using standard OAuth 2.0 flows. This enables federation with AWS, GCP, and other services that support OIDC identity providers.

Overview

┌─────────────────────────────────────────────────────────────────┐ │ CREDDY SERVER │ │ (your-server:8400) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ /.well-known/openid-configuration ← OIDC Discovery │ │ /.well-known/jwks.json ← Public keys (for verify) │ │ /oauth/token ← Get JWT access token │ │ /v1/credentials/{backend} ← Get ephemeral credentials │ │ │ └─────────────────────────────────────────────────────────────────┘ ┌───────────────┴───────────────┐ │ │ ┌────────┴────────┐ ┌────────┴────────┐ │ AI Agent │ │ AWS / GCP │ │ (your bot) │ │ (federation) │ │ │ │ │ │ Uses tokens to │ │ Trusts Creddy │ │ get credentials │ │ as identity │ └─────────────────┘ │ provider │ └─────────────────┘

Enable OIDC

Start the server with an issuer URL:

creddy server --oidc-issuer https://creddy.example.com

The issuer URL must be:

  • HTTPS — Required by OIDC spec
  • Reachable — Agents and federated services (AWS/GCP) need to fetch JWKS

Need TLS? See Server Setup → TLS & OIDC for Tailscale Funnel, Caddy, nginx, and cloud LB options.

Credential Types

When you create an agent, Creddy generates two sets of credentials:

TypeFormatUse Case
Vend Tokenckr_xxx...Simple auth, direct API access
OIDC Credentialsclient_id + client_secretStandard OAuth, federation
creddy agent create my-agent --can github

Output:

{ "name": "my-agent", "token": "ckr_abc123...", // Vend token "oidc": { "client_id": "agent_f8e7d6", // OIDC "client_secret": "cks_xyz789..." } }

Authentication Flows

Step 1: Get Access Token

curl -X POST https://creddy.example.com/oauth/token \ -d "grant_type=client_credentials" \ -d "client_id=agent_f8e7d6" \ -d "client_secret=cks_xyz789" \ -d "scope=openid github"

Response:

{ "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEyMzQ1In0...", "token_type": "Bearer", "expires_in": 3600, "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEyMzQ1In0...", "scope": "openid github" }

Step 2: Use Access Token

# Get ephemeral GitHub token curl https://creddy.example.com/v1/credentials/github?ttl=10m \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." # Check agent status curl https://creddy.example.com/v1/status \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Vend Flow

Skip the OAuth exchange — use the vend token directly:

curl https://creddy.example.com/v1/credentials/github?ttl=10m \ -H "Authorization: Bearer ckr_abc123..."

Both flows work on all endpoints. OIDC is preferred for:

  • Federation (AWS, GCP trust relationships)
  • Short-lived tokens (1 hour vs permanent)
  • Audit trails (JWT contains identity claims)

Token Contents

Access Token

A JWT containing:

{ "iss": "https://creddy.example.com", "sub": "agent-uuid", "exp": 1709740800, "iat": 1709737200, "agent_id": "agent-uuid", "agent_name": "my-agent", "scopes": ["github:owner/repo"], "client_id": "agent_f8e7d6" }

ID Token

Same as access token, plus:

{ "auth_time": 1709737200, "aud": ["https://creddy.example.com"] }

OIDC Endpoints

Discovery

curl https://creddy.example.com/.well-known/openid-configuration

Returns standard OIDC metadata including endpoints, supported algorithms, and claims.

JWKS

curl https://creddy.example.com/.well-known/jwks.json

Returns public keys for verifying token signatures. Keys are RS256.

Token

curl -X POST https://creddy.example.com/oauth/token \ -d "grant_type=client_credentials" \ -d "client_id=..." \ -d "client_secret=..."

UserInfo

curl https://creddy.example.com/oauth/userinfo \ -H "Authorization: Bearer <access_token>"

Returns agent identity claims.

AWS Federation

Creddy can act as an OIDC identity provider for AWS IAM:

1. Create OIDC Provider in AWS

aws iam create-open-id-connect-provider \ --url https://creddy.example.com \ --client-id-list https://creddy.example.com \ --thumbprint-list <certificate-thumbprint>

2. Create IAM Role with Trust Policy

{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::ACCOUNT:oidc-provider/creddy.example.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "creddy.example.com:sub": "agent-uuid" } } }] }

3. Agent Assumes Role

# Get Creddy ID token TOKEN=$(curl -s -X POST https://creddy.example.com/oauth/token \ -d "grant_type=client_credentials" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ | jq -r .id_token) # Assume AWS role aws sts assume-role-with-web-identity \ --role-arn arn:aws:iam::ACCOUNT:role/CredddyAgentRole \ --role-session-name my-agent \ --web-identity-token "$TOKEN"

No static AWS credentials needed!

Key Rotation

OIDC signing keys can be rotated without downtime:

# View current keys curl https://creddy.example.com/.well-known/jwks.json | jq '.keys[].kid' # Rotate (admin) creddy admin keys rotate

Old keys remain in JWKS during a grace period for token validation.

Verifying Tokens

To verify Creddy tokens in your own service:

Go:

import "github.com/getcreddy/creddy/verify" verifier := verify.New("https://creddy.example.com") claims, err := verifier.Verify(ctx, token) if err != nil { // Invalid token } fmt.Println("Agent:", claims.AgentName)

Manual (any language):

  1. Fetch /.well-known/jwks.json
  2. Extract kid from JWT header
  3. Find matching key in JWKS
  4. Verify RS256 signature
  5. Validate iss, exp, aud claims

Comparison

FeatureVend (ckr_)OIDC
Token lifetimePermanent1 hour (configurable)
FormatOpaque stringJWT with claims
AWS/GCP federation
Self-describing✅ (claims in token)
RevocationDelete agentKeys rotate, tokens expire

Use OIDC for production. Use vend tokens for quick testing or simple setups.

Last updated on

Apache 2.0 2026 © Creddy