Infrastructure & secrets
Surplus runs on managed infrastructure, which keeps the security surface small and the operational burden low. This page describes where the platform runs, the services it depends on, and how secrets are handled.
Hosting
All services are containerized with Docker and deployed on Railway:
- API server — three replicas in production.
- Web client — two replicas in production.
- Docs site and cron workers — each its own service.
Builds use each service's Dockerfile with the repository as the build context. See Build and deploy.
Managed data services
The platform deliberately relies on managed providers rather than self-hosted infrastructure, so patching, encryption at rest, and availability are handled by specialists:
- PostgreSQL — Neon. A primary database plus a read replica. A separate, dedicated analytics replica feeds the external insights application.
- Redis — Upstash. One-time codes, rate-limit counters, the analytics cache, and cron locks.
- File storage — Tigris. S3-compatible object storage for uploads, with separate private buckets for backups.
External integrations: Stripe (invoicing), Resend (transactional email), Apitally and Sentry (observability).
Sub-processors
Surplus relies on the following third-party services to operate the platform. This list covers services in this repository's deployment; the separate insights application uses its own Neon analytics replica and hosting, which is outside this monorepo.
| Provider | Role | Data typically processed |
|---|---|---|
| Railway | Application hosting (API, client, docs, crons) | Application code, env-injected secrets, request logs |
| Neon | PostgreSQL (primary + read replica) | All application data |
| Upstash | Redis | OTP codes, rate limits, analytics cache, locks |
| Tigris | S3-compatible storage | Uploaded files, backups |
| Stripe | Invoicing / payments | Billing metadata (not card data stored in Surplus DB) |
| Resend | Transactional email | Email addresses, OTP delivery |
| Apitally | API metrics, logs, traces (staging/production) | Request metadata; sensitive body/header fields masked |
| Sentry | Client error monitoring (staging/production) | Error events, stack traces, release/environment tags (sendDefaultPii: false) |
Provider-specific security and disclosure programs apply to issues in their infrastructure, not in Surplus application logic.
Environment isolation
Surplus runs across distinct environments — development, staging, and production — and the boundaries between them are enforced in code, not just configuration:
- Cookies are named and domain-scoped per environment, so a staging session can never be presented to production. See Authentication.
- CORS allowlists tighten per environment, with production restricted to
*.sharingexcess.com. See Network and application security. - Apitally request logging is enabled only in staging and production.
Secret management
Secrets never live in the repository. They're injected by Railway at runtime and read only at the app layer:
- Packages never read environment variables. Reusable packages receive configuration by injection, so a secret can't accidentally leak into shared code. This is an enforced convention (see Conventions).
- The server validates its configuration on startup through a Zod schema in
apps/server/src/helpers/env.ts. The server Dockerfile runs thisenv-checkat build time, so a deploy missing or misconfiguring a secret fails the build rather than starting in a broken or insecure state. - Local development uses the same injection path via the Railway CLI, so developers don't keep long-lived secrets in local files.
Secrets handled this way include the database connection strings, the JWT signing secret, S3 credentials, and the Stripe and Resend API keys.
What still needs to be documented
The following are infrastructure governance items, tracked as open rather than asserted here:
- Access controls and review cadence for the hosting and data-service accounts (who has production access, and how often it's reviewed).
- Secret rotation policy — the cadence and process for rotating the JWT signing secret and provider credentials.
- Compliance attestations — any certifications (for example SOC 2) held by Surplus itself, as distinct from those held by the underlying providers.