Outbound callout security

Praxis AI treats an outbound target, its resolved socket addresses, and the credentials attached to the request as one trust decision.
On this page

Praxis AI treats an outbound target, its resolved socket addresses, and the credentials attached to the request as one trust decision. Operator-configured HTTP targets are public-only by default. Each request resolves its target once, checks every returned address immediately before connecting, and gives those same addresses to the transport. A single private, loopback, link-local, or otherwise non-public result rejects the whole callout.

Private targets require a filter-specific, explicit opt-in. HTTP proxies and redirect following are disabled for direct callouts. URL userinfo is rejected, and forwarded or configured credentials remain bound to the validated target origin.

Callout inventory

No-follow means a redirect response is returned to the caller and its Location is never requested.

CalloutTarget sourcePrivate opt-inRedirect policyAuthentication mode
openai_web_search, anthropic_web_searchProvider default or configured base_url, executed through the outbound_chain filtered-subrequest executorinsecure_options.allow_private_upstreams (executor-gated on the bound outbound chain)No-followConfigured provider API key; validated origin only
openai_file_resolve Files APIConfigured files_api_url via outbound_chainallow_private_upstreamsNo-followHeaders named by forward_headers plus outbound_chain mutations
openai_file_resolve file_url fetchRequest-derived URLExact allowed_file_url_originsNo-followAnonymous; no downstream headers
openai_file_search_calloutConfigured vector_store_urlallow_private_urlNo-followOnly headers named by forward_headers
openai_responses_compactConfigured inference_urlallow_private_inference_urlNo-followAnonymous; no downstream or cluster headers
ai_guardrails with NeMoConfigured endpointGlobal allow_private_upstreamsNo-followConfigured outbound_chain; no downstream headers by default
http_calloutConfigured target.urlallow_private_addressesNo-followConfigured static headers plus allowed forward_headers
MCP clientRequest-derived server URL or configured connectorallow_loopback for loopback onlyNo-followSanitized request-provided MCP authorization/headers
azure_ad token fetchConfigured authority plus tenantallow_private_authorityNo-followClient secret in the token POST body
gcp_adc metadata fetchProtocol-owned metadata endpointIntrinsic to metadata modeNo-followMetadata-Flavor protocol header; returned token is not forwarded back to metadata

The request-derived file_url and MCP transports retain stricter policies: they pin one validated resolution set, do not follow redirects, and allow private access only through their narrow origin/loopback controls. GCP metadata also uses pinned resolution, no redirects, and no ambient proxy, but intentionally allows its protocol-owned private destination.

Upstream cluster connections are not direct callouts. They use the core Praxis endpoint and TLS policy instead of these filter-level controls.

Adding a callout

A new filter that opens an outbound HTTP connection must:

  1. Classify the target as operator-configured, request-derived, or protocol-owned.
  2. Reuse the shared target/address policy, or document why a stricter dedicated policy is required.
  3. Default to public addresses and expose a narrowly named private-address opt-in only when the use case requires it.
  4. Resolve once per connection attempt, reject the complete result set if any address violates policy, and connect only to that validated set.
  5. Disable ambient proxies and redirects unless their security behavior is explicitly designed and tested.
  6. Reject URL userinfo and bind every credential or forwarded header to the validated origin.
  7. Document the authentication mode and cover loopback/private/link-local, mixed DNS answers, redirects, userinfo, and credential non-disclosure in tests.