[Proposal] Adopt Go Template Syntax for Gateway Artifact Variable and Secret Resolution #1688
renuka-fernando
started this conversation in
Ideas
Replies: 2 comments
-
|
As of now we haven't used the existing $secret internally nor its exposed as a documentation as well. Hence +1 to remove $secret and allow the go template based option. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment


Uh oh!
There was an error while loading. Please reload this page.
-
Summary
text/templatesyntax ({{ env "KEY" }},{{ secret "KEY" }}) for injecting dynamic values into gateway artifact files, replacing the$secret{KEY}syntax.RestApi,LlmProvider,LlmProxy,LlmProviderTemplate,McpProxy, etc.), with template expressions supported in any string field across the entire artifact — not limited to policyparamsas with the current$secret{KEY}support, but also in fields likeupstream.auth, and endpoint configuration.SecretTrackerthat records resolved secret values during rendering so the config-dump endpoint can redact them using value-based replacement.FuncMapincludingenv,secret,redact,default,required, and common string helpers, with zero new external dependencies (stdlibtext/templateonly).Motivation
$secret{KEY}is already supported uniformly across all artifact kinds, but only within policyparams— fields like upstream auth credentials cannot currently reference secrets.$secret{KEY}to cover all artifact fields, and separately adding$env{KEY}for environment variable injection, would require maintaining two custom mini-languages each needing their own parser, error reporting, and documentation.Proposal
text/templateas the single templating layer for all gateway artifact inputs, rendered before format-specific parsing. Template expressions are supported in any string field across the entire artifact —metadata,spec, policyparams, upstream config, etc.FuncMapexposingenv,secret,redact,default,required, and safe string helpers (upper,lower,trim,replace). All Gotext/templatebuilt-in functions are also available —and,or,not,eq/ne/lt/gt,len,printf, etc. — enabling conditionals and comparisons without any additional registration.redactpipe function that marks any value — regardless of source — for redaction in config dumps. TheSecretTrackercollects all values passed throughredactduring rendering; the dump serializer replaces any occurrence of those values in the output with***REDACTED***.secretfunction resolves keys through the existing gateway secrets service and internally pipes throughredact, so secrets are always redacted without the user needing to add| redactexplicitly.envdoes not redact by default — users pipe throughredactwhen the env var holds a sensitive value.{{being interpreted as a flow mapping.{{ env "KEY" | required "KEY must be set" }}aborts loading the artifact with a clear error.This makes a single design decision cover two currently-open questions: (1) variable syntax for artifact files across the whole gateway, and (2) how secrets are redacted when artifact state is exposed via observability or debug endpoints.
Secret Metadata Propagation to Policy Engine
The gateway controller renders templates and resolves secrets before building xDS resources. By the time xDS is sent to the policy engine, all template expressions are gone — the PE sees only resolved values and cannot independently detect which fields contain secrets.
The PE has its own config dump endpoint (used for debugging) and must also redact secrets. Since config dumps are debug-only, value-based redaction is used: the controller passes the set of resolved secret values to the PE via xDS resource metadata, and the PE replaces any occurrence of those values in its dump output.
Proposed approach: The controller populates a
TransportMetadatastruct embedded inStoredPolicyConfigwith the resolved secret values fromSecretTracker.The PE:
transport_metadata.sensitive_valuesas part of the existing xDS update flow, no protocol changes requiredTransportMetadatain memory alongside the configuration***REDACTED***transport_metadatafrom the dump output itself (strip before serializing the dump response)Configuration Changes
{ "apiVersion": "gateway.api-platform.wso2.com/v1alpha1", "kind": "LlmProvider", "metadata": { "name": "openai-prod" }, "spec": { "displayName": "OpenAI Provider", "version": "v1.0", "template": "openai-template", "vhost": "api.openai.local", "upstream": { "url": "{{ env \"OPENAI_ENDPOINT\" | default \"https://api.openai.com/v1\" }}", "auth": { "type": "api-key", "header": "Authorization", "value": "{{ secret \"openai-api-key\" }}" } } } }Examples
Before:
After:
Drawbacks
{{ env "KEY" }}is noisier than$env{KEY}when no defaults or transformations are needed.{{ ... }}as a flow mapping and fails. Error messages must make this obvious.text/templateparse error instead of a config-schema error, which may confuse users debugging field typos.redactdoes not apply to the router:redactonly affects the gateway controller and policy engine config dump endpoints. Any artifact field that is also forwarded to the Envoy router will appear as-is in the Envoy admin config dump —redacthas no effect there. There should be no sensitive data passed to the router; if a user mistakenly appliesredactto a field that flows to the router (e.g., upstream URL), the value will still be visible in the Envoy dump.Alternatives Considered
Alternative 1: Custom
$env{KEY}/$secret{KEY}syntax (current proposal)text/template.Alternative 2: Shell/Docker-style
${env:KEY}/${secret:KEY}${KEY:-default}).Alternative 3: CEL (Common Expression Language)
Secret Redaction Strategy: Value-based vs Path-based
"true","admin").{{ secret ... }}before rendering; redact only those paths in the structured dump. Deterministic, no false positives, but requires translating paths across model boundaries (artifact YAML → xDS → PE internal).Implementation Details
text/templateerrors with file location context before surfacing them, so users seeartifact.yaml:27:14: unknown function "secret"rather than an opaque template engine error.requiredfailure behavior: Treated the same as any other artifact validation failure. In immutable gateway mode, arequiredfailure during startup prevents the gateway controller from starting entirely.Compatibility
$secret{KEY}is replaced by{{ secret "KEY" }}. Any artifact currently using$secret{KEY}in policyparamsmust be migrated. Any artifact config value containing a literal{{must also be escaped as{{ "{{" }}.References
Beta Was this translation helpful? Give feedback.
All reactions