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

# Self-Hosting Guide & Environment Reference

> Comprehensive deployment guide for running toorow on your own infrastructure, featuring an exhaustive environment variable reference.

This guide is for platform engineers and developers running a custom, self-hosted instance of **toorow**.

<Note>
  Self-hosted instances operate in complete isolation. By default, toorow sends no telemetry, phone-home data, or analytics to the maintainers. See [Security Constraints](/constraints) for details.
</Note>

***

## 1. Account & Infrastructure Setup

To deploy a functional self-hosted instance, provision the following services:

1. **Platform Database (PostgreSQL 15+)**: Create a PostgreSQL instance (e.g., Supabase project or Cloud SQL). Apply platform migrations located in `infra/nango/migrations/` (migrations `001` to `029`).
2. **Google Cloud Project (Analytics Warehouse & Google OAuth)**:
   * Enable BigQuery, Cloud Run, and Google APIs (Analytics Data, Search Console, Google Ads, Sheets).
   * Provision BigQuery datasets (`raw_*`, `marts_*`) and a Service Account with `roles/bigquery.dataEditor` and `roles/bigquery.jobUser`. Use the Terraform scripts in `infra/terraform/` (`terraform plan/apply`).
   * Create a Web OAuth 2.0 Client ID for Google connectors.
3. **Nango Broker (Non-Google OAuth)**:
   * Deploy Nango OSS using `infra/nango/docker-compose.yml` or create a Nango Cloud account.
   * Register provider apps (Meta Ads, TikTok, LinkedIn, Shopify, Stripe, Klaviyo) in Nango.

***

## 2. Environment Variable Reference (`.env`)

Copy `.env.example` to `.env` in your deployment environment and configure the required parameters.

### Server & Network Security

| Variable                              | Type    | Default          | Description                                                                       |
| ------------------------------------- | ------- | ---------------- | --------------------------------------------------------------------------------- |
| `PORT`                                | Integer | `8000`           | HTTP listening port for the server. Injected automatically by Cloud Run (`8080`). |
| `HOST_HEADER_VALIDATION`              | String  | `strict`         | Set to `strict` to enforce Host header validation against `ALLOWED_HOST`.         |
| `ALLOWED_HOST`                        | String  | `localhost:8000` | Allowed HTTP Host header value (e.g., `your-api.run.app`).                        |
| `FASTMCP_HTTP_HOST_ORIGIN_PROTECTION` | Boolean | `true`           | Enables FastMCP native host/origin validation.                                    |
| `FASTMCP_HTTP_ALLOWED_HOSTS`          | String  | *Unset*          | Comma-separated list of allowed origins for FastMCP HTTP transport.               |

### Authentication Mode (`TOOROW_AUTH_MODE`)

| Variable                | Type   | Allowed Values                | Description                                                                                                                                                      |
| ----------------------- | ------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TOOROW_AUTH_MODE`      | String | `disabled`, `static`, `oauth` | **`disabled`**: No auth (local tests only).<br />**`static`**: Static token map for QA.<br />**`oauth`**: RS256 JWT verification (**mandatory for production**). |
| `TOOROW_STATIC_TOKEN`   | String | *Unset*                       | Static secret token required when `TOOROW_AUTH_MODE=static`.                                                                                                     |
| `TOOROW_JWT_PUBLIC_KEY` | String | *Unset*                       | PEM RS256 public key (with literal `\n`) for verifying caller JWTs in OAuth mode.                                                                                |
| `TOOROW_JWKS_URI`       | String | *Unset*                       | Remote JWKS JSON endpoint URL (alternative to public key string).                                                                                                |
| `TOOROW_JWT_ISSUER`     | String | *Unset*                       | Required JWT issuer claim (`iss`) matching incoming OAuth tokens.                                                                                                |
| `TOOROW_JWT_AUDIENCE`   | String | *Unset*                       | Required JWT audience claim (`aud`) matching `connector-api`.                                                                                                    |

### Platform Database & Key Governance

| Variable             | Type   | Default            | Description                                                                                                  |
| -------------------- | ------ | ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `PLATFORM_DB_URL`    | String | `postgresql://...` | Connection URI for the PostgreSQL platform database (connections, audit logs, queue).                        |
| `TENANT_KEY_BACKEND` | String | `local`            | Encryption key backend for tenant metadata: `local` (Phase A file) or `secret_manager` (GCP Secret Manager). |
| `TENANT_KEY_DIR`     | String | `infra/keys`       | Local directory for tenant encryption keys when `TENANT_KEY_BACKEND=local`.                                  |

### OAuth Brokers & Providers

