Network & Security
Cloudillo’s network layer uses Rustls with the AWS-LC-RS cryptographic provider for TLS, automatic certificate management via ACME, and runs a dual-server architecture.
TLS architecture
Cloudillo uses Rustls for TLS termination, configured with HTTP/2 (preferred) and HTTP/1.1 via ALPN negotiation.
SNI-based certificate resolution
A custom CertResolver serves the correct certificate for each domain using SNI (Server Name Indication). This is essential for multi-tenant hosting where many users share a single server.
The resolver maintains an in-memory RwLock<HashMap<domain, CertifiedKey>> cache, prepopulated on startup from the database. On a TLS handshake:
- Check in-memory cache (fast path, read lock)
- On cache miss, load from database on a blocking worker thread
- Parse PEM certificate and private key, insert into cache
- Return certificate for TLS handshake
Each tenant gets entries for both its canonical domain (cl-o.{id_tag}) and any custom domain.
Certificate management
Cloudillo uses instant-acme to automatically provision and renew TLS certificates from Let’s Encrypt using the HTTP-01 challenge method.
Dual-server setup
- HTTPS server (primary): Handles all application traffic with TLS via Rustls and the SNI-based certificate resolver
- HTTP server (optional): Serves ACME HTTP-01 challenge responses at
/.well-known/acme-challenge/{token}and redirects everything else to HTTPS
Certificate renewal
A scheduled CertRenewalTask checks all certificates periodically. Certificates expiring within 30 days are automatically renewed. The renewal uses exponential backoff (1s initial, 1.5x factor, 90s timeout) for resilience.
Certificates are stored via the AuthAdapter trait, which provides create_cert, read_cert, delete_cert, and list_domains methods.
Cryptography
Algorithms
| Purpose | Algorithm | Details |
|---|---|---|
| Action token signing | ES384 (P-384) | Federated action tokens between instances |
| Access tokens | HS256 (HMAC-SHA256) | Session JWTs, symmetric secret per instance |
| Web Push (VAPID) | ES256 (P-256) | Push notification subscription keys |
| Password hashing | bcrypt (cost 10) | Per-password random salt |
| Content hashing | SHA256 | File IDs, content addressing, deduplication |
| TLS | TLS 1.2/1.3 | Rustls defaults, modern cipher suites |
Key management
Profile signing keys use the P-384 elliptic curve (ES384). Keys are identified by date-based key IDs (format: YYMMDD) and stored in PKCS#8 PEM format. Each tenant has its own signing key pair:
- Public key: Published for other instances to verify action tokens
- Private key: Used to sign outgoing action tokens
A key failure cache (default size: 100 entries) prevents repeated fetch attempts for unreachable remote keys during federation.
Security policies
Memory safety
Cloudillo enforces unsafe_code = "forbid" as a workspace-wide lint, along with strict clippy rules (unwrap_used = "deny", expect_used = "deny", panic = "deny").
CORS
API endpoints use a permissive CORS policy (CorsLayer::very_permissive()). This is intentional: Cloudillo apps run in sandboxed iframes served from the /apps/ directory and need cross-origin access to the API.
Request size limits
File upload size is configurable per tenant via the file.max_file_size_mb setting (default: 50 MiB).
See also
- Rate Limiting - Hierarchical rate limiting and proof-of-work
- Federation - Inter-instance communication
- Identity System - Cryptographic identity and keys
- Access Control - JWT validation and authorization
- System Architecture - Overall architecture