Documentation Index
Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
Use this file to discover all available pages before exploring further.
Ephemeral Proxy
The Ephemeral Proxy is a one-shot HTTPS proxy. Unlike Routes, there is no pre-configured row — every call is its own invocation. You pass the upstream URL in a header, KnoxCall validates it, swaps any {{ token: ... }} references for the underlying vault values, and forwards the request.
The composition with Vaults is the killer feature: store the token in your database, send the token to KnoxCall, KnoxCall sends the raw value to the upstream. Your systems never hold the raw card number, SSN, or API secret.
When to use it
Use Ephemeral Proxy when:
- The destination URL is dynamic — chosen per-request, not per-route.
- You want to detokenize vault tokens last-mile (PCI-scope reduction, PII handling).
- You need a quick passthrough without configuring a Route, ApiKey scope, environment overrides, etc.
Use Routes when:
- You call the same upstream repeatedly and want signing, rate limits, env overrides, and full per-request observability.
- You need IP allowlisting, mTLS, or method-specific configuration.
- You want logs grouped by route in the dashboard.
How a request flows
Your client → POST https://api.knoxcall.com/v1/proxy
X-Knox-Proxy-URL: https://api.stripe.com/v1/charges
Authorization: Bearer tk_live_...
Content-Type: application/json
{ "amount": 5000,
"currency": "usd",
"source": "{{ token: tok_01H... }}" }
KnoxCall:
1. Authenticates your API key
2. Checks `proxy:invoke` permission + your plan limit
3. Validates the upstream URL (https only, DNS hostname, SSRF-safe)
4. Scans body + query for {{ token: ... }} references
5. Looks up each token in your vaults, gates per-vault detokenize
6. Renders the body with raw values substituted in
7. Sends the rewritten request to the upstream
8. Streams the response back to you, audit-logged
Stripe sees: { "amount": 5000, "currency": "usd",
"source": "tok_visa_real_card_token" }
You see: Stripe's response, passed through unchanged.
The token strings, raw values, and bodies are never logged. Only metadata (upstream host, status code, latency, token count) lands in the audit chain and the Fleet Graph.
Quick example
curl -X POST https://api.knoxcall.com/v1/proxy \
-H "Authorization: Bearer tk_live_abc123..." \
-H "X-Knox-Proxy-URL: https://api.stripe.com/v1/charges" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "usd",
"source": "{{ token: tok_01HZX... }}"
}'
The tok_01HZX... came from a prior POST /v1/vaults/.../tokenize call — see the Vaults overview.
Template syntax
Two reference forms are supported in the JSON body and query string:
| Form | What it does |
|---|
{{ token: tok_xxx }} | Looks up the token in your tenant’s vaults and substitutes the raw value. |
{{ encrypted | json: $.path }} | Reads a value from the optional X-Knox-Encrypted header payload (base64-encoded JSON in v1) using JSONPath. |
Templates are scanned in body and query only. Headers pass through unchanged in v1 — header-injection is a separate hardening pass.
If a token isn’t found, KnoxCall returns 400 token_not_found rather than silently sending an empty value to the upstream.
Required and optional headers
| Header | Required | Purpose |
|---|
Authorization: Bearer <api-key> | Yes | Standard KnoxCall API auth. |
X-Knox-Proxy-URL | Yes | The upstream URL. Must be https://, must be a DNS hostname (no IP literals), must pass SSRF checks. |
Content-Type | Recommended | Defaults to application/json if omitted. |
X-Knox-Encrypted | No | Base64-encoded JSON payload addressable via {{ encrypted | json: ... }}. v1 is opaque base64-JSON; full JWE support is on the roadmap. |
X-Knox-Timeout-Ms | No | Per-request upstream timeout (positive integer ≤ 30000). |
Reserved headers (Authorization, Host, Content-Length, anything starting with X-Knox-) are stripped before the request reaches the upstream. Every other header you send is forwarded unchanged.
What you get back
KnoxCall passes the upstream response through verbatim — same status code, same headers (minus hop-by-hop), same body bytes. KnoxCall adds two headers so you can correlate:
| Response header | Meaning |
|---|
X-Knox-Request-Id | The KnoxCall request ID for audit-log lookup. |
X-Knox-Destination-Status | The upstream’s status code (echoed; useful when proxies/CDNs mangle the surfaced status). |
If the upstream is unreachable, KnoxCall returns 502 upstream_error.
Limits and gates
| Gate | Behaviour |
|---|
| Plan | Requires the Starter plan or above. 402 plan_limit if disabled. |
| Permission | proxy:invoke on resource type ephemeral_proxy. Per-vault vault:detokenize is also evaluated for each referenced token. |
| Tokens per request | Maximum 20 {{ token: ... }} references per request. 400 validation_error past the cap. |
| Upstream URL | HTTPS only, DNS hostname only (no IP literals), private/loopback ranges blocked, dangerous metadata endpoints blocked. |
| Timeout | Default 25s, max 30s. |
Audit and observability
Every invocation writes:
- An
api_requests row with proxy_mode = 'ephemeral', status code, latency, upstream host, token count, and source IP. The body, headers, and token values are not stored.
- An
audit_log entry tagged ephemeral_proxy.invoke.
- A Fleet Graph signal carrying
(method, upstream_host, status_code, latency_ms) — never the body, never the token strings, never the customer’s path.
You can query the audit chain via GET /v1/audit-logs?action=ephemeral_proxy.invoke (Audit Logs).
Comparison: Routes vs Ephemeral Proxy
| Routes | Ephemeral Proxy |
|---|
| Lifecycle | Persistent row, configured once, called many times. | One-shot — no row, no config. |
| Upstream URL | Set per route, can be overridden per environment. | Set per request via X-Knox-Proxy-URL. |
| Discovery in dashboard | Listed under Routes, full per-route metrics. | Not listed — discoverable via audit logs and Fleet Graph. |
| Best for | Repeat traffic to a known partner API. | Tokenization passthrough, dynamic destinations, lightweight use cases. |
| Headers, signing, IP allowlist, mTLS | All configurable. | Headers passthrough only; SSRF + plan gating only. |
| Token resolution | Configured per-route via injection rules. | Inline {{ token: ... }} syntax in request body / query. |
Next steps