Skip to main content
The bridge is a long-running agent, not a sync connector. It dials out from your environment to C1 and relays incoming connections from C1 to one or more local TCP backends. Use it when a self-hosted service needs to be reachable from C1 without opening inbound firewall rules or publishing the service to the public internet.Bridges are configured in C1 under Settings > Bridges.

Capabilities

The bridge authenticates to C1 via OAuth 2.0 Client Credentials with private_key_jwt. It periodically refreshes the bearer token and pushes the new token into the tunnel’s keepalive metadata so the C1 relay re-authenticates on every ping. Services advertised by the bridge appear on the bridge’s detail page in the C1 UI once the agent connects.

Create a bridge in C1

To complete this task, you’ll need the Connector Administrator or Super Administrator role in C1 (specifically the IamV1TunnelCredentialsServiceCreateBridge and IamV1TunnelCredentialsServiceCreateBridgeCredential capabilities — the first creates the bridge, the second issues its credentials).
1
In C1, navigate to Platform > Bridges.
2
Click Create bridge.
3
Enter a Display name for the bridge (required, 512 characters or fewer). For example, prod-vpc-east or finance-appliance. Optionally add a Description (up to 4096 characters) explaining what the bridge connects to.
4
Click Create bridge. The browser navigates to the bridge’s detail page.
5
On the bridge detail page, find the Credentials card and click Create credential. (On a bridge that already has an active credential, this button is labeled Rotate credential instead.)
6
A Credential created dialog opens with the Client ID and Client secret. Copy and save the client secret immediately — it is only visible once. Click Done to close the dialog.These credentials are what the bridge agent uses to authenticate back to C1. You’ll paste them into the agent’s configuration in the next section.
That’s it! Next, deploy the bridge agent.

Deploy the bridge agent

The bridge agent (bridge-client) is a self-hosted, long-running process. Run it inside the network where your local backend services live. The image bakes no configuration — the YAML (or C1_BRIDGE_* env vars) is supplied at runtime.
To complete this task, you’ll need:
  • The Client ID and Client secret generated above
  • A host inside the network where the local backend services run (Kubernetes cluster, VM, or container host)

Resources

Follow these instructions to run the bridge as a Deployment on Kubernetes.When running on Kubernetes, the bridge maintains an ongoing connection with C1. The YAML is supplied at runtime via a Secret volume (use a Secret rather than a ConfigMap so the client secret stays encrypted at rest).

Step 1: Create the Secret

Each entry under ports: accepts the following fields:service_type, service_path, and transport_type are descriptive metadata: C1 records them and uses them to identify and classify the service you advertise — for example, to recognize an MCP server and its endpoint when you connect it in C1. Set them to match the service you’re exposing.api_host is derived automatically from client_id and does not need to be set; specify it only for a non-standard C1 host or port.

Step 2: Create the Deployment

The bridge also supports env-only mode: skip the Secret volume mount and set the same fields via C1_BRIDGE_* env vars on the container instead. See the Environment variables section below for the full list.

Step 3: Deploy

1
Apply both manifests:
2
Back in C1, refresh the bridge’s detail page under Settings > Bridges. The bridge’s status changes to Connected within a few seconds of the pod starting, and any services it advertises appear in the Services section.You can also tail the bridge’s logs locally:
That’s it! Your bridge is now relaying traffic between C1 and your local services.

Environment variables

The fields most commonly varied per deployment can be supplied via C1_BRIDGE_* environment variables instead of (or alongside) a YAML config. Env values take precedence over their YAML counterparts; empty env values are ignored (they do not zero out a non-empty YAML field). Two forms are supported: scalar vars carry the value directly, and locator vars carry a "<secret-id>:<key>" string that the configured secret_backend resolves at startup.

Scalar overrides

Secret-locator overrides

For each scalar above, a sibling C1_BRIDGE_SECRET_<FIELD> env var accepts a "<secret-id>:<key>" locator instead of a literal value. At startup the bridge fetches the value from the configured secret_backend and writes it into the corresponding field — the same shape as the YAML secrets: map but from the environment. Setting both the scalar AND the locator for the same field is an error. ca_pem has no scalar form (C1_BRIDGE_CA_PEM doesn’t exist) — multi-line PEM data doesn’t round-trip cleanly through shell envs, so it lives in YAML or comes from a secret backend.

Single-service env mode

For deployments that don’t want to ship a YAML config at all, a single service mapping can be defined entirely in the environment. When both C1_BRIDGE_SERVICE_LISTEN_PORT and C1_BRIDGE_SERVICE_BACKEND are set, a single port is constructed from the C1_BRIDGE_SERVICE_* vars and replaces any ports: block loaded from YAML. Setting only one of the required pair (LISTEN_PORT without BACKEND, or vice versa) is an error — almost always a typo. With both unset, the service env vars are ignored entirely and YAML’s ports: block is used as-is.

Log verbosity

bridge-client logs JSON to stdout at info by default. Raise or lower it with the --log-level flag or the C1_BRIDGE_LOG_LEVEL env var (debug, info, warn, or error); the env var takes precedence if both are set. debug adds per-connection detail that helps when a backend is reachable but calls fail. Each backend connection also logs its outcome, and a backend that accepts the connection but returns nothing before closing is flagged at warn.

Resolve sensitive fields from HashiCorp Vault

The bridge can pull values for sensitive fields (most commonly client_secret, ca_pem, ca_path) from a HashiCorp Vault backend instead of carrying them as YAML literals. Configure a secret_backend: block with type: vault and a secrets: map that names the field-to-locator mappings; the bridge fetches each value at startup and writes it into the corresponding bridge: field before validation. Vault auth: exactly one of token, credsfile, or userpass in YAML. Setting VAULT_TOKEN in the environment overrides whichever auth source the YAML specifies. The standard VAULT_* env vars (VAULT_ADDR, VAULT_CACERT, and the others) are still honored when secret_backend.vault.url is empty.
Supported fields in the secrets: map: client_id, client_secret, api_host, ca_path, ca_pem. Each entry has an environment-variable equivalent (C1_BRIDGE_SECRET_<FIELD>) so the same locator can be supplied without editing the YAML. Setting a field both as a YAML literal under bridge: AND in secrets: (or its env equivalent) is an error — pick one source per field.

Manage credentials

To rotate or revoke a bridge’s credentials later:
1
In C1, navigate to Platform > Bridges and click the bridge.
2
On the bridge’s detail page, find the Credentials card.
  • Rotate credential issues a new Client ID and Client secret. The new credential dialog opens with the freshly-generated values — copy the secret immediately, since it is only visible once. Update the agent’s configuration with the new values; old credentials continue to work until you revoke them.
  • Revoke credential invalidates a credential immediately. Any bridge agent still using that credential will be disconnected.

MCP servers: tool-call access

When the bridge fronts an MCP server, you register that server in C1 separately — selecting this bridge and its advertised service — so C1 can discover and govern its tools. C1 records each tool’s name, description, and input schema exactly as your server advertises them and surfaces that text to AI clients during discovery, so clear tool descriptions and schemas on your server determine how reliably an agent finds and calls them. Reaching those tools through C1 then has one more requirement beyond connectivity: the requesting user must be an app user of the app the server is registered under, and must hold a grant for the tool. New external apps start with no app users, so a call from an identity that isn’t an app user opens an access request instead of executing. App users come from the destination app’s account sources. Populate them by linking an entitlement from another app (during registration, or via linked entitlements later in the app’s settings), by importing a CSV of app users, or — if the app is backed by a connector — by syncing them from the connector.