# Configuration File

Pangolin is configured using a `config.yml` file. The file is expected to be mounted in `config/config.yml`.

## Sections

### `app`

- `dashboard_url`: string
    - Example: `https://example.com` or `https://pangolin.example.com`
    - The url where the application is hosted. This is used for many things, including generating links.
    - You can run Pangolin on a subdomain or root domain. Users will be redirected to this url to complete the auth step.
- `log_level`: string
    - Options: `debug`, `info`, `warn`, `error`
    - The log level for the application.
- `save_logs`: boolean
    - Whether to save logs to a file. Logs are saved to `config/logs/`.
    - Logs rotate
        - Max size: 20MB
        - Max files: 7 days
- `log_failed_attempts` (optional): boolean
    - Whether to log failed authentication attempts. This is useful for security tools like Crowdsec and Fail2ban.

### `server`

- `external_port`: int
    - The port the external facing (public) API will listen on.
- `internal_port`: int
    - The port the internal private facing (private) API will listen on.
- `next_port`: int
    - The port the frontend server will listen on.
- `internal_hostname`: string
    - Example: `pangolin`
    - The hostname of the Pangolin container. This is used for internal communication between the components.
    - If running with Docker Compose, this should be the name of the container, which is likely `pangolin`.
- `session_cookie_name`: string
    - Example: `p_session_token`
    - The name of the session cookie. This is used to store the session token for the main application.
- `resource_access_token_param`: string
    - Example: `p_token`
    - The query parameter used to pass the access token to the resource. Badger extracts this token and sends it to Pangolin to authenticate. This is used in direct share links that do not require a browser redirect.
- `resource_session_request_param`: string
    - Example: `p_session_request`
    - The query parameter used to pass the session request token to be exchanged for a real session token in Badger.
- `cors`: object (optional)
    - Configuration for Cross-Origin Resource Sharing (CORS).
    - `origins`: array of strings (optional)
        - Example: `["https://pangolin.example.com"]`
        - List of allowed origins for cross-origin requests.
    - `methods`: array of strings (optional)
        - Example: `["GET", "POST", "PUT", "DELETE", "PATCH"]`
        - HTTP methods allowed for CORS requests.
    - `allowed_headers`: array of strings (optional)
        - Example: `["X-CSRF-Token", "Content-Type"]`
        - HTTP headers allowed in CORS requests.
    - `credentials`: boolean (optional)
        - Whether to allow credentials.
        - Default: true
- `trust_proxy`: boolean (optional)
    - Whether to trust the proxy headers (e.g., `X-Forwarded-For`) for determining the client IP address.
    - Default: `true`
- `dashboard_session_length_hours`: int (optional)
    - The length of time in hours that the dashboard session will last after logging in.
    - Default: `720`
- `resource_session_length_hours`: int (optional)
    - The length of time in hours that a session for each resource will last after logging in.
    - Default: `720`

### `domains`

[How do I get a domain?](../../02-Getting%20Started/02-dns-networking.md)

At least one domain must be configured. 

- `<domain_key>`: string
    - The unique key for the domain configuration. This can be anything you want.
    - `base_domain`: string
        - Example: `example.com`
    - `cert_resolver`: string
        - Example: `letsencrypt`
        - The name of the Traefik certificate resolver to use for this domain. This must match the name of the certificate resolver in the Traefik configuration.
    - `prefer_wildcard_cert`: boolean
        - Example: `true`
        - Whether to prefer a wildcard certificate when generating certificates. This is useful if you want to use a wildcard certificate for the base domain and all subdomains.

### `traefik`

- `http_entrypoint`: string
    - Example: `web`
    - The name of the Traefik entrypoint for HTTP traffic. This must match the name of the entrypoint in the Traefik configuration.
- `https_entrypoint`: string
    - Example: `websecure`
    - The name of the Traefik entrypoint for HTTPS traffic. This must match the name of the entrypoint in the Traefik configuration.
- `additional_middlewares`: array of strings (optional)
    - Example: `["middleware1", "middleware2"]`
    - Additional middlewares to apply to the resource router generated at runtime. These must be defined in another Traefik configuration provider like the dynamic file provider.

