Skip to content

docs(metering-and-billing): Add Entitlement Enforcement how-to guides - #6691

Open
gergely-kurucz-konghq wants to merge 14 commits into
release/gateway-3.16from
feat/OM-361-document-mb-entitlement-enforcement
Open

docs(metering-and-billing): Add Entitlement Enforcement how-to guides#6691
gergely-kurucz-konghq wants to merge 14 commits into
release/gateway-3.16from
feat/OM-361-document-mb-entitlement-enforcement

Conversation

@gergely-kurucz-konghq

@gergely-kurucz-konghq gergely-kurucz-konghq commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Description

What

Two how-to guides for the Entitlement Enforcement plugin, plus their supporting pieces.

File
app/_how-tos/gateway/get-started-with-entitlement-enforcement.md Enforce a request-count entitlement on Gateway traffic
app/_how-tos/ai-gateway/v1/enforce-entitlements-on-llm-traffic.md Cap per-customer LLM token usage on AI Gateway traffic
app/_includes/prereqs/metering-and-billing-entitlement-access-spat.md Entitlement Access SPAT prereq (DECK_ENTITLEMENT_ACCESS_TOKEN)
app/konnect-platform/teams-and-roles.md Entitlement Access role row for Metering
app/_indices/metering-and-billing.yaml Index entries for both guides
app/_how-tos/ai-gateway/v1/meter-llm-traffic.md Its enforcement note now links the new LLM guide

Why

The plugin had no how-to coverage. Metering & Billing docs stopped at measuring usage — the LLM metering guide explicitly told readers that traffic is not blocked when an entitlement runs out, and pointed at a concept page instead of a working setup.

How

Each guide builds the full Metering & Billing catalog (meter, metered feature, plan with entitlement, customer, subscription), enables the Metering & Billing plugin to report usage, then the Entitlement Enforcement plugin to block once the limit is hit. Catalog objects are created via konnect_api_request with capture: so the customer's usage_attribution.subject_keys can be pinned to consumer:<id> — the subject the plugin sends. The LLM guide filters its feature to OpenAI prompt tokens with meter.filters and uses usage_period: PT1H, the shortest the API accepts.

Each guide opens with a What you configure table (12 rows for Gateway, 14 for LLM) covering every prerequisite and object, where it's applied, and why it's needed, followed by a diagram of the full request and enforcement flow: client → Route → allowed → Service, the Events and Entitlement Access APIs, Redis as the enforcement cache, and labelled edges for the tokens, the subject key, and the feature.key.

Verified

Both flows were run end to end against Konnect Dev on a 3.16.0.0 Data Plane:

  • Gateway guide: cold-start 403200 within the limit → 429 USAGE_LIMIT_REACHED.
  • LLM guide: five 200s → 429. At 22 prompt tokens per request, the documented limit: 100 is spent on the fifth request, as the guide states.

Frontmatter validator and Vale pass. Both pages render locally with their tables, diagrams, callouts, and plugin links intact.

Notes for reviewers

  • Depends on feat(gateway/m&b): Entitlement enforcement plugin docs #7015, which adds the plugin page. Both guides link /plugins/entitlement-enforcement/ and its #enforcement-decisions-and-response-codes anchor, so feat(gateway/m&b): Entitlement enforcement plugin docs #7015 should land first or together with this.
  • feat(gateway/m&b): Entitlement enforcement plugin docs #7015 links the LLM guide by its old path. This branch moved that guide under ai-gateway/v1/, so its permalink is now /ai-gateway/v1/how-to/enforce-entitlements-on-llm-traffic/. Three references in feat(gateway/m&b): Entitlement enforcement plugin docs #7015 need updating: _kong_plugins/entitlement-enforcement/index.md, _kong_plugins/metering-and-billing/index.md, and metering-and-billing/entitlements.md. No file conflicts otherwise.
  • ssl_verify: true is set on both plugins and in the Entitlement Enforcement plugin's redis block. The Redis one matters: its schema default is false, and a Data Plane running with a global tls_certificate_verify rejects the entire configuration push and silently keeps serving its previous config.
  • Credit balance is not mentioned in these guides. Credit-backed entitlements aren't in the product — Metering & Billing never returns no_credit_available, and include_credits is not implemented — so per docs guidance the 402 default and the NO_CREDIT_AVAILABLE reason are left out entirely rather than carrying a coming-soon note. feat(gateway/m&b): Entitlement enforcement plugin docs #7015's plugin page still describes credit balance in its description frontmatter, its blocking-conditions list, and its response-code table.
  • The Entitlement Access query endpoint the plugin polls is internal and unstable, and absent from the published spec. Each guide shows it once, for verification only, behind a warning.
  • min_version.gateway: '3.16' is set on both guides.

