Skip to main content

Token Management

Learn how to manage access tokens, refresh tokens, and token lifecycle.

Token Refresh

Access tokens expire after a set duration (typically 1 hour). Use refresh tokens to obtain new access tokens without re-authentication.

Refreshing an Access Token

curl -X POST "https://auth.propper.ai/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID"

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "new_refresh_token...",
"scope": "openid profile sign:read"
}
tip

The response may include a new refresh token. Always store the latest refresh token to maintain access.

Token Introspection

Validate and inspect tokens to check if they're still active and retrieve metadata.

curl -X POST "https://auth.propper.ai/oauth2/introspect" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "token=TOKEN_TO_INSPECT"

Active Token Response:

{
"active": true,
"scope": "sign:read sign:write",
"client_id": "your_client_id",
"sub": "user_123",
"exp": 1704067200,
"iat": 1704063600,
"token_type": "Bearer"
}

Inactive Token Response:

{
"active": false
}

Token Revocation

Revoke tokens when users log out or when tokens are compromised.

Revoking an Access Token

curl -X POST "https://auth.propper.ai/oauth2/revoke" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "token=TOKEN_TO_REVOKE" \
-d "token_type_hint=access_token"

Revoking a Refresh Token

curl -X POST "https://auth.propper.ai/oauth2/revoke" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "token=REFRESH_TOKEN_TO_REVOKE" \
-d "token_type_hint=refresh_token"

The endpoint returns 200 OK on success (empty response body).

JWT Token Structure

Propper access tokens are JWTs with the following claims:

{
"iss": "https://auth.propper.ai",
"sub": "user_123",
"aud": "propper-api",
"exp": 1704067200,
"iat": 1704063600,
"scope": "sign:read sign:write",
"org_id": "org_abc123"
}
ClaimDescription
issToken issuer (Propper Auth)
subSubject (user or client ID)
audIntended audience
expExpiration timestamp
iatIssued at timestamp
scopeGranted permissions
org_idOrganization context

Validating Tokens

Using JWKS

Fetch the public keys to verify token signatures:

curl "https://auth.propper.ai/.well-known/jwks.json"

Response:

{
"keys": [
{
"kty": "RSA",
"kid": "key_123",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}

Validation Steps

  1. Fetch JWKS from the well-known endpoint
  2. Verify signature using the matching key (by kid)
  3. Check expiration (exp claim)
  4. Validate issuer (iss should be https://auth.propper.ai)
  5. Verify audience (aud should match your expected audience)

Best Practices

  1. Cache JWKS - Don't fetch on every request, cache with reasonable TTL
  2. Handle token expiry gracefully - Implement automatic refresh
  3. Revoke on logout - Always revoke tokens when users sign out
  4. Use short token lifetimes - Balance security vs. user experience
  5. Implement refresh token rotation - Use new refresh tokens when issued