- Go 78.1%
- HTML 21.1%
- Dockerfile 0.8%
|
All checks were successful
Build Docker Image / build (push) Successful in 1m4s
Reviewed-on: #5 |
||
|---|---|---|
| .forgejo/workflows | ||
| config | ||
| handlers | ||
| jwks | ||
| keys | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| README.md | ||
| renovate.json | ||
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=noneand all other algorithms are rejected- Reserved claims (
iss,iat,exp,nbf,jti,sub,aud,alg,kid,typ) cannot appear inclaims claimsobject must be ≤ 4 KB when JSON-encodedsubmust be ≤ 255 characters- Each
audentry 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.