Preview Links

Checklist

  • Tested how-to docs. If not, note why here.
  • All pages contain metadata.
  • Any new docs link to existing docs.
  • All autogenerated instructions render correctly (API, decK, Konnect, Kong Manager).
  • Style guide (capitalized gateway entities, placeholder URLs) implemented correctly.
  • Every page has a description entry in frontmatter.
  • Add new pages to the product documentation index (if applicable).

@gergely-kurucz-konghq
gergely-kurucz-konghq requested a review from a team as a code owner August 17, 2026 14:20
@CLAassistant

CLAassistant commented Aug 17, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@netlify

netlify Bot commented Aug 17, 2026

Copy link
Copy Markdown

Deploy Preview for kongdeveloper ready!

Name Link
🔨 Latest commit 4b3b194
🔍 Latest deploy log https://app.netlify.com/projects/kongdeveloper/deploys/6aa147f187e1b80008ff34da
😎 Deploy Preview https://deploy-preview-6691--kongdeveloper.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@lena-larionova lena-larionova self-assigned this Aug 17, 2026
@gergely-kurucz-konghq
gergely-kurucz-konghq force-pushed the feat/OM-361-document-mb-entitlement-enforcement branch from f8f489a to ce58189 Compare September 7, 2026 11:53
@gergely-kurucz-konghq
gergely-kurucz-konghq changed the base branch from main to release/gateway-3.16 September 7, 2026 12:03

This guide shows how to enforce {{site.metering_and_billing}} entitlements on {{site.base_gateway}} API traffic with the [Entitlement Enforcement plugin](/plugins/entitlement-enforcement/). Unlike the {{site.metering_and_billing}} plugin, which only meters usage, the Entitlement Enforcement plugin actively **blocks** requests: it polls the {{site.metering_and_billing}} Entitlement Access API for each customer and returns an error when the customer has no access to a feature or has exhausted a usage limit.

In this guide, you'll:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a high level diagram here, list all configurations need to be added, why they need to be added, and the relationship between each configuration. That will help customer to understand better about the workflow

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, thanks — done in c608568, 6d84096, and 8da72d9.

Both guides now have a "What you configure" table before the diagram, listing every prerequisite and object with where it's applied and why it's needed. The diagram was already there, but it only showed entity associations, so it now also shows the request path, the Events and Entitlement Access APIs, Redis, and labels on every edge (which token each call uses, the subject key, the feature.key).

Let me know if the level of detail is roughly what you had in mind.

Add a how-to for enforcing Metering & Billing entitlements on Gateway
traffic with the Governance plugin: provisions the M&B graph (meter,
metered + boolean features, plan with entitlements, customer,
subscription) and configures the plugin against a local Redis on a
self-hosted Data Plane.

- New guide: app/_how-tos/gateway/get-started-with-governance-metering-and-billing.md
- New prereq include for the Governance-role SPAT
- Document the Governance role in the Metering & Billing role table
Follow up two upstream renames. The Kong Gateway plugin is now Entitlement
Enforcement, and the Konnect API it calls is now Entitlement Access
(POST /v3/openmeter/entitlement-access/query, previously
/v3/openmeter/governance/query). Both renames happened because "Governance"
already means API governance in Konnect (spec linting, policy compliance,
catalog hygiene), so the old name misled readers about what the feature does.

