Back to Docs
Security

Security

Defense-in-depth security across 11 integrated layers. Your data never leaves your infrastructure.

Grid implements a defense-in-depth security architecture. No single layer is sufficient on its own — each layer provides independent protection, and together they create a comprehensive security posture. Since Grid is self-hosted, your data, source code, and deployments never leave your infrastructure.

Defense-in-Depth Layers

1

Sandboxed Container Runtime

Every user container runs in an isolated sandbox. Grid automatically selects the best available runtime: Kata Containers (VM-level isolation via KVM) when hardware virtualization is available, gVisor (user-space kernel) when KVM is not, or standard runc as a fallback. The runtime is detected at deploy time and injected into the container configuration.

  • Kata Containers: VM-level isolation with dedicated kernel per container
  • gVisor (runsc): User-space kernel with syscall filtering, ~50MB overhead
  • Auto-detection: priority kata > gVisor > runc
  • Env override: SMSLY_CONTAINER_RUNTIME for manual selection
2

Falco Runtime Threat Detection

Falco monitors syscall activity across all containers using eBPF. It detects unauthorized process execution, shell spawning, sensitive file access, reverse shells, and privilege escalation attempts in real time.

  • Driver: modern_eBPF (no kernel headers needed, kernel >= 5.8)
  • Image: falcosecurity/falco:0.39.2
  • JSON output for structured alerting
  • Capabilities: SYS_PTRACE, SYS_ADMIN, SYS_RESOURCE (minimum for eBPF)
3

Mandatory Access Control

AppArmor enforces mandatory access control on every container with the docker-default profile. The Docker daemon has seccomp enabled by default, filtering dangerous syscalls. Combined with no-new-privileges and cap_drop ALL, containers operate in a severely restricted capability space.

  • AppArmor: docker-default profile on all containers
  • seccomp: enabled in Docker daemon.json
  • no-new-privileges: prevents privilege escalation via setuid
  • cap_drop: ALL + selective cap_add (NET_BIND_SERVICE, CHOWN, SETUID, SETGID)
  • pids-limit: 1024 (fork bomb protection)
4

Zero Trust HMAC V2 Authentication

All API requests are verified by a SecurityMiddleware that enforces HMAC V2 signatures. The signed payload includes method, path, timestamp, nonce, and body hash. Replay attacks are blocked via timestamp validation (5-minute window) and one-use nonce caching.

  • Signed payload: METHOD|PATH|TIMESTAMP|NONCE|BODY_HASH
  • Timestamp validation: rejects requests older than 5 minutes
  • Nonce replay protection: each nonce cached for 600 seconds
  • Timing-safe comparison via hmac.compare_digest()
  • Fail-closed: missing or invalid signatures return 403
5

Encryption at Rest

All sensitive data is encrypted using Fernet symmetric encryption (AES-128-CBC). The encryption key is generated during installation and stored separately from encrypted data. Supports file-based key storage for enhanced security.

  • Fernet encryption (AES-128-CBC) for all sensitive fields
  • EncryptedCharField for API keys, passwords, tokens
  • File-based key storage: /opt/smsly-hosting/secrets/field-encryption-key
  • Backup encryption with V2 header format (key_id + fingerprint)
  • Auto-encryption enabled in production (DEBUG=False)
6

TLS & Certificate Management

Automatic Let's Encrypt certificates via Caddy with on-demand TLS. Domain validation prevents unauthorized certificate issuance. Wildcard subdomains supported via Cloudflare DNS-01 challenge. Inter-node communication uses TLS by default.

  • On-demand TLS: certificates provisioned automatically on first HTTPS visit
  • Domain validation: /api/v1/services/check-domain/ endpoint gates issuance
  • Wildcard support: Cloudflare DNS-01 challenge for *.your-domain.com
  • HSTS headers: 31536000 seconds, includeSubdomains, preload
  • Inter-node TLS: fail-closed by default (ALLOW_INSECURE_INTER_NODE_TLS=false)
7

Immutable Audit Logging

Every state change writes an immutable, hash-linked AuditLog entry. Each entry hashes the previous hash, timestamp, actor, action, target, and metadata. The chain is tamper-evident — modifying one entry breaks all subsequent hashes.

  • SHA-256 hash chain: previous_hash + timestamp + actor + action + target + metadata
  • Immutability: save() raises ValidationError on existing PK
  • Concurrency-safe: select_for_update() prevents race conditions
  • Genesis block: first entry has previous_hash = "0" * 64
8

Vulnerability Scanning & Image Signing

Trivy scans container images for CRITICAL and HIGH CVEs, including secret detection (AWS keys, private keys, JWTs, API keys). Cosign signs images after build and verifies before deployment, with fail-closed behavior when verification is required.

  • Trivy: scans CRITICAL+HIGH CVEs, detects leaked secrets
  • Cosign: signs images with private key or keyless (Sigstore/Fulcio)
  • CI pipeline: daily Trivy scans of backend and frontend images
  • Fail-closed: deployment blocked if image verification fails
9

Network Security & Firewall

Multi-layer network defense: UFW firewall (deny all, allow SSH/HTTP/HTTPS/WireGuard), iptables DOCKER-USER chain restricting infrastructure ports to WireGuard mesh only, and CrowdSec behavioral threat detection as a WAF.

  • UFW: default deny incoming, allow outgoing
  • Allowed: SSH (22), HTTP (80), HTTPS (443), WireGuard (51820/UDP)
  • iptables: ports 5000, 5432, 6379, 5672 locked to localhost + Docker bridges + WireGuard mesh
  • CrowdSec: behavioral WAF with 4-hour default ban, 24-hour for scanners
  • WireGuard mesh: 10.100.0.0/24 subnet, all infrastructure traffic encrypted
