For NIH-funded genomic research customers and university procurement review
| Control Family | Selected Controls | How Baseshift Addresses It | Where to Find Evidence |
|---|---|---|---|
| Access Control (AC) | AC-2, AC-3, AC-6, AC-12 |
Account creation in routes/auth.js:13-61 (signup) and routes/auth.js:64-103 (login) requires bcrypt-hashed password (routes/auth.js:32, 12-round cost factor). JWT session cookie bs_auth set httpOnly, sameSite='lax', secure in production (lib/auth-helpers.js:11-19); 30-day expiry (lib/auth-helpers.js:6). Route-level requireAuth middleware (lib/auth-helpers.js:36-52) gates /dashboard, /compare, /api-access (server.js:86-90). All upload and variant queries scoped to req.userId via WHERE user_id = $1 patterns in db/batches.js and db/compare.js; users cannot read other users' variants. |
lib/auth-helpers.js, routes/auth.js, route mounts in server.js |
| Audit & Accountability (AU) | AU-2, AU-3, AU-12 |
The analytics_events table (migrations/1747000000000_create_analytics_events.js) records event_type, user_id, session_id, metadata with the insertEvent helper in db/analytics.js. Signup/login funnel events fire from routes/auth.js:53; payment, contact, and batch lifecycle events fire from routes/payments.js, routes/contact.js, and routes/batches.js. Every Express request passes through the global error handler at server.js:128-134 (logs Unhandled error with status). Schema-change audit trail maintained in _migrations table (server.js:143). API key usage tracked in api_keys.last_used_at (migrations/1751140800_api_keys.js) and per-job state in analysis_jobs (migrations/1751140801_analysis_jobs.js). |
db/analytics.js, migrations/1747000000000_create_analytics_events.js, server.js:128-134 |
| System & Communications Protection (SC) | SC-7, SC-8, SC-13, SC-28 |
Production TLS terminated at the Render edge (configured in polsia.toml). Data-in-transit to the Polsia AI proxy uses HTTPS — the fetch call in lib/polsia-ai.js:9 builds https://polsia.com/api/proxy/ai and lib/polsia-ai.js:33 issues the POST request over TLS. Neon Postgres connection is TLS-protected via the DATABASE_URL sourced from polsia.toml:9 (source = "rdbms"). Raw genomic files are stored in Cloudflare R2 (TLS by default) — referenced in public/sales/dua-addendum.html:138-144. Password storage uses bcrypt cost-12 (routes/auth.js:32); AI-traffic payloads are stripped of patient identifiers before transmission (public/sales/dua-addendum.html:3.4). |
lib/polsia-ai.js, polsia.toml, routes/auth.js |
| Incident Response (IR) | IR-4, IR-5, IR-6, IR-8 |
Written 72-hour breach-notification commitment to customers documented in public/sales/dua-addendum.html:4.1-4.4 (notification content, downstream-notification cooperation, evidence-preservation cooperation). The BAA + DUA template at public/sales/dua-addendum.html defines "Security Incident" scope and the third-party access rules. Current subprocessor list maintained and available on request (public/sales/dua-addendum.html:3.5: Neon, Cloudflare R2, Polsia AI proxy). Render infra provides outage detection via /api/health (server.js:24-26) wired to polsia.toml:6 healthcheck_path = "/api/health". The Polsia email proxy (POLSIA_API_KEY) enables out-of-band customer notification (lib/email.js). |
public/sales/dua-addendum.html:4.1-4.4, polsia.toml, server.js:24-26 |
Additional NIST SP 800-53 Rev. 5 families an NIH procurement reviewer typically inspects first.
| Control Family | Selected Controls | How Baseshift Addresses It | Where to Find Evidence |
|---|---|---|---|
| Identification & Authentication (IA) | IA-2, IA-5, IA-8 |
User identity established by email + bcrypt password (routes/auth.js:32); session identity maintained by signed JWT (lib/auth-helpers.js:8-10). API consumers use Bearer keys issued in api_keys table (migrations/1751140800_api_keys.js). |
lib/auth-helpers.js, routes/auth.js |
| Configuration Management (CM) | CM-2, CM-3 | All schema changes flow through the startup migration runner at server.js:140-174 (runStartupMigrations); migrations are idempotent and tracked in the _migrations table (server.js:143). |
server.js:140-174, migrations/ |
| System Integrity (SI) | SI-2, SI-7 | Render-hosted deployment with platform-level monitoring; liveness probe at /api/health (server.js:24-26) declared in polsia.toml:6. Code dependencies pinned via package.json with semantic versions. |
polsia.toml, server.js:24-26, package.json |
| Media Protection (MP) | MP-4, MP-6 | Raw genomic files stored in Cloudflare R2 object storage; 90-day post-delivery retention window documented in public/sales/dua-addendum.html:2.1. Secure deletion via overwrite or cryptographic erasure per NIST SP 800-88 (public/sales/dua-addendum.html:2.3). |
public/sales/dua-addendum.html:2.1 |
| Supply Chain Risk (SR) | SR-3, SR-6 | Subprocessor list maintained and disclosed to customers (public/sales/dua-addendum.html:3.5): Neon database hosting, Cloudflare R2 storage, Polsia AI proxy. Subprocessors operate under written data processing agreements at least equivalent to the DUA. |
public/sales/dua-addendum.html:3.5 |