Skip to content

bug: the Admin API Key in GatewayProxy is missing certain validity checks #2651

@bzp2010

Description

@bzp2010

Current Behavior

apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
  name: ingress-apisix-config
  namespace: ingress-apisix
spec:
  provider:
    controlPlane:
      auth:
        adminKey:
          ##### value => base64(edd1c9f034335f136f87ad84b625c8f1\n)
          valueFrom:
            secretKeyRef:
              name: apisix-admin-credentials
              key: admin
        type: AdminKey
      service:
        name: ingress-apisix-admin
        port: 9180
    type: ControlPlane

The Ingress Controller assumes the value is always correct, for example, ensuring compliance with HTTP spec regarding Header values. ref: https://www.rfc-editor.org/rfc/rfc9110.html#name-field-values

If this value is user-specified, it may occasionally contain invalid characters. For example, an ASCII control character such as \n might be encoded in base64, and Kubernetes secrets impose no restrictions on this.
However, should an invalid character appear within the key, synchronisation will fail.

Expected Behavior

Determine whether this should be checked and intercepted prior to sending to the ADC /sync API, and whether we might implement webhook validation for secrets.

Error Logs

2025-11-13T15:38:44.216Z	INFO	client	client/client.go:176	syncing all resources
2025-11-13T15:38:44.220Z	ERROR	executor	client/executor.go:273	failed to run http sync for server	{"server": "http://10.244.3.17:9180/", "error": "ServerAddr: http://10.244.3.17:9180/, Err: HTTP 500: {\"message\":\"TypeError [ERR_INVALID_CHAR]: Invalid character in header content [\\\"X-API-KEY\\\"]\"}"}
2025-11-13T15:38:44.220Z	ERROR	client	client/client.go:264	failed to execute adc command	{"config": {"name":"GatewayProxy/apisix/apisix-config","serverAddrs":["http://10.244.3.17:9180/"],"tlsVerify":false}, "error": "ADC execution error for GatewayProxy/apisix/apisix-config: [ServerAddr: http://10.244.3.17:9180/, Err: HTTP 500: {\"message\":\"TypeError [ERR_INVALID_CHAR]: Invalid character in header content [\\\"X-API-KEY\\\"]\"}]"}
2025-11-13T15:38:44.220Z	ERROR	client	client/client.go:208	failed to sync resources	{"name": "GatewayProxy/apisix/apisix-config", "error": "ADC execution errors: [ADC execution error for GatewayProxy/apisix/apisix-config: [ServerAddr: http://10.244.3.17:9180/, Err: HTTP 500: {\"message\":\"TypeError [ERR_INVALID_CHAR]: Invalid character in header content [\\\"X-API-KEY\\\"]\"}]]"}

Steps to Reproduce

Copy from: https://the-asf.slack.com/archives/CUC5MN17A/p1762895096601199

Hey guys, I hope this find everybody well.
I'm trying to deploy APISIX Standalone API-Driven mode into my kind cluster, with differente credentials (admin and viewer keys) but for some reason, my apisix pod doesnt get ready... probes is failing with: "Readiness probe failed: HTTP probe failed with statuscode: 503"
Im creating a local helm package to achieve this using the official as dependency...
Thats my Chart.yaml file:

apiVersion: v2
name: apisix
description: A Helm chart for deploy Apisix in standalone mode
type: application
version: 1.0.0
appVersion: "1.0.0"
dependencies:
  - name: apisix
    version: 2.12.2
    repository: https://apache.github.io/apisix-helm-chart

And this is the values:

adminPasswordSecretValue: OWhUZFludU1QV2NPQzhDN2RXS3BHMUJ1Y0h5TksxR1oK
viewerPasswordSecretValue: VFU5cGJVRXpVMXBHUmtFM2FqZEdlVkJNU0hGTGNsVncK

apisix:
  service:
    type: LoadBalancer
  etcd:
    enabled: false
  apisix:
    deployment:
      role: traditional
      role_traditional:
        config_provider: yaml
    admin:
      enable_admin_ui: false
      credentials:
        secretName: apisix-admin-credentials
  ingress-controller:
    enabled: true
    config:
      provider:
        type: apisix-standalone
    apisix:
      adminService:
        namespace: apisix
    gatewayProxy:
      createDefault: true
      provider:
        controlPlane:
          auth:
            adminKey:
              valueFrom:
                secretKeyRef:
                  name: apisix-admin-credentials
                  key: admin

And thats the secret template:

apiVersion: v1
kind: Secret
metadata:
  name: apisix-admin-credentials
  namespace: {{ .Release.Namespace }}
type: Opaque
data:
  admin: {{ .Values.adminPasswordSecretValue | quote }}
  viewer: {{ .Values.viewerPasswordSecretValue | quote }}

Anybody knows what am I doing wrong? If I remove the secret from apisix configuration (letting him use the defaults ones) it apparently works...

Environment

  • APISIX Ingress controller version (run apisix-ingress-controller version --long): 2.0.0-rc5
  • Kubernetes cluster version (run kubectl version): N/A
  • OS version if running APISIX Ingress controller in a bare-metal environment (run uname -a): N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions