Skip to content

Security Guide

This guide covers security best practices for deploying and operating Bifrost in production environments.

server:
http:
listen: ":8443"
tls:
enabled: true
cert_file: "/etc/bifrost/certs/server.crt"
key_file: "/etc/bifrost/certs/server.key"

For testing only:

Terminal window
# Generate private key
openssl genrsa -out server.key 4096
# Generate certificate
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 365 \
-subj "/CN=bifrost.example.com"

For production, use certificates from Let’s Encrypt:

Terminal window
# Install certbot
sudo apt install certbot
# Obtain certificate
sudo certbot certonly --standalone -d bifrost.example.com
# Certificate location
# /etc/letsencrypt/live/bifrost.example.com/fullchain.pem
# /etc/letsencrypt/live/bifrost.example.com/privkey.pem
server:
http:
tls:
enabled: true
cert_file: "/etc/letsencrypt/live/bifrost.example.com/fullchain.pem"
key_file: "/etc/letsencrypt/live/bifrost.example.com/privkey.pem"
Terminal window
# Secure key file
chmod 600 /etc/bifrost/certs/server.key
chown bifrost:bifrost /etc/bifrost/certs/server.key

ModeUse CaseSecurity Level
noneInternal networks onlyLow
nativeSmall deploymentsMedium
systemUnix/PAM integrationMedium-High
ldapEnterprise/AD integrationHigh
oauthSSO/Modern appsHigh

Generate secure password hashes using bcrypt:

Terminal window
# Using htpasswd (Apache utils)
htpasswd -nbBC 12 "" "your-password" | cut -d: -f2
# Using Python
python3 -c "import bcrypt; print(bcrypt.hashpw(b'your-password', bcrypt.gensalt(rounds=12)).decode())"

Warning: Password Hash Security

  • Always use bcrypt cost factor of 12 or higher
  • Never store plaintext passwords in config files
  • Rotate passwords regularly
auth:
providers:
- name: native
type: native
enabled: true
priority: 1
config:
users:
- username: admin
password_hash: "$2a$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.gS6T9I2P9z8K2G"
auth:
providers:
- name: ldap
type: ldap
enabled: true
priority: 1
config:
url: "ldaps://ldap.example.com:636" # Use LDAPS
tls: true
insecure_skip_verify: false # Always verify in production
bind_dn: "cn=bifrost-svc,ou=services,dc=example,dc=com"
bind_password: "${LDAP_BIND_PASSWORD}" # Use environment variable

Tip: LDAP Best Practices

  • Use a dedicated service account with minimal permissions
  • Store bind password in environment variable
  • Use LDAPS (port 636) instead of StartTLS
  • Verify server certificates
auth:
providers:
- name: oauth
type: oauth
enabled: true
priority: 1
config:
client_id: "${OAUTH_CLIENT_ID}"
client_secret: "${OAUTH_CLIENT_SECRET}" # Never commit to git
issuer_url: "https://auth.example.com"
redirect_url: "https://bifrost.example.com/callback"
scopes:
- openid
- profile

Always set an API token for production:

api:
enabled: true
listen: ":7082"
token: "${BIFROST_API_TOKEN}"

Generate a secure token:

Terminal window
# Generate random token
openssl rand -hex 32
Terminal window
# Header authentication (recommended)
curl -H "Authorization: Bearer your-token" http://localhost:7082/api/v1/status
# Query parameter (less secure, avoid in production)
curl "http://localhost:7082/api/v1/status?token=your-token"

Bind the API to localhost if only local access is needed:

api:
listen: "127.0.0.1:7082" # Only localhost

Terminal window
# Allow proxy ports from specific networks
sudo ufw allow from 10.0.0.0/8 to any port 8080 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 1080 proto tcp
# Allow Web UI from admin network only
sudo ufw allow from 192.168.1.0/24 to any port 8081 proto tcp
# Block API from external access
sudo ufw deny 8082/tcp
Terminal window
# Allow proxy from internal network
iptables -A INPUT -p tcp --dport 8080 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP

Restrict which client IPs may use the proxy with two CIDR lists, whitelist and blacklist:

access_control:
# If non-empty, ONLY IPs matching one of these CIDRs are allowed.
# Leave empty to allow all IPs that are not blacklisted.
whitelist:
- "10.0.0.0/8"
- "192.168.0.0/16"
# IPs matching any of these CIDRs are always denied.
blacklist:
- "203.0.113.0/24"

Evaluation order:

  1. The blacklist is checked first — a match is always denied (blacklist takes precedence over the whitelist).
  2. If the whitelist is non-empty, the IP must match an entry in it; otherwise the request is denied.
  3. If the whitelist is empty, any IP not on the blacklist is allowed.

Both lists accept individual addresses (e.g. 192.168.1.10) as well as CIDR ranges. Access control is enforced only when at least one list is non-empty, and changes are hot-reloaded.

There is no enabled, default_action, or rules key — the presence of entries in the lists is what activates enforcement.


Protect against abuse with rate limiting:

rate_limit:
enabled: true
requests_per_second: 100
burst_size: 200
per_ip: true
per_user: true

Prevent bandwidth abuse:

rate_limit:
bandwidth:
enabled: true
upload: "10Mbps"
download: "100Mbps"

Never commit secrets to version control. Use environment variables:

# config.yaml
auth:
providers:
- name: ldap
type: ldap
enabled: true
priority: 1
config:
bind_password: "${LDAP_PASSWORD}"
api:
token: "${API_TOKEN}"
Terminal window
# Set environment variables
export LDAP_PASSWORD="secret"
export API_TOKEN="your-secure-token"
# Run with environment
bifrost-server -c config.yaml

Create /etc/bifrost/env:

Terminal window
LDAP_PASSWORD=secret
API_TOKEN=your-secure-token

Add to service file:

[Service]
EnvironmentFile=/etc/bifrost/env

Secure the file:

Terminal window
chmod 600 /etc/bifrost/env
chown root:bifrost /etc/bifrost/env
# docker-compose.yml
services:
bifrost-server:
environment:
- API_TOKEN_FILE=/run/secrets/api_token
secrets:
- api_token
secrets:
api_token:
file: ./secrets/api_token.txt

Bifrost automatically redacts sensitive data from logs, but review your configuration:

logging:
level: info # Avoid 'debug' in production
format: json

Warning: Log Review

  • Regularly review logs for sensitive data leaks
  • Don’t log full request/response bodies in production
  • Secure log files with appropriate permissions
Terminal window
chmod 640 /var/log/bifrost/*.log
chown bifrost:bifrost /var/log/bifrost/*.log

  • TLS enabled on all public listeners
  • Valid certificates (not self-signed)
  • Authentication enabled
  • API token set
  • Secrets in environment variables (not config)
  • Config file permissions restricted (600)
  • Firewall rules configured
  • Rate limiting enabled
  • Rotate API tokens quarterly
  • Update TLS certificates before expiry
  • Review access logs for anomalies
  • Update to latest Bifrost version
  • Audit user accounts
  • Test backup and recovery procedures
  • Document API endpoints and access
  • Have a process for revoking tokens
  • Know how to disable authentication temporarily
  • Have backup configurations ready
  • Know how to review logs quickly

If you discover a security vulnerability, please report it responsibly:

  1. Do not open a public GitHub issue
  2. Email the maintainers directly
  3. Include:
    • Description of the vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if any)

Subscribe to releases to stay informed about security updates:

Terminal window
# Watch the repository on GitHub
# Or check releases periodically
curl -s https://api.github.com/repos/rennerdo30/bifrost-proxy/releases/latest | jq -r .tag_name