Skip to main content

Architecture Overview

High-level overview of the SVA OAuth architecture and how all components work together.

System Components

SVA OAuth consists of three main services:

┌─────────────────┐         ┌──────────────────┐         ┌─────────────────┐
│ SVA OAuth │ │ SVA Core │ │ SVA Client │
│ Provider │◄────────┤ (Server) │────────►│ (Frontend) │
│ (sva_oauth) │ │ (sva_server) │ │ (sva_client) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ │ │
└───────────────────────────┴────────────────────────────┘


┌─────────────────┐
│ Third-Party │
│ App │
│ (Your App) │
└─────────────────┘

SVA OAuth Provider (sva_oauth)

Role: Public-facing OAuth 2.0/OIDC server

Responsibilities:

  • Manages OAuth applications and client credentials
  • Handles authorization requests
  • Issues authorization codes
  • Exchanges codes for tokens
  • Provides token endpoints

Endpoints:

  • GET /oauth/authorize - Authorization endpoint
  • POST /oauth/token - Token endpoint
  • GET /oauth/userinfo - UserInfo endpoint
  • POST /oauth/revoke - Token revocation

SVA Core (sva_server)

Role: User account and vault management

Responsibilities:

  • Manages user accounts
  • Stores encrypted user data (zero-knowledge)
  • Issues signed data tokens (cryptographic notary)
  • Validates consent requests
  • Attests to user claims

Endpoints:

  • POST /api/internal/attest-data/ - Issue data token
  • GET /api/internal/oauth/requests/{id}/ - Get auth request (proxy)
  • POST /api/internal/oauth/requests/{id}/complete/ - Complete consent (proxy)

SVA Client (sva_client)

Role: User-facing consent UI

Responsibilities:

  • Displays consent screen
  • Allows users to approve/deny scopes
  • Decrypts user data client-side
  • Initiates data attestation

Pages:

  • /consent - Consent screen

OAuth Flow Architecture

Standard OAuth 2.0 Flow

SVA OAuth follows the standard OAuth 2.0 Authorization Code Flow with PKCE:

┌─────────┐         ┌──────────────┐         ┌─────────────┐         ┌──────────────┐
│ App │────────▶│ SVA OAuth │────────▶│ SVA Client │────────▶│ SVA Server │
│ │ │ Provider │ │ (Consent) │ │ (Attest) │
└─────────┘ └──────────────┘ └─────────────┘ └──────────────┘
│ │ │ │
│ 1. Auth Request │ │ │
│─────────────────────▶ │ │
│ │ │ │
│ │ 2. Redirect to Consent│ │
│ │────────────────────────▶ │
│ │ │ │
│ │ │ 3. Fetch Request │
│ │ │───────────────────────▶
│ │ │ │
│ │ │ 4. User Approves │
│ │ │ │
│ │ │ 5. Attest Data │
│ │ │───────────────────────▶
│ │ │ │
│ │ 6. Consent Complete │ │
│ │◄──────────────────────── │
│ │ │ │
│ 7. Auth Code │ │ │
│◄───────────────────── │ │
│ │ │ │
│ 8. Exchange Code │ │ │
│─────────────────────▶ │ │
│ │ │ │
│ 9. Tokens + Data │ │ │
│◄───────────────────── │ │

Zero-Knowledge Architecture

Data Encryption

User data is stored encrypted in SVA Core:

User Data → Encrypt (Client-Side) → Encrypted Data → Store in SVA Core

Data Decryption

Data is decrypted only in the user's browser:

Encrypted Data → Fetch from SVA Core → Decrypt (Client-Side) → Plaintext Data

Data Attestation

SVA Core attests to user claims without seeing plaintext:

Plaintext Data (Client) → Build Claims → Request Attestation → Signed Data Token

Service Communication

Internal Service Tokens

All inter-service communication uses a shared secret:

INTERNAL_SERVICE_TOKEN = 'shared-secret'

Service-to-Service Calls

Services communicate via HTTP with service token authentication:

headers = {
'X-Service-Token': INTERNAL_SERVICE_TOKEN
}
response = requests.get(url, headers=headers)

Security Model

  • Service Token: Shared secret for service authentication
  • Data Token Secret: Separate secret for JWT signing
  • HTTPS: All production communication over HTTPS
  • Network Isolation: Services communicate via internal network

Data Token Architecture

Token Structure

Data tokens are JWTs containing user claims:

{
"sub": "user_id",
"aud": "client_id",
"auth_request_id": "uuid",
"claims": {
"email": "[email protected]",
"name": "John Doe",
"phone": "+1234567890"
},
"exp": 1234567890,
"iat": 1234567890
}

Token Lifecycle

  1. Generation: Created by SVA Core after user consent
  2. Signing: Signed with DATA_TOKEN_SECRET
  3. Inclusion: Included in token exchange response
  4. Storage: Stored in application session
  5. Verification: Verified on each request
  6. Expiration: Short-lived (5 minutes default)

Stateless Design

No /userinfo Endpoint

Unlike traditional OAuth providers, SVA OAuth delivers user data directly in the token response:

Traditional OAuth:

Token Exchange → Access Token → Call /userinfo → User Data

SVA OAuth:

Token Exchange → Access Token + Data Token → Decode Data Token → User Data

Benefits

  • Zero Network Overhead: No additional API calls
  • Better Performance: Data available immediately
  • Offline Capability: Data accessible even if provider is down
  • Reduced Latency: No round-trip to /userinfo

Security Architecture

PKCE (Proof Key for Code Exchange)

Prevents authorization code interception:

1. Generate code_verifier (random)
2. Generate code_challenge = SHA256(code_verifier)
3. Send code_challenge in authorization request
4. Send code_verifier in token exchange
5. Provider verifies: SHA256(code_verifier) == code_challenge

State Parameter

CSRF protection:

1. Generate random state
2. Store in session
3. Include in authorization request
4. Verify in callback

Data Token Verification

Cryptographic integrity:

1. Verify signature with DATA_TOKEN_SECRET
2. Verify expiration
3. Verify audience (client_id)
4. Verify subject (user_id)

Next Steps