> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/trailbaseio/trailbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Configuration file format, environment variables, and runtime options

## Overview

TrailBase uses a combination of configuration files, environment variables, and CLI flags to manage settings. Configuration is stored in the data directory (default: `./traildepot/`) using protobuf text format.

## Configuration Files

### config.textproto

The main configuration file located at `<data-dir>/config.textproto`. This file stores non-sensitive configuration in a human-readable protobuf text format.

<Info>
  If `config.textproto` doesn't exist when TrailBase starts, it will be automatically created with default values.
</Info>

**Location:** `<data-dir>/config.textproto`

**Example:**

```protobuf theme={null}
# Auto-generated config.Config textproto

server {
  application_name: "TrailBase"
  site_url: "https://example.com"
  logs_retention_sec: 604800  # 7 days
}

auth {
  auth_token_ttl_sec: 3600      # 1 hour
  refresh_token_ttl_sec: 2592000 # 30 days
  
  oauth_providers {
    key: "google"
    value {
      provider_id: OAUTH_PROVIDER_ID_GOOGLE
      client_id: "your-client-id"
      client_secret: "<REDACTED>"
    }
  }
}

email {
  smtp_host: "smtp.gmail.com"
  smtp_port: 587
  smtp_username: "noreply@example.com"
  smtp_password: "<REDACTED>"
  smtp_encryption: SMTP_ENCRYPTION_STARTTLS
  sender_address: "noreply@example.com"
  sender_name: "TrailBase"
}

record_apis {
  name: "posts"
  table_name: "posts"
  # ... additional API configuration
}
```

### secrets.textproto

Sensitive configuration is automatically extracted and stored in `<data-dir>/secrets/secrets.textproto`. This file contains secrets that are referenced in `config.textproto` using the `<REDACTED>` placeholder.

**Location:** `<data-dir>/secrets/secrets.textproto`

**Example:**

```protobuf theme={null}
# Auto-generated config.Vault textproto

secrets {
  key: "TRAIL_EMAIL_SMTP_PASSWORD"
  value: "actual-smtp-password"
}

secrets {
  key: "TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_SECRET"
  value: "actual-oauth-secret"
}
```

<Warning>
  Never commit `secrets.textproto` to version control. The data directory includes a `.gitignore` that excludes the `secrets/` directory by default.
</Warning>

## Configuration Hierarchy

Configuration is resolved in the following order (later sources override earlier ones):

1. **Base configuration** - `config.textproto`
2. **Secrets** - `secrets.textproto` (merged into fields marked as `<REDACTED>`)
3. **Environment variables** - `TRAIL_*` prefixed variables
4. **CLI flags** - Command-line arguments

## Data Directory Structure

When TrailBase initializes, it creates the following directory structure:

```
traildepot/
├── data/
│   ├── main.db          # Main SQLite database
│   ├── logs.db          # Logs database
│   └── queue.db         # Job queue database
├── secrets/
│   ├── secrets.textproto # Secrets vault
│   └── keys/            # Encryption keys
├── migrations/
│   └── main/            # User migrations for main database
├── backups/             # Database backups
├── uploads/             # User-uploaded files
├── wasm/                # WASM components
├── config.textproto     # Main configuration
├── metadata.textproto   # Runtime metadata
└── .gitignore           # Excludes sensitive directories
```

## Environment Variables

### Configuration Environment Variables

All configuration fields can be overridden using environment variables with the `TRAIL_` prefix. The naming convention follows the configuration structure:

**Format:** `TRAIL_<SECTION>_<FIELD>`

<CodeGroup>
  ```bash Server Configuration theme={null}
  # Server settings
  export TRAIL_SERVER_APPLICATION_NAME="MyApp"
  export TRAIL_SERVER_SITE_URL="https://example.com"
  export TRAIL_SERVER_LOGS_RETENTION_SEC="604800"
  ```

  ```bash Auth Configuration theme={null}
  # Auth token TTLs
  export TRAIL_AUTH_AUTH_TOKEN_TTL_SEC="3600"
  export TRAIL_AUTH_REFRESH_TOKEN_TTL_SEC="2592000"
  ```

  ```bash Email Configuration theme={null}
  # SMTP settings
  export TRAIL_EMAIL_SMTP_HOST="smtp.gmail.com"
  export TRAIL_EMAIL_SMTP_PORT="587"
  export TRAIL_EMAIL_SMTP_USERNAME="noreply@example.com"
  export TRAIL_EMAIL_SMTP_PASSWORD="your-password"
  export TRAIL_EMAIL_SMTP_ENCRYPTION="1"  # STARTTLS
  export TRAIL_EMAIL_SENDER_ADDRESS="noreply@example.com"
  export TRAIL_EMAIL_SENDER_NAME="TrailBase"
  ```

  ```bash OAuth Configuration theme={null}
  # OAuth provider settings (for nested maps)
  export TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_ID="your-client-id"
  export TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_SECRET="your-secret"
  ```
