Skip to main content
Operator’s governance integration is two independent pieces, and you can use either on its own:
  • Ruleset management as code. The TykRuleset custom resource lets a ruleset definition live in Git next to the APIs it applies to.
  • Compliance enforcement and reporting for the APIs Operator manages. An admission webhook can reject a non-compliant TykOasApiDefinition outright, so Kubernetes never saves it.
Currently supported: TykOasApiDefinition only. Before you start:
  • This requires a Tyk license with API Governance enabled. Without the license’s governance scope, every governance endpoint returns 403 Forbidden. Operator treats this as “not licensed”: it skips governance handling and does not fail (see Licensing and skip conditions). Contact your Tyk account team to have it enabled.
  • The OperatorContext your TykRuleset and TykOasApiDefinition resources reference needs a Dashboard token with write or admin on the Governance permission group to manage rulesets. It also needs read on Governance to run compliance checks.
A note on “blocking”: elsewhere in Tyk Governance, a ruleset’s action is either none or warn. That’s true whether you save an API in Dashboard or run a CI/CD sandbox check. Nothing is ever stopped outright, only flagged. Tyk Operator is the exception.You can set a TykRuleset to action: block. The Kubernetes admission layer enforces this and can stop an API manifest before it ever reaches Kubernetes or Dashboard. See Action semantics for exactly how that works, and what it does and doesn’t affect.

Manage Rulesets as Code

Step 1: Write a TykRuleset Resource

The Spectral rule body can live inline in the resource, or in a separate ConfigMap or Secret. Inline is the simplest option for small rulesets and keeps a ruleset change to a one-file diff:
  • contextRef is optional in both source modes. It falls back to the default OperatorContext for the namespace when omitted. It’s included here for clarity, not because inline raw rulesets need it any more than objRef ones do.
  • action also defaults to none if you leave it out entirely. Tyk then evaluates the ruleset for visibility only. It never surfaces a warning or blocks anything until you explicitly set action to warn or block.
Reference an object instead of an inline rule body when the ruleset is larger, or shared by several TykRuleset resources. Do the same if the content shouldn’t sit in a plain ConfigMap, for example internal endpoint names or naming patterns:
Exactly one of ruleset.raw or ruleset.objRef must be set. The cluster rejects a resource that sets both, or neither, before it’s ever created, so Operator never has to guess which one you meant.

Step 2: Apply It

Operator creates the matching ruleset in Tyk Dashboard and keeps it in sync with the resource, and with the referenced ConfigMap or Secret if you used objRef. If you edit either one, Operator triggers an update. If you delete the TykRuleset, Operator deletes the ruleset from Dashboard.

Step 3: Verify

Dashboard assigns RulesetID, and it only appears after the first successful reconcile. kubectl describe tykruleset payments-ruleset shows the full status, such as ObjectID, Owner, and OrgID, all read back from Dashboard, never set from the spec. Rulesets apply to APIs through categories, the same mechanism used everywhere else in Tyk Governance. Add the matching category to the TykOasApiDefinition you want this ruleset to check. There’s no new field for this; spec.categories is the same field Operator already supports:
On a fresh org, apply the categorized TykOasApiDefinition before the TykRuleset that references that category. Dashboard rejects a ruleset’s categories if no API carries them yet.

Enforce and Observe Compliance at Apply Time

Step 1: Enable the Webhook (Optional)

The admission webhook is an optional part of Operator’s existing webhook infrastructure, enabled by default. Teams that don’t need enforcement see no behavior change. Enable it in your Helm values:
If you don’t enable it, Operator still reports compliance on every TykOasApiDefinition (see Step 4); you just don’t get a hard stop at kubectl apply time.

Step 2: Apply an API With Matching Categories

Take the payments-api resource from the previous section. kubectl apply now runs it against every active TykRuleset in the same namespace whose categories intersect the API’s spec.categories (resourceType: oas-api only).

Step 3: See the Outcome

With the webhook enabled, one of three things happens: Denied, when a matching block ruleset has error-level findings:
The object is never saved, not to Kubernetes, not to Dashboard. Fix the spec and re-apply. Admitted with warnings, when findings exist but nothing at error severity against a block ruleset:
Tyk admits and reconciles the API normally. The warning doesn’t name the ruleset. If the evaluation truncates the results, the message appends (results truncated). Violation details are only inlined for error-level findings. For a warnings-only case, you only get the summary line above. See status.governancePreflight or the Dashboard for the actual violations. Admitted silently, when there are no categories, no matching active oas-api rulesets in the namespace, or nothing to flag:
If the webhook isn’t enabled at all, every apply looks like this, and compliance is only visible on the resource’s status (next step).

