Skip to main content

Security posture

The controls below are implemented end-to-end. v1 is a young codebase: we publish our threat model and disclosure process, and we will earn the rest with time and operator feedback.

HMAC-chained audit log

Per-row HMAC-SHA256 signed by the server secret + prev_row_hmac chain. Tamper-evident against both row modification AND deletion, even by a DBA with raw table access.

Argon2id password hashing

64 MiB memory, 3 iterations, parallelism 4. Password policy: min 12 chars, 3-of-4 character classes, ~1,500 denylist entries.

Wire-protocol HMAC v2

Every WebSocket frame signed. Replay guard (±60s + nonce + monotonic seq). Session-bound frames. SignatureError closes the socket with code 4403.

CSRF double-submit

__Host-prefixed CSRF cookie + X-CSRF-Token header required on every mutating endpoint. Constant-time comparison.

Secure cookies

HttpOnly session cookie, Secure + SameSite=Lax in prod, __Host- prefix. No JS access to session tokens.

IP rate limits

/auth/login (20/min), /invitations (30/min), /auth/password-reset (10/min). Bounded memory via inline prune + 120-char key cap.

Account lockout

5 failed login attempts → 15-minute account lockout. Combines with IP rate limits for layered defense.

Redaction pipeline

Recursive scrubber at the agent (~40 patterns: API keys, tokens, AWS creds, private keys). Defense-in-depth re-scrub on the brain.

SSRF hardening

Every outbound URL (webhooks, SMTP, Slack) passes through: private-IP block, DNS-rebinding resolve-before-dial, scheme allow-list.

HSTS + CSP

Strict-Transport-Security (1yr), strict Content-Security-Policy (no unsafe-inline, no unsafe-eval), X-Frame-Options: DENY, Referrer-Policy: strict-origin.

RBAC everywhere

Every mutating endpoint checks membership + role. UI mirrors the server policy (useCan hook). Cross-project access = 403.

Secret storage

Tokens stored as HMAC-SHA256 hashes only, never plaintext. Server secret in env, not on disk. No 'recovery' codes.

transparency

Audit notes

We publish our pre-release reviews so you can read what we looked at and what we fixed. They are not a proof of security — only a record of what was checked.

disclosure

Reporting a vulnerability

Please report security issues privately to [email protected]. Include a clear reproduction, expected vs. actual behavior, and a severity estimate.

Response targets: initial acknowledgment within 48 hours; triage within 7 days; fix + advisory within 30 days for HIGH or CRITICAL findings.

We credit reporters in the advisory (opt-in). We do not offer a paid bounty at this time.

Read the full security docs

Threat model, controls, CVE disclosure policy, compliance posture: all on z4j.dev.