</CodeGroup>

### CLI Environment Variables

CLI options can also be set via environment variables:

<CodeGroup>
  ```bash Server Options theme={null}
  export DATA_DIR="/var/lib/trailbase"
  export PUBLIC_URL="https://example.com"
  export ADDRESS="0.0.0.0:4000"
  export ADMIN_ADDRESS="localhost:4001"
  export PUBLIC_DIR="/var/www/static"
  export SPA="true"
  export RUNTIME_ROOT_FS="/var/lib/trailbase/fs"
  export GEOIP_DB_PATH="/var/lib/geoip/GeoLite2-City.mmdb"
  export CORS_ALLOWED_ORIGINS="https://example.com,https://www.example.com"
  export RUNTIME_THREADS="4"
  ```

  ```bash Command-Specific theme={null}
  # For 'trail schema' command
  export MODE="insert"

  # For 'trail email' command
  export TO="user@example.com"
  export SUBJECT="Welcome"
  export BODY="Welcome to our service!"
  ```
</CodeGroup>

## Configuration Sections

### Server Configuration

<ParamField path="server.application_name" type="string" default="TrailBase">
  Application name displayed in UI and emails. Must contain only alphanumeric characters, spaces, or `_`, `-`, `.`.

  **Environment variable:** `TRAIL_SERVER_APPLICATION_NAME`
</ParamField>

<ParamField path="server.site_url" type="string">
  Public site URL. Required for OAuth redirects and email links.

  **Environment variable:** `TRAIL_SERVER_SITE_URL`
</ParamField>

<ParamField path="server.logs_retention_sec" type="integer" default="604800">
  Logs retention period in seconds. Default is 7 days (604800 seconds).

  **Environment variable:** `TRAIL_SERVER_LOGS_RETENTION_SEC`
</ParamField>

### Auth Configuration

<ParamField path="auth.auth_token_ttl_sec" type="integer" default="3600">
  Authentication token time-to-live in seconds. Default is 1 hour (3600 seconds) in production, 2 minutes in debug builds.

  **Environment variable:** `TRAIL_AUTH_AUTH_TOKEN_TTL_SEC`
</ParamField>

<ParamField path="auth.refresh_token_ttl_sec" type="integer" default="2592000">
  Refresh token time-to-live in seconds. Default is 30 days (2592000 seconds).

  **Environment variable:** `TRAIL_AUTH_REFRESH_TOKEN_TTL_SEC`
</ParamField>

<ParamField path="auth.oauth_providers" type="map<string, OAuthProviderConfig>">
  Map of OAuth provider configurations. Keys are provider names, values are provider configurations.
</ParamField>

**OAuth Provider Configuration:**

<ParamField path="provider_id" type="enum" required>
  OAuth provider type:

  * `OAUTH_PROVIDER_ID_GOOGLE` - Google OAuth
  * `OAUTH_PROVIDER_ID_GITHUB` - GitHub OAuth
  * `OIDC0` - Generic OpenID Connect
</ParamField>

<ParamField path="client_id" type="string" required>
  OAuth client ID from the provider.

  **Environment variable:** `TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_ID`
</ParamField>

<ParamField path="client_secret" type="string" required>
  OAuth client secret from the provider. Automatically moved to secrets vault.

  **Environment variable:** `TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_SECRET`
</ParamField>

<ParamField path="auth_url" type="string">
  Authorization URL (required for OIDC0 provider).

  **Environment variable:** `TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_AUTH_URL`
</ParamField>

<ParamField path="token_url" type="string">
  Token exchange URL (required for OIDC0 provider).

  **Environment variable:** `TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_TOKEN_URL`
</ParamField>

<ParamField path="user_api_url" type="string">
  User info API URL (required for OIDC0 provider).

  **Environment variable:** `TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_USER_API_URL`
</ParamField>

