Skip to content

Metaform/jwtlet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jwtlet

Jwtlet is an RFC 8693 OAuth 2.0 token exchange service for participant context operations. Clients exchange a Kubernetes service account token for a signed JWT that encodes participant context claims. The service validates the incoming token against a Kubernetes OIDC issuer, resolves resource mappings and scope-to-claims mappings, and signs the resulting token via HashiCorp Vault.

Jwtlet runs two HTTP servers: a token exchange API (default port 8080) and a management API (default port 8081) for administering resource and scope mappings.

Building

Requires Rust (stable toolchain).

# Build all crates
cargo build

# Build the release binary
cargo build --release -p jwtlet-server

Running the Tests

Unit and integration tests:

cargo nextest run

or

cargo test

End-to-end tests run against a local kind Kubernetes cluster with Vault. Requires Docker and kind installed.

cd e2e

make all          # full cycle: cluster setup, build, test, cleanup

# or individual steps:
make setup        # create KIND cluster and initialize Vault
make build        # build and load the Docker image into the cluster
make test         # run tests
make cleanup      # tear down the cluster

Running the Server

Pass a TOML config file as the first argument, or set JWTLET_CONFIG_FILE:

jwtlet-server /path/to/config.toml
# or
JWTLET_CONFIG_FILE=/path/to/config.toml jwtlet-server

Individual settings can also be overridden with environment variables using the JWTLET__ prefix (double underscore as the nesting separator), e.g. JWTLET__TOKEN_EXCHANGE_PORT=9090.

Configuration Reference

# Ports and bind address
token_exchange_port = 8080   # default
management_port = 8081   # default; must differ from token_exchange_port
bind = "0.0.0.0"

# Storage backend: "memory" (default) or "postgres"
[storage_backend]
type = "memory"
# type = "postgres"
# url  = "postgresql://user:pass@host:5432/jwtlet"

# Kubernetes OIDC validation
[k8s]
api_server_url = "https://kubernetes.default.svc"               # required
cluster_issuer = "https://kubernetes.default.svc.cluster.local" # required
token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"

# Token issuance
[token]
client_audience = "https://kubernetes.default.svc.cluster.local" # required – expected aud of incoming tokens
audience = "my-service"                                    # required – aud of issued tokens
participant_context_claim = "jwtlet_pc"  # default
token_ttl_secs = 3600         # default

# Vault signing backend
[vault]
url = "http://vault:8200"           # required
token_file = "/vault/secrets/.vault-token" # use token_file in production
# token    = "s.xxxxx"                     # or a literal token for development

# Management API authorization
# Keys are Kubernetes service account identifiers; values are lists of roles.
# A caller must hold the "management:write" role to use any management endpoint.
[service_accounts]
"system:serviceaccount:my-namespace:my-sa" = ["management:write"]

Management API Authentication

All management API endpoints (/api/v1/mappings, /api/v1/scopes) require a Authorization: Bearer <token> header. The token must be a valid Kubernetes service account token issued with the same audience as token.client_audience. Jwtlet verifies the token via the Kubernetes TokenReview API and checks that the resolved service account identity holds the management:write role.

To obtain a suitable token from within a cluster:

kubectl create token my-sa -n my-namespace \
  --audience=https://kubernetes.default.svc.cluster.local

Logging

Set RUST_LOG to control verbosity (trace, debug, info, warn, error):

RUST_LOG=debug jwtlet-server config.toml

License

Apache-2.0

About

Token exchange service for participant context operations

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages