Skip to main content
Everything in the diagram below ships in one container image — there are no sidecars, agents, or required external services. The same image runs as a single container or as N replicas behind a load balancer; see Deployment Tiers for how to move between those shapes.
Conduit architecture: untrusted clients reach Conduit through your TLS edge; inside the container an OAuth 2.1 authorization server, a management API, an MCP gateway, and SCIM provisioning share one storage backend; every outbound request leaves through a hardened HTTP client.Conduit architecture: untrusted clients reach Conduit through your TLS edge; inside the container an OAuth 2.1 authorization server, a management API, an MCP gateway, and SCIM provisioning share one storage backend; every outbound request leaves through a hardened HTTP client.

Clients are untrusted

Three kinds of clients reach Conduit, and none of them is trusted: AI clients speaking MCP, browsers using the web UI, and your directory pushing SCIM changes. Every request is authenticated — there is no ambient trust in a connection. On the MCP path the bearer token is re-validated on every request, the workspace is resolved from the URL path, and the caller’s membership is checked live, so removing someone takes effect immediately rather than when a session expires. The MCP channel runs in both directions: over the same connection, Conduit can send the client a prompt (for example, a link to connect an account) and live tool-list updates when an administrator changes what’s available.

TLS terminates at your edge

Conduit requires HTTPS. Most deployments terminate TLS at a reverse proxy or load balancer in front; a single-box install can use Conduit’s built-in TLS instead. If a proxy fronts your instance, tell Conduit which addresses to trust for client IP attribution. Replicas need no session affinity: a server-to-client prompt’s answer that reaches another instance is handed to the one that asked.

Authorization is checked at every layer

Inside the container, the surfaces enforce their own checks rather than trusting each other:
  • The OAuth 2.1 authorization server issues tokens bound to their audience, so a token minted for an MCP client cannot drive the management API, and a web session cannot be replayed as an MCP bearer. It is the only token issuer: externally issued tokens (your identity provider’s JWTs included) are not accepted at the MCP endpoint — the identity provider authenticates the human during sign-in, and Conduit mints what clients hold. See How MCP Authorization Works.
  • Every management API call is checked against the caller’s role and workspace.
  • The policy engine computes each user’s effective tool set (allow policies ∩ the user’s enabled connectors) and enforces it on every tool listing and every call — a tool hidden from the list cannot be invoked by name. See Access Control.
  • SCIM provisioning writes are capped at workspace-admin authority: a directory credential can never evict a workspace owner or touch an instance administrator. See SCIM provisioning.
Every tool call, sign-in, and admin change lands in the audit log, with OpenTelemetry traces and usage dashboards built in.

One way out

Every HTTP request Conduit makes — tool calls, identity-provider fetches, email via API — leaves through a single hardened client that blocks requests to private and internal addresses, never follows redirects, and requires HTTPS. Network Access lists every host Conduit connects to and how that client is hardened. Upstream calls use Conduit’s own credentials for each connector — the client’s bearer token is never forwarded to an upstream service. Where those credentials come from, and when the upstream sees the calling user’s identity instead of a shared one, is covered in Connectors.

State

State lives in one place: the embedded database on a volume (the default), or your PostgreSQL 14+ when you point CONDUIT_DATABASE_URL at it. Sessions and tokens are stored as one-way hashes, and credentials Conduit must present upstream are encrypted at rest. Restarts are cheap by design — nothing a restart loses is needed to keep sessions or connections alive. When running multiple replicas, they coordinate through the database and a cluster event bus (PostgreSQL NOTIFY) that propagates policy and configuration changes, so a change made on one replica takes effect on all of them within moments.