### Email Configuration

<ParamField path="email.smtp_host" type="string">
  SMTP server hostname. If not provided, TrailBase falls back to system's `sendmail`.

  **Environment variable:** `TRAIL_EMAIL_SMTP_HOST`
</ParamField>

<ParamField path="email.smtp_port" type="integer">
  SMTP server port (typically 587 for STARTTLS, 465 for SSL).

  **Environment variable:** `TRAIL_EMAIL_SMTP_PORT`
</ParamField>

<ParamField path="email.smtp_username" type="string">
  SMTP authentication username.

  **Environment variable:** `TRAIL_EMAIL_SMTP_USERNAME`
</ParamField>

<ParamField path="email.smtp_password" type="string">
  SMTP authentication password. Automatically moved to secrets vault.

  **Environment variable:** `TRAIL_EMAIL_SMTP_PASSWORD`
</ParamField>

<ParamField path="email.smtp_encryption" type="enum">
  SMTP encryption method:

  * `SMTP_ENCRYPTION_NONE` (0) - No encryption
  * `SMTP_ENCRYPTION_STARTTLS` (1) - STARTTLS
  * `SMTP_ENCRYPTION_SSL` (2) - SSL/TLS

  **Environment variable:** `TRAIL_EMAIL_SMTP_ENCRYPTION`
</ParamField>

<ParamField path="email.sender_address" type="string">
  Email address to use as sender. If not set, defaults to `noreply@<host>`.

  **Environment variable:** `TRAIL_EMAIL_SENDER_ADDRESS`
</ParamField>

<ParamField path="email.sender_name" type="string">
  Display name for the sender.

  **Environment variable:** `TRAIL_EMAIL_SENDER_NAME`
</ParamField>

### Email Templates

Email templates support variable substitution:

* `{{ VERIFICATION_URL }}` - Full verification link
* `{{ CODE }}` - Verification code only

<ParamField path="email.user_verification_template" type="EmailTemplate">
  Template for user email verification emails.
</ParamField>

<ParamField path="email.change_email_template" type="EmailTemplate">
  Template for email change confirmation emails.
</ParamField>

<ParamField path="email.password_reset_template" type="EmailTemplate">
  Template for password reset emails.
</ParamField>

**EmailTemplate structure:**

```protobuf theme={null}
email {
  user_verification_template {
    subject: "Verify your email"
    body: "Click here to verify: {{ VERIFICATION_URL }}"
  }
}
```

### Database Configuration

<ParamField path="databases" type="repeated DatabaseConfig">
  Additional databases to attach. Main and logs databases are always attached.
</ParamField>

**DatabaseConfig structure:**

<ParamField path="name" type="string" required>
  Database name. Must be alphanumeric with `_` or `-`. Cannot be "main", "logs", or empty.

  **Environment variable:** `TRAIL_DATABASES_<INDEX>_NAME`
</ParamField>

### Record APIs Configuration

<ParamField path="record_apis" type="repeated RecordApiConfig">
  Configuration for table-based REST APIs.
</ParamField>

**RecordApiConfig structure:**

<ParamField path="name" type="string" required>
  API endpoint name.
</ParamField>

<ParamField path="table_name" type="string" required>
  Database table name.
</ParamField>

### JSON Schema Configuration

<ParamField path="schemas" type="repeated JsonSchemaConfig">
  Custom JSON schemas for validation.
</ParamField>

**JsonSchemaConfig structure:**

<ParamField path="name" type="string" required>
  Schema identifier.
</ParamField>

<ParamField path="schema" type="string" required>
  JSON Schema definition (as string).
</ParamField>

### Job Configuration

<ParamField path="jobs.system_jobs" type="repeated JobConfig">
  Scheduled system jobs using cron syntax.
</ParamField>

**JobConfig structure:**

<ParamField path="id" type="string" required>
  Unique job identifier.
</ParamField>

<ParamField path="schedule" type="string" required>
  Cron expression (e.g., `0 0 * * *` for daily at midnight).
</ParamField>

## Runtime Options

These options are set via CLI flags and cannot be changed via configuration files:

<ParamField path="--data-dir" type="string" default="./traildepot">
  Base directory for all TrailBase data. **Requires server restart to change.**
</ParamField>

<ParamField path="--public-url" type="string">
  Public URL for external access. **Requires server restart to change.**
</ParamField>

