apache / apache/apisix-helm-chart
Admin API allowlist bypassed when ingress-controller enabled (+ missing IPv6)
- Dominant language
- Go Template
- Stars
- 289
- Forks
- 282
- Avg merge
- 15h 55m
- Merged PRs (30d)
- 3
Description
## Description
The admin API allowlist logic in `templates/configmap.yaml` has two critical issues when `ingress-controller.enabled: true`:
1. **Security bypass**: User-specified allowlist is overridden by unconditionally appending `0.0.0.0/0`
2. **Missing IPv6 support**: Only `0.0.0.0/0` is 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:
```yaml
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`:**
```yaml
apisix:
admin:
allow:
ipList:
- 127.0.0.1/24 # Secure default - localhost only
```
---
> **⚠️ Edge Case Note:**
> Currently, an empty `ipList: []` defaults to `0.0.0.0/0` via 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
1. Configure values.yaml with restricted allowlist:
```yaml
apisix:
admin:
allow:
ipList:
- 10.244.0.0/16 # Restrict to pod network only
ingress-controller:
enabled: true
```
2. Deploy the chart: `helm install apisix apisix/apisix -f values.yaml`
3. Check the generated ConfigMap: `kubectl get configmap apisix -o yaml`
### Expected Behavior
Admin API should only be accessible from `10.244.0.0/16`:
```yaml
allow_admin:
- 10.244.0.0/16
```
### Actual Behavior
User's restriction is bypassed:
```yaml
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:**
```yaml
# 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
1. Deploy to an IPv6-only Kubernetes cluster
2. Enable ingress-controller with default settings
3. 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)
```yaml
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 `ipList` still 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)
```yaml
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 `ipList` who relied on auto-added `0.0.0.0/0` must add it explicitly
```yaml
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:
```yaml
apisix:
admin:
allow:
ipList:
- 127.0.0.1/24
autoAddIngressControllerAccess: true # New option (default: true)
```
Template logic:
```yaml
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.*
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in templates/configmap.yaml and compare the allow_admin rendering with the documented values and ingress-controller settings. Render the chart with Helm using a restricted ipList, an empty list, ingress enabled, and IPv6-related values, then inspect the generated ConfigMap. Done means the maintainer-selected behavior is explicit, preserves intended restrictions, and covers both IPv4 and IPv6 access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- helm, kubernetes
- Domain
- devops, infrastructure, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100