Skip to main content
Apragya AI
Docs · Security & Admin

Plan-feature gates: how the platform enforces what your plan includes

The two-layer access model - plan first, RBAC second - why menu items disappear off-plan, and the common gotchas.

Most SaaS platforms enforce plan limits by trust ("hope nobody hits the limit") or by post-fact billing ("charge them when they go over"). Apragya AI enforces by hard gates - if your plan doesn't include a feature, you literally can't use it. This guide explains the model so admins don't try to RBAC-grant a feature their plan doesn't include and then wonder why it doesn't work.

The two-layer model

  • Layer 1: Plan-feature gate. Does your plan even include this capability? Stored in pricing_plans.feature_flags (JSONB), edited by SaaS Admin via the Edit Plan modal
  • Layer 2: RBAC gate. Within what the plan allows, does this user's role have the right permission? Stored in the per-app permission matrix, edited by Org Admin
  • Plan-feature gate runs FIRST. RBAC gate runs SECOND - only on the subset of features the plan includes

Why the order matters

RBAC's can() resolvers intentionally short-circuit to TRUE for admin-tier roles (SaaS Admin, Platform Developer, Org Admin). That's correct for ROLE checks - admins should be able to do anything within their scope. But it's catastrophically wrong if a developer reaches for can() to gate a PLAN feature - the admin bypass would leak paid capability to underpaying tenants. The plan resolver (useFeatureGate.can / check_feature) has no admin bypass.

Behaviour when off-plan: sidebar hides the menu item. Mutating routes (POST/PUT/PATCH/DELETE) return 403. Read routes (GET) stay open so a tenant who downgrades doesn't lose visibility into historical data. Re-enabling the plan toggle restores write access without data loss.

What's gated

  • Vibe Studio (Chat-to-Build) - requires studio.local_llm flag on the plan
  • Multi-region deployment - requires platform.multi_region
  • SSO (SAML/OIDC) - requires security.sso
  • Audit log export to SIEM - requires audit.siem_export
  • Custom roles - requires rbac.custom_roles (built-in roles always work)
  • Add-on AI Credit packs - requires billing.addon_packs
  • And ~25 other capability keys; see Admin Settings > Pricing Plans > Edit Plan for the full list

Strict mode

A missing feature flag in pricing_plans.feature_flags is treated as OFF, not ON. The platform refuses to invent permissive defaults - if SaaS Admin hasn't explicitly granted the capability on the plan, it's gated. This is the safe default for any new feature; it requires the SaaS Admin to deliberately enable, not deliberately disable.

Common gotchas

  • "I'm an Org Admin and I can't do X" - check the plan first. Org Admin bypasses RBAC, not plan gates
  • "This feature worked yesterday" - someone changed the plan, or you got downgraded. Check pricing_plans audit history
  • "The sidebar item disappeared" - sidebar hides off-plan items entirely (it doesn't show them disabled). Easy to mistake for a regression
  • "My API call returns 403" - the error body's detail field carries the feature key that gated it. Grep your code for that key + the plan to confirm

Need help building this? Talk to a real engineer

← All docs
Ask Vippy anything