Skip to content

feat: serverless-ready production deployment — Redis cache/vault, Postgres DB, Dockerfile, self-hosting guide #376

@manojbajaj95

Description

@manojbajaj95

Summary

Prepare authsome for stateless, horizontally-scalable production deployments. The current implementation relies on local disk for KV storage and session state, which breaks in containerised/serverless environments where the filesystem is ephemeral and multiple replicas can't share state.

Motivation

  • File-based storage (DiskStore, local KV) does not persist across container restarts or scale beyond a single process.
  • Session state stored in-process is lost on eviction or pod churn.
  • Operators deploying to Railway, Fly.io, Render, or any container platform need a clear production path.

Scope of work

1. Dockerfile

  • Multi-stage build (builder + runtime) using the uv tool-chain.
  • Non-root user, minimal image (e.g. python:3.12-slim).
  • Health-check endpoint (GET /health).
  • Expose AUTHSOME_* env vars for all runtime config.

2. Postgres as the relational store

  • Wire up the five server-owned registries (IdentityRegistry, PrincipalRegistry, VaultRegistry, IdentityClaimRegistry, PrincipalVaultBindingRegistry) to use Postgres when AUTHSOME_DATABASE_URL starts with postgresql://.
  • Ensure connection pooling is configured (e.g. via asyncpg + SQLAlchemy async engine).
  • Migration strategy (Alembic or equivalent) so schema is applied at startup.

3. Redis as session cache

  • Replace any in-process or file-backed session/token cache with Redis.
  • JTI replay cache (PoP auth anti-replay, src/authsome/identity/proof.py) must use Redis with a TTL equal to the token window.
  • AUTHSOME_REDIS_URL controls the connection; fall back to in-memory only in test/dev mode.

4. Redis as vault backend

  • Add a RedisVaultBackend alongside the existing DiskStore backend.
  • Encrypted blobs (already encrypted by Vault) stored as Redis keys with the same vault:<vault_id>:... naming scheme.
  • Backend selected via AUTHSOME_VAULT_BACKEND=redis (default: disk for local dev).
  • Master key continues to be loaded from env (AUTHSOME_MASTER_KEY) or OS keyring; never stored in Redis.

5. Remove file-as-cache anti-patterns

  • Audit the codebase for any use of temp files, local JSON caches, or in-process dicts that would break under multiple replicas.
  • Replace each with Redis (for shared mutable state) or move to stateless computation.

6. Self-hosting guide (docs/guides/self-hosting.md)

  • Prerequisites: Docker, a Postgres instance, a Redis instance.
  • Environment variable reference (AUTHSOME_DATABASE_URL, AUTHSOME_REDIS_URL, AUTHSOME_VAULT_BACKEND, AUTHSOME_MASTER_KEY, etc.).
  • Step-by-step: pull image → set env vars → authsome init → verify with GET /health.
  • Example docker-compose.yml for local production simulation (authsome + Postgres + Redis).
  • Notes on secret management (do not put AUTHSOME_MASTER_KEY in compose files in production; use Doppler/Vault/cloud secrets).
  • Upgrade/migration instructions.

Acceptance criteria

  • docker build produces a working image; docker run with env vars starts the daemon cleanly.
  • All five registries read/write to Postgres when AUTHSOME_DATABASE_URL is set.
  • JTI replay cache uses Redis; a second replica rejects a replayed PoP JWT.
  • Vault blobs are stored in Redis when AUTHSOME_VAULT_BACKEND=redis; encrypted at rest.
  • No local file writes in the hot path when Redis/Postgres backends are active.
  • docs/guides/self-hosting.md is complete, including a working docker-compose.yml example.
  • uv run pytest passes (new integration tests for Redis/Postgres backends, gated behind optional deps or docker fixtures).
  • uv run ruff check and uv run ty check pass.

Implementation notes

  • Keep DiskStore and SQLite paths working for local dev — operators should be able to run authsome init without any external services.
  • Backend selection should be via env vars, not code changes.
  • Do not introduce Redis or Postgres as hard dependencies for the base install; use optional extras (authsome[redis], authsome[postgres]).
  • Follow existing engineering principles: YAGNI, deep modules, no premature abstraction.

References

  • Architecture overview: CLAUDE.md → Architecture section
  • Current store: src/authsome/server/store/repositories.py
  • PoP auth / JTI cache: src/authsome/identity/proof.py
  • Vault backend: src/authsome/vault/
  • ServerSettings: src/authsome/server/settings.py
  • Existing self-hosting stub: docs/guides/self-hosting.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions