Repository navigation
Security
This page covers security features, best practices, hardening procedures, and vulnerability reporting for Authify.
IMPORTANT: If you find a critical security vulnerability that could be actively exploited, please report it privately using GitHub's Security Advisories feature instead of creating a public issue:
- Go to the Security tab
- Click "Report a vulnerability"
- Follow the private disclosure process
We take security seriously and will respond promptly to legitimate reports.
- Password Security - Bcrypt hashing with complexity requirements
- Token Security - Secure JWT generation and validation with RS256 signing
- Session Security - Secure session management with proper cleanup
- Role-based Access Control - Admin and user roles with proper authorization
- Multi-tenant Isolation - Strict data scoping prevents cross-org access
- Input Validation - Comprehensive input validation via Ecto changesets
- CSRF Protection - Phoenix built-in CSRF token validation
- Security Headers - Configured via Phoenix endpoint
- Secrets Encryption - SMTP credentials and sensitive data encrypted at rest
- SQL Injection Protection - Parameterized queries via Ecto
- Per-organization rate limits - Prevent abuse and brute force attacks
- Hierarchical quotas - Super admin quotas with org-specific overrides
- Multiple scopes - Separate limits for auth, OAuth, SAML, and API
- 429 responses - Graceful rate limit exceeded handling
See Architecture for rate limiting configuration.
| Category | Recommendation | Status |
|---|---|---|
| TLS | Terminate HTTPS at ingress/LB; enable HSTS (force_ssl) | |
| Secrets | Store SECRET_KEY_BASE & ENCRYPTION_PASSWORD in secret manager |
|
| Database | Enforce least privilege DB user; enable backups & binlogs | |
| Metrics | Restrict /metrics endpoint to internal network/scrape targets |
|
| Headers | Validate CSP / strict transport / X-Frame-Options via endpoint config | ✅ Configured |
| SAML | Rotate signing certs periodically (procedure documented below) | ⏳ Manual |
| OAuth | Monitor token issuance volume & anomalous scope escalation | ⏳ Manual |
| Sessions | Set secure cookies behind TLS; review idle/absolute timeout policies | ✅ Configured |
| Rate Limits | Tune quotas for production traffic profile | ✅ Configurable |
| Logging | Add structured audit logging before broad external use | ⏳ Roadmap |
For Kubernetes deployments, configure TLS at the ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: authify
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- auth.example.com
secretName: authify-tls
rules:
- host: auth.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: authify
port:
number: 4000Enable HSTS and force SSL in production config:
# config/prod.exs
config :authify, AuthifyWeb.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]],
https: [
port: 443,
cipher_suite: :strong,
keyfile: System.get_env("SSL_KEY_PATH"),
certfile: System.get_env("SSL_CERT_PATH")
]Never commit secrets to version control. Use environment variables or secret managers:
Kubernetes Secrets:
apiVersion: v1
kind: Secret
metadata:
name: authify-secrets
type: Opaque
stringData:
SECRET_KEY_BASE: "generate-with-mix-phx-gen-secret"
ENCRYPTION_PASSWORD: "generate-with-mix-phx-gen-secret"
DATABASE_URL: "ecto://user:password@mysql:3306/authify"Docker Environment File:
# .env.production (never commit!)
SECRET_KEY_BASE=<generate-with-mix-phx-gen-secret>
ENCRYPTION_PASSWORD=<generate-with-mix-phx-gen-secret>
DATABASE_URL=ecto://user:password@mysql:3306/authify# Generate a new secret key
mix phx.gen.secret
# Use different values for SECRET_KEY_BASE and ENCRYPTION_PASSWORD
SECRET_KEY_BASE=$(mix phx.gen.secret)
ENCRYPTION_PASSWORD=$(mix phx.gen.secret)Important:
- Never reuse the same value for both variables
- Store secrets in a secure secret manager (HashiCorp Vault, AWS Secrets Manager, etc.)
- Rotate secrets periodically (document any required restart procedures)
Create a dedicated database user with minimal permissions:
CREATE USER 'authify'@'%' IDENTIFIED BY 'strong-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON authify.* TO 'authify'@'%';
FLUSH PRIVILEGES;Do not grant:
-
CREATE,DROP,ALTERin production (use migration user separately) -
SUPER,FILE, or admin privileges - Access to other databases
Enable binary logging for point-in-time recovery:
# my.cnf
[mysqld]
log_bin = /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds = 604800 # 7 daysSee Operations for backup procedures.
Via Web UI:
- Navigate to
/<org-slug>/settings - Click "Certificates"
- Click "Generate New Certificate"
- Configure subject, key size, and validity period
- Click "Activate" to make it the active signing certificate
Via API:
curl -X POST -H "Authorization: Bearer TOKEN" \
https://auth.example.com/org-slug/api/certificates \
-H "Content-Type: application/json" \
-d '{
"certificate": {
"bits": 2048,
"subject": "CN=auth.example.com"
}
}'- Generate new certificate (via UI or API)
- Activate the new certificate (via UI or API)
- Update SP metadata - Service Providers need the new IdP metadata
- Monitor for errors - Some SPs may cache old metadata
- Delete old certificate after confirming all SPs updated
Recommended rotation schedule: Every 12-24 months
The /metrics endpoint exposes Prometheus-compatible metrics on port 9568.
Kubernetes Network Policy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: authify-metrics
spec:
podSelector:
matchLabels:
app: authify
ingress:
- from:
- podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9568Firewall Rules:
- Only allow Prometheus scraper IPs
- Block external access to port 9568
- Use authentication if exposing publicly
Authify enforces password complexity requirements:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Users are required to meet these criteria during:
- Initial account creation
- Password changes
- Password resets
- Sessions use Phoenix's built-in signed cookies
- Cookies are
httpOnlyandsecure(when force_ssl enabled) - Session data stored server-side with secure tokens
- Sessions invalidated on logout
Future enhancements (see Roadmap):
- Configurable session idle timeout
- Absolute session lifetime
- Concurrent session limits
- Authorization codes are single-use and expire quickly
- Client secrets are required for confidential clients
- Redirect URIs are validated exactly (no wildcards)
- Scopes are validated and enforced
- PKCE support planned for public clients (roadmap)
- Assertions signed with RSA-SHA256
- XMLDSig compliant signatures
- Certificate management with activation workflow
- Clock skew tolerance for timing validation
- Encryption planned for sensitive attributes (roadmap)
Set up alerts for security-relevant events:
- High authentication failure rate (potential brute force)
- Unusual token issuance patterns
- Rate limit breaches by organization
- Certificate expiration warnings
- Failed database connection attempts
- 5xx error rate spikes
See Operations for metrics details.
Current security gaps (see Roadmap for planned improvements):
- No audit logging - Authentication and authorization events not logged to immutable store
- No MFA - Multi-factor authentication not yet implemented
- SAML encryption - Only signing currently supported (encryption planned)
- No PKCE - OAuth PKCE flow not yet supported for public clients
- Session limits - No concurrent session or absolute timeout controls
Planned security enhancements:
Near-term:
- Structured audit logging with immutable event stream
- MFA Phase 1 (TOTP app-based)
- SAML assertion/response encryption
- Enhanced rate limiting (burst + sustained windows)
Mid-term: 5. WebAuthn / FIDO2 support 6. PKCE for OAuth public clients 7. Session management enhancements (idle timeout, absolute lifetime) 8. JWT key rotation automation
See Roadmap for full details and timelines.
- Keep Authify updated to the latest version
- Subscribe to security advisories
- Enable and monitor audit logs (when available)
- Use managed database services with automated backups
- Implement defense in depth (WAF, DDoS protection, etc.)
- Regular security assessments and penetration testing
- Follow Contributing guidelines
- Never commit secrets or credentials
- Use parameterized queries (Ecto handles this)
- Validate all user input
- Implement proper error handling
- Review security implications of changes
- Use strong, unique passwords
- Enable MFA when available
- Rotate Personal Access Tokens regularly
- Review OAuth application permissions
- Report suspicious activity
Authify is designed with security best practices, but compliance is deployment-specific:
- GDPR - Supports data deletion, encryption at rest (via MySQL), per-tenant isolation
- SOC 2 - Logging, rate limiting, and access controls support audit requirements
- HIPAA - Additional encryption and audit controls may be required
- PCI-DSS - Not recommended for storing payment card data
Consult your compliance team for specific requirements.
- Operations - Deploy securely to production
- Architecture - Understand multi-tenant isolation
- Roadmap - See planned security features
- Contributing - Security-focused contribution guidelines
