Admin API allowlist bypassed when ingress-controller enabled (+ missing IPv6)
Description
The admin API allowlist logic in templates/configmap.yaml has two critical issues when ingress-controller.enabled: true:
-
Security bypass: User-specified allowlist is overridden by unconditionally appending
0.0.0.0/0 -
Missing IPv6 support: Only
0.0.0.0/0is added, breaking IPv6-only clusters
Environment
- Helm Chart Version: 2.12.4
- Kubernetes Version: 1.34
- Helm Version: 3.18.4 (through Terraform's Helm provider)
Current Behavior
The template always appends 0.0.0.0/0 when ingress-controller is enabled:
allow_admin:
{{- if .Values.apisix.admin.allow.ipList }}
{{- range $ips := .Values.apisix.admin.allow.ipList }}
- {{ $ips }}
{{- end }}
{{- else }}
- 0.0.0.0/0
{{- end}}
{{- if (index .Values "ingress-controller" "enabled") }}
- 0.0.0.0/0 # Always appended - overrides user security
{{- end}}
Default values.yaml:
apisix:
admin:
allow:
ipList:
- 127.0.0.1/24 # Secure default - localhost only
⚠️ Edge Case Note: Currently, an empty
ipList: []defaults to0.0.0.0/0via the{{- else }}branch. This is likely unintentional behavior, but exists in production. All proposed options below change this edge case.
Problem 1: Security Bypass
Steps to Reproduce
- Configure values.yaml with restricted allowlist:
apisix: admin: allow: ipList: - 10.244.0.0/16 # Restrict to pod network only ingress-controller: enabled: true - Deploy the chart:
helm install apisix apisix/apisix -f values.yaml - Check the generated ConfigMap:
kubectl get configmap apisix -o yaml
Expected Behavior
Admin API should only be accessible from 10.244.0.0/16:
allow_admin:
- 10.244.0.0/16
Actual Behavior
User's restriction is bypassed:
allow_admin:
- 10.244.0.0/16
- 0.0.0.0/0 # Unconditionally added - allows all traffic
Impact
Users cannot properly secure the admin API through the allowlist when using ingress-controller. Security hardening attempts are silently ignored.
Example with default values:
# User expects: localhost only
allow_admin:
- 127.0.0.1/24 # Secure default
- 0.0.0.0/0 # Auto-added - silently weakens security!
Problem 2: IPv6 Not Supported
Steps to Reproduce
- Deploy to an IPv6-only Kubernetes cluster
- Enable ingress-controller with default settings
- Check ingress-controller pod logs
Expected Behavior
Ingress-controller should be able to access the admin API using its IPv6 address.
Actual Behavior
Access is denied because the allowlist only includes 0.0.0.0/0 (IPv4):
[error] access forbidden by rule, client: [2001:db8::1]
Impact
Chart is non-functional in IPv6-only clusters without manual workarounds.
Proposed Solutions
I see three potential approaches, each with different tradeoffs:
Option A: Always Append (Fixes IPv6, Maintains Current Behavior)
allow_admin:
{{- range $ips := .Values.apisix.admin.allow.ipList }}
- {{ $ips | quote }}
{{- end }}
{{- if (index .Values "ingress-controller" "enabled") }}
- 0.0.0.0/0
- "::/0"
{{- end }}
Pros:
- Minimal change - most backward compatible
- Fixes IPv6 support
- Simple logic
Cons:
- Still overrides user security (documents the issue but doesn't fix it)
- Users with custom
ipListstill get wildcards appended
Breaking Changes:
- Empty
ipList: []no longer defaults to allow-all (see edge case note above) - Otherwise maintains current behavior + adds IPv6
Option B: Respect User Configuration (Most Secure)
allow_admin:
{{- if .Values.apisix.admin.allow.ipList }}
{{- range $ips := .Values.apisix.admin.allow.ipList }}
- {{ $ips | quote }}
{{- end }}
{{- else }}
{{- if (index .Values "ingress-controller" "enabled") }}
- 0.0.0.0/0
- "::/0"
{{- end }}
{{- end }}
Pros:
- Respects user security choices
- No more silent security bypass
- IPv6 support in defaults
Cons:
- Breaking change for users relying on the current buggy behavior
- Users must explicitly allow ingress-controller access when using custom
ipList
Breaking Changes:
- Empty
ipList: []no longer defaults to allow-all (see edge case note above) - Users with custom
ipListwho relied on auto-added0.0.0.0/0must add it explicitly
apisix:
admin:
allow:
ipList:
- 10.244.0.0/16 # Custom restriction
- 0.0.0.0/0 # Must add explicitly for ingress-controller (if cidr is unknown)
- "::/0" # IPv6 support
Option C: Make It Configurable (Future-Proof)
Add new value to control behavior:
apisix:
admin:
allow:
ipList:
- 127.0.0.1/24
autoAddIngressControllerAccess: true # New option (default: true)
Template logic:
allow_admin:
{{- range $ips := .Values.apisix.admin.allow.ipList }}
- {{ $ips | quote }}
{{- end }}
{{- if and (index .Values "ingress-controller" "enabled") .Values.apisix.admin.allow.autoAddIngressControllerAccess }}
- 0.0.0.0/0
- "::/0"
{{- end }}
Pros:
- Gives users explicit control
- Backward compatible (default: true maintains current behavior)
- Clear and self-documenting
- Easy to disable for security-conscious users
Cons:
- More complex (adds new configuration option)
- Requires documentation updates
Breaking Changes:
- Empty
ipList: []no longer defaults to allow-all (see edge case note above)
Recommendation
I'm inclined to suggest Option C as it balances all concerns:
- Fixes IPv6 support
- Maintains backward compatibility
- Gives users control over security
- Makes behavior explicit and documented
However, I'm happy to implement whichever approach is preferred.
I'm also happy to submit a PR for this fix, combined with my other issue (#920) about IPv6 quoting since both touch the same ConfigMap template file.
Note: AI helped format this issue. The issue identification and proposed solutions are my own work.