Renamed the guide to get-started-with-entitlement-enforcement.md with the
permalink /metering-and-billing/entitlement-enforcement/get-started/, and the
prereq include to metering-and-billing-entitlement-access-spat.md. The plugin
config block now uses name: entitlement-enforcement and
entitlement_access_endpoint, and the token variable became
ENTITLEMENT_ACCESS_TOKEN (exported as DECK_ENTITLEMENT_ACCESS_TOKEN). The
Konnect role row is now Entitlement Access, matching the renamed
MeteringEntitlementAccess role. The example feature was renamed from
governed_api_access to premium_api_access to drop the remaining
governance-flavored wording.

No redirect is needed, because the guide has not shipped yet. Also added the
guide to the Metering & Billing index, where it was missing.

Request and response fields, reason codes, and the endpoint's internal and
unstable markers are unchanged, so only the URL and the names moved.
…nt Enforcement

The Entitlement Enforcement plugin ships in Kong Gateway 3.16, so declare it
in the guide's frontmatter. Note that 3.16 is not in
app/_data/products/gateway.yml yet, so the release-info generator finds no
matching release and treats the page as released: the version gating starts
working on its own once the 3.16 entry lands.
The AI Gateway story stopped at metering: meter-llm-traffic.md reports what a
customer consumed but tells readers that traffic is not blocked when their
entitlement runs out, pointing only at a concept page. This adds the guide
that closes the loop, capping per-customer LLM token usage with the
Entitlement Enforcement plugin.

The new guide combines the LLM metering setup with the Entitlement Enforcement
plugin: AI Proxy on gpt-4o, a summing meter over kong.llm_request tokens, and
a feature filtered to OpenAI prompt tokens through the API field meter.filters,
which is the API equivalent of the group-by filters the metering guide sets in
the UI. The allowance is a metered entitlement of 100 tokens with a PT1H usage
period, one hour being the shortest period the API accepts. Catalog objects are
created through the API so the customer's usage-attribution subject key can be
pinned to the Consumer's ID, which is what the plugin sends.

The validation section calls out both delays that make enforcement look broken
otherwise: entitlement usage aggregates at one-minute granularity, and the
plugin needs another refresh_interval to poll the updated state.

Also registers the guide in the Metering & Billing index and points the
metering guide's enforcement note at it.
…the guide

The Entitlement Enforcement plugin enforces exactly one feature key per
instance (schema.lua: feature record with a single required key), so the
priority_support boolean feature the guide created was never enforced by
anything in the tutorial. It appeared once more in the entitlement access
query response and nowhere else, which invited readers to expect a gateway
behavior the guide does not set up.

Removes the boolean feature, its rate card, and its mentions, and replaces
them with a sentence in the plugin section stating the one-feature-per-instance
rule and how boolean entitlements are evaluated: no access is denied with 403
and a feature_unavailable reason code.
The plugin reference page is being added in a separate PR, so both guides can
now link it instead of naming the plugin as plain text.

Links it from each guide's tldr, the opening paragraph, and related_resources,
and points the plugin configuration step at the plugin reference for the full
list of settings. The Gateway guide's note about denial reasons now defers to
the plugin page's response-code table rather than naming a single reason code,
which keeps the reason semantics documented in one place.
… guides

Credit-backed entitlements are planned but not yet supported by Metering &
Billing: the OpenMeter service declares the no_credit_available reason without
ever assigning it, and the include_credits request field is marked as not
implemented.

Removes include_credits from both entitlement access query examples, since it
has no effect today and a reader copying the request would be setting a field
that does nothing. The response_codes bullet still documents the plugin's real
402 default, now followed by a callout stating that the NO_CREDIT_AVAILABLE
reason does not occur in practice yet.
Review feedback on the get-started guide asked for a high-level view of the
configuration: what has to be created, why each piece is needed, and how the
pieces relate. The guides listed the steps and showed a diagram of entity
associations, but neither explained why a step exists or which piece depends
on which.

Adds a table before the diagram in both guides listing every configuration
object, where it's applied, and why it's needed, calling out the dependencies
that are easy to get wrong: the subject key that ties a Consumer to a customer,
the feature key the plugin enforces, the subscription that materializes the
entitlement, and the fact that nothing counts against a limit unless the
Metering & Billing plugin reports usage.

