Skip to content

[Bug]: Gateway silently drops subscriptions for dp→cp synced APIs #3247

Description

@nimsara66

Please select the area the issue is related to

Gateway

Please select the aspect the issue is related to

Aspect/API (API backends, definitions, contracts, interfaces, OpenAPI)

Description

A subscription for an API created directly on a gateway is accepted by the CP, broadcast, received by the gateway, then discarded. The API keeps returning 403 {"error":"forbidden","message":"Subscription required for this API"} while the portal and CP both show it ACTIVE.

The two planes identify the same API by different UUIDs, and the event carries the wrong one for this direction:

Component Line Behaviour
artifact_import.go 51–56 CP mints its own UUID by design. The pushed DP UUID is kept only as the DPID and is never used as the CP artifact UUID.
subscription_service.go 233 Broadcasts ApiId: sub.ArtifactUUID, which is the CP UUID.
subscription_snapshot.go 119, 126 The accept-set is built using apiIDs[cfg.UUID], which is the gateway UUID. On a UUID mismatch, the entry is silently skipped with a bare continue.

CP-originated APIs work because the two ids agree, which masks the bug.

The strongest point, and the one not in the original finding: the fix already exists one package over. api_key.go:1910-1928 hits the identical dual-UUID problem and falls back to GetConfigByCPArtifactID (sql_store.go:1310). The column is populated post-sync and the gateway's own IT suite asserts it's written (dp-to-cp.feature:168).

The subscription snapshot is the one consumer that never reads it — so this is a missed case, not a missing capability.

Two secondary possible defects on the same code:

  • Silent, inconsistently. Same loop: missing plan warns and aborts (line 144); missing API just continues.
  • Kind == "RestApi" (line 118) drops MCP subscriptions even when UUIDs match — separate possible bug, needs independent confirmation.

Steps to Reproduce

  1. Create a RestApi with securityScheme: subscription directly on the Gateway.
  2. Verify in the Gateway DB that cp_artifact_id ≠ uuid. This difference is the precondition for the issue.
  3. Verify that the CP mints its own UUID while the dpid retains the Gateway-generated UUID.
  4. Subscribe to the API through the Portal.
  5. Observe the subscription logs. All four log lines succeed, ultimately showing subscription_count=0.
  6. Invoke the API and observe that the request fails with HTTP 403.
  7. Repeat the same sequence with the API created on the CP and deployed to the Gateway. In this case, the API invocation succeeds with HTTP 200.

Severity Level of the Issue

Severity/Blocker (Core functionality is broken and consumer is blocked. Need immediate attention)

Environment Details (with versions)

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions