You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bring APISIX's native secrets secret-manager resource (Vault / AWS / GCP) into
the controller's resource model, so a secrets manager can be declared through the
controller and becomes part of the full-config snapshot ADC pushes. That makes $secret://<manager>/<id>/... references usable on controller-managed resources
(routes, plugin configs, consumers, SSL, GatewayProxy), instead of the value having
to exist as a plaintext Kubernetes Secret.
Follow-up to #2821 (the standalone sync deadlock). As discussed there, the supported
answer isn't out-of-band registration — it's making secrets a first-class resource
the controller owns and syncs. This issue is the design discussion for that.
Motivation / use case
We want to reference secrets from plugin config via APISIX's native $secret://
indirection rather than materializing the value into the config. Concrete case:
central, HA-safe rotation of the openid-connectsession/cookie secret via Vault —
# today (works, but the value lives in the data-plane env / a k8s Secret):session:
secret: "$env://APISIX_SESSION_SECRET"# what we'd like — resolved from a Vault secret manager, rotated centrally:session:
secret: "$secret://vault/oidc/oidc/session_secret"
APISIX itself already resolves $secret://vault/... in API-driven standalone mode
(verified in #2821). The only missing piece is a controller-side way to declare the
backing secrets manager.
Why not secretRef
secretRef reads a Kubernetes Secret and injects the plaintext value into the
pushed config — a different mechanism. It doesn't give APISIX's native $secret://
indirection, where the data plane fetches from Vault/AWS/GCP at request time and the
secret material never has to live in the k8s config or the ADC snapshot. Both are
useful; this request is specifically about the native secrets managers.
Proposed direction (for discussion)
Add secrets to the control-plane resource model so it's part of the snapshot. Open
questions we'd love maintainer input on:
Where to declare it. Two shapes we can see:
a secrets list on GatewayProxy (alongside pluginMetadata) — simple, one
place, naturally scoped to the gateway the controller drives; or
a dedicated CRD (e.g. ApisixSecret / SecretManager) translating to APISIX's secrets resource — more flexible, referenceable across namespaces, its own
lifecycle/status.
Backends. APISIX supports vault, aws, and gcp managers — mirror those
fields (uri, prefix, auth, etc.).
Manager credentials should not be inline plaintext. The Vault token / AWS / GCP
credentials the manager needs should be sourceable from a Kubernetes Secret via a valueFrom: { secretKeyRef: ... } pattern — the same shape the chart already uses
for GatewayProxyadminKey.valueFrom. (This is the one place secretRef-style
k8s-Secret reading is still needed — to bootstrap the manager's own auth.)
Referencing. Confirm the reference syntax works from the plugin configs we care
about (ApisixPluginConfig / ApisixRoute plugins, openid-connectsession.secret,
and ideally ApisixConsumer / SSL).
Description
Summary
Bring APISIX's native
secretssecret-manager resource (Vault / AWS / GCP) intothe controller's resource model, so a
secretsmanager can be declared through thecontroller and becomes part of the full-config snapshot ADC pushes. That makes
$secret://<manager>/<id>/...references usable on controller-managed resources(routes, plugin configs, consumers, SSL,
GatewayProxy), instead of the value havingto exist as a plaintext Kubernetes Secret.
Follow-up to #2821 (the standalone sync deadlock). As discussed there, the supported
answer isn't out-of-band registration — it's making
secretsa first-class resourcethe controller owns and syncs. This issue is the design discussion for that.
Motivation / use case
We want to reference secrets from plugin config via APISIX's native
$secret://indirection rather than materializing the value into the config. Concrete case:
central, HA-safe rotation of the
openid-connectsession/cookie secret via Vault —APISIX itself already resolves
$secret://vault/...in API-driven standalone mode(verified in #2821). The only missing piece is a controller-side way to declare the
backing
secretsmanager.Why not
secretRefsecretRefreads a Kubernetes Secret and injects the plaintext value into thepushed config — a different mechanism. It doesn't give APISIX's native
$secret://indirection, where the data plane fetches from Vault/AWS/GCP at request time and the
secret material never has to live in the k8s config or the ADC snapshot. Both are
useful; this request is specifically about the native
secretsmanagers.Proposed direction (for discussion)
Add
secretsto the control-plane resource model so it's part of the snapshot. Openquestions we'd love maintainer input on:
Where to declare it. Two shapes we can see:
secretslist onGatewayProxy(alongsidepluginMetadata) — simple, oneplace, naturally scoped to the gateway the controller drives; or
ApisixSecret/SecretManager) translating to APISIX'ssecretsresource — more flexible, referenceable across namespaces, its ownlifecycle/status.
Backends. APISIX supports
vault,aws, andgcpmanagers — mirror thosefields (
uri,prefix, auth, etc.).Manager credentials should not be inline plaintext. The Vault token / AWS / GCP
credentials the manager needs should be sourceable from a Kubernetes Secret via a
valueFrom: { secretKeyRef: ... }pattern — the same shape the chart already usesfor
GatewayProxyadminKey.valueFrom. (This is the one placesecretRef-stylek8s-Secret reading is still needed — to bootstrap the manager's own auth.)
Referencing. Confirm the reference syntax works from the plugin configs we care
about (
ApisixPluginConfig/ApisixRouteplugins,openid-connectsession.secret,and ideally
ApisixConsumer/ SSL).Ownership semantics. Once the controller owns
secrets, a manager registered outof band is (correctly) removed on the next full sync — that's expected and fine; it's
the flip side of bug: standalone/ADC - an out-of-band
secretsresource deadlocks the sync loop (secrets_conf_version400), blocking all reconciliation #2821 and we're not asking for out-of-band to be supported.