<ParamField path="--address" type="string" default="localhost:4000">
  Server bind address. **Requires server restart to change.**
</ParamField>

<ParamField path="--admin-address" type="string">
  Separate admin interface address. **Requires server restart to change.**
</ParamField>

<ParamField path="--runtime-threads" type="integer">
  WASM runtime thread pool size. **Requires server restart to change.**
</ParamField>

<Note>
  A good rule of thumb: if a setting requires a server restart, it should be a CLI option. Otherwise, it should be in the config file.
</Note>

## Configuration Validation

TrailBase validates configuration on startup and when updating via the admin API. Validation checks:

* **Application name:** Alphanumeric characters, spaces, `_`, `-`, `.` only
* **URLs:** Valid URL format for `site_url`, OAuth URLs
* **Email addresses:** Valid email format for sender addresses
* **Database names:** Alphanumeric with `_` or `-`, not reserved names
* **API names:** Unique across all configured APIs
* **OAuth providers:** Required fields present, valid provider IDs
* **Cron schedules:** Valid cron syntax
* **JSON schemas:** Valid JSON Schema format

## Editing Configuration

### Via Admin UI

The admin interface provides a configuration editor:

1. Navigate to Admin → Configuration
2. Edit the configuration in the text editor
3. Save changes
4. Configuration is validated before saving

### Via Text Editor

1. Stop the TrailBase server
2. Edit `<data-dir>/config.textproto`
3. For secrets, edit `<data-dir>/secrets/secrets.textproto`
4. Start the server (configuration is validated on startup)

### Via Environment Variables

Set environment variables before starting the server:

```bash theme={null}
export TRAIL_SERVER_APPLICATION_NAME="MyApp"
export TRAIL_EMAIL_SMTP_PASSWORD="secret-password"
trail run
```

## Secrets Management

### How Secrets Work

1. **Writing:** When you set a secret field in `config.textproto`, TrailBase extracts it to `secrets.textproto` and replaces it with `<REDACTED>`
2. **Reading:** On startup, TrailBase merges secrets back into the configuration
3. **Environment override:** Environment variables override both config and secrets

### Secret Fields

The following fields are automatically treated as secrets:

* `email.smtp_password`
* `auth.oauth_providers.*.client_secret`
* Any field marked with `[(secret) = true]` in the protobuf definition

### Rotating Secrets

<Accordion title="Rotate SMTP password">
  ```bash theme={null}
  # Option 1: Edit secrets file
  vim ./traildepot/secrets/secrets.textproto
  # Update TRAIL_EMAIL_SMTP_PASSWORD value

  # Option 2: Use environment variable
  export TRAIL_EMAIL_SMTP_PASSWORD="new-password"
  trail run
  ```
</Accordion>

<Accordion title="Rotate OAuth secrets">
  ```bash theme={null}
  # Edit secrets file
  vim ./traildepot/secrets/secrets.textproto
  # Update TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_SECRET

  # Or use environment variable
  export TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_SECRET="new-secret"
  trail run
  ```
</Accordion>

## Configuration Examples

### Minimal Configuration

```protobuf theme={null}
server {
  application_name: "MyApp"
}
```

### Production Configuration

```protobuf theme={null}
server {
  application_name: "Production App"
  site_url: "https://app.example.com"
  logs_retention_sec: 2592000  # 30 days
}

auth {
  auth_token_ttl_sec: 3600
  refresh_token_ttl_sec: 2592000
  
  oauth_providers {
    key: "google"
    value {
      provider_id: OAUTH_PROVIDER_ID_GOOGLE
      client_id: "123456789-abcdefghijklmnop.apps.googleusercontent.com"
      client_secret: "<REDACTED>"
    }
  }
}

email {
  smtp_host: "smtp.sendgrid.net"
  smtp_port: 587
  smtp_username: "apikey"
  smtp_password: "<REDACTED>"
  smtp_encryption: SMTP_ENCRYPTION_STARTTLS
  sender_address: "noreply@example.com"
  sender_name: "My App"
}
```

### Development Configuration

```bash theme={null}
# Use environment variables for development
export TRAIL_SERVER_APPLICATION_NAME="Dev Server"
export TRAIL_EMAIL_SMTP_HOST="localhost"
export TRAIL_EMAIL_SMTP_PORT="1025"
export TRAIL_EMAIL_SMTP_ENCRYPTION="0"

trail run --dev --address localhost:3000
```
