Skip to content

Functional Requirements

This section formalizes normative requirements and measurable outcomes. Requirements are numbered FR-### (Functional Requirement) and outcomes SC-### (Success Criterion). This structure supports test mapping, due diligence review, and implementation tracking. (Source: §40; FRs §40.1, outcomes §40.2.)

Each FR has a stable anchor (#fr-065) so historical citations and the SRE guide's Part-D traceability resolve. Success criteria are on the Success Criteria page.

How to cite

Link a requirement as [FR-065](functional-requirements.md#fr-065) (or from another tab, ../reference/functional-requirements.md#fr-065). IDs are immutable; the list is additive.

Authentication & Users

  • FR-001 — System MUST allow users to register with email and password (post-MVP per §39.3; MVP uses SSO only)
  • FR-002 — System MUST authenticate users via JWT with 15-minute access tokens and rotatable refresh tokens
  • FR-003 — System MUST allow users to log out and invalidate all active refresh tokens
  • FR-004 — System MUST enforce password minimum length of 8 characters (post-MVP)
  • FR-005 — System MUST support OAuth SSO via GitHub and Google at MVP

Workspaces, Projects, Environments

  • FR-006 — Users MUST be able to create workspaces with unique slugs
  • FR-007 — Users MUST be able to create projects within a workspace, with unique slugs per workspace
  • FR-008 — Each project MUST be pinned to exactly one cluster at creation time (§20.1)
  • FR-009 — Users MUST be able to create user-defined environments per project (e.g., production, staging, dev)
  • FR-010 — System MUST isolate all environment-scoped resources (Var Groups, databases, buckets) at the environment level
  • FR-011 — Production environment protection flag (§15) MUST block non-admin deploys by default

Services & Deployment

  • FR-012 — Users MUST be able to create services linked to GitHub repositories
  • FR-013 — Users MUST be able to configure which branch deploys to which environment
  • FR-014 — System MUST trigger builds automatically on Git push to configured branches (debounced, §16.11)
  • FR-015 — System MUST build container images using Railpack (primary) or Dockerfile (fallback) via Depot SaaS
  • FR-016 — System MUST authenticate with GitHub using installation tokens when cloning private repositories
  • FR-017 — System MUST generate fresh GitHub installation tokens per build to ensure validity
  • FR-018 — System MUST deploy built images to Kubernetes with zero-downtime rolling updates
  • FR-019 — Users MUST be able to view deployment history and rollback to any previous successful version
  • FR-020 — System MUST provide customer-configurable health checks (liveness, readiness, startup probes)
  • FR-021 — System MUST display deployment progress with distinct steps: clone, build, push, deploy (§16.12)
  • FR-022 — System MUST display public URL after successful deployment
  • FR-023 — System MUST support user-initiated build cancellation in pending, building, or deploying states

Databases (Managed Primitive)

  • FR-024 — Users MUST be able to provision PostgreSQL databases per environment
  • FR-025 — Users MUST be able to provision Redis/Valkey instances per environment
  • FR-026 — System MUST automatically inject database credentials as environment variables via system Secret
  • FR-027 — System MUST display database connection strings and credentials after provisioning, subject to RBAC
  • FR-028 — System MUST encrypt database credentials at rest in Postgres using AES-256-GCM

Object Storage (Managed Primitive)

  • FR-029 — Users MUST be able to provision S3-compatible object storage buckets per environment
  • FR-030 — System MUST automatically inject storage credentials (endpoint, access key, secret key) as environment variables via system Secret
  • FR-031 — System MUST display storage endpoint and credentials after bucket creation, subject to RBAC
  • FR-032 — Users MUST be able to configure buckets as public or private
  • FR-033 — System MUST encrypt storage credentials at rest in Postgres using AES-256-GCM

Environment Variables & Secrets (Var Groups)

  • FR-034 — Users MUST be able to create, read, update, and delete Var Groups per project
  • FR-035 — Users MUST be able to attach Var Groups to services on a per-environment basis
  • FR-036 — System MUST encrypt all Var Group entry values at rest using AES-256-GCM
  • FR-037 — System MUST distinguish between variable entries (plaintext in UI) and secret entries (masked in UI)
  • FR-038 — System MUST translate each attached Var Group into a separate K8s Secret (§38.4)
  • FR-039 — System MUST display a warning when a Var Group attachment creates a key collision (§38.3)
  • FR-040 — System MUST trigger a rolling pod restart when any attached Var Group value changes (via checksum annotation, §24B.2)

GitHub Integration

  • FR-041 — Users MUST be able to install the Starform GitHub App on their accounts or organizations
  • FR-042 — System MUST store GitHub installation IDs to access repositories
  • FR-043 — System MUST process GitHub push webhooks with response within 10 seconds
  • FR-044 — System MUST verify webhook signatures with HMAC-SHA256 before processing
  • FR-045 — System MUST handle installation lifecycle events (created, deleted, suspended, unsuspended)
  • FR-046 — System MUST detect and handle stale or revoked installations gracefully, marking affected services as broken
  • FR-047 — System MUST deduplicate webhook deliveries by X-GitHub-Delivery header (24-hour retention)
  • FR-048 — System MUST handle GitHub API rate limits (5000 req/hour per installation) with exponential backoff

Observability

  • FR-049 — Users MUST be able to view real-time logs via live streaming (WebSocket or SSE from ClickHouse)
  • FR-050 — Users MUST be able to view CPU and memory usage metrics per service
  • FR-051 — System MUST retain logs and metrics per plan tier: 7 days (Hobby), 30 days (Pro), 90 days (Enterprise). Implementation note (v1.9): the two stores enforce this differently. Logs — per-tier TTL in ClickHouse by partition, so retention can vary per tenant cleanly. Metrics — single-node VictoriaMetrics retention is a global, per-instance setting (not per-tenant), so at MVP retention is set to the top tier (90 days) for all tenants; storage is trivial at launch volume. Per-tier metric retention requires either downsampling or multiple VM instances and is revisited at scale.
  • FR-052 — All Shuttle-created resources MUST carry the label set defined in §24
  • FR-053 — All Shuttle-created resources MUST carry the annotation set defined in §24B

Billing

  • FR-054 — System MUST track pod-level usage via Shuttle Snapshot Runnable every 60s (§19)
  • FR-055 — System MUST apply plan credit ($10 Hobby / $30 Pro) before charging usage overage
  • FR-056 — System MUST expire unused credits monthly (Railway-style)
  • FR-057 — Users MUST be able to view current estimated monthly cost with breakdown by resource category
  • FR-058 — System MUST bill build minutes at $0.05/min against plan credit (§16.7)

Security

  • FR-059 — System MUST enforce rate limiting of 100 requests per minute per user
  • FR-060 — System MUST encrypt all sensitive data at rest using AES-256-GCM (§39.1 item 18 for catalog)
  • FR-061 — System MUST enforce TLS 1.3 for all external communications
  • FR-062 — System MUST enforce NetworkPolicies between environments within a project namespace (§20.4)

Observability & Platform Operations (v1.9 additions)

  • FR-063 — System MUST provide per-service L7 metrics — request latency (p50/p95/p99), request rate (RPS), error rate (5xx ÷ total), and throughput — sourced from Envoy Gateway (§35.2). (Complements FR-050's CPU/memory.)
  • FR-064 — System MUST attribute every customer metric and log line to the tenant key project_id + environment + service_id, with workspace_id carried as the billing-boundary label (§24.1, §35.2)
  • FR-065 — System MUST scope all customer metric and log queries by a tenant filter injected server-side from the authenticated session; the client MUST NOT be able to supply or override it
  • FR-066 — System MUST ship customer telemetry over the private network (DO VPC peering) authenticated with a per-cluster bearer token at the metrics and logs ingress (§35.4)
  • FR-067 — System MUST constrain Envoy per-route metric cardinality (stat-inclusion matcher and custom histogram buckets) and MUST NOT emit per-route metrics for ephemeral (preview) environments, identified by the is_ephemeral flag rather than name-matching (§35.2, §39.1)
  • FR-068 — System MUST install metrics-server at cluster bootstrap to expose the Kubernetes Metrics API for HPA and kubectl top (not bundled on DOKS) (§26.3)
  • FR-069 — System MUST monitor its own platform components (Starbase API/Worker, control-plane Postgres, ClickHouse, VictoriaMetrics, Envoy Gateway, Load Balancers, Shuttle) via Grafana Cloud (hosted metrics + Grafana Alerting + OnCall), with a dedicated per-cluster Grafana Alloy agent shipping the platform series (separate from vmagent), at MVP; customer identifiers MUST be excluded from the platform series, or an EU-residency stack used (§35.5)
  • FR-070 — System MUST validate environment names as an RFC 1123 label (lowercase [a-z0-9-], start/end alphanumeric, ≤30 chars) — the name is load-bearing in HTTPRoute naming (§20.2) and as a K8s label value (§24.1)
  • FR-071 — System MUST serve cross-region telemetry reads over the private network (DO VPC peering) through an authenticated store front-door (vmauth + a read-only ClickHouse user) — never a public endpoint — and MUST apply the server-side tenant filter on that read path (§4.4, §35.4; complements FR-065 / FR-066)