Trust Center · 02
← Back to Trust Center
Secure software development lifecycle
EFFECTIVE: MAY 1, 2026 · LAST UPDATED: MAY 1, 2026
This document describes how the Arx engineering team designs, builds, reviews, tests, and ships code, and the security controls that apply at each stage. It is the public-facing summary of our Secure Software Development Lifecycle (SSDLC). Detailed runbooks live in our internal documentation and are available to assessors under NDA.
1. Guiding principles
- Secure by default. Workspace data is private unless an action explicitly shares it.
- Least privilege. Every code path receives the narrowest set of credentials, scopes, and database privileges it needs.
- Defence in depth. Authentication, authorisation, Row-Level Security, input validation, and rate limiting are all enforced independently.
- Automation over discipline. Where we can automate a check we do, so that no individual reviewer is the last line of defence.
- Reproducible builds. Production code is built and deployed only by CI from a protected branch.
2. Design & threat modeling
Significant features begin with a written design document that includes the threat surface (untrusted inputs, new third parties, new tokens, new data categories) and the controls applied. New external integrations require a written review of the OAuth scopes, token storage, retention, and revocation flow before any code is written. Features that handle sensitive workflows (cap table, data room sharing, AI tool calls, MCP, payments) require sign-off from the engineering lead.
3. Coding standards
- The codebase is TypeScript end-to-end, with strict compiler settings.
- All HTTP inputs are validated through Zod schemas; we do not trust query strings, route params, or request bodies.
- All database access is through Drizzle ORM with parameterised queries; raw SQL is reviewed case by case and never accepts unsanitised user input.
- All workspace-scoped queries include the resolved
company_id and rely on Row-Level Security as a second-line defence. - React components encode dynamic content by default.
dangerouslySetInnerHTML is forbidden on user-provided content; usage requires written justification in code review. - Authentication tokens, OAuth tokens, and signing secrets are only ever read through dedicated helpers that enforce decryption and audit logging.
4. Code review & branch protection
- The
main branch is protected. Direct pushes are disabled. - All changes land via pull request from a short-lived feature branch.
- Each pull request requires at least one approving review from someone other than the author.
- Reviewers are required to verify that the change preserves authentication, authorisation, and tenant-isolation invariants.
- Force-pushing to
main is disabled. History is append-only after merge. - Pull request authors and reviewers are recorded in the audit trail kept by our source-control provider.
5. Automated testing
Every pull request and every push to main runs a full verification job in CI:
- Lint — ESLint across all packages.
- Typecheck — TypeScript compiler in strict mode across all packages.
- Unit & integration tests — the project test suite runs against a fresh database; tests are required to pass before merge.
- Build — production builds of every deployable.
- Dockerfile validation — container build for backend services.
- Tenant-isolation tests — a dedicated test suite verifies that a user in one workspace cannot read or write rows belonging to another workspace, exercising both application code and Row-Level Security policies.
6. SAST, DAST & dependency scanning
- SAST — static analysis runs on every pull request. We use a combination of language-aware linters and security-focused rules to detect insecure patterns, injection sinks, and risky API usage. Findings above the configured threshold block merge until they are fixed or formally accepted.
- Dependency scanning —
pnpm audit and provider advisories run on every pull request and on a daily schedule against main. Critical and high advisories trigger an alert and a patch task. - Container scanning — built container images are scanned for known CVEs before deploy.
- DAST — authenticated and unauthenticated dynamic scans run against a staging environment on a defined cadence and before major releases. Findings are tracked in the same vulnerability backlog as SAST and external reports (see /responsible-disclosure).
- Secret scanning — every commit and pull request is scanned for high-entropy strings and known credential patterns; matches block merge.
7. Secret management
- Production secrets live in the hosting providers' encrypted environment-variable stores.
- Secrets are never committed to source control; pre-commit hooks and CI scanners block accidental commits.
- OAuth tokens we hold for customers are AES-256-GCM-encrypted at the application layer before being written to the database. The encryption key is provisioned only to the production API process.
- Developer machines do not hold production secrets. Local development uses dedicated test credentials with limited scope.
- Secrets are rotated on a defined cadence and immediately on any suspected compromise.
8. CI / CD pipeline
Continuous integration runs on GitHub Actions. The pipeline:
- Checks out the pull request, installs dependencies through pnpm with a lockfile, and runs the verification suite (§5).
- Runs SAST, dependency, and secret scans (§6).
- Builds production artefacts for every deployable.
- Only after all checks pass on
main are deploys triggered by the hosting providers (Vercel, Railway). No human can push code straight to production.
9. Deployment & rollback
- Deploys to production are immutable and atomic: each deploy is a fresh build identified by commit SHA.
- Vercel and Railway support instant rollback to a prior successful build; we exercise rollback regularly.
- Database migrations are versioned, peer-reviewed, and applied through a controlled process. Migrations are reversible where reasonably possible and are tested against a staging copy before production.
- Feature flags gate user-visible changes to high-risk surfaces, allowing rapid kill-switching without a redeploy.
10. Production access
- Production cloud consoles (Vercel, Railway, Supabase) require hardware-backed two-factor authentication.
- Production database access is restricted to a small number of named engineers. Ad-hoc queries against production data are logged and require written justification.
- Customer-content access by Arx personnel is not part of any routine workflow. Where it is unavoidable (debugging a specific incident at customer request), it is documented and time-bounded.
- Access is revoked the same day a contract ends.
11. Change management & audit
- Every code change is recorded in source control with author, reviewer, and reviewer-approval timestamp.
- Every infrastructure change goes through the same pull-request process or is recorded in a written change ticket.
- Production deploy events, including the commit SHA, deployer, and outcome, are retained by the hosting provider and our observability backend.
- Customer-workspace audit logs capture mutating actions taken inside the application (who, what, when) for at least 12 months.
12. Engineering training
- All engineers complete secure-coding training during onboarding.
- Refresher training, including a review of OWASP Top 10 categories most relevant to our stack, runs at least annually.
- Lessons learned from incidents, vulnerability reports, and pen-test findings are shared with the team in writing.
Production environment: foundersarx.com, app.foundersarx.com, api.foundersarx.com.