Issues JWT tokens in an OIDC-compliant-ish way. As it name suggests this is for testing purposes only!
  • Go 78.1%
  • HTML 21.1%
  • Dockerfile 0.8%
Find a file
Sophie 7286881ed6
All checks were successful
Build Docker Image / build (push) Successful in 1m4s
Merge pull request 'chore(deps): update golang docker tag to v1.26' (#5) from renovate/dependencies into main
Reviewed-on: #5
2026-08-08 11:03:47 +10:00
.forgejo/workflows build a container 2026-05-30 04:31:45 +00:00
config initial commit 2026-04-11 22:14:51 +10:00
handlers feat: add browser-based HTML frontend for token generation 2026-04-11 22:58:04 +10:00
jwks feat: add browser-based HTML frontend for token generation 2026-04-11 22:58:04 +10:00
keys initial commit 2026-04-11 22:14:51 +10:00
.gitignore initial commit 2026-04-11 22:14:51 +10:00
Dockerfile chore(deps): update golang docker tag to v1.26 2026-08-08 01:03:12 +00:00
go.mod Update module github.com/lestrrat-go/jwx/v2 to v2.1.7 2026-08-08 11:01:56 +10:00
go.sum Update module github.com/lestrrat-go/jwx/v2 to v2.1.7 2026-08-08 11:01:56 +10:00
main.go feat: add browser-based HTML frontend for token generation 2026-04-11 22:58:04 +10:00
README.md initial commit 2026-04-11 22:14:51 +10:00
renovate.json Update renovate.json 2026-08-08 10:55:08 +10:00

test-token-service

A local OIDC JWT token service for development and testing. Issues signed JWTs and exposes standard OIDC discovery endpoints so your app can validate tokens against a real JWKS.

Quick start

go run .

This generates fresh RSA-2048 and EC P-384 signing keys on startup and begins serving on port 8080.

Configuration

All options can be set via flags or environment variables.

Flag Env var Default Description
-port TOKEN_SERVICE_PORT 8080 Port to listen on
-issuer TOKEN_SERVICE_ISSUER http://localhost:<port> Issuer URL embedded in tokens
-default-ttl TOKEN_SERVICE_DEFAULT_TTL 3600 Default token lifetime (seconds)
-max-ttl TOKEN_SERVICE_MAX_TTL 86400 Maximum token lifetime (seconds)

Endpoints

POST /token

Issues a signed JWT. Requires Content-Type: application/json.

Request body:

{
  "alg": "RS256",
  "sub": "user-123",
  "aud": "my-service",
  "expires_in": 3600,
  "claims": {
    "email": "user@example.com",
    "role": "admin"
  }
}
Field Type Required Description
alg string yes Signing algorithm: RS256 or ES384
sub string no Subject claim
aud string or array no Audience — single string or array of up to 10 strings
expires_in integer no Token lifetime in seconds (capped at max-ttl)
claims object no Additional claims to embed in the token

Response:

{
  "access_token": "<jwt>",
  "token_type": "Bearer",
  "expires_in": 3600
}

Constraints:

  • alg=none and all other algorithms are rejected
  • Reserved claims (iss, iat, exp, nbf, jti, sub, aud, alg, kid, typ) cannot appear in claims
  • claims object must be ≤ 4 KB when JSON-encoded
  • sub must be ≤ 255 characters
  • Each aud entry must be ≤ 255 characters; max 10 entries
  • Request body is capped at 64 KB

GET /.well-known/openid-configuration

Returns the OIDC discovery document pointing at this service.

GET /.well-known/jwks.json

Returns the public keys as a JSON Web Key Set. Use this URI when configuring your app's token verifier.

Example

# Issue a token
TOKEN=$(curl -s -X POST http://localhost:8080/token \
  -H 'Content-Type: application/json' \
  -d '{"alg":"RS256","sub":"alice","aud":"my-api","claims":{"role":"admin"}}' \
  | jq -r .access_token)

# Inspect the token (header + payload, no verification)
echo $TOKEN | cut -d. -f1,2 | tr '.' '\n' | base64 -d 2>/dev/null | jq

Docker

Build and run standalone:

docker build -t test-token-service .
docker run --rm -p 8080:8080 test-token-service

To use in another project's docker-compose.yml:

services:
  token-service:
    build:
      context: ../test-token-service   # adjust path as needed
    ports:
      - "8080:8080"
    environment:
      TOKEN_SERVICE_ISSUER: http://token-service:8080

Set TOKEN_SERVICE_ISSUER to the container's service name so tokens embed the correct iss claim — your app's JWKS verifier needs to reach that same URL to fetch /.well-known/jwks.json.

Development

go test ./...

Keys are ephemeral — regenerated on every restart. This service is intended for local development only and should not be used in production.