QualitySecurity
42 days

Security Posture

The controls that keep an Uploz deployment honest, grouped by domain — what is enforced today, what is still partial, and what is owed before the PROD posture can be signed off. Postgres is the enforcement boundary (R5): Row-Level Security and the write-path RPCs are the spine of this board, and the verification rows track the adversarial confirmation (including a pending third-party pen-test) still outstanding.

15

Controls tracked

6

Enforced

9

Outstanding

40%

Fully enforced

Database (RLS + RPC)

Database (RLS + RPC)

Row-Level Security on all tenant tables

Critical

Every tenant-scoped table denies by default; policies scope rows to the caller’s org via the JWT claim. RLS is the enforcement boundary, not the app layer (R5).

Evidence: force_row_level_security on each table; policy regression suite asserts cross-tenant reads return zero rows.

Supabase Postgres · R5

Enforced

Writes only through SECURITY DEFINER RPCs

Critical

No direct table grants to clients. State transitions go through validated RPCs (e.g. fn_request_transition) that re-check the transition boundary server-side.

Evidence: Anon/auth roles hold no INSERT/UPDATE/DELETE grants; transition-boundary tests gate illegal moves.

apps/web, apps/worker · R5

Enforced

Service-role key is server-only

Critical

The service-role key bypasses RLS and is restricted to the worker / server runtime. It is never bundled into the browser.

Evidence: Key read only from server env; build check fails if a NEXT_PUBLIC_* alias leaks it to the client bundle.

apps/worker

Enforced

Authentication

Authentication

JWT verification on every authenticated request

Critical

GoTrue-issued JWTs are verified on the read path; expiry and signature are checked before any RLS claim is trusted.

Evidence: Signature + exp validated at the API gateway; expired tokens are rejected before reaching Postgres.

Supabase API / Auth

Enforced

JWT signing-key rotation

High

Signing keys are rotated on a schedule with an overlap window so live sessions are not dropped.

Evidence: Rotation procedure documented and rehearsed in DEV; PROD rotation cadence not yet automated.

Next: Wire the rotation into the scheduled job and alert on key age > 90 days.

Supabase API / Auth

Partial

dev-admin IP allowlist

High

The internal cockpit is reachable in PROD only from an allowlisted CIDR range, read-only against PROD data.

Evidence: ADMIN_ALLOWLIST_CIDR enforced at the edge; SSO in front of the cockpit is still pending.

Next: Put SSO in front of dev-admin so access is identity-bound, not just network-bound.

apps/dev-admin

Partial

Transport

Transport

TLS termination at the edge

High

All public traffic is HTTPS; the edge terminates TLS and forwards over the private network.

Evidence: Edge enforces HTTPS redirect; no plaintext listener exposed in PROD.

Edge / CDN

Enforced

Security response headers (HSTS, CSP)

Medium

HSTS, a restrictive Content-Security-Policy, and frame-ancestors are set on the app responses.

Evidence: HSTS + frame-ancestors live; CSP currently report-only while inline-style sources are tightened.

Next: Promote CSP from report-only to enforce after the report queue is clean for a week.

apps/web

Partial

Abuse / rate-limiting

Abuse / rate-limiting

Edge rate-limiting on public endpoints

High

Per-IP request budgets on auth and write-adjacent endpoints to blunt credential-stuffing and floods.

Evidence: Coarse per-IP limits live at the edge; per-account and per-RPC budgets not yet tuned.

Next: Add per-account limits keyed on the JWT subject and alert on sustained 429 rates.

Edge / CDN

Partial

Write-path RPC throttling

Medium

Transition RPCs are throttled so a compromised session cannot drive runaway state churn.

Evidence: Design noted; no per-caller RPC budget enforced yet.

Next: Add a token-bucket check inside the SECURITY DEFINER RPCs keyed on caller + request.

Supabase Postgres

Planned

Supply chain

Supply chain

Contract-validated inputs

High

All inbound payloads are parsed against the shared @uploz/contracts schemas before any write is attempted.

Evidence: Zod schemas reject malformed input at the boundary; security-input tests cover injection-shaped strings.

packages/contracts

Enforced

Dependency vulnerability audit

Medium

Lockfile is audited for known-vulnerable transitive dependencies on each build.

Evidence: Audit runs in CI and reports; build does not yet fail on high-severity advisories.

Next: Gate the build on high/critical advisories once the current backlog is triaged.

CI

Partial

Secret scanning on commits

Medium

Pre-merge scanning blocks accidental commit of keys, tokens, and connection strings.

Evidence: Not yet wired; relying on reviewer vigilance and the server-only-key build check.

Next: Enable push-protection secret scanning on the repository.

CI

Planned

Verification

Verification

Third-party penetration test

High

External assessment of the auth, RLS, and write-path boundaries before the PROD posture is signed off.

Evidence: Scope drafted (tenant isolation, JWT, RPC abuse); engagement not yet booked.

Next: Book the engagement and reserve a remediation window after the report lands.

Security

Pending verification

Adversarial cross-tenant verification

Critical

Independent confirmation that RLS cannot be bypassed via crafted JWTs or RPC argument tampering.

Evidence: Internal regression suite passes; awaiting the external pen-test to corroborate.

Next: Fold the pen-test findings back into the policy regression suite as new cases.

Security · R5

Pending verification

State legend

How each control’s lifecycle state maps onto the traffic-light vocabulary.

EnforcedPartialPlannedPending verification

Authored from the architecture / security notes (illustrative project-tracking state, permitted per R1), not the output of a live scanner. The service-role key and write-path grants live server-side only; this board is read-only and never holds a credential.