Configuration
The Gateway has no configuration file. Every setting lives on the gateway pool in your Britive tenant, and each container fetches its own settings from there when it starts. A platform administrator changes a setting in the tenant portal, and every gateway in the pool picks it up on its next sync - no file to edit, no restart, no redeploy.
What the container itself needs is three values: which tenant to ask, how to authenticate, and where its database is.
docker run \
-e TENANT=acme \
-e GATEWAY_POOL_TOKEN=<pool token> \
-e DATABASE_URL=postgresql://... \
britive/mcp-gatewayHow Settings Reach a Gateway
sequenceDiagram
participant A as Platform admin
participant T as Britive tenant<br/>(gateway pool record)
participant G as Gateway container
A->>T: Edit settings in the tenant portal
G->>T: GET /pools/self/bootstrap<br/>Authorization: PoolToken
T-->>G: Pool identity, encryption key, resolved settings
Note over G: Applied and validated<br/>before serving traffic
loop Every backendSyncIntervalSeconds (default 300s)
G->>T: Re-fetch, with the settings version it holds
T-->>G: 304 Not Modified, or the new settings
end
The pool token identifies the pool, so there is nothing else to name: one token resolves to exactly one pool, and that pool’s settings are what the container runs.
The same request also returns the pool’s encryption key - the secret from which the at-rest encryption key and the token-signing key are derived. It is minted by the platform, identical for every gateway in the pool, and never displayed to anyone. That is what lets replicas read each other’s sessions, and it is why there is no master secret for you to generate, distribute, or keep in sync.
Every setting is live. Nothing on the pool requires a restart to take effect. The person who changes a setting is a platform administrator in the tenant portal; the person who can restart a container is often someone else.
Environment Variables
These are the only variables the Gateway reads. Each is here because it is needed before the platform can be asked, or because it is a resource of yours the platform should not hold.
| Variable | Required | Purpose |
|---|---|---|
TENANT | Yes | Which Britive tenant to ask - a bare subdomain (acme) or a full URL (https://acme.example.com). The platform API base, the OAuth issuer, and the JWKS endpoint are all derived from it. |
GATEWAY_POOL_TOKEN | Yes | Authenticates the Gateway to the platform and identifies which pool this container belongs to, which is what decides the settings it runs with. |
DATABASE_URL | Yes | Your own Postgres, with your own credentials. Deliberately not held on the pool record, so database credentials stay on your side. |
PORT | No | Port to bind inside the container. Defaults to 8080. A listening socket cannot change on a running process, so this is the orchestrator’s business rather than the platform’s. |
LOG_LEVEL | No | Logging level during startup, before settings arrive. The pool’s Log level takes over once they do. |
GATEWAY_EXTRA_CA_FILE | No | Path to an additional CA certificate to trust, for backends behind an internal CA. Appended to the public roots rather than replacing them. |
There is no variable for the platform URL. TENANT accepts a full https:// URL,
and everything - API base, OAuth issuer, JWKS - follows from it. Point TENANT at
the URL rather than looking for a second place to say the same thing.
Where to Change a Setting
In the Britive tenant portal, open the gateway pool and choose Settings. The form is grouped, and the groups are the same ones used throughout this documentation:
| Group | What it holds |
|---|---|
| General | The public base URL, log level, and the shape of the tool catalogue. |
| Client Access | Which clients may connect and how they identify themselves. |
| Sessions & Tokens | How long a signed-in client stays signed in. |
| Backend Policy | Where the Gateway is willing to send a user’s credentials. |
| Inspection | Detectors, mode, and the URL blocklist. |
| Audit | What is recorded, how long it is kept, and what reaches your tenant. |
| Integrations | The SIEM webhook and Prometheus metrics. |
| Rate Limits | Ceilings sized to stop a runaway agent. |
| Advanced | Cache lifetimes and timeouts. Collapsed by default; each has a sensible default. |
Every field is listed in the Settings reference, with its default, the values it accepts, and what it is for.
Only settings an administrator has actually changed are stored on the pool. Everything else resolves to the platform default, so the settings you see are a short list of deliberate decisions rather than a full copy of the schema.
What to Set First
Almost everything has a default worth keeping. One setting does not:
Public base URL
publicBaseUrl is the address MCP clients actually use to reach the Gateway. The
OAuth issuer, the redirect URI, and the protected-resource URLs are all built from
it, so it has to match how clients connect - which behind a load balancer or TLS
edge is the edge’s address, not the container’s port.
Left empty, a gateway falls back to http://localhost:<port> and logs a warning.
Nothing fails at startup, which is exactly the problem: the deployment comes up
advertising a localhost address that no other machine can complete a sign-in
against, and the failure surfaces later as clients that cannot finish an OAuth flow.
Treat that warning as a defect anywhere but local development.
Beyond that, the settings most deployments review are:
- Audit → Retention and Audit → Send events to Britive, to match your retention and reporting requirements. See Audit & SIEM.
- Inspection → Mode, which starts in
auditso you can see what enforcement would have done before it does it. See Payload Inspection. - Backend Policy, if your backends are all public SaaS - turning off private networks then closes a route nothing legitimate uses.
- Integrations → SIEM webhook, to stream events to your own pipeline.
Checking What a Container Is Running
The Gateway’s own admin console has a read-only Settings tab showing every setting in effect, where each value came from, and which values differ from their default. It is read-only on purpose: the platform is the single writer, and an editable second copy would immediately raise the question of which one wins.
Two states are worth knowing how to spot there:
| What the console shows | What it means |
|---|---|
| A staleness notice on the Settings tab | The last re-fetch failed. The settings on screen are still in effect, but may no longer match the portal. |
| A value marked as changed from default | Someone set it deliberately. Useful when comparing two pools, or explaining behaviour that differs from the documentation. |
The console shows setting names in snake_case (public_base_url) because that is
how the Gateway holds them internally; the portal and this documentation use the
API’s camelCase (publicBaseUrl). They are the same setting.
When the Platform Cannot Be Reached
| When | Behaviour |
|---|---|
| At startup | Fatal. The container exits non-zero with the reason. Every catalogue, checkout, and policy decision is a platform call, so a gateway that cannot reach the tenant cannot serve anything - and one that started on guessed settings would look healthy while being configured by accident. |
| On a later re-fetch | Survivable. The settings already in effect stay in effect and the failure is recorded. A transient outage must not reconfigure a working gateway. |
A startup failure names the two causes that produce the same HTTP status, because
the status code does not tell them apart: a tenant whose platform predates gateway
pool settings, or a pool token that is not current and active. Run
make doctor to find out which.