Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions docs/gateway/policies/apikey-authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
Introduce **APIKeyAuthentication Policy (v1.0.0)** featuring:
- API key validation from headers or query parameters
- Configurable key extraction with optional prefix stripping
- Flexible authentication source configuration (header/query)
- Pre-shared key validation against configured key lists
- Request context enrichment with authentication metadata

## Configuration Schema

```yaml
name: APIKeyAuthentication
version: v1.0.0
description: |
Implements API Key Authentication to protect APIs with pre-shared API keys.
Validates API keys from request headers or query parameters against a configured
list of valid keys and sets authentication metadata in the request context.

parameters:
type: object
additionalProperties: false
properties:
key:
type: string
required: true
description: |
The name of the header or query parameter that contains the API key.
For headers: case-insensitive matching is used (e.g., "X-API-Key", "Authorization")
For query parameters: exact name matching is used (e.g., "api_key", "token")
validation:
minLength: 1
maxLength: 128

in:
type: string
required: true
description: |
Specifies where to look for the API key.
Must be either "header" or "query".
enum:
- "header"
- "query"

value-prefix:
type: string
required: false
description: |
Optional prefix that should be stripped from the API key value before validation.
Case-insensitive matching and removal. Common use case is "Bearer " for Authorization headers.
If specified, the prefix will be removed from the extracted value.
validation:
minLength: 1
maxLength: 64

required:
- key
- in

initParameters:
type: object
properties: {}
```

## Configuration Notes

The APIKeyAuthentication policy configuration only requires user provided parameters when attaching to an API or API resource. The policy does not define system-level initialization parameters (`initParameters` is empty), meaning all configuration is done by the API developer who attaches this policy to an API or API resource.

Valid API keys are generated by the gateway, management portal, or developer portal. When a request is received, the API key sent in the request will be validated against the keys generated by these services. The policy handles the extraction and validation logic, while the actual key generation and management is handled by the platform's key management system.

## Example API/Per-Route Configurations

### Header-based API Key Authentication

```yaml
# API key in custom header
name: APIKeyAuthentication
version: v1.0.0
params:
key: X-API-Key
in: header
```

### Authorization Header with Bearer Prefix

```yaml
# API key in Authorization header with Bearer prefix
name: APIKeyAuthentication
version: v1.0.0
params:
key: Authorization
in: header
value-prefix: "Bearer "
```

### Query Parameter Authentication

```yaml
# API key as query parameter
name: APIKeyAuthentication
version: v1.0.0
params:
key: api_key
in: query
```

### Custom Header with Prefix

```yaml
# API key in custom header with custom prefix
name: APIKeyAuthentication
version: v1.0.0
params:
key: X-Custom-Auth
in: header
value-prefix: "ApiKey "
```
1 change: 0 additions & 1 deletion gateway/gateway-controller/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ help: ## Show this help message
generate: ## Generate API server code from OpenAPI spec
@echo "Generating API server code from OpenAPI spec..."
@go run github.com/oapi-codegen/oapi-codegen/v2/cmd/[email protected] --config=oapi-codegen.yaml api/openapi.yaml

test: ## Run unit and integration tests
@echo "Running tests..."
@go test -v ./... -cover
Expand Down
214 changes: 211 additions & 3 deletions gateway/gateway-controller/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ paths:
description: Filter by deployment status
schema:
type: string
enum: [pending, deployed, failed]
enum: [ pending, deployed, failed ]
example: pending
responses:
"200":
Expand Down Expand Up @@ -347,6 +347,108 @@ paths:
schema:
$ref: "#/components/schemas/ErrorResponse"

/apis/{id}/api-key:
post:
summary: Generate API key for an API
description: |
Generate a new API key for the specified API. The generated key can be
used by clients to authenticate requests to the API if API Key validation
policy is applied. The key is a 32-byte random value encoded in hexadecimal
and prefixed with "apip_".
operationId: generateAPIKey
tags:
- API Management
parameters:
- name: id
in: path
required: true
description: |
Unique public identifier of the API to generate the key for
schema:
type: string
example: weather-api-v1.0
requestBody:
required: true
content:
application/yaml:
schema:
$ref: "#/components/schemas/APIKeyGenerationRequest"
application/json:
schema:
$ref: "#/components/schemas/APIKeyGenerationRequest"
responses:
'201':
description: API key generated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/APIKeyGenerationResponse"
"400":
description: Invalid configuration (validation failed)
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: API configuration not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Internal server error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"

/apis/{id}/api-key/{apiKey}:
delete:
summary: Revoke an API key
description: |
Revoke a previously generated API key for the specified API. Once revoked,
the key can no longer be used to authenticate requests.
operationId: revokeAPIKey
tags:
- API Management
parameters:
- name: id
in: path
required: true
description: |
Unique public identifier of the API to revoke the key for
schema:
type: string
example: weather-api-v1.0
- name: apiKey
in: path
required: true
description: The API key to revoke
schema:
type: string
example: apip_4f3c2e1d5a6b7c8d9e0f1a2b3c4d5e6f
responses:
'204':
description: API key revoked successfully
"400":
description: Invalid configuration (validation failed)
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: API configuration not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Internal server error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"

/certificates:
get:
summary: List all custom certificates
Expand Down Expand Up @@ -608,7 +710,7 @@ paths:
description: Filter by deployment status
schema:
type: string
enum: [pending, deployed, failed]
enum: [ pending, deployed, failed ]
example: pending
responses:
"200":
Expand Down Expand Up @@ -1757,6 +1859,112 @@ components:
format: date-time
example: 2025-10-11T11:45:00Z

APIKeyGenerationRequest:
type: object
properties:
name:
type: string
description: Name of the API key
example: my-weather-api-key
operations:
type: array
description: List of API operations the key will have access to
items:
$ref: '#/components/schemas/Operation'
expires_in:
type: object
description: Expiration duration for the API key
properties:
unit:
type: string
description: Time unit for expiration
enum:
- seconds
- minutes
- hours
- days
- weeks
- months
example: days
duration:
type: integer
description: Duration value for expiration
example: 30
required:
- unit
- duration
expires_at:
type: string
format: date-time
description: Expiration timestamp
example: "2026-12-08T10:30:00Z"
APIKeyGenerationResponse:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: API key generated successfully
api_key:
$ref: '#/components/schemas/APIKey'
required:
- status
- message
APIKey:
type: object
description: Details of an API key
properties:
name:
type: string
description: Name of the API key
example: my-weather-api-key
api_key:
type: string
description: Generated API key with apip_ prefix
example: "apip_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
apiId:
type: string
description: Unique public identifier of the API that the key is associated with
example: weather-api-v1.0
operations:
type: string
description: List of API operations the key will have access to
example: "[GET /{country_code}/{city}, POST /data]"
status:
type: string
description: Status of the API key
enum:
- active
- revoked
- expired
example: active
created_at:
type: string
format: date-time
description: Timestamp when the API key was generated
example: "2025-12-08T10:30:00Z"
created_by:
type: string
description: Identifier of the user who generated the API key
example: api_consumer
expires_at:
type: string
format: date-time
nullable: true
description: Expiration timestamp (null if no expiration)
example: "2025-12-08T10:30:00Z"
required:
- name
- api_key
- apiId
- operations
- status
- created_at
- created_by
- expires_at

APIListItem:
type: object
properties:
Expand Down Expand Up @@ -2559,7 +2767,7 @@ components:
example: Certificate uploaded and SDS updated successfully
status:
type: string
enum: [success, error]
enum: [ success, error ]
example: success

CertificateListResponse:
Expand Down
Loading
Loading