10

Brute-Force Protection & Rate Limiting

Three-layer rate limiting: application middleware (1000 req/min sliding window), DRF throttle classes (18 scopes), and throttled auth views. fail2ban adds IP banning for SSH, Caddy auth failures, and DDoS patterns.

  • Layer 1: sliding window middleware (1000 req/min anonymous)
  • Layer 2: 18 DRF throttle classes (login 10/min, deployment 10000/min, AI 30/min)
  • Layer 3: throttled auth views (login, logout, password reset, registration)
  • fail2ban: sshd (3 retries/1h), caddy-auth (5 retries/1h), caddy-dos (300 req/5min)
  • recidive jail: repeat offenders get 24-hour ban
11

Kernel & System Hardening

Host kernel is hardened via sysctl with ASLR, ptrace restrictions, BPF restrictions, and filesystem protections. auditd monitors critical files and syscalls. Docker daemon is configured with log rotation, live restore, and user namespace remapping.

  • sysctl: ASLR (randomize_va_space=2), ptrace_scope=1, kptr_restrict=2
  • auditd: monitors /etc/shadow, /etc/passwd, /etc/sudoers, .env, secrets/, docker exec
  • Docker daemon: json-file log driver, max-size 10m, live-restore, userns-remap
  • Filesystem: protected_hardlinks=1, protected_symlinks=1, suid_dumpable=0
12

SSRF & DNS Rebinding Protection

Outbound requests are validated against an SSRF guard that blocks loopback, metadata endpoints, private IPs, and reserved ranges. Serverless functions have additional DNS rebinding protection that resolves DNS and blocks responses pointing to internal IPs.

  • Blocks: localhost, 127.0.0.1, ::1, 169.254.169.254 (cloud metadata)
  • Blocks: all RFC 1918 private IPs, link-local, reserved ranges
  • DNS rebinding: resolves DNS and blocks private/reserved IP responses
  • Function-level: safeFetch() overrides global fetch with validation
13

Secrets Management

Infisical provides a self-hosted secrets management vault with versioning, RBAC, audit logs, and auto-reload. The secrets rotation script rotates all platform secrets with safety checks and upstream action checklists.

  • Infisical: self-hosted vault, binds to 127.0.0.1:8085 only
  • Secret rotation: SECRET_KEY, FIELD_ENCRYPTION_KEY, DB/Redis passwords, API tokens
  • Safety: writes to .env.rotated.<timestamp> (mode 0600), never overwrites original
  • Validation: bash -n parse check before applying rotated secrets

Authentication & Access Control

Multi-Layer Authentication

  • API Tokens: SHA-256 hashed, smsly_ prefix, bearer auth
  • API Keys: bcrypt hashed, sk_ prefix, expiry support
  • Cookie-Aware Token: HttpOnly cookies with __Host- prefix in production
  • HMAC: inter-node sync with timestamp + nonce + replay protection

Two-Factor Authentication

  • TOTP-based 2FA with provisioning URI generation
  • Backup codes: 10 single-use static codes
  • Rate-limited 2FA login verification
  • Password verification required to disable 2FA

Device Trust (Beta)

  • Browser fingerprint-based device identification
  • SSH public key fingerprint matching
  • Trust scoring: 0-100, incremented on success, decremented on suspicious activity
  • Manual approval for unknown devices

Container Security Stack

Every container in Grid — infrastructure services, user deployments, and addons — runs with the same security hardening:

# Applied to ALL containers:
security_opt:
  - no-new-privileges:true    # Block setuid privilege escalation
  - apparmor:docker-default   # Mandatory access control
cap_drop: ALL                  # Drop all Linux capabilities
cap_add:                       # Add only what's needed
  - NET_BIND_SERVICE
  - CHOWN
  - SETUID
  - SETGID
pids_limit: 1024               # Fork bomb protection

# User containers additionally get:
# - Sandboxed runtime (Kata/gVisor)
# - Resource limits (memory, CPU)
# - Read-only root filesystem where possible
# - tmpfs for /run and /tmp

Network Architecture

Internet → Caddy (80/443)
  ├─ TLS termination (Let's Encrypt)
  ├─ On-demand TLS domain validation
  ├─ HSTS + security headers
  ├─ CrowdSec WAF filtering
  ├─ /api/* → backend (8000)
  │    └─ Zero Trust HMAC V2 verification
  └─ /* → frontend (3000)

Internal network (Docker, encrypted WireGuard mesh):
  ├─ PostgreSQL (5432) — mesh only
  ├─ Redis (6379) — mesh only
  ├─ RabbitMQ (5672) — mesh only
  ├─ Falco — eBPF syscall monitoring
  ├─ Infisical — secrets vault (127.0.0.1:8085)
  └─ Socket Proxy — filtered Docker API access

Security Status API

Grid exposes a GET /api/v1/system/security-status/ endpoint that reports the real-time status of every security layer. This includes container runtime detection, AppArmor status, seccomp, Falco health, CrowdSec bans, fail2ban jails, auditd status, and kernel hardening state.

Reporting Vulnerabilities

If you discover a security vulnerability in Grid, please report it responsibly. Do not open a public GitHub issue for security vulnerabilities. Instead, email security@smsly.cloud with:

  • A description of the vulnerability
  • Steps to reproduce
  • Potential impact assessment
  • Any suggested fixes (optional)

We aim to acknowledge reports within 48 hours and provide a resolution timeline within 5 business days.