apache / apache/apisix

feat: Add Bearer Token Support to key-auth Plugin

Open
#12,908 2 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Lua
Stars
17.1k
Forks
2.9k
Avg merge
3d 16h
Merged PRs (30d)
63

Description

### 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 `), 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 `
- 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:

```json
{
"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

```bash
# 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]

Contributor guide

Open the contributing guide

Research direction

Start by locating the key-auth plugin implementation, its schema, and its existing authentication tests. Trace how the configured header and WWW-Authenticate response are handled, then add coverage for bearer_token enabled and disabled, including valid and invalid Authorization values. Done means the requested token extraction, strict format error, response scheme, and backward compatibility are verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
api, authentication
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.