Secret Handling & Token Management
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Secret Handling and Token Management within LiveCanvas encompasses the lifecycle of sensitive credentials, including user passwords, OAuth tokens, and session-based identifiers. The system is designed to minimize the exposure of raw secrets by utilizing one-way hashing for persistence and ensuring that sensitive data is only returned to clients once during issuance.
The architecture prioritizes security by leveraging PostgreSQL as the sole persistent store for hashed secrets while maintaining ephemeral state in OTP and Phoenix PubSub for transient needs. This module ensures that authentication and authorization remain robust across GraphQL, REST, and WebSocket transports.
Sources: ARCHITECTURE.md:213-217, ARCHITECTURE.md:270-278, AGENTS.md:12-14
Core Token Architecture
The backend implements a unified user_tokens model to handle various authentication and verification contexts. Unlike other relational tables that use bigint primary keys, the token system uses pure UUIDv7 identifiers for global uniqueness and temporal sorting.
Persistent Token Storage
LiveCanvas strictly adheres to a policy where raw secrets are never stored in a recoverable form. The user_tokens table utilizes a secret_hash column for validation.
| Field | Type | Description |
|---|---|---|
id | UUIDv7 | Primary key for the token record. |
user_id | Foreign Key | Reference to the users table. |
secret_hash | Binary | SHA3-based hash of the token secret. |
context | String | Purpose of the token (e.g., session, refresh, reset). |
Sources: AGENTS.md:10-14, ARCHITECTURE.md:213-228
Hashing Requirements
The project mandates the use of SHA3-based hashing for all persisted token secrets. This is a specific convention to replace older SHA-2 standards, providing enhanced security against collision attacks. Passwords specifically are stored using strong, industry-standard password hashes.
Sources: AGENTS.md:14, ARCHITECTURE.md:271-272
Authentication Lifecycle & Flows
The system supports multiple login methods, all converging on a unified token issuance process. The primary client interaction occurs through GraphQL mutations.
Auth Token Flow
When a user successfully authenticates via password, magic link, or OAuth, the server generates a pair of tokens: an Access Token and a Refresh Token.
The raw secret is returned to the client exactly once and is never re-transmitted by the server.
Sources: ARCHITECTURE.md:226-228, mobile/schema.graphql:169-178
GraphQL Auth Mutations
The RootMutationType provides specific endpoints for token lifecycle management:
| Mutation | Input Type | Description |
|---|---|---|
issueViewerAuthTokens | IssueViewerAuthTokensInput | Issues initial token pair for a device. |
refreshAuthTokens | RefreshAuthTokensInput | Uses a refresh token to obtain a new access token. |
revokeRefreshToken | RevokeRefreshTokenInput | Invalidates a specific refresh token. |
beginAuthChallenge | BeginAuthChallengeInput | Initiates multi-step flows like Passkeys. |
Sources: mobile/schema.graphql:47-50, mobile/schema.graphql:197-211
Secret Handling Policies
OAuth and Third-Party Secrets
For external providers (Apple, Google, etc.), the backend stores linked identity metadata. Any retained provider-specific tokens must be encrypted at rest to prevent exposure in the event of a database compromise.
Sources: ARCHITECTURE.md:273, mobile/schema.graphql:440-444
Transport Security
- GraphQL: The primary API for durable reads/writes.
- WebSockets: Phoenix Channels require authentication and authorization per topic. Joins must validate viewer eligibility and session access.
- CSRF Protection: Standard Phoenix CSRF tokens are utilized to protect the LiveView and socket connections.
Sources: ARCHITECTURE.md:255-260, assets/js/app.js:25-27
Implementation Example: Token Structure
The GraphQL schema defines the structure of the token returned to clients, ensuring transparency regarding expiration.
type Token {
serializedValue: String!
tokenVersion: Int!
expiresAt: String
insertedAt: String
updatedAt: String
}
Sources: mobile/schema.graphql:525-531
Security Audit and Logging
The system implements Telemetry to track sensitive authentication events without leaking the secrets themselves. This includes:
- Auth attempts and failure codes (e.g.,
INVALID_CREDENTIALS,TOKEN_EXPIRED). - Credential link/unlink events.
- Token revocation actions.
Sources: ARCHITECTURE.md:280-282, ARCHITECTURE.md:307-310, mobile/schema.graphql:414-424
Summary
Secret handling in the LiveCanvas backend is centralized around a secure-by-default posture using SHA3 hashing and UUIDv7 identifiers. By separating persistent hashed facts from ephemeral runtime state and strictly controlling the issuance of raw secrets, the system mitigates risks associated with identity theft and unauthorized access across its multi-transport architecture.