Step 4: Check Compliance Status

Whether or not you enable the webhook, the reconciler records the result on every reconcile that resolves an OAS document:
This is a status-only reflection of the last evaluation, not a live feed. It updates on reconcile, and reconciles are hash-gated (see Reconciler behavior below), so an unchanged API in a steady state produces no new Dashboard calls.

Detailed Reference

TykRuleset Spec

For all fields, see TykRuleset in the Tyk Operator CRD reference.

Action Semantics

status.governancePreflight Fields

Populated on TykOasApiDefinition by the reconciler on every reconcile that resolves an OAS document.

How Evaluation Gets Triggered

Governance is opt-in via categories. An API is only evaluated when its spec.categories intersect the categories of active TykRuleset resources (resourceType: oas-api) in the same namespace.
  1. No categories on the TykOasApiDefinition → skipped, no Dashboard call.
  2. No matching active TykRuleset resources in the namespace → skipped, no Dashboard call. Operator checks this against the Kubernetes API directly, so it works even when governance isn’t licensed (see below).
  3. Otherwise, Operator resolves the matching ruleset set locally and evaluates against it. Operator always resolves rulesets to explicit ruleset IDs itself; it never asks Dashboard to resolve by category the way the CI/CD sandbox check can. That’s because Dashboard only ever sees block rulesets as warn (see Action semantics). So the set of TykRuleset resources in the namespace has to be the source of truth for what actually enforces.

Reconciler Behavior (Visibility)

The reconciler never blocks or withholds the Dashboard sync based on a governance result; that’s the webhook’s job. It only ever updates status and emits a Kubernetes Event (GovernancePreflightPassed / Warned / Blocked / Error):
  • A blocked result does not fail the reconcile. The API still syncs to Dashboard, with status.governancePreflight.status: blocked recorded for visibility.
  • A transport error or empty response from the evaluation call sets status: error and does fail the reconcile, which requeues. A cached error result is always re-evaluated on the next reconcile rather than trusted.
  • Evaluation is hash-gated. Operator skips the call if nothing has changed since the last evaluation. That means the OAS document, and the matched ruleset set: which resources, their action, their rule content. In steady state, a reconcile that resolves an already-evaluated API makes zero governance calls.
  • A TykRuleset create, update, or delete requeues every TykOasApiDefinition in the namespace whose categories intersect it, for a status-only re-evaluation. The API is never re-pushed to Dashboard just because a ruleset changed. This also means the reconciler only reacts to TykRuleset changes made through Kubernetes. A ruleset edited directly in the Dashboard UI doesn’t trigger a re-evaluation of already-synced APIs on its own.

Admission Outcomes

Licensing and Skip Conditions

Governance is a licensed feature. If your org’s license doesn’t include the governance scope, every governance endpoint, ruleset CRUD and evaluation alike, returns 403 Forbidden. Operator treats this as a permanent, expected condition rather than an infrastructure failure:
  • A TykRuleset whose Create/Update call gets 403 stays in a Failed transaction state with no RulesetID. In an unlicensed org, namespaces end up with zero working TykRuleset resources. So step 2 above (no matching active rulesets) skips evaluation automatically, and Operator never needs a separate license check.
  • Sometimes a TykRuleset resource is present and licensed, but the evaluation call itself returns 403. This can happen after a license change. When that happens, both the webhook and the reconciler admit or continue anyway. They log a warning and record status: skipped, not blocked or error.

Failure Policy

The webhook needs its evaluation call to reach Tyk Dashboard. webhooks.governanceFailurePolicy controls what happens when it can’t. This one setting covers two distinct failure points: the kube-apiserver unable to reach the webhook pod, and the webhook pod unable to reach Dashboard.

RBAC

The Operator manager role needs events: create;patch in addition to its existing tykrulesets read access. Without it, the API server rejects the Kubernetes event recorder used for GovernancePreflight* events. This is cluster-side RBAC for the Operator’s own service account, separate from the Dashboard-side OperatorContext token permissions listed under Before you start.

Sample Manifests

Operator ships sample manifests to apply as a starting point: