ZuploZuplo
LoginStart for Free
  • Documentation
  • API Reference
Getting Started
    Develop in the portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
    Develop locally with the CLI
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
Concepts
API Management
AI Gateway
    OverviewGetting StartedSource ControlUniversal API
    Providers
    Teams
    Apps
    Policies
      Overview
      Authentication
      Model Routing
      Usage & Cost
      Caching
      Security & Validation
      Observability
      Configuration
      Other
        Ensure Gateway Internal Invocation OnlyPrompt Injection Protection
    Cookbooks
    Integrations
MCP Gateway
MCP Server
Developer Portal
Development
Deploying & Source Control
Analytics
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsVersion Support PolicySecuritySupportTrust & ComplianceChangelog
powered by Zuplo
Other

Ensure Gateway Internal Invocation Only Policy

AI Gateway Policy

This policy is for use with the AI Gateway. See the AI Gateway documentation to learn how to configure and govern AI models with Zuplo.

The Ensure Gateway Internal Invocation Only policy admits a request only when this gateway made it with context.invokeRoute, and answers every request that arrived over the network with 403 Forbidden.

Add it to an application's inboundPolicyChain in place of AI Gateway Authentication when the application is only ever called by other routes and policies on the same gateway, such as the classifier application behind the Smart Router or Prompt Injection Protection policies. Those calls never leave the gateway, so an API key on them protects nothing; this policy checks the one thing that matters. It has no options, makes no network calls, and never reads the request body.

Configuration

The configuration shows how to configure the policy in the 'policies.json' document.

Code
{ "name": "my-ai-gateway-internal-only-inbound-policy", "policyType": "ai-gateway-internal-only-inbound", "handler": { "export": "AIGatewayInternalOnlyInboundPolicy", "module": "$import(@zuplo/runtime)", "options": {} } }

Policy Configuration

  • name <string> - The name of your policy instance. This is used as a reference in your routes.
  • policyType <string> - The identifier of the policy. This is used by the Zuplo UI. Value should be ai-gateway-internal-only-inbound.
  • handler.export <string> - The name of the exported type. Value should be AIGatewayInternalOnlyInboundPolicy.
  • handler.module <string> - The module containing the policy. Value should be $import(@zuplo/runtime).
  • handler.options <object> - The options for this policy. See Policy Options below.

Policy Options

The options for this policy are specified below. All properties are optional unless specifically marked as required.

Using the Policy

How it works

context.invokeRoute runs a route on this gateway without leaving the process, and the runtime marks the request it creates by setting context.parentContext to the calling request's context. Nothing else sets that property. A request that arrives over the network never has one, whatever headers, URL, or body it carries. This policy passes a request when context.parentContext is present and rejects it otherwise.

Request originResult
Any HTTP client, with or without an API key403
context.invokeRoute from a policy, handler, or custom module on this gatewayPasses
The MCP server handler calling the route as a toolPasses
An internal application calling another internal applicationPasses

The rejection is a 403 Forbidden problem response. On AWS Bedrock Runtime routes it uses the AWS error envelope (AccessDeniedException) so the AWS SDKs surface the message.

The policy does not authenticate the caller and does not set request.user. Metering records the request against the application with no consumer, and a budget rule keyed on request.user has no value to accumulate for these requests. Attach per-consumer budgets to the calling application instead.

Add the policy

Declare the policy in config/policies.json:

Code
{ "policies": [ { "name": "ai-gateway-internal-only-inbound", "policyType": "ai-gateway-internal-only", "handler": { "export": "AIGatewayInternalOnlyInboundPolicy", "module": "$import(@zuplo/runtime)", "options": {} } } ] }

Then select it in the application's inboundPolicyChain in place of ai-gateway-auth-v2-inbound. Put it first so nothing else runs for a rejected request:

Code
{ "inboundPolicyChain": [ { "name": "ai-gateway-internal-only-inbound" }, { "name": "ai-gateway-model-filtering-v2-inbound" }, { "name": "ai-gateway-metering-v2-inbound" } ] }

The policy also works as a route-level inbound policy on any route that should be reachable only through context.invokeRoute.

Call the application

Call the application from a policy or handler on the same gateway. No Authorization header is needed:

Code
const response = await context.invokeRoute( `/${classifierAppId}/v1/chat/completions`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ model: "openai/gpt-5-mini", messages }), }, );

The Smart Router and Prompt Injection Protection policies already call their classifier applications this way.

A direct call from outside the gateway is rejected:

TerminalCode
curl https://gateway.example.com/my-classifier-app/v1/chat/completions \ --header "Content-Type: application/json" \ --data '{ "model": "openai/gpt-5-mini", "messages": [{ "role": "user", "content": "Hello" }] }'

The response is 403 Forbidden, and its detail explains that the application only accepts requests made from inside the gateway with context.invokeRoute.

What it does not check

This policy asserts that a request originated inside this gateway deployment, not that the caller is trusted. Any route on the same gateway that forwards requests through context.invokeRoute, including an MCP server that exposes the application as a tool, reaches the application. Protect such routes with their own authentication, exactly as you would an internal URL.

Read more about how policies work

Edit this page
Last modified on September 22, 2026
Configuration ExecutorPrompt Injection Protection
On this page
  • Configuration
    • Policy Configuration
    • Policy Options
  • Using the Policy
  • How it works
  • Add the policy
  • Call the application
  • What it does not check
JSON
JSON
JSON
TypeScript