Also labels the diagram edges, so the diagram now shows which token each plugin
uses, which entity each plugin attaches to, and the subject key and feature key
relationships, rather than unlabeled arrows.
…al flow

The diagrams showed which entities were associated, but skipped hops the
guides actually configure and left out one required component:

* The Metering & Billing plugin posts usage to the Events API, which the meter
  then aggregates. The arrow went straight from the plugin to the meter, so the
  ingest endpoint the guide configures was invisible.
* Redis was absent, even though it's a prerequisite and a plugin config field.
  It now appears as the enforcement cache the plugin reads and writes.
* Neither diagram showed a request arriving, being allowed, and reaching the
  Service, so the enforcement point wasn't visible.
* The edge between the API and the customer was unlabeled and pointed as if the
  API produced the customer, rather than reading their entitlement.

Both diagrams now include a client, the Events API, the Entitlement Access API,
and Redis, with every edge labeled: which token each call uses, which entity
each plugin attaches to, and the subject key and feature key relationships. The
LLM diagram also shows AI Proxy sending the prompt to OpenAI.
…on tables

The tables covered what the guides create but not what has to exist first, so
three things the plugin configuration points at were missing or buried: Redis
appeared only as a clause inside the Entitlement Enforcement plugin row, the
two system account tokens were named without explaining that their roles are
mutually exclusive, and the Service and Route the plugins attach to were only
referenced in the Where column.

Adds prerequisite rows for the Service and Route, the two tokens, and Redis,
ordered before the objects that depend on them, and gives Redis its own row
explaining that the plugin's background timer writes fetched state there while
each worker syncs its local cache from it. The LLM guide also lists the OpenAI
API key, since without a working model call there are no tokens to meter.
…ateway/v1

The guide configures AI Proxy from AI Gateway v1, so it belongs with the other
v1 how-tos next to its companion metering guide, not at the top level of the
ai-gateway directory.

Moves it to app/_how-tos/ai-gateway/v1/ and adopts the directory's conventions:
the permalink is now /ai-gateway/v1/how-to/enforce-entitlements-on-llm-traffic/
and products lists ai-gateway alongside gateway and metering-and-billing, as
meter-llm-traffic.md does.

Updates the inbound links: the enforcement note in meter-llm-traffic.md and both
entries in the Metering & Billing index. No redirect is added because the old
permalink has never shipped.
…v1 path

Both guides now live under ai-gateway/v1, so link the metering guide by its
actual permalink instead of the pre-v1 /how-to/meter-llm-traffic/ path. That
old path redirects to the AI Gateway metering policy page rather than the
tutorial, so the link no longer landed where the surrounding prose said it
would.

Covers the related_resources entry and the opening paragraph. The remaining
references to the old path elsewhere in the docs are left alone pending a
decision on what that redirect is meant to do.
Both plugins verify the TLS certificate of the endpoint they call, and the
Entitlement Enforcement plugin also connects to Redis. The snippets left all
three settings implicit, which mattered for the Redis one: its schema default
is false, so a Data Plane running with a global tls_certificate_verify rejects
the whole configuration push and silently keeps serving its previous config.

Sets ssl_verify: true on the Metering & Billing plugin, on the Entitlement
Enforcement plugin, and in that plugin's redis block, in both guides. The two
plugin-level settings restate the schema default and make the intent explicit.
…guides

Credit-backed entitlements aren't part of the product: Metering & Billing never
returns the no_credit_available reason, and the include_credits request field is
not implemented. The guides described the plugin's 402 default and then used a
callout to explain that it doesn't happen, which reads as a coming-soon notice.

Per docs guidance, functionality that isn't in the product isn't mentioned at
all unless it's stated as a limitation. Removes the credit clause from the
response_codes bullet and deletes the callout in both guides. The plugin
reference page documents the full set of denial reasons and default responses,
and both guides already link it.
@gergely-kurucz-konghq
gergely-kurucz-konghq force-pushed the feat/OM-361-document-mb-entitlement-enforcement branch from 3765fdb to 4b3b194 Compare September 9, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants