DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk5 min

Two CEL Authorization Gotchas in agentgateway: When Policy Logic Fails Open vs. Fails Closed

A CEL error in agentgateway is treated as false, so require denies but deny quietly doesn't match. External authorization failure is a separate setting.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In agentgateway, “fail open” and “fail closed” describe two unrelated events. The first is a CEL expression that cannot be evaluated, for example because a JWT claim is missing. The second is an external authorization service that is down or returning errors. Mixing them up can leave a mandatory check unenforced.

The short version: in standalone HTTP authorization, an expression that errors is treated as false. A require that is false or errors denies the request. A deny that is false or errors simply does not match, so it blocks nothing by itself. External authorization availability is a separate setting, failureMode, which defaults to FailClosed.

As an Amazon Associate I earn from qualifying purchases.

Scope note: this article is based on the official agentgateway documentation, which is published under rolling “latest” paths. Those pages do not name a specific release, and no geographic limitation is stated. Check the behavior against the version and configuration mode you actually run. The docs label their authorization code examples as automatically tested; that is the vendor’s statement, not something verified independently here.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Gotcha 1: a failing CEL expression is just false

The standalone HTTP authorization documentation states: “A CEL expression that cannot be evaluated is treated as false.” Its example of an undefined value is a missing jwt.aud. Whether “false” is safe depends on which rule type holds the expression.

Rule type Expression true Expression false or errors Net effect
require Condition satisfied Request denied Fails closed
deny Request blocked Rule does not match; it does not deny Effectively fails open for that rule
allow Request permitted Rule does not match; fallback applies Depends on whether other allow rules exist

The trap with deny

Take the docs’ rule deny: 'jwt.aud != "my-service"'. It reads like “block anything not meant for my service.” But if the token has no aud claim, the expression errors, is treated as false, and the deny does not match. The request is not blocked by that rule. If other rules permit it, or nothing else gates it, traffic proceeds.

The fix: use require for mandatory conditions

The docs say: “For mandatory conditions such as ‘all requests must have a valid audience claim,’ prefer require, which fails closed.” Every require rule must match, so a missing claim denies the request instead of slipping past.

When a claim is optional and you are testing it, guard it with has(), as the docs do: has(jwt.group) && jwt.group == 'eng'. This evaluates cleanly to false when the claim is absent, rather than relying on an error being coerced to false.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How standalone rules combine

The documented evaluation order for standalone HTTP authorization:

  1. No rules configured: the request is allowed.
  2. Any matching deny blocks the request.
  3. Any non-matching require blocks the request.
  4. A matching allow permits it.
  5. Otherwise the fallback depends on whether any allow rule exists. With allow rules configured, unmatched requests are denied (allowlist behavior). With none, unmatched requests are allowed (denylist behavior).

This is why an erroring deny is risky in a denylist setup: with no allow rules, nothing else catches the request. In an allowlist setup, a failed deny is less dangerous only because the request must still match some allow rule.

Kubernetes AgentgatewayPolicy works differently

On Kubernetes, authorization lives in an AgentgatewayPolicy authorization block with one action and a policy made of CEL match expressions. The syntax and combination rules differ from the standalone rules examples, so don’t copy semantics between them.

  • Allow: grants access when at least one expression matches.
  • Require: every expression must evaluate true.
  • Deny: blocks when at least one expression matches.

Across policies, Deny is evaluated first, then Require, then Allow. If any Allow rule exists, one Allow expression must match. If only Require rules exist, requests that pass all of them can proceed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Kubernetes guide’s treatment of erroring expressions is not covered in the material reviewed here; the “treated as false” sentence appears on the standalone page. The same reasoning is still prudent: write mandatory conditions as Require, and guard optional claims with has().

Authentication comes first

A missing, malformed, or unverifiable JWT fails authentication with a 401 before any authorization expression runs. Authorization denials return 403. So the missing-claim problem applies to a token that is valid but lacks a particular claim, not to a missing or invalid token.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Gotcha 2: external authorization has its own failure mode

If you delegate decisions to an external authorization service, the API reference provides failureMode:

  • FailClosed (default): the request is denied if the service is unavailable or returns an error.
  • FailOpen: the request continues in that situation.

This is about service availability. It has nothing to do with a CEL deny evaluating to false. Setting FailClosed won’t make an errored deny expression block traffic, and a require rule’s strictness doesn’t tell you what happens when your auth service is down.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick comparison

Axis CEL expression error External auth service failure
Failure source Expression cannot be evaluated (e.g., missing jwt.aud) Service unavailable or returning an error
Controlled by Rule type: require, deny, allow failureMode
Default behavior Treated as false; outcome depends on rule type FailClosed
Risky choice Mandatory check written as deny FailOpen on a security-critical path

Neighboring failure settings

Other features have their own switches, which is another reason to avoid a global mental model of “fail open”:

  • External processing (ExtProc): failOpen applies only before request body bytes begin streaming to the processor. Once streaming starts, a failure returns an error even with failOpen.
  • Remote rate limiting: fails closed by default on service failure, with an explicit failOpen option to allow requests while the rate limit service is unavailable.

Review checklist

  • Identify your mode: standalone HTTP authorization rules, or Kubernetes AgentgatewayPolicy actions.
  • Express every must-have condition as require (Require), not as an inverted deny.
  • Guard optional claims with has() before comparing them.
  • Know your fallback: are any allow rules configured? If not, unmatched requests are allowed in standalone mode.
  • Test with tokens that are valid but missing the claim, not just tokens with wrong values. The standalone docs point to the built-in CEL playground in the agentgateway UI for trying expressions.
  • Set failureMode deliberately for external authorization, and leave it at FailClosed unless availability outweighs enforcement.

The Kubernetes setup path requires installing agentgateway, creating a Gateway and a sample backend, then applying an AgentgatewayPolicy. The documentation reviewed contains no statistics or benchmarks on these behaviors, and none are cited here.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.