Skip to content

v0.1.25.50 — security: tenant webhook event_categories boundary

Choose a tag to compare

@amavashev amavashev released this 11 Jul 00:05

Security release. Closes an authorization gap in tenant self-service webhook subscriptions.

Security

  • Tenant-plane webhook event_categories are now validated against the tenant-accessible boundary. Tenant self-service webhook create and update rejected admin-only event_types (api_key/policy/webhook/system), but did not validate event_categories — and category matching is additive with type matching. A tenant key could create or update a subscription with one allowed event_type plus "event_categories": ["api_key"] (or policy/webhook/system) and receive admin-only event classes for its tenant. Both create and update now reject admin-only categories with 400 INVALID_REQUEST, deriving the boundary from a single EventCategory.isTenantAccessible() source (governance spec revision v0.1.25.38, runcycles/cycles-protocol#126). Admin-plane webhook endpoints are unaffected.
  • Operators: audit existing tenant-plane subscriptions created on 0.1.25.49 and earlier for smuggled admin-only categories, and for the match-ALL rows below. A copy-pasteable redis-cli + jq recipe (flagging both ADMIN_CATEGORIES and MATCH_ALL rows, with the admin-provisioned-provenance caveat) is in CHANGELOG.md [0.1.25.50] Security.

Fixed

  • Empty-both match-ALL door closed. WebhookService.update applied an empty event_types: [] verbatim; with no categories, the matcher's empty-both branch made the subscription match every event class (admin-only included). Update now rejects a change that would leave a subscription with neither event_types nor event_categories (both planes; the state is not creatable on either). Category-only subscriptions remain legal.

Follow-up (tracked, not in this release): whether a tenant should retain admin-only categories on a legacy/admin-created subscription it owns is a separate provenance/ownership question — tracked as #209.

Compatibility

  • No HTTP request/response schema, Redis data model, or Lua change. Requests that previously smuggled admin-only categories now return 400; legitimate tenant-accessible categories are unaffected. Legacy offender rows keep delivering until repaired — see the audit recipe.
  • Full-stack compose bundles cycles-server 0.1.25.47 and cycles-server-events 0.1.25.22.

1,566 tests green including integration + contract validation against governance spec v0.1.25.38; JaCoCo ≥95% on all modules; external security review (codex) SHIP. Full details: CHANGELOG.md [0.1.25.50], AUDIT.md, PR #208.