Exposure model
Nothing in Conduit requires public reachability. It needs to be reachable by exactly three parties — its users’ browsers, their AI clients, and (if used) the identity provider pushing SCIM changes — so a deployment on a private network or behind a VPN is fully supported, and for an internal tool it is the right default. Identity-provider sign-in works from a private network too: the OIDC flow is browser redirects, so only the user’s browser needs to reach the provider. Where Conduit is exposed further, put it behind your normal edge — the TLS-terminating load balancer you already run, with a WAF if your policy calls for one. Conduit requires HTTPS in any case, and when a proxy fronts it, setCONDUIT_TRUSTED_PROXIES so audit records and per-IP limits attribute
requests to real clients rather than the proxy — see
client IP attribution.
What Conduit rate-limits itself
Every surface where an unauthenticated caller could guess, flood, or probe is throttled per client IP, with no configuration:- Sign-in and the identity-provider redirect routes. Password failures are counted per account and per IP; on the PostgreSQL tier those counters are shared across replicas, while successful sign-ins do not write a counter.
- Every OAuth endpoint — registration, authorize, consent, token, and the device-approval flow.
- Failed MCP authentication and failed SCIM authentication — requests presenting invalid bearers. Valid traffic is unaffected; a guesser is slowed to a crawl. On the PostgreSQL tier these two counters are shared across replicas, so running N replicas does not multiply the rate a credential-guesser gets.
- CSP violation reports and the CLI download routes.
rate_limited
reason in the auth-failure metrics.
Conduit does not impose sustained throughput quotas on authenticated tool
calls — a burst of legitimate agent traffic is business, not abuse, and
distinguishing the two is a policy decision. If your deployment needs
volumetric caps (requests per second per source, geo rules), enforce them at
the edge in front; every call is still individually authorized, audited, and
measured inside.
Request and response size limits
Nothing reads an unbounded body, in either direction:- Requests on pre-authentication surfaces are capped at 1 MiB.
- Requests on authenticated surfaces — the MCP endpoint, the API, SCIM — are capped at 10 MiB.
- Responses from upstreams (connectors, identity providers) are capped when read.
Session and token handling
- Browser sessions live in an
HttpOnly,Secure, host-only cookie on HTTPS deployments; no session token ever appears in a response body where script, HAR captures, or proxy logs would see it. Existing sessions using the legacy cookie name are migrated on their next authenticated response. - Every bearer credential — sessions, MCP access tokens, refresh tokens, authorization codes, SCIM tokens — is a 256-bit random value stored only as a one-way hash. MCP tokens are additionally audience-bound; the full token model is on How MCP Authorization Works.
- Stored secrets (connector credentials, client secrets, provider keys) are encrypted at rest with a key you control, and are write-only in the API — see where credentials live.
Browser-facing hardening
Every response carriesX-Content-Type-Options: nosniff,
X-Frame-Options: DENY, and X-Robots-Tag: noindex (an instance is a private
gateway; robots.txt disallows crawling too), plus a Content-Security-Policy
pinned to the application’s own assets — external origins are enumerated per
directive, with images the one deliberate exception since connector icons are
admin-chosen URLs. CONDUIT_CSP selects delivery: enforce (the default),
report-only, or off; the frame denial remains active in every mode. In both
active CSP modes, browsers POST violations to a rate-limited report endpoint,
and each report is logged and emitted as a telemetry event so regressions stay
observable. Reports that say nothing about the deployment are dropped rather
than recorded: content a browser extension injected into the page (which no
policy can govern), and reports naming a page outside CONDUIT_BASE_URL, which
the endpoint being unauthenticated otherwise lets anyone submit.
Cookie-authenticated Connect GET requests require the exact Conduit origin;
sibling subdomains and merely CORS-allowed origins are not trusted.
When CONDUIT_BASE_URL uses https://, Conduit also sends
Strict-Transport-Security: max-age=31536000. The policy is host-only: Conduit
does not opt unrelated subdomains into HSTS and does not request browser preload.
No HSTS header is sent for a plain-HTTP development URL.