Skip to content

Add API Key support for WebBroker APIs#1988

Merged
ShalkiWenushika merged 2 commits into
wso2:mainfrom
senthuran16:apikey-for-webbroker-api
May 19, 2026
Merged

Add API Key support for WebBroker APIs#1988
ShalkiWenushika merged 2 commits into
wso2:mainfrom
senthuran16:apikey-for-webbroker-api

Conversation

@senthuran16
Copy link
Copy Markdown
Member

@senthuran16 senthuran16 commented May 18, 2026

Purpose

$Subject.

Engaging API Key auth as a policy is supported with this PR, either at allChannels level, or at a particular channel level.

Example 1: All Channels need API Key auth

{
  "apiVersion": "gateway.api-platform.wso2.com/v1alpha1",
  "kind": "WebBrokerApi",
  "metadata": {
    "name": "stock-trading-v1.0"
  },
  "spec": {
    "displayName": "Stock Trading WebBroker API",
    "version": "v1.0",
    "context": "/stock-trading/v1.0",
    "receiver": {
      "name": "websocket-receiver",
      "type": "websocket"
    },
    "broker": {
      "name": "kafka-driver",
      "type": "kafka",
      "properties": {
        "brokers": [
          "kafka:29092"
        ]
      }
    },
    "allChannels": {
      "on_connection_init": {
        "policies": [
            {
                "name": "api-key-auth",
                "version": "v1",
                "params": {
                    "in": "header",
                    "key": "X-API-Key"
                }
            }
        ]
      },
      "on_produce": {
        "policies": []
      },
      "on_consume": {
        "policies": []
      }
    },
    "channels": {
      "prices": {
        "produceTo": {
          "topic": "stock.prices"
        },
        "consumeFrom": {
          "topic": "dummy.prices"
        },
        "on_connection_init": {
          "policies": []
        },
        "on_produce": {
          "policies": []
        },
        "on_consume": {
          "policies": []
        }
      }
    }
  }
}

Example: prices channel doesn't need an API Key auth (on_connection_init), but the alerts channel needs

{
  "apiVersion": "gateway.api-platform.wso2.com/v1alpha1",
  "kind": "WebBrokerApi",
  "metadata": {
    "name": "stock-trading-v1.0"
  },
  "spec": {
    "displayName": "Stock Trading WebBroker API",
    "version": "v1.0",
    "context": "/stock-trading/v1.0",
    "receiver": {
      "name": "websocket-receiver",
      "type": "websocket"
    },
    "broker": {
      "name": "kafka-driver",
      "type": "kafka",
      "properties": {
        "brokers": [
          "kafka:29092"
        ]
      }
    },
    "allChannels": {
      "on_connection_init": {
        "policies": []
      },
      "on_produce": {
        "policies": []
      },
      "on_consume": {
        "policies": []
      }
    },
    "channels": {
      "prices": {
        "produceTo": {
          "topic": "stock.prices"
        },
        "consumeFrom": {
          "topic": "dummy.prices"
        },
        "on_connection_init": {
          "policies": []
        },
        "on_produce": {
          "policies": []
        },
        "on_consume": {
          "policies": []
        }
      },
      "alerts": {
        "produceTo": {
          "topic": "to.alerts"
        },
        "consumeFrom": {
          "topic": "from.alerts"
        },
        "on_connection_init": {
          "policies": [
            {
                "name": "api-key-auth",
                "version": "v1",
                "params": {
                    "in": "header",
                    "key": "X-API-Key"
                }
            }
          ]
        },
        "on_produce": {
          "policies": []
        },
        "on_consume": {
          "policies": []
        }
      }
    }
  }
}

Related Issues

#1977 - Since API Key auth is engaged as a policy.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Review Change Stack

📝 Walkthrough

API Key Support for WebBroker APIs

This PR adds API Key authentication support for WebBroker APIs, including management endpoints and policy handling updates.

Documentation

  • Added comprehensive documentation for WebBroker API key management endpoints covering creation, listing, regeneration, updating, and revocation operations
  • Documented API-key operations with HTTP methods, authentication requirements, request/response schemas, and error handling

