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
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 beai-gateway-internal-only-inbound.handler.export<string>- The name of the exported type. Value should beAIGatewayInternalOnlyInboundPolicy.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 origin | Result |
|---|---|
| Any HTTP client, with or without an API key | 403 |
context.invokeRoute from a policy, handler, or custom module on this gateway | Passes |
| The MCP server handler calling the route as a tool | Passes |
| An internal application calling another internal application | Passes |
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
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
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
The Smart Router and Prompt Injection Protection policies already call their classifier applications this way.
A direct call from outside the gateway is rejected:
Code
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