Skip to content

Security Best Practices

This guide covers hardening SLOzy for production use.

HTTPS / TLS

Terminate TLS at your reverse proxy or load balancer. Recommended configuration:

nginx
# nginx example
server {
    listen 443 ssl;
    server_name slozy.example.com;

    ssl_certificate     /etc/ssl/certs/slozy.crt;
    ssl_certificate_key /etc/ssl/private/slozy.key;
    ssl_protocols       TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

For local development, the application sets HSTS headers in internal/middleware/security.go: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Secrets Management

Never store secrets in configuration files or source code. Use environment variables:

bash
# .env (never commit this file)
JWT_SECRET=$(openssl rand -base64 32)
POSTGRES_PASSWORD=<strong-random-password>
REDIS_PASSWORD=<strong-random-password>

In production, use a secrets manager (Hashicorp Vault, AWS Secrets Manager, or Kubernetes Secrets).

JWT Secret Rotation

  • Generate a 256-bit (32-byte) secret: openssl rand -base64 32
  • Configure via JWT_SECRET environment variable (see internal/config/config.go)
  • Rotate secrets periodically and after any suspected compromise
  • Token expiration is controlled by JWT_EXPIRATION (default: 8h)

Database Connection Encryption

PostgreSQL SSL modes are configured via POSTGRES_SSL_MODE:

ModeUse Case
disableDevelopment only
requireEncrypted connection, no certificate validation
verify-caEncrypted + CA verification
verify-fullEncrypted + full certificate verification (recommended for production)
bash
POSTGRES_SSL_MODE=verify-full
POSTGRES_SSL_CERT=/path/to/client.crt
POSTGRES_SSL_KEY=/path/to/client.key
POSTGRES_SSL_ROOT_CERT=/path/to/ca.crt

Rate Limiting

SLOzy uses a token bucket algorithm implemented in internal/middleware/security.go. Configure via RateLimiterConfig:

ParameterDescriptionRecommended Value
GlobalRateRequests per minute (all users)1000
GlobalBurstBurst size for global limiter2000
PerIPRateRequests per minute per IP60
PerIPBurstBurst size per IP100
WhitelistIPs exempt from rate limitingInternal monitoring IPs
BlacklistIPs always blockedKnown bad actors

Rate limit headers (X-RateLimit-Limit, X-RateLimit-Reset) are returned on every response.

Security Headers Checklist

The middleware in internal/middleware/security.go sets these headers automatically:

HeaderValuePurpose
X-Frame-OptionsDENYPrevents clickjacking
X-Content-Type-OptionsnosniffPrevents MIME sniffing
X-XSS-Protection1; mode=blockEnables XSS filter
Referrer-Policystrict-origin-when-cross-originControls referrer leakage
Permissions-Policydefault-src 'self'Restricts API access
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadEnforces HTTPS
Content-Security-Policydefault-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; ...Prevents XSS and data injection
Cross-Origin-Opener-Policysame-originIsolates cross-origin windows
Cross-Origin-Embedder-Policyrequire-corpRestricts cross-origin resource loading

CORS Restrictions

Configure allowed origins via CORS_ORIGINS (comma-separated). In production, never use wildcard origins:

bash
# Good — explicit allowed origins
CORS_ENABLED=true
CORS_ORIGINS=https://app.slozy.example.com,https://admin.slozy.example.com

The CORS middleware (see internal/middleware/security.go) validates the Origin header and responds with appropriate Access-Control-Allow-* headers. Credentials are supported only for explicit (non-wildcard) origins.

API Key Management

  • Generate API keys with sufficient entropy (minimum 32 bytes)
  • Store hashed keys in PostgreSQL — never log or expose raw keys
  • Implement key rotation: issue a new key, migrate clients, revoke the old key
  • Use scoped keys with least-privilege permissions via the RBAC system

Audit Logging

  • Enable structured JSON logging: LOG_FORMAT=json
  • Log all authentication events (login, logout, failed attempts)
  • Log SLO create/update/delete operations with user and timestamp
  • Log RBAC permission changes
  • Ship logs to a centralized system (ELK, Loki, Datadog) for analysis

Regular Dependency Updates

Scan for vulnerabilities and update dependencies regularly:

bash
# Go dependencies
go list -m all | go-licenses check
go mod tidy

# Update specific packages
go get -u github.com/gin-gonic/gin

Use automated dependency scanning tools (Dependabot, Renovate, or Snyk) integrated with your CI pipeline.