API Key Management Endpoints

  • Added five new WebBroker API management endpoints:
    • POST /webbroker-apis/{id}/api-keys - Create an API key
    • GET /webbroker-apis/{id}/api-keys - List API keys for a WebBroker API
    • POST /webbroker-apis/{id}/api-keys/{apiKeyName}/regenerate - Regenerate an API key
    • PUT /webbroker-apis/{id}/api-keys/{apiKeyName} - Update an API key
    • DELETE /webbroker-apis/{id}/api-keys/{apiKeyName} - Revoke an API key
  • Implemented HTTP handlers for all five operations with proper parameter binding and error mapping
  • Updated OpenAPI specification with the new endpoints and their schemas

Policy Chain Refactoring

  • Refactored connection initialization policy handling from a split request/response model to a unified ProcessConnectionInit method across:
    • MessageProcessor interface (replaced ProcessConnectionInitRequest and ProcessConnectionInitResponse with single ProcessConnectionInit)
    • Hub message processing
    • WebSocket broker API connector
  • Updated policy binding structure to use simplified []PolicyRef type instead of nested ConnectionInitPolicies
  • Modified runtime policy chain generation to use single ConnInitKey instead of separate request/response keys

Code Generation and Configuration

  • Updated generated management API code to include new WebBroker API key operation signatures and routes
  • Added default role mappings for API key management endpoints in controller configuration
  • Enhanced resource response handling to support WebBrokerApi types
  • Updated API key utility functions to handle WebBrokerApi configuration extraction

Walkthrough

This PR adds WebBroker API key lifecycle management endpoints to the gateway controller and consolidates connection initialization policy handling in the event gateway. The API key feature introduces five new HTTP operations (create, list, regenerate, update, revoke) under /webbroker-apis/{id}/api-keys, supported by OpenAPI contracts, generated middleware, request handlers, and authorization mappings. The connection initialization refactoring replaces separate request and response processing methods with a single unified handler, eliminates redundant policy execution stages, and streamlines runtime chain key management from two keys to one.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant APIServer as APIServer Handler
  participant APIKeyService as API Key Service
  participant Storage
  
  Client->>APIServer: POST /webbroker-apis/{id}/api-keys
  APIServer->>APIKeyService: CreateAPIKey(ctx, Kind, Handle, CorrelationID)
  APIKeyService->>Storage: Create record
  Storage-->>APIKeyService: Result or error (404/409/500)
  APIKeyService-->>APIServer: Response
  APIServer-->>Client: HTTP 201/400/404/409/500
Loading
sequenceDiagram
  participant Client
  participant WebSocket as WebSocket Connector
  participant Hub
  participant Binding
  
  Client->>WebSocket: WebSocket connect handshake
  WebSocket->>Hub: ProcessConnectionInit(ctx, bindingName, msg)
  Hub->>Binding: Resolve by name
  Hub->>Hub: Apply on_connection_init policies via SubscribeChainKey
  alt Short-circuit
    Hub->>WebSocket: ImmediateResponse
    WebSocket->>Client: Close or respond
  else Allowed
    Hub->>WebSocket: Modified message with policy headers
    WebSocket->>Client: Continue handshake
  end
Loading

Suggested reviewers

  • RakhithaRR
  • VirajSalaka
  • Arshardh
  • HeshanSudarshana
  • HiranyaKavishani
  • pubudu538
  • ashera96
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description lacks several required sections from the template: Goals, Approach, User stories, Automation tests, Security checks, Samples, Related PRs, and Test environment are absent or incomplete. Complete the PR description by adding all required template sections including Goals, Approach, User stories, Automation tests (unit and integration), Security checks, Samples, Related PRs, and Test environment details.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add API Key support for WebBroker APIs' clearly and directly summarizes the main change across the changeset, which involves adding API key management capabilities to WebBroker API resources.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
event-gateway/gateway-runtime/internal/hub/hub.go (1)

533-562: 💤 Low value

Stale comment reference to removed concept.

Line 543 references "on_connection_init.request" but the request/response split has been removed. Consider updating the comment to reflect the unified model.

