Skip to content

feat: Add Bearer Token Support to key-auth Plugin #12908

@Ronan-WeScale

Description

@Ronan-WeScale

Description

Description

The key-auth plugin currently only supports custom header names (default: apikey) for API key authentication. However, it does not support the standard OAuth 2.0 Bearer token format (Authorization: Bearer <token>), which is widely used in modern APIs and is the standard way to pass authentication tokens.

Current Behavior

Currently, when using the key-auth plugin:

  • The API key can be passed via a custom header (default: apikey) or query parameter
  • The header parameter allows customization of the header name
  • Example: apikey: my-secret-key or X-API-KEY: my-secret-key

Expected Behavior

The plugin should support the standard Bearer token format:

  • Accept tokens in the format: Authorization: Bearer <token>
  • When enabled, the plugin should:
    • Force the use of the Authorization header (ignoring the header parameter)
    • Extract the token after the "Bearer " prefix
    • Validate the token format strictly
    • Update the WWW-Authenticate response header to use "Bearer" scheme instead of "apikey"

Use Case

Many APIs and OAuth 2.0-based authentication systems use the Bearer token format as a standard. Supporting this format in the key-auth plugin would:

  1. Standards Compliance: Follow RFC 6750 (Bearer Token Usage) and OAuth 2.0 specifications
  2. Interoperability: Allow APISIX to work seamlessly with existing OAuth 2.0 clients and tools
  3. Migration: Enable easier migration from other API gateways that support Bearer tokens
  4. Developer Experience: Provide familiar authentication patterns that developers expect

Proposed Solution

Add a new boolean parameter bearer_token to the plugin schema:

{
  "plugins": {
    "key-auth": {
      "bearer_token": true
    }
  }
}

When bearer_token is set to true:

  • The plugin should read from the Authorization header only
  • Extract the token after "Bearer " prefix
  • Return 401 with error message "Invalid Bearer token format" if the prefix is missing
  • Set WWW-Authenticate: Bearer realm="key" in error responses

Example Configuration

# Create a consumer
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "jack",
    "plugins": {
      "key-auth": {
        "key": "my-secret-token"
      }
    }
  }'

# Create a route with bearer_token enabled
curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "uri": "/protected",
    "plugins": {
      "key-auth": {
        "bearer_token": true
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

# Valid request
curl "http://127.0.0.1:9080/protected" \
  -H "Authorization: Bearer my-secret-token"
# Returns: 200 OK

# Invalid request (missing Bearer prefix)
curl "http://127.0.0.1:9080/protected" \
  -H "Authorization: my-secret-token"
# Returns: 401 Unauthorized
# Response: {"message":"Invalid Bearer token format"}

Benefits

  • Backward compatible (default: false)
  • No breaking changes to existing configurations
  • Follows OAuth 2.0 and RFC 6750 standards
  • Simple to implement and use
  • Improves security by enforcing standard token format

Alternative Considered

Using the existing header parameter set to "Authorization" doesn't work because:

  1. It doesn't validate the "Bearer " prefix
  2. The WWW-Authenticate response header still uses "apikey" scheme
  3. Tokens without "Bearer " prefix would be accepted, which is non-standard

Environment

  • APISIX Version: [version]
  • Operating System: [OS]
  • Deployment: [Docker/Bare Metal/Kubernetes]

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Status

    📋 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions