Skip to main content

Data Tokens

Understanding data tokens - the cryptographically signed JWTs that contain user identity claims.

What are Data Tokens?

Data tokens are JSON Web Tokens (JWTs) that contain user identity claims (blocks) in a cryptographically signed format. Unlike traditional OAuth providers that require a separate /userinfo endpoint call, SVA OAuth delivers user data directly in the token response.

Token Structure

{
"alg": "HS256",
"typ": "JWT"
}

Payload

{
"sub": "user_id_123",
"aud": "client_id_abc",
"auth_request_id": "uuid-here",
"claims": {
"email": "[email protected]",
"name": "John Doe",
"phone": "+1234567890",
"username": "johndoe"
},
"exp": 1234567890,
"iat": 1234567890
}

Signature

The token is signed using HMAC-SHA256 (or RS256) with the DATA_TOKEN_SECRET.

Token Lifecycle

1. Generation

Data tokens are generated by SVA Core after user consent:

  1. User approves scopes on consent screen
  2. Frontend decrypts user data from vault
  3. Frontend builds claims object from approved scopes
  4. Frontend requests data attestation from SVA Core
  5. SVA Core validates request and generates signed token

2. Signing

The token is signed with DATA_TOKEN_SECRET:

import jwt

token = jwt.encode(
payload,
DATA_TOKEN_SECRET,
algorithm='HS256'
)

3. Inclusion

The data token is included in the token exchange response:

{
"access_token": "...",
"refresh_token": "...",
"data_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600
}

4. Storage

The data token is stored in the Django session:

request.session['sva_oauth_data_token'] = data_token

5. Verification

On each request, the token is verified:

decoded = jwt.decode(
data_token,
DATA_TOKEN_SECRET,
algorithms=['HS256'],
options={
"verify_signature": True,
"verify_exp": True,
"verify_aud": False,
}
)

6. Expiration

Data tokens expire in 5 minutes (default). After expiration:

  • Token verification fails
  • SVATokenError is raised
  • User is logged out automatically
  • User must re-authenticate

Token Claims

Standard Claims

  • sub - Subject (user ID)
  • aud - Audience (client ID)
  • auth_request_id - Authorization request ID
  • exp - Expiration time (Unix timestamp)
  • iat - Issued at time (Unix timestamp)

Custom Claims

The claims object contains all approved identity blocks:

{
"claims": {
"email": "[email protected]",
"name": "John Doe",
"phone": "+1234567890",
"address": {
"street": "123 Main St",
"city": "New York"
}
}
}

Security Features

Cryptographic Signing

  • Token is signed with DATA_TOKEN_SECRET
  • Signature verification prevents tampering
  • Any modification invalidates the token

Expiration

  • Short-lived tokens (5 minutes default)
  • Prevents token reuse
  • Forces re-authentication for fresh data

Audience Validation

  • Token includes aud claim (client ID)
  • Prevents token reuse across clients
  • Ensures token is for the correct application

Subject Validation

  • Token includes sub claim (user ID)
  • Links token to specific user
  • Prevents user impersonation

Verification Process

When you call get_sva_claims(request), the following happens:

  1. Retrieve Token: Get data token from session
  2. Verify Signature: Check token signature with DATA_TOKEN_SECRET
  3. Verify Expiration: Check token hasn't expired
  4. Extract Claims: Return claims dictionary
from sva_oauth_client.utils import get_sva_claims

claims = get_sva_claims(request)
# Token is automatically verified
# If invalid or expired, SVATokenError is raised

Why Data Tokens?

Stateless Design

  • No /userinfo endpoint needed
  • Data available immediately after token exchange
  • No additional network requests

Performance

  • Zero network overhead
  • Reduced latency
  • Better scalability

Security

  • Cryptographically signed
  • Tamper-proof
  • Self-contained

Privacy

  • User controls what data is included
  • Only approved scopes are in token
  • Short expiration limits exposure

Configuration

Secret Key

# settings.py
SVA_DATA_TOKEN_SECRET = 'your-secret-key-here'

Important: This must match the secret configured in your SVA provider.

Algorithm

# settings.py
SVA_DATA_TOKEN_ALGORITHM = 'HS256' # or 'RS256'

Expiration

Data token expiration is configured on the SVA provider side (default: 5 minutes).

Error Handling

Invalid Token

from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError

try:
claims = get_sva_claims(request)
except SVATokenError:
# Token is invalid or expired
# User will be logged out automatically
pass

Expired Token

If the token is expired:

  1. SVATokenError is raised
  2. User is logged out automatically
  3. User must re-authenticate
  4. New data token is issued

Best Practices

  1. Always verify tokens - Never trust unverified tokens
  2. Handle expiration - Implement proper error handling
  3. Store securely - Tokens are in server-side session
  4. Don't expose tokens - Never send tokens to client-side
  5. Monitor expiration - Watch for token expiration errors

Next Steps