Security
Last reviewed: [INSERT DATE]
This page describes how we protect your data and isolate user code. The full threat model lives in our internal docs/security.md — happy to share with prospective enterprise customers under NDA.
Encryption
- In transit: TLS 1.2+ for all client-server traffic. HSTS preload list submitted. HTTP redirected to HTTPS at the edge.
- At rest: AES-256 encryption of all RDS volumes (AWS-managed). S3 buckets use SSE-S3 server-side encryption.
- Sensitive fields: AI provider API keys, OAuth refresh tokens, and project-level secrets are additionally encrypted with AES-256-GCM at the application layer using a 256-bit key separate from database access. Plaintext is never logged.
- Passwords: bcrypt with cost factor 12. We never store, log, or cache plaintext passwords.
Authentication
- JWT-based access tokens (15-min lifetime) + rotating refresh tokens (7-day lifetime, per-device session).
- OAuth 2.0 (Google, GitHub, GitLab, Bitbucket, LinkedIn) for sign-in. Account-link policy: identity providers and emails are linked only when the email is verified by both the provider and us.
- Multi-factor authentication is optional for users; required for admin dashboard access.
- Biometric lock available in the mobile app for re-entry after backgrounding.
Container isolation
User code runs in Docker-isolated containers with the following posture:
NetworkMode: noneby default (preview mode opts into bridge networking with whitelisted ports only)CapDrop: ALL— no Linux capabilitiesSecurityOpts: no-new-privilegesPidsLimit: 256- Hard CPU + memory caps enforced by cgroups
- Per-container 500 MB writable filesystem quota (xfs/pquota where supported)
- Read-only root filesystem with explicitly allowed writable paths
- Containers run via
docker-socket-proxywith a whitelist of permitted Docker API operations (noVOLUMES,NETWORKS,EXEC privileged)
Data isolation
- Per-user row-level security in Postgres — every query is scoped to the requesting user's
userId. - Container file-injection happens via
putArchiveon stopped containers; no exec-mkdir-cat window where another user's job could observe. - Project secrets injected as environment variables only at job-create time; decrypted in memory, never written to disk on the runtime host.
- Socket.IO room-level access control: a user can only subscribe to job log streams for jobs they own, verified server-side on every
job:subscribe.
Payments
- Stripe handles all card data. We are PCI compliance scope SAQ-A (we never see card data).
- Stripe webhooks are signature-verified before processing. Replay protection via
StripeEventuniqueness constraint. - Idempotency keys on every Stripe API call (top-up create, refund issue, subscription update).
- Wallet balance changes use optimistic locking via
Wallet.ledgerVersionto prevent race-condition double-spend.
Infrastructure
- AWS ap-south-1 (Mumbai), VPC-isolated subnets
- RDS Postgres with automated daily snapshots; 7-day point-in-time recovery
- Quarterly disaster-recovery drills via automated
scripts/dr-drill.sh(restore + verify + cleanup) - Cloudflare WAF + DDoS protection at edge
- AWS GuardDuty + CloudTrail enabled (anomaly detection + audit trail)
- IAM access via MFA-protected user accounts; no long-lived root keys
Operational practices
- Encrypted backups, encrypted secrets-at-rest in CI/CD via GitHub Secrets + AWS Secrets Manager (or k8s sealed-secrets at scale)
- Production deploy gated by GitHub Actions Required Reviewers
- Single-tenant database for V1; row-scoped multi-tenant model audit-tested before shipping
- Vulnerability scanning via
npm audit, GitHub Dependabot, SAST in CI - Automated rollback via image-tag swap (
scripts/rollback.sh) + git-based revert path
Vulnerability disclosure
If you find a security issue, please report it responsibly:
- Email security@offcoder.com
- For sensitive disclosures, request our PGP key first
- We respond within 24 hours, acknowledge within 72 hours
- We commit to fix critical issues within 7 days, high-severity within 30 days
- We will credit you publicly if you wish (or keep your report confidential)
- We do not currently run a paid bounty program, but plan to launch one post-launch on HackerOne
Out of scope (for vulnerability reports)
- Self-XSS that requires a victim to paste content into their own browser console
- Reports based on outdated software versions on third-party services we use
- Lack of HTTP security headers without a demonstrated exploit
- Spam / clickjacking on pages with no sensitive user actions
Compliance roadmap
- India DPDPA 2023 — compliant; Grievance Officer designated; consent management in app
- EU/UK GDPR — compliant for EU/UK users; SCCs in place with non-EU processors
- SOC 2 Type II — planned for post-launch (12+ months in)
- ISO 27001 — planned for enterprise tier