Skip to content

fix(standalone): resolve env var references in config pushed via Admin API#13540

Open
AlinsRan wants to merge 1 commit into
apache:masterfrom
AlinsRan:fix/standalone-admin-env-var
Open

fix(standalone): resolve env var references in config pushed via Admin API#13540
AlinsRan wants to merge 1 commit into
apache:masterfrom
AlinsRan:fix/standalone-admin-env-var

Conversation

@AlinsRan

@AlinsRan AlinsRan commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

TL;DR

In standalone mode, ${{VAR}} references in config pushed via the Admin API are stored literally (never resolved), so a reference in a pattern-constrained field (e.g. proxy-rewrite.uri) is even rejected with 400.

Cause

Standalone has two config sources; only the file path resolves ${{VAR}}:

  • File (apisix.yaml): resolved in core/config_yaml.lua parse(), before schema validation.
  • Admin API (admin/standalone.lua update()): validates and stores the JSON body without ever calling resolve_conf_var.

The divergence was introduced by #13078, which moved resolution into the file-parse path only.

Fix

update() now calls file.resolve_conf_var(req_body) before validate_configuration, mirroring the file path. Both the schema check and the stored config see resolved, natively-typed values — resolve_conf_var coerces resolved scalars to their native type (e.g. "2"2), and an unresolvable reference (no env var, no :=default) now fails fast with 400 instead of being stored literally.

Scope: this resolves the ${{VAR}} syntax only. $ENV:// / $secret:// references are a separate, lazily-resolved mechanism and are unaffected.

Test

t/admin/standalone.spec.ts, Variable resolution:

  • ${{VAR:=default}} in proxy-rewrite.uri resolves and the route returns the hello body (a literal value would not match);
  • ${{VAR:=2}} into the integer upstream.retries returns 202 (native-type coercion; a literal "2" would fail integer validation);
  • an unresolvable ${{VAR}} returns 400 with failed to resolve variables in config.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change (N/A)
  • I have verified that the changes pass the existing tests

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 12, 2026
@AlinsRan AlinsRan force-pushed the fix/standalone-admin-env-var branch from 3fa7450 to dd45c6a Compare June 12, 2026 06:39
…n API

In standalone mode, the file-based config path resolves ${{VAR}} / $ENV://
references in config_yaml.parse(), but config pushed through the Admin API
(`PUT /apisix/admin/configs`) is JSON-decoded straight into _update_config
and bypassed that step, so the references were kept literal.

Resolve them in the Admin API update path before applying the config, so
both standalone config sources behave consistently. Adds a test that pushes
a route whose proxy-rewrite uri uses a ${{VAR:=default}} reference and
verifies the gateway resolves it.

Signed-off-by: AlinsRan <alinsran@apache.org>
@AlinsRan AlinsRan force-pushed the fix/standalone-admin-env-var branch from dd45c6a to 83204eb Compare June 12, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant