> For the complete documentation index, see [llms.txt](https://docs.p0.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.p0.dev/agentic-access/agentic-gateway/gateway.md).

# Gateway

What registering a P0 AI Gateway with P0 establishes, and how to register a gateway you deployed yourself.

The **Gateway** component registers a deployed AI gateway, part of [P0 Runtime Access for AI](/readme/agentic-control-plane.md), with P0. Once registered, P0 recognizes the gateway's identity, pushes it the definitions of the [MCP server](/agentic-access/agentic-gateway/mcp-server.md) it should host, and enforces policy at runtime. You register one Gateway component per gateway deployment.

Registration normally happens as part of deployment: the console installer walks you through both in a single pass. For the steps, see [Deploying the gateway](/agentic-access/agentic-gateway/gateway/deploy.md). This page covers what that registration establishes, and how to register a gateway you deployed some other way.

## What registration establishes

**A gateway identity.** P0 assigns each gateway its own service account when you begin the install. P0 calls your gateway's management API as that account, and the gateway accepts those calls only if the account is listed in its `accessProxy.manageAllowedEmails` value. The console installer resolves this for you: the Terraform it generates already carries the assigned address, so the gateway trusts P0 from its first boot.

### An outbound management tunnel

Every gateway deployment runs a websocket tunnel, which dials out to P0. Finishing the install has P0 confirm it can reach the gateway over the tunnel. Every management call for this gateway goes through the tunnel — this is what lets a gateway with no public DNS record or TLS certificate be managed by P0. See [Install from the P0 console](/agentic-access/agentic-gateway/gateway/deploy/install-from-the-p0-console.md#provide-the-management-tunnel-public-key).

**A token issuer.** P0 verifies the requests it receives from the gateway against the gateway's Auth server endpoint, which serves `.well-known/jwks.json`. It has to match the issuer your deployed Auth Server actually presents. It defaults to the gateway's own URL, which is correct unless you run the Auth Server on a separate host.

**A configuration sync.** After registration, the gateway asks P0 to sync its configuration, once at startup and then every 45 minutes by default. P0 pushes the [MCP server](/agentic-access/agentic-gateway/mcp-server.md) and [A2A bridge](/agentic-access/agentic-gateway/a2a-bridge.md) configured for this gateway, adding newly configured ones and removing ones no longer configured, through the management tunnel. No servers are available through the gateway until you configure them.

**Optionally, an activity source.** Link a [Log provider](/agentic-access/agentic-gateway/log-provider.md) to the gateway and P0 shows its MCP tool calls and A2A agent calls on the [Event log](/agentic-access/using-the-gateway/event-log.md). Without one, the gateway still ships access logs to the sink you configured at deployment, but P0 doesn't read them back.

## When P0 is unavailable

If the gateway can't reach P0, it fails open for access that already exists and fails closed for anything that needs P0 to change state:

* *Fail-open.* Existing sessions and access continue as provisioned, access leases expire on schedule, and registered clients can create new sessions.
* *Fail-closed.* New client registrations, new access leases, and the kill switch are unavailable until the controller reconnects.

## Register a gateway you deployed yourself

If you deployed with either Helm chart, as in [Deploying the gateway](/agentic-access/agentic-gateway/gateway/deploy.md#deployment-options), rather than through the console installer, the gateway isn't registered yet, and you face an ordering problem: the gateway must already trust P0's service account before P0 can reach it, but P0 assigns that account only during registration. The console never displays the address, so you can't resolve this from the console alone.

Register with the P0 Terraform provider instead, which splits registration into two resources:

1. [`p0_ai_gateway_staged`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/ai_gateway_staged) reserves the gateway and returns the assigned address as `service_account_email`.
2. Set that address as `accessProxy.manageAllowedEmails` in your chart values, and roll out the gateway so it trusts the account.
3. [`p0_ai_gateway`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/ai_gateway) finalizes the install, at which point P0 runs its reachability check using the gateway's outbound management tunnel ([#an-outbound-management-tunnel](#an-outbound-management-tunnel "mention")).

## Troubleshooting

### The install fails with a reachability error

P0 couldn't reach the gateway over its management tunnel. See [#an-outbound-management-tunnel](#an-outbound-management-tunnel "mention"). Confirm the `braekhus-client` pod is running and can connect outbound to your configured tunnel host and port:

```bash
kubectl -n <namespace> logs deploy/braekhus-client
```

Reconnecting after a lost or regenerated key requires re-pasting the public key in the console; there's no automatic fallback to a direct connection.

### The gateway registers, but no servers appear

Registration alone exposes nothing. Configure the MCP servers this gateway should front, as in [MCP server](/agentic-access/agentic-gateway/mcp-server.md). Then wait for the next sync or restart the gateway to pull them immediately.

### Sign-in fails with a redirect URI mismatch

Google shows `Error 400: redirect_uri_mismatch` instead of your gateway's sign-in page. The OIDC client entered as the upstream OIDC client ID in [Install from the P0 console](/agentic-access/agentic-gateway/gateway/deploy/install-from-the-p0-console.md) doesn't list the gateway's URL as an authorized redirect URI. Add `https://<gateway-host>` to that client's authorized redirect URIs at your identity provider. On Google, the scheme, case, and trailing slash all have to match, so enter the URL without a trailing slash, exactly as shown. A change can take a few minutes to take effect.

### Long tool calls or agent tasks fail after about 5 minutes

A call that runs for several minutes without returning anything fails partway through, while shorter calls succeed. Envoy, which routes traffic to the gateway, closes a stream that stays idle for 5 minutes by default, and the gateway doesn't send heartbeats to keep MCP and A2A streams active. Raise `streamIdleTimeout` to much larger than your longest expected call, as described in [Deploying the gateway](/agentic-access/agentic-gateway/gateway/deploy.md#stream-timeouts-for-long-running-calls).

### "Authentication failed. Please try again." <a href="#authentication-failed-please-try-again" id="authentication-failed-please-try-again"></a>

Google's sign-in succeeds and the browser returns to your gateway's own domain, but the gateway shows this instead of finishing sign-in. Reaching this page rather than a Google error page means the redirect URI is already correct. Look in the Auth Server's log for the failed token exchange:

```bash
kubectl -n <namespace> logs deploy/agentic-auth-server | grep "OIDC token exchange"
```

The line ends with the status and the code your provider returned, like `HTTP 401 (invalid_client)`. A code rejecting the client, which Google calls `invalid_client`, means `OIDC_CLIENT_SECRET` is still the placeholder, or was patched without restarting `agentic-auth-server`. Confirm which by reading the secret back:

```bash
kubectl -n <namespace> get secret app-secrets \
  -o jsonpath='{.data.OIDC_CLIENT_SECRET}' | base64 -d
```

If you set the chart's `secretsName` to something other than the default, use that name instead of `app-secrets`. The literal string `placeholder` means it was never set. Google issues client secrets with a `GOCSPX-` prefix, so a value that looks nothing like that is usually the client ID pasted by mistake. The console install instructions in [Install from the P0 console](/agentic-access/agentic-gateway/gateway/deploy/install-from-the-p0-console.md) cover setting the real value and restarting the Auth Server.

## Next steps

* Configure the [MCP server](/agentic-access/agentic-gateway/mcp-server.md) this gateway should front.
* Add a [Log provider](/agentic-access/agentic-gateway/log-provider.md) so P0 can show the gateway's activity.
* [Connect an MCP client](/agentic-access/using-the-gateway/connect-an-mcp-client.md).
