This document describes all claims available in TokenSmith JWTs and how they are used.
These claims are present in every TokenSmith JWT and follow the JWT standard.
| Claim | Type | Description | Example | Required |
|---|---|---|---|---|
iss |
string | Issuer: identifies who issued the token | "https://tokensmith.example.com" |
Yes |
sub |
string | Subject: the principal this token represents | "user123" or "admin@example.com" |
Yes |
aud |
string or array | Audience: intended recipients of the token | "service-a" or ["service-a", "service-b"] |
No |
exp |
number | Expiration time (Unix timestamp in seconds) | 1703088000 |
Yes |
nbf |
number | Not Before: earliest time token is valid (Unix timestamp) | 1703080000 |
Yes |
iat |
number | Issued At: when token was created (Unix timestamp) | 1703084000 |
Yes |
jti |
string | JWT ID: unique identifier for this token | "abc123def456" |
No |
{
"iss": "https://tokensmith.example.com",
"sub": "user123",
"aud": ["service-a", "service-b"],
"exp": 1703088000,
"nbf": 1703080000,
"iat": 1703084000,
"jti": "abc123def456"
}These claims come from the upstream OIDC provider (if using OIDC flow) or are set by TokenSmith when minting local user tokens.
| Claim | Type | Description | Example | Source |
|---|---|---|---|---|
name |
string | End-user's full name | "John Doe" |
OIDC provider |
email |
string | End-user's email address | "john@example.com" |
OIDC provider |
email_verified |
boolean | Is the email verified by the provider? | true |
OIDC provider |
nonce |
string | Replay attack mitigation value | "n-0S6_WzA2Mj" |
OIDC provider |
auth_time |
number | When user authenticated (Unix timestamp) | 1703084000 |
OIDC provider |
{
"name": "John Doe",
"email": "john@example.com",
"email_verified": true,
"auth_time": 1703084000,
"nonce": "n-0S6_WzA2Mj"
}These claims describe how the user authenticated and their assurance level. Used for policy enforcement.
| Claim | Type | Description | Example | Notes |
|---|---|---|---|---|
amr |
array | Authentication Methods used | ["pwd", "otp"] |
From OIDC provider |
acr |
string | Authentication Context Class Reference | "urn:mace:incommon:iap:silver" |
From OIDC provider |
auth_level |
string | Identity Assurance Level (IAL) | "IAL1", "IAL2", "IAL3" |
From OIDC provider |
auth_factors |
number | Number of distinct auth factors | 1 or 2 |
Counted by TokenSmith |
auth_methods |
array | Specific authentication methods used | ["password", "webauthn"] |
Set by TokenSmith |
auth_events |
array | History of authentication events | ["login", "mfa_verify"] |
Set by TokenSmith |
{
"amr": ["pwd", "otp"],
"acr": "urn:mace:incommon:iap:silver",
"auth_level": "IAL2",
"auth_factors": 2,
"auth_methods": ["password", "totp"],
"auth_events": ["login", "mfa_complete"]
}// Example: Require IAL2 for sensitive operations
func authorizeByAssurance(ctx context.Context) error {
claims, err := authn.VerifiedClaimsFromContext(ctx)
if err != nil {
return err
}
if claims.AuthLevel != "IAL2" && claims.AuthLevel != "IAL3" {
return fmt.Errorf("insufficient assurance level: %s", claims.AuthLevel)
}
return nil
}These claims represent permissions granted to the token holder.
| Claim | Type | Description | Example |
|---|---|---|---|
scope |
array | OAuth scopes granted | ["read", "write", "admin"] |
{
"scope": ["users:read", "users:write", "admin:read"]
}// Example: Check for required scope
func requireScope(ctx context.Context, required string) error {
claims, err := authn.VerifiedClaimsFromContext(ctx)
if err != nil {
return err
}
for _, scope := range claims.Scope {
if scope == required {
return nil
}
}
return fmt.Errorf("missing required scope: %s", required)
}These claims manage token and session lifecycle.
| Claim | Type | Description | Example |
|---|---|---|---|
session_id |
string | Unique session identifier | "sess_abc123" |
session_exp |
number | Session expiration (Unix timestamp) | 1703084000 |
{
"session_id": "sess_abc123xyz789",
"session_exp": 1703084000
}// Example: Enforce max session duration
func checkSessionExpiry(ctx context.Context) error {
claims, err := authn.VerifiedClaimsFromContext(ctx)
if err != nil {
return err
}
sessionExpiry := time.Unix(claims.SessionExp, 0)
if time.Now().After(sessionExpiry) {
return errors.New("session expired")
}
return nil
}These claims are specific to the OpenCHAMI project and environment.
| Claim | Type | Description | Example |
|---|---|---|---|
cluster_id |
string | OpenCHAMI cluster identifier | "cluster-prod-us-west" |
openchami_id |
string | OpenCHAMI unique entity identifier | "node-001" |
{
"cluster_id": "cluster-prod-us-west",
"openchami_id": "node-001"
}Here's a complete example of a TokenSmith JWT with all claim categories:
{
"iss": "https://tokensmith.example.com",
"sub": "user123",
"aud": ["service-a", "service-b"],
"exp": 1703088000,
"nbf": 1703080000,
"iat": 1703084000,
"jti": "abc123def456",
"name": "John Doe",
"email": "john@example.com",
"email_verified": true,
"auth_time": 1703084000,
"amr": ["pwd", "otp"],
"acr": "urn:mace:incommon:iap:silver",
"auth_level": "IAL2",
"auth_factors": 2,
"auth_methods": ["password", "totp"],
"auth_events": ["login", "mfa_complete"],
"scope": ["read", "write", "admin"],
"session_id": "sess_abc123xyz789",
"session_exp": 1703084000,
"cluster_id": "cluster-prod-us-west",
"openchami_id": "node-001"
}# Get a token and decode it
TOKEN="<your-jwt-token>"
# Decode header
echo "$TOKEN" | cut -d. -f1 | base64 -d | jq .
# Decode claims (payload)
echo "$TOKEN" | cut -d. -f2 | base64 -d | jq .
# Decode signature (not readable without the key)
echo "$TOKEN" | cut -d. -f3 | base64 -d | od -ximport (
"github.com/OpenCHAMI/tokensmith/pkg/authn"
"context"
)
func myHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get verified claims from context
claims, err := authn.VerifiedClaimsFromContext(ctx)
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Use claims
userID := claims.Subject
email := claims.Email
scopes := claims.Scope
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Hello %s <%s>\n", userID, email)
}TokenSmith enforces these validation rules on all tokens:
- Expiration (
exp): Token must not be expired at validation time. - Not Before (
nbf): Current time must be >=nbf. - Issued At (
iat): Token must not be issued in the future. - Issuer (
iss): Must match the expected issuer. - Subject (
sub): Must not be empty. - Signature: Must be valid using the correct key.
See Security Notes for detailed validation policies.
- Token Flows — Understanding upstream vs local token flows
- Security Notes — Security considerations for token validation
- CLI Reference — Creating tokens with
user-token create - Context Guide — Using TokenSmith middleware with claims