### `gerbil`

    - `start_port`: int
      - This is the starting port for WireGuard tunnels that new Gerbil exit nodes will use and increment as they register with Pangolin. Advised to choose a base of a range with no conflicts.
    - `base_endpoint`: string
      - This is the domain name automatically included in Newt and WireGuard config for tunnel connections.
    - `use_subdomain`: boolean
      - If set to true, new Gerbil exit nodes will be assigned a unique subdomain off of the base domain. Advised to keep this to false.
    - `subnet_group`: string
      - IP address CIDR from which to choose smaller CIDR ranges for new Gerbil exit node registrations. Each "Gerbil" gets a subnet from this range.
    - `block_size`: int
      - The block size of the smallest CIDR ranges for new Gerbil exit node registrations.
    - `site_block_size`: int
      - The block size of the smallest CIDR ranges for new sites connected to Gerbil.

### `rate_limits`

- `global`: object
    - The global rate limit configuration for all requests to the external Pangolin API.
    - `window_minutes`: int
        - Example: `1`
        - The window in minutes for the rate limit.
    - `max_requests`: int
        - Example: `100`
        - The maximum number of requests allowed in the window.

### `email` (optional)

- `smtp_host` (optional): string
    - The SMTP host for sending emails.
- `smtp_port` (optional): int
    - The SMTP port for sending emails.
- `smtp_user` (optional): string
    - The SMTP username for sending emails.
- `smtp_pass` (optional): string
    - The SMTP password for sending emails.
- `smtp_secure` (optional): boolean
    - Whether to use a secure connection when sending emails. Use this if you're using port 465.
    - Default: `false`
- `no_reply` (optional): string
    - Example: `no-reply@example.com`
    - The address to send emails from. This can be any email address. Most often this will be the same as the `smtp_user`.
- `smtp_tls_reject_unauthorized` (optional): boolean
    - Do not fail if the server certificate cannot be verified.
    - Default: `false`

### `users`

- `server_admin`: object
    - The server admin who can always create new organizations. This user will always be created on startup.
    - `email`: string
        - Env: USERS_SERVERADMIN_EMAIL
        - The email address of the server admin.
    - `password`: string
        - Env: USERS_SERVERADMIN_PASSWORD
        - The password of the server admin.
        - This password will always overwrite the password in the database on startup. This is useful for resetting the password.
        - The password must meet the following requirements:
            - At least 8 characters
            - At least one uppercase letter
            - At least one lowercase letter
            - At least one digit
            - At least one special character

### `flags` (optional)

- `require_email_verification` (optional): boolean
    - Whether to require email verification for new users. If set to `true`, new users will need to verify their email address before they can log in.
    - Only turn this on if you have email configured.
- `disable_signup_without_invite` (optional): boolean
    - Whether to allow users to sign up without an explicit invite. If set to `true`, the "Sign Up" button will be removed from the login form.
    - Users will still be able to sign up if they have a valid invite.
- `disable_user_create_org` (optional): boolean
    - Whether to allow users to create new organizations. If set to `true`, users will not be able to create new organizations.
    - The server admin can always create new organizations.
- `allow_raw_resources` (optional): boolean
    - Whether to allow users to create raw TCP/UDP resources. If set to `false`, users will only be able to create http/https resources.
- `allow_base_domain_resources` (optional): boolean
    - Whether to allow users to create resources on the base domain. If set to `false`, users will only be able to create resources on subdomains.

## Example Configuration File

This is just an example and is not meant to be used as is. It is not complete. You should customize the configuration to your needs.

```yaml
app:
    dashboard_url: "https://example.com"
    log_level: "info"
    save_logs: false

domains:
    domain1:
        base_domain: "example.com"
        cert_resolver: "letsencrypt"
        prefer_wildcard_cert: false

server:
    external_port: 3000
    internal_port: 3001
    next_port: 3002
    internal_hostname: "pangolin"
    session_cookie_name: "p_session_token"
    resource_access_token_param: "p_token"
    resource_session_request_param: "p_session_request"

traefik:
    cert_resolver: "letsencrypt"
    http_entrypoint: "web"
    https_entrypoint: "websecure"

gerbil:
    start_port: 51820
    base_endpoint: "example.com"
    use_subdomain: false
    block_size: 24
    site_block_size: 30
    subnet_group: 100.89.137.0/20

rate_limits:
    global:
        window_minutes: 1
        max_requests: 100

email:
    smtp_host: "host.hoster.net"
    smtp_port: 587
    smtp_user: "no-reply@example.com"
    smtp_pass: "aaaaaaaaaaaaaaaaaa"
    no_reply: "no-reply@example.com"

users:
    server_admin:
        email: "admin@example.com"
        password: "Password123!"

flags:
    require_email_verification: true
    disable_signup_without_invite: true
    disable_user_create_org: true
    allow_raw_resources: true
    allow_base_domain_resources: true
```
