Current Behavior
Environment
- APISIX version: 3.16.0 (debian image)
- Deployment: Kubernetes via apisix-ingress-controller 2.1.0 + ADC 0.26.0
- Gateway API mode (HTTPRoute + PluginConfig v1alpha1)
Description
Two related bugs in the authz-keycloak plugin when used with the Kubernetes Secret Manager ($secret://kubernetes/...):
Bug 1: encrypt_fields corrupts services on startup
When client_secret is stored in etcd as a $secret://kubernetes/... reference and the Kubernetes Secret Manager resolves it at runtime, APISIX encrypts the resolved value (because client_secret is in encrypt_fields) before storing it back to etcd via the Admin API. The resulting encrypted value (AES-256-CBC base64, ~128-152 chars) exceeds the maxLength: 100 defined in the plugin's JSON schema for client_secret.
On next startup, config_etcd.lua:load_full_data() validates the schema against the already-encrypted value and fails, causing every service that uses authz-keycloak to be skipped entirely:
lua config_etcd.lua:612: load_full_data(): failed to check item data of
/apisix/services err: failed to check the configuration of plugin
authz-keycloak err: property "client_secret" validation failed: string too
long, expected at most 100, got 128
This results in 404 for all routes using the affected services.
Root cause: Schema validation runs against the post-encryption value instead of the pre-encryption plaintext. The maxLength: 100 constraint is designed for the user-supplied credential, not the AES-encrypted output.
Bug 2: authz-keycloak plugin schema maxLength: 100 is too restrictive
Even without encryption, real-world OAuth2 client_secret values frequently exceed 100 characters (e.g. Keycloak-generated secrets of 32+ random bytes encoded in various formats, or Azure AD client secrets). The limit of 100 characters for both client_id and client_secret is unnecessarily restrictive.
Additionally, when using $secret://kubernetes/<namespace>/<secret-name>/<key> references, the reference string itself can exceed 100 characters (e.g. $secret://kubernetes/my-long-namespace/my-secret-name/client_secret = 68+ chars), causing the Admin API to reject the configuration before APISIX even tries to resolve it.
Expected Behavior
- Schema validation should run against the pre-encryption value, not the encrypted output
maxLength for client_id and client_secret should accommodate encrypted values and $secret:// reference strings (suggest 4096 or removing the limit entirely)
Error Logs
No response
Steps to Reproduce
- Configure
authz-keycloak plugin with $secret://kubernetes/<ns>/<secret>/<key> references for client_id and client_secret
- Ensure the Kubernetes secret contains a
client_secret value (any non-trivial OAuth2 secret)
- APISIX resolves the reference at runtime, encrypts the value, and stores it in etcd
- Restart APISIX
- Observe
load_full_data() error for all services using authz-keycloak
Environment
The $secret://kubernetes Secret Manager implementation (apisix/secret/kubernetes.lua) appears to be absent from the official 3.16.0-debian Docker image, which means $secret://kubernetes/... references are silently treated as literal strings at the plugin level, while the Admin API validation (which has the 100-char limit) still applies. This makes the feature completely unusable in Kubernetes environments without custom image builds.
Related files:
- apisix/plugins/authz-keycloak.lua — lines 34-35 (maxLength), line 75 (encrypt_fields)
- apisix/secret/ — missing kubernetes.lua in official debian image
Current Behavior
Environment
Description
Two related bugs in the
authz-keycloakplugin when used with the Kubernetes Secret Manager ($secret://kubernetes/...):Bug 1:
encrypt_fieldscorrupts services on startupWhen
client_secretis stored in etcd as a$secret://kubernetes/...reference and the Kubernetes Secret Manager resolves it at runtime, APISIX encrypts the resolved value (becauseclient_secretis inencrypt_fields) before storing it back to etcd via the Admin API. The resulting encrypted value (AES-256-CBC base64, ~128-152 chars) exceeds themaxLength: 100defined in the plugin's JSON schema forclient_secret.On next startup,
config_etcd.lua:load_full_data()validates the schema against the already-encrypted value and fails, causing every service that usesauthz-keycloakto be skipped entirely:lua config_etcd.lua:612: load_full_data(): failed to check item data of
/apisix/services err: failed to check the configuration of plugin
authz-keycloak err: property "client_secret" validation failed: string too
long, expected at most 100, got 128
This results in 404 for all routes using the affected services.
Root cause: Schema validation runs against the post-encryption value instead of the pre-encryption plaintext. The
maxLength: 100constraint is designed for the user-supplied credential, not the AES-encrypted output.Bug 2:
authz-keycloakplugin schemamaxLength: 100is too restrictiveEven without encryption, real-world OAuth2
client_secretvalues frequently exceed 100 characters (e.g. Keycloak-generated secrets of 32+ random bytes encoded in various formats, or Azure AD client secrets). The limit of 100 characters for bothclient_idandclient_secretis unnecessarily restrictive.Additionally, when using
$secret://kubernetes/<namespace>/<secret-name>/<key>references, the reference string itself can exceed 100 characters (e.g.$secret://kubernetes/my-long-namespace/my-secret-name/client_secret= 68+ chars), causing the Admin API to reject the configuration before APISIX even tries to resolve it.Expected Behavior
maxLengthforclient_idandclient_secretshould accommodate encrypted values and$secret://reference strings (suggest 4096 or removing the limit entirely)Error Logs
No response
Steps to Reproduce
authz-keycloakplugin with$secret://kubernetes/<ns>/<secret>/<key>references forclient_idandclient_secretclient_secretvalue (any non-trivial OAuth2 secret)load_full_data()error for all services usingauthz-keycloakEnvironment
The $secret://kubernetes Secret Manager implementation (apisix/secret/kubernetes.lua) appears to be absent from the official 3.16.0-debian Docker image, which means $secret://kubernetes/... references are silently treated as literal strings at the plugin level, while the Admin API validation (which has the 100-char limit) still applies. This makes the feature completely unusable in Kubernetes environments without custom image builds.
Related files: