Authorization & Row-Level Security
Relevant source files
The following files were used as context for generating this wiki page:
Authorization and security in the LiveCanvas backend are implemented through a layered architecture that combines robust authentication, social-graph-based relationship checks, and strict data ownership rules. The system is designed to prevent Insecure Direct Object Reference (IDOR) vulnerabilities by re-applying authorization at every level of the GraphQL execution and data fetching process.
The primary goal of this security model is to ensure that private content, live sessions, and user-specific data are only accessible to authorized viewers based on their relationship with the content owner (e.g., following status, blocks, or mutes).
Sources: ARCHITECTURE.md:282-297, AGENTS.md:10-12
Layered Authorization Architecture
Authorization is enforced across three primary layers to ensure consistent security across different transport protocols (GraphQL, WebSockets, and REST).
- Authentication Layer: Establishes the
current_useridentity. - Relationship Layer (Social Context): Enforces access based on the follower graph, including private/public account status.
- Domain/Resource Layer: Enforces specific ownership rules for resources like posts, media assets, and chat messages.
Sources: ARCHITECTURE.md:283-288
Authorization Flow Diagram
The following diagram illustrates the decision flow when a user attempts to access a protected resource.
This flowchart shows the sequential checks from initial authentication through social relationship validation to final resource-level ownership.
Sources: ARCHITECTURE.md:282-300, mobile/schema.graphql:391-410
Social-Graph Based Security
The Social context serves as the primary policy layer for visibility. It manages follows, blocks, and mutes to determine who can interact with whom.
Relationship States
The system tracks several states that impact authorization:
- Public vs. Private: Private accounts require a follow request/approval before content is visible.
- Blocks: Hard restrictions that override all other visibility rules.
- Mutes: Affects the visibility of content in the viewer's feed but does not necessarily restrict access to the resource itself.
Sources: ARCHITECTURE.md:214-220, mobile/schema.graphql:236-242
Relationship State Summary
| State | Description | Access Level |
|---|---|---|
ACCEPTED | Follower request approved | Full access to follower-only content |
BLOCKED | Hard restriction | No visibility or interaction |
REQUESTED | Pending follow request | Restricted access (public only) |
PUBLIC | Open visibility | Access to all public content |
NONE | No relationship | Access to public content only |
Sources: mobile/schema.graphql:236-242, ARCHITECTURE.md:255-257
GraphQL & IDOR Prevention
A critical security convention in the backend is the re-application of viewer authorization in GraphQL node fetchers and child field resolvers. Globally refetchable IDs (Relay-first) must not bypass ownership or visibility rules (addressing CWE-639).
Implementation Strategy
- Node Fetchers: When fetching a node by its global ID, the system must verify the
viewerhas permission to see that specific entity. - Foreign Keys: Raw foreign keys in input objects are treated as untrusted and validated against the session's user.
Sources: AGENTS.md:10-12, ARCHITECTURE.md:118-120
GraphQL Node Security Pattern
The sequence diagram demonstrates how the resolver consults the Social context before returning data for a specific Node ID.
Sources: AGENTS.md:10-12, ARCHITECTURE.md:214-220
Realtime & WebSocket Security
Security for realtime features is handled via Phoenix Channel authentication and topic-level authorization.
- Channel Joins: Every attempt to join a topic (e.g.,
live_session:idorchat:id) must validate the viewer's eligibility and role (Host vs. Viewer). - Presence: Payloads are restricted to the minimum client-visible state to prevent data leakage.
- CSRF Protection: WebSockets use CSRF tokens established during the initial page load to prevent cross-site request forgery.
Sources: ARCHITECTURE.md:302-307, assets/js/app.js:23-27
Data Persistence & Secret Handling
The system adheres to strict rules regarding the storage of sensitive information to ensure security at the database level.
- Token Hashing: Token secrets (for sessions, password resets, etc.) are never stored in raw form. They are hashed using SHA3-based algorithms before being persisted in the
user_tokenstable. - UUIDv7 for Identifiers: Default relational tables use
bigintprimary keys with an:entropy_id(UUIDv7) for public-facing identifiers, which prevents sequential ID enumeration. - Normalized Identity: Sensitive user data like email and phone numbers are normalized into separate tables (
email_addresses,phone_numbers) with verification timestamps (verified_at).
Sources: AGENTS.md:5-9, ARCHITECTURE.md:267-279
Token Data Model
| Field | Type | Description |
|---|---|---|
id | uuid (v7) | Primary key (Postgres-generated) |
user_id | bigint | Reference to owner |
secret_hash | binary | SHA3 hash of the token secret |
context | string | Purpose (e.g., session, password_reset) |
Sources: ARCHITECTURE.md:276-281, AGENTS.md:5-9
Conclusion
The Authorization & Row-Level Security system in LiveCanvas provides a defense-in-depth approach. By integrating social relationship logic directly into the authorization flow and enforcing strict conventions for GraphQL node fetching and token persistence, the backend ensures that user data remains private and resistant to common web vulnerabilities like IDOR and credential exposure.
Sources: ARCHITECTURE.md:282-290, AGENTS.md:10-12