| Variable                     | Type   | Purpose                                                                                                           |
| ---------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| `NANGO_BASE_URL`             | String | Base URL of Nango instance (e.g., `https://api.nango.dev` or `http://localhost:3003`).                            |
| `NANGO_SECRET_KEY`           | String | Secret API key generated in Nango console.                                                                        |
| `GOOGLE_OAUTH_CLIENT_ID`     | String | Google Web Application OAuth Client ID.                                                                           |
| `GOOGLE_OAUTH_CLIENT_SECRET` | String | Google Web Application OAuth Client Secret.                                                                       |
| `GOOGLE_OAUTH_REDIRECT_URI`  | String | OAuth redirect URI (must match GCP console URI, e.g., `https://<host>/api/google/oauth/callback`).                |
| `GOOGLE_OAUTH_STATE_SECRET`  | String | Secret key for signing anti-CSRF OAuth state tokens (`python -c "import secrets; print(secrets.token_hex(32))"`). |

### Background Queue & Scheduler

| Variable                      | Type    | Default        | Description                                                                             |
| ----------------------------- | ------- | -------------- | --------------------------------------------------------------------------------------- |
| `QUEUE_BACKEND`               | String  | `local`        | Job queue backend: `local` (Postgres worker thread) or `cloud_tasks` (GCP Cloud Tasks). |
| `QUEUE_POLL_INTERVAL_SECONDS` | Integer | `5`            | Polling frequency for local queue worker.                                               |
| `SCHEDULER_ENABLED`           | Boolean | `false`        | Enables in-process nightly scheduler thread. Set `true` in production containers.       |
| `SCHEDULER_NIGHTLY_HOUR`      | Integer | `2`            | Local hour (0–23) to trigger nightly ingestion and dbt runs.                            |
| `SCHEDULER_TIMEZONE`          | String  | `Europe/Paris` | IANA timezone string for computing daily boundaries (`yesterday`).                      |

### Read-Through Cache (DuckDB)

| Variable                   | Type    | Default                  | Description                                                                                                 |
| -------------------------- | ------- | ------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `TOOROW_CACHE_ENABLED`     | Boolean | `false`                  | Set `true` to enable ephemeral read-through cache for fast query responses (\~50ms).                        |
| `TOOROW_CACHE_PATH`        | String  | `cache_warehouse.duckdb` | Distinct DuckDB file path for caching recent marts.                                                         |
| `TOOROW_CACHE_WINDOW_DAYS` | Integer | `30`                     | Rolling day window included in the ephemeral cache.                                                         |
| `TOOROW_CACHE_TABLES`      | String  | *Default marts*          | Comma-separated list of analytical marts cached (`fact_daily_kpi,semantic_ctr,semantic_cpa,semantic_roas`). |

### Optional Telemetry & Tracing

| Variable                | Type    | Default                 | Description                                                                                |
| ----------------------- | ------- | ----------------------- | ------------------------------------------------------------------------------------------ |
| `TRACING_ENABLED`       | Boolean | `false`                 | Set `true` to enable OpenTelemetry spans exported to Langfuse (`uv sync --extra tracing`). |
| `LANGFUSE_PUBLIC_KEY`   | String  | *Unset*                 | Langfuse project public key.                                                               |
| `LANGFUSE_SECRET_KEY`   | String  | *Unset*                 | Langfuse project secret key.                                                               |
| `LANGFUSE_HOST`         | String  | `http://localhost:3004` | Langfuse host URL.                                                                         |
| `GA4_MP_MEASUREMENT_ID` | String  | *Unset*                 | Optional server-side GA4 Measurement Protocol ID (`G-XXXXXXX`). Unset = zero telemetry.    |
| `GA4_MP_API_SECRET`     | String  | *Unset*                 | Optional GA4 Measurement Protocol API secret. Unset = zero telemetry.                      |

***

## 3. Container Deployment (Cloud Run)

1. **Build Container Image**:
   ```bash theme={null}
   docker build -t europe-west1-docker.pkg.dev/<PROJECT_ID>/connector/mcp-server:latest -f infra/docker/mcp-server/Dockerfile .
   ```
2. **Push Image & Deploy**:
   ```bash theme={null}
   docker push europe-west1-docker.pkg.dev/<PROJECT_ID>/connector/mcp-server:latest

   gcloud run deploy mcp-server \
     --image europe-west1-docker.pkg.dev/<PROJECT_ID>/connector/mcp-server:latest \
     --region europe-west1 \
     --platform managed \
     --min-instances=0 \
     --max-instances=4 \
     --set-env-vars "TOOROW_AUTH_MODE=oauth,TOOROW_JWT_JWKS_URI=https://<your-auth-provider>/.well-known/jwks.json,HOST_HEADER_VALIDATION=strict,ALLOWED_HOST=<your-domain>"
   ```

***

## Next Steps & Cross-References

<CardGroup cols={2}>
  <Card title="Prerequisites" icon="list-check" href="/prerequisites">
    Verify required GCP APIs, service accounts, and database connections.
  </Card>

  <Card title="Security Constraints" icon="shield-check" href="/constraints">
    Review the pre-live security checklist and architectural invariants.
  </Card>

  <Card title="Cloud Hosting" icon="cloud" href="/cloud-hosting">
    Examine the maintainers' managed Cloud Run setup.
  </Card>

  <Card title="Developer Quickstart" icon="rocket" href="/quickstart">
    Run a lightweight local sandbox instance for testing.
  </Card>
</CardGroup>
