################################################################ # Portier Broker configuration template # # All settings in this template are listed with their defaults. If the default # value of a setting is fine, you can leave the setting out of your # configuration. # # If a setting in this template is commented, that means it is unset by # default, and any value listed is an example only. # # Alternatively, the broker can be configured using the environment. Each # setting here has a matching `BROKER_*` environment variable. For example, # `public_url` can also be set using the `BROKER_PUBLIC_URL` environment # variable. # # Configuration from the environment takes precedence over the configuration # file. (It's also possible to use the environment only, without a # configuration file.) ################################################################ # Basic settings # The IP address and port to bind the HTTP server to. Note that `listen_ip` # accepts IPv4 and IPv6, but currently not hostnames. # # Alternatively, you may use systemd socket activation to pass in a listening # socket, in which case these settings are ignored. (See the included systemd # unit file.) # # Also note that the broker currently only talks plain HTTP, and not HTTPS. # Using HTTPS is strongly recommended, but you'll need to add a reverse proxy # in front of the broker to do this. (Apache or Nginx can do this for you.) # # If using the Docker image, you can leave these settings out of your config. listen_ip = "127.0.0.1" listen_port = 3333 # The broker server's public-facing URL. # # It's important to set this correctly, or JSON Web Tokens will fail to # validate. Relying Parties will use the same value for their Broker URL. To # ensure consistency, trailing slashes should be avoided. public_url = "broker.flylocal.io" # Required # A list of IP addresses or subnets (CIDR-notation) of trusted reverse proxies. # # Portier uses this to determine the actual client IP address, and setting this # correctly is important for rate-limits. # # Portier will look for the `X-Forwarded-For` header sent by reverse proxies. # In Nginx, you'd accomplish this with: # # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for # trusted_proxies = ["127.0.0.0/8", "::1"] # The 'From' name and address used by Portier to send emails. from_name = "FlyLocal Team" from_address = "no-reply@iflylocal.com" # Required # Optional Google Client ID for verifying `@gmail.com` addresses. # You can create one of these at: https://console.cloud.google.com/ #google_client_id = "" # To generate RSA keys, the broker runs an external command. By default, this # looks for the OpenSSL CLI in `$PATH`, but you may need to change this for # your environment. Whatever command you specify here should output a single # PEM key on stdout. # # Using automatic key rotation is strongly recommended, but if you cannot # provide a working value for this setting, it's possible to manually configure # keys. See the `keyfiles` and `keytext` options in the advanced section for # how to do this. generate_rsa_command = ["openssl", "genrsa", "2048"] ################################################################ # Storage # Selecting one of these storage methods is required. # # For simple installations, SQLite is recommended. Alternatively, Redis can be # useful when running multiple instances of the broker, or when there's no # persistent file storage. This is common with cloud hosting, like Heroku. # Setting `sqlite_db` enables SQLite storage. Please also read: # https://github.com/portier/portier-broker/blob/main/docs/storage/sqlite.md sqlite_db = "/data/db.sqlite3" # Setting `redis_url` enables Redis storage. Please also read: # https://github.com/portier/portier-broker/blob/main/docs/storage/redis.md #redis_url = "redis://localhost/0" # Setting `memory_storage` enables in-memory storage. This should only be used # for local testing. #memory_storage = true ################################################################ # Sending mail # Selecting one of these methods to send mail is required. # # If you're looking for an easy way to test the broker locally, consider using # SMTP with Mailhog: https://github.com/mailhog/MailHog # Setting `smtp_server` enables SMTP to send mail. The value should be a # hostname or IP address, and may optionally have a port. (If not specified, # port 25 is used.) The `smtp_username` and `smtp_password` fields are # optional. smtp_server = "smtp.gmail.com" smtp_username = "no-reply" smtp_password = "2^kS0jn$yQ8d" # Setting `sendmail_command` enables sending mail using the given `sendmail` # executable. The path in this example is usually the correct one. #sendmail_command = "/usr/sbin/sendmail" # Setting `postmark_token` enables sending mail using the Postmark API. The # value is a Postmark server API token. #postmark_token = "" # Setting the following variables enables sending mail using the Mailgun API. # `mailgun_token` is your API token, `mailgun_api` is the Mailgun base URL for # your region (typically either `https://api.mailgun.net/v3` or # `https://api.eu.mailgun.net/v3`), and `mailgun_domain` is the sending domain # you would like to use. In order to use Mailgun, `mailgun_token` and # `mailgun_domain` are required. #mailgun_token = "" #mailgun_api = "https://api.mailgun.net/v3" #mailgun_domain = "" ################################################################ # Access control # List of (exact) website origins that are allowed to use this broker. If left # unset, the broker will allow any Relying Party to use it. (Note that this is # different from an empty list, which would deny all instead.) # # Entries may also be files, by specifying a path prefixed with `@`. These # files must contain one value per line, but may contain empty lines or # comments starting with `#`. # # Note that files are only loaded once during startup, and the broker must be # restarted after updating them. #allowed_origins = ["https://example.com"] # List of (exact) email domains that are explicitely allowed to use this # broker. Domains in this list bypass the `blocked_domains` and # `verify_with_resolver` checks. # # Similar to `allowed_origins`, this list may also contain files. allowed_domains = [] # List of (exact) email domains that are explicitely blocked from using this # broker. Domains in this list are rejected before the `verify_with_resolver` # check. Note that `allowed_domains` is checked first, and domains that appear # in both will not be rejected. # # Similar to `allowed_origins`, this list may also contain files. blocked_domains = [] # A DNS server used to verify email domains. If set, the domain must have an # MX, A or AAAA record, or it will be rejected. # # Leaving this unset means no DNS check is performed at all. Using the host OS # resolver is unfortunately not possible, because it is not designed for the # amount of requests the broker may want need to make. # # This example lists the Cloudflare public DNS resolver. If your broker is # public or may otherwise see a decent amount of traffic, consider running your # own caching resolver instead (even if it just forwards to Cloudflare or # similar), because the broker itself does not do any DNS caching. Popular # options for this are Unbound, BIND, or dnsmasq. #verify_with_resolver = "1.1.1.1:53" # If both this and `verify_with_resolver` are set, the DNS check will ignoreIP # addresses that are not in the public address space. (For example, domains # that resolve only to local network addresses will be rejected.) verify_public_ip = true # Set this flag to true to treat any email domain not in `allowed_domains` as # blocked. This effectively disables other checks. Useful for private brokers. allowed_domains_only = false ################################################################ # Advanced settings # By default, the broker automatically generates and rotates keys used to sign # JSON Web Tokens. If for some reason you wish to provide keys manually, you # can do so with these settings. # # Only PEM format is accepted, but the `keytext` and each file in `keyfiles` # may contain multiple PEM blocks. The broker will list all public keys in API # responses, but will only use the last key for signing. keyfiles = [] #keytext = """ #-----BEGIN PRIVATE KEY----- #[...] #""" # Signing algorithms to use for JSON Web Tokens. Currently supported values # are: RS256, EdDSA. The protocol for selecting algorithms other than RS256 is # experimental and non-standard, so by default only RS256 is enabled. signing_algs = ["RS256"] # Directory that contains broker data files. This directory should contain the # `lang`, `res` and `tmpl` subdirectories. The default empty string value for # this setting causes the broker to use the current working directory. data_dir = "" # Various Time-To-Live values can be tweaked from their recommended defaults. # If the default values don't suit your deployment, we'd love to hear why! # HTTP max-age for our static resources static_ttl = 604800 # 1 week # HTTP max-age for our discovery JSON discovery_ttl = 604800 # 1 week # Key rotation rate, and HTTP max-age for our keys JSON keys_ttl = 86400 # 1 day # Duration that JSON Web Tokens are valid for token_ttl = 600 # 10 minutes # Time that users have to complete authentication session_ttl = 900 # 15 minutes # Time that relying parties have to redeem an authorization code auth_code_ttl = 600 # 10 minutes # Minimum cache time for downstream HTTP requests made by the broker cache_ttl = 3600 # 1 hour ################################################################ # Rate limits # Limits can be set in a flexible way. We've tried to provide some sensible # defaults, but if you're exposing your broker to the internet, you may need # control over limits. # # Limits are specified as a list of strings. When setting these using the # `BROKER_LIMITS` environment variable, they can be space or comma separated. # Each entry contains a count, a time window, and may be preceded with optional # flags separated by semi-colons. # # Here are some examples to illustrate what's possible: # # - `1000/sec` - A global limit of 1000 requests per second. # # - `email:5/min` - Per email address, max 5 requests per minute. # # - `ip:origin:10/s` - Max 10 requests per second for each unique combination # of IP and Relying Party origin. (A 'compound key' in database terminology.) # # - `email:decr_complete:5/15m` - Per email, allow max 5 in-progress attempts # per 15 minutes. The `decr_complete` flag ensures that when the user # completes a login, effectively a new 'slot' opens up for them. # # - `ip:extend_window:1000/s` - Max 1000 requests per second, per IP, with an # extending window. For example, during an ongoing attack, the IP does not # get new slots the next second, because its ongoing attempts keep extending # the window further. The penalty is lifted only when attempts stop # completely for one full second after the last attempt. This flag can have # drastic effects, and is usually only applied to short time windows. # # Flags control what the limit applies to and its behavior. These are all the # currently implemented flags: # # - `ip`: Apply the limit to the users IP address. # - `email`: Apply the limit to the users email address. # - `domain`: Apply the limit to the users email domain. # - `origin`: Apply the limit to the Relying Party origin. # - `decr_complete`: Decrement the counter for completed requests. # - `extend_window`: Extend the window on every hit, instead of just the first. # # The time window is a number followed by a unit. The number may be omitted, # which will mean 1 of the given unit. The following units can be used: # # - `s` / `sec` / `secs` / `second` / `seconds` # - `m` / `min` / `mins` / `minute` / `minutes` # - `h` / `hour` / `hours` # - `d` / `day` / `days` # # Note that each limit added also increases the amount of queries to your # selected storage method. The list order does not matter, because all limits # are always tested on every attempt, and processing does not short-circuit. limits = [ # Per IP, max 50 requests per second. "ip:50/s", # Per IP, max 100 requests per 5 seconds, with an extending window. "ip:extend_window:100/5s", # Per IP and email, max 30 requests per hour. "ip:email:30/h", # Per IP and email, allow 5 slots per 15 minutes. "ip:email:decr_complete:5/15m", # Per IP and email, allow 2 slots per 15 minutes on each site. "ip:email:origin:decr_complete:2/15m", ] ################################################################ # WebFinger overrides # The broker uses WebFinger to discover domains that provide custom # authentication. If WebFinger cannot be configured on a domain, custom # overrides can be configured with sections like the ones below. (Note that it # is currently not possible to configure these overrides using environment # variables.) # The following example enables Google authentication for a domain. Note that # both `rel` and `href` should be treated as magic constants. #[[domain_overrides."example.com"]] #rel = "https://portier.io/specs/auth/1.0/idp/google" #href = "https://accounts.google.com" # The following example configures a custom Portier Identity Provider for a # domain. Note that `rel` here should be treated as a magic constant, and # `href` points to the actual Identity Provider implementation. #[[domain_overrides."example.com"]] #rel = "https://portier.io/specs/auth/1.0/idp" #href = "https://identity-provider.example.com"