This feature is currently in public preview and is not recommended for production use.
Header injection
api.stripe.com normally - the proxy intercepts the request, injects the Authorization and Stripe-Version headers with the resolved secret, and forwards it. The sandbox never sees the raw API key.
Body injection (POST requests)
Multiple routing rules
Global catch-all rule
["*"] destination matches all proxied traffic.
Proxy bypass
Domains listed inbypass skip the proxy tunnel entirely (direct connection):
Secret interpolation
Secrets are referenced in headers and body values using the{{SECRET:name}} syntax:
- Multiple
{{SECRET:...}}placeholders can appear in a single value - Secrets are resolved server-side by the proxy — the sandbox runtime never sees raw secret values
- Secrets are write-only: the
secretsfield is stripped from API responses - Secrets are scoped per routing rule: a secret defined on route A cannot be resolved by route B
- User code inside the sandbox can also send
{{SECRET:name}}in its own request headers or body — the proxy will resolve them if the secret exists on the matching route
Dynamic value injection
Alongside secrets, you can inject values that are generated fresh for every request using the{{FUNC:name(args)}} syntax. Use them for idempotency keys, request IDs, timestamps, nonces, and other one-time values.
X-Request-Id. Function names are case-insensitive, and each occurrence is evaluated independently, so {{FUNC:uuid()}}-{{FUNC:uuid()}} produces two different UUIDs.
Available functions
Random functions use a cryptographically secure random source.
randstr draws uniformly from [a-zA-Z0-9].
Where dynamic values apply
{{FUNC:*}} expansion runs only in the header and body values you define on a routing rule. It never runs on data that code inside the sandbox sends. Request headers and body content your code sends are resolved for {{SECRET:name}} only; any {{FUNC:*}} text your code sends is passed through unchanged.
Within a single value, functions are expanded before secrets are substituted. A secret whose value happens to contain
{{...}} syntax is inserted verbatim and never re-interpreted as a placeholder.
Functions expand only in the values you configure on a routing rule, never in data your sandbox code sends. This keeps a caller from packing a request with many expensive placeholders to force disproportionate work.
Reading generated values from the response
Because generated values are produced inside the proxy, each injected header or body field that used a function is echoed back on the response as its own header, keyed by the injection target:{{FUNC:uuid()}} into the X-Request-Id header adds the following response header:
name=value tokens, in generation order. Only function values are echoed. Resolved {{SECRET:*}} values are never returned to your code. A value is echoed only when its injection resolves cleanly: if a value combines a function with a secret that fails to resolve, the whole injection is skipped and nothing is echoed for it.
Fail-safe behavior and limits
Anything the proxy cannot resolve is left as literal text rather than blanked out or failing the request:- Unknown function, for example
{{FUNC:notafunction()}} - Malformed placeholder with missing parentheses, for example
{{FUNC:uuid}} - Invalid argument, for example
{{FUNC:randhex(abc)}}or{{FUNC:randint(0)}} - Over the size cap, for example
{{FUNC:randstr(5000)}} - Beyond the per-request budget
- Per-function output:
randstrandrandhexcap their length argument at 1024 characters - Per-request count: at most 10 functions are expanded per request, counted across all header and body values combined. Any beyond the limit are left as literal text
