Skip to Content
FeaturesSubscription-Based Authorization

Subscription-Based Authorization

Enable runtime authorization enforcement without replacing customer authentication. Teams subscribe to APIs; Winspect enforces whether a given identity is allowed to call them.

Status

Planned P0

Completion: 0% — Design complete. The catalog-side subscription workflow and ABAC are built. The runtime enforcement API is not yet implemented.


Strategic Position

Winspect does not replace your authentication. Your services continue to use whatever auth they use today (OAuth, mTLS, API keys, cloud IAM). Winspect adds a subscription-based authorization layer on top of it:

Caller → Your Auth (unchanged) → Winspect AuthZ check → Your API

The POST /v1/authz/check call answers: “Given this identity, is it allowed to call this API?” — based on subscriptions, approved permissions, and rate limits configured in the catalog.


What’s Already Built

The catalog-side infrastructure exists and is shipped:

ComponentStatus
Subscription request flow (PENDING → APPROVED / REJECTED)Shipped
Approval workflow with versioningShipped
Permission level selection on approval (VIEW, MANAGE, ADMIN)Shipped
Rate limit fields on subscription (stored, not yet enforced)Shipped
ABAC v2 policy engine (internal catalog access control)Shipped
Subscription uniqueness constraint (identity_type, identity_value, api_id)Shipped

What’s missing is the external-facing AuthZ API — the endpoint that external services call to check if a request should be allowed.


Data Model

Subscription entity

type Subscription = { id: string; // UUID apiId: string; // which API subscriberTeamId: string; identityType: string; // see identity types below identityValue: string; // e.g. "client-id-xyz" status: string; // PENDING, APPROVED, REJECTED permissionLevel: string;// VIEW, MANAGE, ADMIN rateLimitPerMinute?: number; rateLimitPerDay?: number; approvedAt?: string; approvedBy?: string; };

Uniqueness constraint

UNIQUE (identity_type, identity_value, api_id)

One subscription per (identity, API) pair. An identity cannot have two subscriptions to the same API. This constraint is intentional and must not be loosened — see PDR-003.

Supported identity types

TypeExample value
OAUTH_CLIENT_IDclient-123-abc
OAUTH_SUBJECTuser@example.com
MTLS_SUBJECT_DNCN=service,O=Company
MTLS_SPIFFE_IDspiffe://trust/ns/default/sa/svc
API_KEYsk-abc123
AWS_IAM_ROLE_ARNarn:aws:iam::123:role/my-svc
GCP_SERVICE_ACCOUNTsvc@project.iam.gserviceaccount.com
AZURE_MANAGED_IDENTITYobject-id-guid
K8S_SERVICE_ACCOUNTdefault:my-service
CUSTOMAny custom identifier

Phased Rollout

Build incrementally. Stop at any phase once sufficient value is delivered. Phases are independent — B does not require D, D does not require B.

PhaseNameWhat It DoesLatencyEffort
AExternal AuthZ REST APIHTTP endpoint external services call to check authorization5–50ms4–6 weeks
BGateway pluginsNative plugins for Kong, Envoy, AWS API Gateway5–50ms8–12 weeks
DOPA policy bundlesEdge-deployable bundles, offline-capablesub-1ms6–8 weeks
CPlatform SDKsTypeScript, Python, Java, Go client librariessub-1ms cached16–24 weeks

Recommended order: A → B → D → C

Phase A is the fastest path to value. It requires no infrastructure changes from customers and works with any gateway, proxy, or application. See PDR-004 for the rationale.


Phase A: External AuthZ REST API

Endpoint

POST /v1/authz/check Content-Type: application/json Authorization: Bearer <api-key>

Request

{ "subject": { "type": "OAUTH_CLIENT_ID", "value": "client-123-abc" }, "resource": { "apiId": "550e8400-e29b-41d4-a716-446655440000" }, "action": "READ" }

Response

{ "allowed": true, "subscription": { "id": "sub-uuid", "status": "APPROVED" }, "permissions": ["VIEW"], "rateLimit": { "perMinute": 100, "perDay": 10000 }, "decision": { "reason": "SUBSCRIPTION_APPROVED", "evaluatedAt": "2026-03-01T10:00:00Z" } }

Evaluation logic

1. Look up subscriptions WHERE identity_type = ? AND identity_value = ? AND api_id = ? 2. If no subscription found → { allowed: false, reason: "NO_SUBSCRIPTION" } 3. If subscription found but status != APPROVED → { allowed: false, reason: "SUBSCRIPTION_PENDING/REJECTED" } 4. If subscription APPROVED → return allowed: true with permission level and rate limit

Backend implementation target

  • Package: platform-backend-core/src/main/java/com/platform_backend/authz/
  • Controller: AuthzController (new)
  • Service: AuthzService / AuthzServiceImpl (new)
  • Endpoint spec: add to api-spec.yaml under /v1/authz/check

ABAC Integration

The existing ABAC v2 engine enforces internal catalog access (who can view/manage/delete APIs within the Winspect UI). The subscription AuthZ API enforces external access (whether an external system’s identity is allowed to call an API at runtime).

These are complementary, not conflicting:

ScopeEngineWho calls it
Internal catalog accessABAC v2 (platform-backend-core)Winspect UI / API users
External API accessAuthZ check API (/v1/authz/check)External services, gateways, agents

The AuthZ check API reads from the same subscriptions table. It does not run the full ABAC policy chain — it only checks subscription status and permission level for the given identity.


Phase B: Gateway Plugins

Native plugins embed the AuthZ check locally, eliminating the network round-trip:

  • Kong: Lua plugin calling AuthZ check with local caching
  • Envoy: External authorization filter (gRPC)
  • AWS API Gateway: Lambda authorizer backed by Winspect

Configuration flow:

  1. Customer installs plugin
  2. Plugin is configured with Winspect API URL and org API key
  3. On each request, plugin calls /v1/authz/check (or uses cached decision)
  4. Plugin returns 200 (pass) or 403 (deny) to the gateway

Phase D: OPA Policy Bundles

Winspect generates OPA (Open Policy Agent) policy bundles from the subscription data. Customers deploy OPA as a sidecar. Decisions are made locally — no network call required.

  • Bundle refresh: periodic pull from Winspect API (configurable interval)
  • Latency: sub-1ms (local evaluation)
  • Offline-capable: last-known bundle used if Winspect is unreachable

Frontend Considerations

The subscription workflow UI is already built. For the AuthZ check API (Phase A), the UI may need:

  1. A way to view which external identities have subscriptions (subscription management page enhancement)
  2. A way to test the AuthZ check from the UI (optional developer tool)
  3. API key management (already built in settings) — org API keys are used to authenticate AuthZ check calls

Repositories

  • platform-backend-service — AuthZ check API, subscription entities, ABAC engine, OPA bundle generation (future)
Last updated on