Policies
Secure Development Lifecycle Policy
Effective date: TODO — set on legal approval
AI draft— pending legal & owner review; not legally binding.
1. Purpose and Scope
This Secure Development Lifecycle (SDLC) Policy defines how Persoon.ai Inc. (“ShipReady Metrics”) designs, implements, tests, and verifies changes to the ShipReady Metrics platform so that security is enforced by the pipeline rather than by promises. It applies to all application code, database schema changes, and delivery tooling in the platform’s source repository, across all environments.
This policy works together with the Change Management Policy (how changes are approved, deployed, and traced) and is anchored by the Information Security Policy. Where this document describes automated controls, those controls exist in the repository’s CI configuration and codebase and are verifiable there.
2. Development Model and Responsibility
ShipReady Metrics is developed by a single founder/owner with extensive use of AI-assisted development tooling. Because of this, the SDLC deliberately concentrates assurance in automated, non-bypassable verification: every change — regardless of who or what authored it — must pass the same machine-enforced gates before it reaches production.
- The founder/owner is responsible for all code that ships and for the review of AI-assisted changes. [Owner to confirm: review practice to be documented as the team grows.]
- There is no separate QA organization; quality assurance is performed by the automated suites described in Sections 5 and 6.
- Peer review requirements will be introduced when additional engineers join. [Owner to confirm: threshold and mechanism.]
3. Secure Design Principles
New features are designed against the platform’s standing security invariants:
- RLS-first data model: every tenant-scoped table enables Postgres Row-Level Security with org-scoped policies; there is no code path that trusts the client for tenant scoping. Authorization is evaluated in the application layer and again at the database layer.
- Default deny: access is denied unless explicitly granted. The most sensitive tables (e.g. encrypted connector secrets) are deny-all to every client role and accessible only via the service role.
- Fail closed: entitlement and capability resolution falls back to the most restrictive state on error rather than the most permissive.
- Honest data: scoring, compliance, and evidence features must never fabricate results — an unreachable probe or missing signal is surfaced as a gap, not defaulted to a pass.
- Server-side enforcement: privileged operations are implemented as server actions or authenticated API routes; client state is never the authority.
4. Secure Coding Standards
- TypeScript throughout, with compiler type-checking (tsc --noEmit) enforced in CI on every change.
- Static analysis and style: ESLint and Prettier are enforced both locally (pre-commit via lint-staged) and in CI (lint and format checks fail the build).
- Input validation with Zod schemas at trust boundaries (API routes, server actions, external payloads); output encoding via React’s default escaping.
- Secrets never enter the repository: environment files are gitignored, runtime secrets live in the hosting platform’s environment configuration, connector tokens are encrypted with AES-256-GCM before storage, and long-lived bearer tokens are persisted only as SHA-256 hashes.
- Browser-boundary hardening ships with the framework configuration: a per-request Content-Security-Policy with a cryptographic nonce and strict-dynamic, plus HSTS, X-Frame-Options DENY, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy headers.
- Commit hygiene: commit messages follow the Conventional Commits standard, enforced by commitlint on every commit.
5. Automated Verification Gates (CI)
Two independent CI pipelines run on every pull request and every push to the production branch. A failure in either fails the run:
| Pipeline | What it verifies |
|---|---|
| Verify (ci.yml) | Type-check, lint, format check, the full unit-test suite, a production build, and a SECURITY DEFINER function-grant audit that statically blocks database functions from being exposed to unintended roles. |
| DB Tests (db-tests.yml) | Applies every database migration from scratch against a disposable Postgres instance, then runs the pgTAP suite that proves tenant isolation (cross-tenant reads denied) and catches any migration that does not apply cleanly. |
The function-grant audit exists because of a real, fixed incident class: a SECURITY DEFINER function whose EXECUTE grant was left at the PostgreSQL default. The auditor fails CI on any new migration that creates or re-creates a guarded privileged function without revoking those grants in the same file.
6. Testing Standards
- Unit tests (Vitest) cover the scoring engine, provider adapters, connector validation, RBAC gates, route classification, rate limiting, and related server modules; the suite runs in CI on every change.
- The pure scoring engine is additionally held to explicit code-coverage thresholds (95% statements/functions/lines, 90% branches) enforced by the coverage run.
- Database tests (pgTAP) assert Row-Level Security behavior directly in SQL: org members see their rows; non-members and anonymous principals see zero rows; deny-all tables are invisible to client roles. These run in CI on every change.
- End-to-end tests (Playwright) cover authentication screens, route protection, and authenticated journeys, including a production-verification spec that can be run against the live environment. The e2e suite runs on demand rather than in the per-change CI pipeline. [Owner to confirm: cadence for running e2e against production.]
- Security-relevant regressions (e.g. the RLS privilege-escalation and grant-leak classes) are captured as permanent automated tests so the same bug class cannot silently return.
7. Dependency and Supply-Chain Management
- A single package manager (pnpm) with a committed lockfile pins the full dependency tree; CI installs with --frozen-lockfile, so an unreviewed dependency change cannot slip into a build.
- Dependency upgrades land as normal commits and pass every gate in Sections 5 and 6 before deployment.
- [Owner to confirm: automated dependency-vulnerability scanning and upgrade cadence — no automated update bot is currently configured in the repository.]
- Third-party services in the runtime path are documented in the Subprocessors list; their attestations are collected as vendor evidence.
8. Database Change Discipline
Schema changes follow an append-only migration model: each change is a new, sequentially numbered SQL migration committed to the repository; existing migrations are never edited. Every migration must apply cleanly from scratch (proven in CI), must preserve the RLS posture of the tables it touches, and must pass the function-grant audit. Deployment, drift detection, and out-of-band handling for migrations are governed by the Change Management Policy.
9. Vulnerability Management and Security Testing
- External reports: security researchers can report vulnerabilities responsibly under the Vulnerability Disclosure Policy published in the Trust Center.
- Internally found issues are triaged by severity; verified vulnerabilities are fixed through the standard pipeline, and deferred items are tracked explicitly rather than forgotten.
- Runtime protections that reduce exploitability — the per-request CSP, security headers, rate limiting on authentication and AI endpoints, and CSRF protections — are part of the deployed configuration and verifiable in the repository.
- [Owner to confirm: whether and when third-party penetration testing will be commissioned; none is claimed at this time.]
10. Exceptions and Review
Exceptions to this policy follow the exception process in the Information Security Policy: written, scoped, time-bound, and owner-approved. This policy is reviewed on the cadence defined there. This document is an AI-generated draft pending legal and owner review and is not binding until approved and dated.