Security is not a feature.
It's the foundation.
Every claim on this page maps to real code in the sh0 codebase. 34 issues found and fixed across 3 parallel audits. 6 critical vulnerabilities resolved. Zero shortcuts.
Audit results
Full security audit across authentication, cryptography, API surface, and frontend.
What we protect
Six core security layers, each verified in the Rust source code.
AES-256-GCM Encryption
All secrets, env vars, backup files, SSH keys, and API tokens encrypted with AES-256-GCM via the ring crate. Nonce format: nonce(12) || ciphertext || tag(16). Authenticated encryption ensures both confidentiality and integrity.
Argon2id Password Hashing
OWASP-recommended Argon2id for all password storage. PHC-format hash output with unique random salt per password. TOTP backup codes also hashed with Argon2id.
HTTP-Only Cookie Auth
Access tokens (15 min) and refresh tokens (30 days) stored in HTTP-only cookies with SameSite=Strict. Secure flag auto-enabled in production. CSRF double-submit cookie pattern.
API Key Security
Format: sh0_ prefix + 32 random chars. SHA-256 hashed storage, prefix-based lookup (first 8 chars). Constant-time comparison via the subtle crate to prevent timing attacks.
RBAC & Project Permissions
Owner, Admin, Developer, Viewer roles with per-project membership. Dedicated extractors (AuthUser, AdminUser, ProjectAccess) verify authorization on every API endpoint.
TOTP Two-Factor Auth
RFC 6238 compliant, 6-digit codes, 30-second step, SHA-1 with +/-1 skew tolerance. 8 backup codes per user, each Argon2id-hashed. Provisioning URI for QR code setup.
Defense in depth
Encrypted at rest
Master key derived via PBKDF2-HMAC-SHA256 with 100,000 iterations and a 16-byte salt. Every secret -- env vars, SSH private keys, backup dumps, API tokens -- is AES-256-GCM encrypted before touching disk.
Authenticated at every layer
JWT (HS256) from Bearer header or HTTP-only cookie, with API key fallback. Refresh tokens SHA-256 hashed in the database. Expired tokens caught with specific error codes. Multi-strategy auth on every request.
Rate-limited and throttled
Per-IP sliding window: 10 login attempts/15 min, 5 TOTP attempts/5 min, 50 invitations/min. Global read/write rate limits with automatic cleanup. Health and webhook paths exempt.
Audited and traceable
Every significant action logged: user ID, action, resource type/ID, IP address (X-Forwarded-For aware), timestamp. Paginated queries with filtering by user, resource type, and resource ID.
The security stack
Every layer reinforces the next -- compromise one and the rest still hold
Cryptographic dependencies
No custom cryptography. Battle-tested Rust crates only.
Verified in source code
Every finding mapped to the crate where it's implemented.
Without sh0
- x Store tokens in localStorage (XSS-vulnerable)
- x Write custom encryption per service
- x Manage SSH keys in plaintext on disk
- x Hope nobody SQL-injects your queries
- x Share root credentials across team
- x No audit trail of who did what
With sh0
- HTTP-only cookies, SameSite=Strict, CSRF protection
- AES-256-GCM for everything, master key with PBKDF2
- SSH keys encrypted at rest, loaded in-memory only
- Parameterized queries + input validation everywhere
- RBAC with 4 roles + per-project permissions
- Full audit log with IP, user, action, resource tracing
Questions & answers
Has sh0 been security audited? +
How are secrets stored? +
How does authentication work? +
What about two-factor authentication? +
Can one user access another user's containers? +
What about container security? +
Which cryptographic libraries do you use? +
Enterprise-grade security, built in
34 issues found. 34 issues fixed. AES-256-GCM, Argon2id, TOTP 2FA, RBAC, audit logs, rate limiting. Security you can verify in the source.