proxy.toml Reference
Placed in app/proxy.toml to configure API routing for Application Modules. It is never served to end-users.
[[route]]
# Static route
path = "/api/external"
target = "https://api.example.com/v1"
# Forward these headers from the browser
forward_headers = ["Accept"]
# Inject secure headers from the backend
[route.inject_headers]
"Authorization" = "Bearer ${env.API_TOKEN}"
# Graph-driven dynamic routes
[[route]]
origin_resource = "provider"
match_on = [{ property = "type", value = "internal" }]
path = "/api/{{ origin_resource.name }}/*"
target = "{{ origin_resource.api_url }}/"
Variables like ${env.X} use fast regex expansion. Variables like {{ env.X }} use full Tera templating and have access to the request context object (for HMAC signing).
Dynamic Request Signatures:
For APIs that require every request to be cryptographically signed (such as Exoscale’s v2 API)
# app/proxy.toml
[[route]]
path = "/api/exoscale"
target = "https://api-ch-dk-2.exoscale.com/v2"
forward_headers = ["Accept", "User-Agent"]
[route.inject_headers]
"Content-Type" = "application/json"
"Authorization" = """
{%- set expires = request.timestamp + 600 -%}
{%- set msg = request.method ~ " " ~ request.path ~ "\n" ~ request.body ~ "\n" ~ request.query_values ~ "\n\n" ~ expires -%}
{%- set sig = msg | hmac_sha256(key=env.EXOSCALE_API_SECRET, encoding="base64") -%}
EXO2-HMAC-SHA256 credential={{ env.EXOSCALE_API_KEY }}{% if request.signed_query_args %},signed-query-args={{ request.signed_query_args }}{% endif %},expires={{ expires }},signature={{ sig -}}
"""