-	// Apply connection_init request policies if present.
-	if binding.SubscribeChainKey != "" { // Reuse SubscribeChainKey for on_connection_init.request
+	// Apply on_connection_init policies if present.
+	if binding.SubscribeChainKey != "" { // Reuse SubscribeChainKey for on_connection_init
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@event-gateway/gateway-runtime/internal/hub/hub.go` around lines 533 - 562,
The top-of-function comment for ProcessConnectionInit mentions
"on_connection_init.request" and a request/response split that no longer exists;
update that comment to describe the unified on_connection_init policy model and
how this function applies the policy during connection handshake (used for
WebSocket/SSE upgrades) and returns the (possibly mutated) message and
short-circuit flag. Also remove or replace the inline comment that reuses
SubscribeChainKey for "on_connection_init.request" and instead state that
SubscribeChainKey is reused for on_connection_init policy execution so callers
can locate the policy invocation (referencing ProcessConnectionInit,
binding.SubscribeChainKey, and h.engine.ExecuteRequestHeaderPolicies).
event-gateway/gateway-runtime/internal/connectors/receiver/websocket/broker_api_connector.go (1)

255-280: ⚡ Quick win

Consider sending a WebSocket close frame with a reason.

When channel-specific on_connection_init policies reject the connection, the code calls ws.Close() directly. This results in an abrupt close without any reason being communicated to the client. Sending a close frame with a status code would improve client-side observability.

		if shortCircuited {
			slog.Warn("[3] Connection rejected by channel on_connection_init policy", "api", e.channel.Name, "channel", channelName)
-			ws.Close()
+			ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.ClosePolicyViolation, "connection rejected by policy"))
+			ws.Close()
			return
		}

The same applies to the error case at lines 271-273.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@event-gateway/gateway-runtime/internal/connectors/receiver/websocket/broker_api_connector.go`
around lines 255 - 280, The connection is closed abruptly by calling ws.Close()
in the on_connection_init error and short-circuit branches; instead, send a
WebSocket close frame with a status code and human-readable reason before
closing. Update the branches around connInitChainKey handling (where
e.processor.ProcessByChainKey is called) to construct a CloseMessage (e.g.,
using websocket.FormatCloseMessage with an appropriate code such as
ClosePolicyViolation or CloseNormal and a brief reason that includes
e.channel.Name and channelName), write that control message to the socket (e.g.,
via ws.WriteControl or WriteMessage), then call ws.Close(); apply this change in
both the err and shortCircuited branches so clients receive a close frame and
reason.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/rest-apis/gateway/webbroker-api-management.md`:
- Around line 801-809: The PUT example for
/webbroker-apis/{id}/api-keys/{apiKeyName} is incorrect: update payloads must
include an "apiKey" property when supplying a custom key and the response
example must show the update result shape/message (not a "generated
successfully" message or quota fields). Update the request example JSON to
include "apiKey": "<custom-value>" and adjust the response example to match the
update response schema used by the API (e.g., an update confirmation/message and
the updated key name/metadata), and apply the same fixes to the duplicate
examples in the 833–849 section so both request and response examples reflect
custom-key update semantics.
- Around line 910-913: Update the 404 response description for the revoke
operation to reflect actual behavior: change the text that currently reads
"WebBroker API or API key not found" to only indicate the WebBroker API is not
found (e.g., "WebBroker API not found"), because missing API keys are treated as
successful revokes; locate the revoke response row in the table (the line with
the 404 status under the revoke operation) and edit the description to mention
only the API resource, not the API key, unless you intend to change the service
behavior to return 404 for missing keys instead.
- Around line 680-697: The sample response shows a full API key in the "apiKeys"
array (object with name "my-production-key") but this endpoint returns masked
keys; update the "apiKey" field in that example to a masked format (keep the
"apip_" prefix then replace the majority of characters with asterisks and
optionally show trailing characters) so the example matches runtime behavior and
the masked-key contract.

---

Nitpick comments:
In
`@event-gateway/gateway-runtime/internal/connectors/receiver/websocket/broker_api_connector.go`:
- Around line 255-280: The connection is closed abruptly by calling ws.Close()
in the on_connection_init error and short-circuit branches; instead, send a
WebSocket close frame with a status code and human-readable reason before
closing. Update the branches around connInitChainKey handling (where
e.processor.ProcessByChainKey is called) to construct a CloseMessage (e.g.,
using websocket.FormatCloseMessage with an appropriate code such as
ClosePolicyViolation or CloseNormal and a brief reason that includes
e.channel.Name and channelName), write that control message to the socket (e.g.,
via ws.WriteControl or WriteMessage), then call ws.Close(); apply this change in
both the err and shortCircuited branches so clients receive a close frame and
reason.

In `@event-gateway/gateway-runtime/internal/hub/hub.go`:
- Around line 533-562: The top-of-function comment for ProcessConnectionInit
mentions "on_connection_init.request" and a request/response split that no
longer exists; update that comment to describe the unified on_connection_init
policy model and how this function applies the policy during connection
handshake (used for WebSocket/SSE upgrades) and returns the (possibly mutated)
message and short-circuit flag. Also remove or replace the inline comment that
reuses SubscribeChainKey for "on_connection_init.request" and instead state that
SubscribeChainKey is reused for on_connection_init policy execution so callers
can locate the policy invocation (referencing ProcessConnectionInit,
binding.SubscribeChainKey, and h.engine.ExecuteRequestHeaderPolicies).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ed532505-e936-426a-8bab-ffb724149eeb

📥 Commits

Reviewing files that changed from the base of the PR and between e184aed and df3ae35.

📒 Files selected for processing (14)
  • docs/rest-apis/gateway/README.md
  • docs/rest-apis/gateway/webbroker-api-management.md
  • event-gateway/gateway-runtime/internal/binding/types.go
  • event-gateway/gateway-runtime/internal/connectors/receiver/websocket/broker_api_connector.go
  • event-gateway/gateway-runtime/internal/connectors/types.go
  • event-gateway/gateway-runtime/internal/hub/hub.go
  • event-gateway/gateway-runtime/internal/runtime/runtime.go
  • event-gateway/gateway-runtime/internal/xdsclient/handler.go
  • gateway/gateway-controller/api/management-openapi.yaml
  • gateway/gateway-controller/cmd/controller/main.go
  • gateway/gateway-controller/pkg/api/handlers/resource_response.go
  • gateway/gateway-controller/pkg/api/handlers/webbroker_api_handler.go
  • gateway/gateway-controller/pkg/api/management/generated.go
  • gateway/gateway-controller/pkg/utils/api_key.go

Comment thread docs/rest-apis/gateway/webbroker-api-management.md
Comment thread docs/rest-apis/gateway/webbroker-api-management.md
Comment thread docs/rest-apis/gateway/webbroker-api-management.md
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
docs/rest-apis/gateway/webbroker-api-management.md (1)

834-850: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update example response message does not match the update operation.

At Line 837, the example says "API key generated successfully" under PUT /webbroker-apis/{id}/api-keys/{apiKeyName}. This conflicts with the update semantics and the responses table at Line 857 (API key updated successfully).

Suggested doc fix
 {
   "status": "success",
-  "message": "API key generated successfully",
+  "message": "API key updated successfully",
   "remainingApiKeyQuota": 9,
   "apiKey": {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/rest-apis/gateway/webbroker-api-management.md` around lines 834 - 850,
The example JSON response for the PUT /webbroker-apis/{id}/api-keys/{apiKeyName}
operation uses the wrong message text; change the "message" field value from
"API key generated successfully" to "API key updated successfully" so it matches
the update semantics and the responses table; locate the example JSON near the
PUT /webbroker-apis/{id}/api-keys/{apiKeyName} heading and update only the
"message" string accordingly (leave other fields like "apiKey",
"remainingApiKeyQuota", and "status" unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/rest-apis/gateway/webbroker-api-management.md`:
- Line 623: The examples use two different apiId values; replace all instances
of "apiId": "reading-list-api-v1.0" with the consistent value "apiId":
"stock-trading-v1.0" so every WebBroker API example on the page uses the same
API identifier (also update the other occurrences of "reading-list-api-v1.0"
mentioned in the review). Locate and update the string occurrences (search for
"apiId" and "reading-list-api-v1.0") in the document so examples like the API
key snippets match the rest of the page's "stock-trading-v1.0" usage.

---

Duplicate comments:
In `@docs/rest-apis/gateway/webbroker-api-management.md`:
- Around line 834-850: The example JSON response for the PUT
/webbroker-apis/{id}/api-keys/{apiKeyName} operation uses the wrong message
text; change the "message" field value from "API key generated successfully" to
"API key updated successfully" so it matches the update semantics and the
responses table; locate the example JSON near the PUT
/webbroker-apis/{id}/api-keys/{apiKeyName} heading and update only the "message"
string accordingly (leave other fields like "apiKey", "remainingApiKeyQuota",
and "status" unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1273cce2-a99f-4836-ae0a-f225f9d02c54

📥 Commits

Reviewing files that changed from the base of the PR and between df3ae35 and b207a56.

📒 Files selected for processing (2)
  • docs/rest-apis/gateway/webbroker-api-management.md
  • gateway/gateway-controller/api/management-openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • gateway/gateway-controller/api/management-openapi.yaml

Comment thread docs/rest-apis/gateway/webbroker-api-management.md
@ShalkiWenushika ShalkiWenushika merged commit 76b4fa4 into wso2:main May 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants