DeployForge enforces security controls at the data storage, authentication, network routing, and host execution layers.
All sensitive secrets (VPS passwords, private keys, environment variables) are encrypted before write operations:
- Module:
@deployforge/security(EncryptionService). - Algorithm: AES-256-GCM with a unique 12-byte IV per entry.
- Storage Format:
iv:authTag:encryptedData(hex-encoded). - Key Source:
ENCRYPTION_KEYenv var β must be a 64-character hex string. - Transparent Middleware: Prisma middleware auto-encrypts/decrypts the
envfield onDeploymentandDeploymentHistorymodels.
- Algorithm: Argon2id via
@deployforge/security. - Parameters: Memory 64MB, 3 iterations, 4 threads (production-grade).
- Minimums: User passwords β₯ 6 chars; Super Admin password β₯ 8 chars.
The API validates all environment variables at startup using Zod (apps/api/src/config/env.ts):
- Placeholder Detection: Rejects secrets starting with
replace_with_,your_,changeme, etc. - Production Enforcement:
APP_URLandAPI_URLmust usehttps://and must not point tolocalhostwhenNODE_ENV=production. - Format Checks:
ENCRYPTION_KEYmust be 64 hex chars;DATABASE_URLmust be a valid PostgreSQL URI. - Hard Exit: Any failure causes
process.exit(1)with descriptive error messages.
- Access Tokens (JWT): 15-minute lifetime with
userId,role, andsessionId. - Refresh Tokens: Long-lived, stored as SHA-256 hash in database.
- Immediate Revocation:
authGuardvalidatessessionIdagainst active DB records on every request. - Replay Protection: Reused refresh tokens trigger full session revocation for that user.
- Isolated Model:
AdminUserandAdminSessionare fully separate from regularUsersessions. - Brute-Force Lockout: Configurable via
ADMIN_MAX_ATTEMPTS(default5) andADMIN_LOCKOUT_TIME(default900seconds). - Separate Secret:
ADMIN_JWT_SECRETsigns admin tokens β distinct from userJWT_SECRET.
Critical actions are written to the AuditLog table:
- Scope:
auth,sessions,password,github,accountcategories. - Metadata: IP address, OS, browser, device parsed from user-agent.
Double-submit cookie pattern (apps/api/src/plugins/csrf.ts):
- Token signed via HMAC-SHA256.
- Client must send token in both
csrfTokencookie andX-CSRF-Tokenheader for all state-changing requests. - Comparison uses
crypto.timingSafeEqualto prevent timing attacks.
- CSP:
default-src 'none'β scripts, styles, frames, objects all blocked. - Frame Ancestors:
'none'β prevents clickjacking. - HSTS:
max-age=31536000; includeSubDomains; preload(production only). - Permissions Policy: Restricts camera, microphone, geolocation, payment, USB.
- Referrer Policy:
no-referrer.
- Global:
RATE_LIMIT_MAXrequests perRATE_LIMIT_WINDOW(defaults: 100/minute). - Sensitive routes have tighter per-route limits.
- Returns
HTTP 429with{ code: "RATE_LIMIT_EXCEEDED" }.
A preValidation hook rejects any request body, query, or params containing __proto__, prototype, or constructor with HTTP 400.
- Shell arguments are escaped via prototype-safe
shellQuote/shellPathhelpers in@deployforge/vps. - Archive extractions use a Python3 wrapper script on the target VPS to prevent path traversal.
--cap-drop ALLβ removes all root-level kernel capabilities.--security-opt no-new-privilegesβ blocks privilege escalation.
Before execution, the DeploymentSandbox system scores the deployment configuration, estimates CPU/RAM/Disk usage, and flags violations. Deployments with status rejected are blocked from proceeding.
Both api and web Docker services run with:
read_only: truefilesystem (only/tmpwritable viatmpfs).no-new-privileges: true.cap_drop: ALL.
The /metrics endpoint is protected by an optional Bearer token:
- Config: Set
METRICS_TOKENto a random 64-char hex string.node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" - Usage:
Authorization: Bearer <METRICS_TOKEN> - If
METRICS_TOKENis empty, the endpoint is unprotected (dev-only; not recommended for production).