Security is not a feature.
It's the foundation.
Every claim on this page maps to real code in the sh0 codebase. An internal audit on 17 March 2026 found 34 issues; the 6 critical ones were fixed by the report date.
Audit results
Internal security audit across authentication, cryptography, API surface and frontend.
Internal audit of 17 March 2026: 34 issues found (6 critical, 10 high, 12 medium, 6 low). On the report date, the 6 critical issues and 8 of the 10 high ones were fixed; the others were scheduled for a hardening phase. From 5 October 2026, fixed vulnerabilities are published here.
What we protect
Six core security layers, each verified in the Rust source code.
AES-256-GCM Encryption
All secrets, env vars, SSH keys, and API tokens -- and backup files when backup encryption is enabled -- 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? +
Who is responsible for the security of one-click templates? +
Which cryptographic libraries do you use? +
Report a vulnerability
Write to us at the address below. Include the sh0 version, the steps to reproduce and the impact you observed. Please do not open a public issue.
If you get no reply, also use the contact form: sh0.dev/contact
Our commitments
- Acknowledgement of your report within 72 hours.
- Fix targeted within 7 days for a critical flaw, 30 days for a high one, 90 days otherwise.
- For critical and high flaws, a pre-announcement 48 to 72 hours before the fix: date, severity and component only. Details are published with the fix.
- Security fixes will ship as patch releases, not mixed with new features, so that automatic updates in patch mode can install them on their own.
Good-faith research
We will not take legal action against research carried out in good faith on your own sh0 instance: no access to other people's data, no disruption of a service you do not own, and reasonable time for us to fix the flaw before any publication.
Rewards
There is no cash bounty at launch: researchers are thanked publicly on this page, with their agreement. A bounty programme could follow the external penetration test.
Acknowledgements
No report received yet. The first names will appear here.
Security advisories
Published advisories, and a machine-readable feed that the sh0 dashboard will check with every update check.
Enterprise-grade security, built in
AES-256-GCM, Argon2id, TOTP 2FA, RBAC, audit logs, rate limiting. Security you can verify in the source, and vulnerabilities reported through a public disclosure policy.