Skip to content

security: define a non-persistent production demo principal #548

Description

@tiankaima

Goal

Provide a production demo experience without a normal demo login entry and without creating demo User, Account, Session, enrollment, todo, or other business rows in PostgreSQL.

This is a security/product RFC before broad implementation.

Proposed boundary

  • Enter through an explicit /demo bootstrap/direct link protected by rate limits and a kill switch; obscurity is not an authorization control.
  • Mint a server-signed, short-lived DemoPrincipal that is not a Better Auth DB session and does not impersonate a user ID.
  • Render deterministic fixture/read projections; demo courses/subscriptions/todos are not database rows.
  • Intercept an allowlisted set of mutable commands before Prisma, R2, OAuth, webhooks, or public side effects. Return simulated: true rather than pretending persistence succeeded.
  • Persist only privacy-safe structured audit events: allowlisted action/operation/tool, request ID, timestamp, and opaque demo-session hash. Never log bodies, tokens, or PII.
  • Explicitly prohibit admin, OAuth client/consent/token, account linking/deletion, uploads, public comments/descriptions/homework, calendar feeds, and webhooks in v1.

Required decisions

  • entrypoint and session TTL;
  • read fixtures and mutable allowlist;
  • whether short-lived simulated state is signed-cookie overlay or an isolated TTL store;
  • audit sink, retention, alerting, and abuse limits;
  • consistent simulated semantics for UI, REST/GraphQL, and MCP.

Draft PR target

After the RFC decisions, open a draft vertical slice covering principal + /demo + fixtures + central command gate for one feature and negative side-effect tests. Keep it draft until the threat model is accepted.

Acceptance criteria

  • Demo requests cause zero business writes to DB/R2/OAuth/external systems; audit is the only allowed durable effect.
  • No real user/FK/session exists and a cookie/email cannot be forged into demo mode.
  • Simulated writes are visibly and machine-readably marked.
  • Normal/authenticated/admin behavior is unchanged.
  • Logs contain no sensitive values; kill switch and rate limits are tested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, OAuth, identity, authorization, roles, scopes, and credentialsarea: infrastructureProduction runtime, Cloudflare, storage, containers, deployment, and releaseskind: securityKind: security

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions