Security

Built secure.
Not bolted on.

Security controls are embedded at every layer — authentication, transport, database, file handling, and audit. Designed to satisfy enterprise security questionnaires and compliance reviews.

Deployment Options →
Implemented Controls

12 security controls, all active

Every control below is live in production — not planned, not partial.

🍪

httpOnly Cookie Authentication

JWT session tokens are stored in httpOnly cookies — completely inaccessible to JavaScript. Eliminates the entire class of XSS-based token theft attacks. Cookie is also marked Secure and SameSite=Strict in production.

🌐

CORS Origin Allowlist

The API rejects requests from any origin not in the explicit allowlist. No wildcard CORS. Unknown origins receive a hard rejection — not a fallback accept — protecting against cross-site request forgery from malicious websites.

👤

Role-Based Access Control

Granular permission levels: View Only, Limited Access, Full Access, and Admin. Each level controls exactly which actions a user can perform. Portal users are restricted to their assigned customer at the query level, not just the UI.

🔑

bcrypt-Hashed API Keys

API keys are shown exactly once on creation and never stored in plaintext. Only bcrypt hashes are persisted. Keys are revocable per-user and every API action is logged to the audit trail with full attribution.

🛡️

Path Traversal Protection

All file upload paths are validated against an explicit entity type allowlist before touching the filesystem. Download paths are resolved with path.resolve() and verified to remain within the upload directory boundary.

📋

Document Access Control

Document downloads verify that the requesting user owns or has permission for the parent entity. Portal users can only download documents attached to their own customer account — cross-customer access returns HTTP 403.

🔐

Password Policy Enforcement

Minimum 10 characters, at least one uppercase, one lowercase, and one number. Enforced server-side on both account creation and password changes — cannot be bypassed by a client-side only check.

⏱️

Rate Limiting

Login, password changes, and API key generation are all rate-limited independently. Login: 20 req/15 min. Sensitive write endpoints: 30 req/15 min. Prevents brute force and enumeration attacks.

📰

Security Headers

Full suite served by nginx: Strict-Transport-Security (HSTS, 1 year), Content-Security-Policy, Referrer-Policy: no-referrer, Permissions-Policy, X-Frame-Options, X-Content-Type-Options, and X-XSS-Protection.

🗄️

Parameterised SQL Queries

Every database query throughout the application uses prepared statements with bound parameters. The SQL injection surface is zero — no string interpolation, no dynamic query construction, no exceptions.

📝

Tamper-Evident Audit Log

Every action is logged: logins, record views, edits, deletions, document uploads, API key reveals, and admin changes. The actor is always the authenticated server-side identity — client-supplied user fields are ignored.

🚀

JWT Secret Startup Guard

The server refuses to start in production if JWT_SECRET is missing or matches the default development value. Prevents accidental deployment with a known, forgeable token secret — a common misconfiguration in deployed apps.

Architecture

Defence in depth

Security controls operate at every layer of the stack — not just at login.

Transport Layer

TLS 1.2+ enforced via Let's Encrypt. HSTS prevents downgrade attacks. All HTTP traffic redirected to HTTPS by nginx.

Application Layer

CORS lockdown, rate limiting, input validation, httpOnly cookie auth, and permission checks on every route.

Data Layer

Parameterised queries throughout. bcrypt password hashing. Scoped customer data — portal users are filtered at the query level.

Infrastructure Layer

UFW firewall, AWS security groups scoped to your IP, no unnecessary open ports. IAM role with minimal permissions.

Security Roadmap

What's coming next

SSO / SAML 2.0

Okta, Azure AD, Google Workspace integration

Planned

Server-Side Session Revocation

Instant token invalidation — with PostgreSQL migration

In Progress

Magic-Byte MIME Verification

File type validated beyond Content-Type header

Planned

SOC 2 Type II Readiness

Formal controls documentation and audit prep

Roadmap
Security First

Inspect the security controls live

Log into the demo and explore the audit log, permission system, and API key management yourself.

Deployment Options →