Skip to main content
The Ephemeral Proxy is a single endpoint — ANY /v1/proxy — that accepts any HTTP method and forwards the request to the URL you supply in the X-Knox-Proxy-URL header. References of the form {{ token: ... }} in the body or query string are resolved against your tenant’s vaults before the request reaches the upstream. For a conceptual overview see the Ephemeral Proxy guide.
Unlike the Routes endpoints — which manage proxy configuration — this endpoint executes a one-shot proxy call. There is no id to look up, no row to list, and no environment overrides.

Invoke

Forwards the request to the URL in X-Knox-Proxy-URL. Body and query-string {{ token: ... }} references are resolved against your tenant’s vaults before the upstream call is made. The upstream response is streamed back unchanged.

Request Headers

All other headers you send are forwarded to the upstream except for hop-by-hop headers (Connection, Keep-Alive, TE, Trailers, Transfer-Encoding, Upgrade, Proxy-Authorization, Proxy-Authenticate), the Authorization and Host headers, and any header beginning with X-Knox-.

Request Body

Optional. Sent to the upstream after token substitution. The body is scanned recursively for two template forms: Anything else shaped like {{ ... }} is rejected with 400 template_error rather than forwarded to the upstream. See Templates. Maximum 20 distinct token references per request.

Response

The upstream’s response is streamed back unchanged: same status code, same headers (minus hop-by-hop and Content-Length), same body bytes. KnoxCall adds two correlation headers:

Errors


Templates

{{ token: <token-id> }}

Substituted with the raw value of the matching vault token. Tokens are tenant-globally unique — you do not need to specify the vault.
If the token doesn’t exist in any of your tenant’s vaults, the request fails with 400 token_not_found. If the token exists but you lack vault:detokenize permission for the vault that owns it, the request fails with 403 (PolicyDenied).

{{ encrypted | json: $.path }}

Reads a value from the decoded X-Knox-Encrypted payload using JSONPath. Useful when you want to keep ad-hoc sensitive values out of your application’s heap.
In v1 the payload is opaque base64-encoded JSON; full JWE with per-tenant frontend keypairs is on the roadmap.

\{{ ... }} — sending literal braces

Any {{ ... }} that is not one of the two forms above is rejected with 400 template_error. It is never forwarded. That is deliberate: silently passing an unrendered {{ token: ... }} through would disclose the token identifier to the third-party upstream and deliver a request with a hole where a credential should be. When the braces are meant for the upstream’s own templating, escape the opening delimiter with a backslash. The escape renders a literal {{, and the text after it is never treated as a template — so a single body can carry both:
The upstream receives card_number substituted with the real value, and email_subject as the literal Hi {{ first_name }}, your receipt. Note the doubled backslash: JSON has no \{ escape, so a literal backslash is written \\ in the source. Only the opening {{ is escapable — a bare }} was never a delimiter and always passes through untouched, so nested JSON such as {"a":{"b":{"c":1}}}} is never rewritten. To bypass templating entirely and forward your bytes verbatim, send X-Knox-Proxy-Mode: transparent instead.

Permissions

Each invocation evaluates two permissions: The vault:detokenize check is enforced per token reference, scoped to the vault that owns the token. A denial throws PolicyDenied and the request fails with 403.

Audit

Every invocation writes:
  • An api_requests row with proxy_mode = 'ephemeral', status code, latency, upstream host, source IP, and token count. The body, headers, and resolved token values are never stored.
  • An audit_logs entry tagged ephemeral_proxy.invoke (Audit Logs).
  • A Fleet Graph signal carrying method, upstream host, status code, and latency. The customer’s path is recorded as /proxy — never the raw upstream path.