Putting a resource behind payment is one line: `include RequireEntitlement` in its controller.
Leaving it out is also one line: don't include it. There's no separate configuration file listing
which features are paid; the controller itself is the declaration.

## Gating a controller

```ruby
class InvoicesController < ApplicationController
  include RequireEntitlement
  # ...
end
```

On every action, this checks `Billing.for(Current.account).entitled?` and redirects to the pricing
page when it's false. The example `ProjectsController` uses exactly this include; copy it as the
reference when you scaffold a new paid resource with
[Adding a Resource](/docs/building-features/adding-a-resource).

## Who gets through anyway

Admin accounts (`User#role == "admin"`) are exempt from the entitlement check, so an admin can
always reach a paid controller regardless of subscription status. This matters for support and for
console-driven operations: see [Roles and Teams](/docs/core-concepts/roles-and-teams) for what
`admin?` covers today.

## What this doesn't do

`RequireEntitlement` answers one question: is this workspace allowed to use the paid surface at
all. It says nothing about which specific records the signed-in user can see or modify within that
surface; that's Pundit's job, and it applies regardless of whether the feature is paid or free. A
controller almost always needs both: `include RequireEntitlement` at the top, and `authorize
@record` / `policy_scope(...)` in each action. See
[Authorization](/docs/core-concepts/authorization) for why these stay separate.

## Testing the gate

Add an entitlement-gate test alongside the tenant-isolation test in your request spec: an
unsubscribed account hitting a paid controller's action should be redirected to pricing, not shown
the feature and not met with an error. The `Project` resource's request spec is the reference for
this assertion.

## Next

See how to configure the plan the gate checks against:
[Stripe Setup](/docs/billing-entitlements/stripe-setup).
