Checkpoint Docs
Enforce

Deny List (Legacy)

Block a specific agent — the legacy list, and the Cedar rule that replaces it

Blocking a specific agent

The task on this page — "block this specific agent" — is now expressed as a Cedar policy authored in Compose, not as a standalone list. Cedar is the current enforcement model; the deny list described further down is the legacy structured layer it supersedes.

The deny list is part of the older structured/WAF policy layer. It still runs today, but new enforcement should be authored as Cedar. The dashboard's list UI has moved to Agent Lists (the old /deny-list route now redirects to /agent-lists).

To block a named agent everywhere, add a forbid rule. Author it in plain language in Compose and Checkpoint compiles it to Cedar like this:

@id("block-gptbot")
@verdict("BLOCK")
forbid ( principal, action, resource )
when { principal.name == "GPTBot" };

A composed policy is allow-by-default with forbid carve-outs — every forbid rule you add carves out a stricter verdict (here, BLOCK) for the traffic it names, and everything else keeps flowing. Because Cedar is forbid-overrides, a matching block always wins.

Block a set of agents

To block several agents in one rule, OR the names together. A named-agent match is a principal.name equality, so a set is a disjunction of equalities:

@id("block-scraper-agents")
@verdict("BLOCK")
forbid ( principal, action, resource )
when { (principal.name == "GPTBot" || principal.name == "CCBot") };

Do not reach for Cedar's in operator here. in tests entity-hierarchy membership, not String set-membership, so principal.name in ["GPTBot", "CCBot"] would never fire. Use an OR of == equalities, as above.

Block on specific paths, or add exceptions

Because it's Cedar, the same rule composes with paths and carve-outs — for example, block an agent only on /pricing, or block unless it presents a verified identity. See Common patterns for path scoping, redirect, challenge, and consent-scope examples.

The legacy deny list

This section documents the legacy behavior for projects still running the structured layer. For new work, prefer the Cedar forbid rule above. Manage existing entries under Agent Lists in the dashboard.

The legacy deny list blocks matching traffic with an HTTP 403. It matches on the detected agent, not on raw request attributes:

Match typeSemantics
Agent DIDExact match against the request's delegation DID
Client nameSubstring match against the detected agent name (case-insensitive)

There is no separate wildcard-pattern engine for deny entries — a "client name" entry of scraper matches any detected agent name that contains scraper; you do not write *scraper*. IP-address, CIDR, and browser-fingerprint blocking are not part of the edge deny-list path.

Evaluation order

The deny list is not the highest-priority check. Detection runs first, then the structured policy pipeline evaluates in this order:

1. Path rules      (may allow or block a specific path)
2. Allow list      (exempt a named agent)
3. Deny list       ← evaluated here, after path rules and allow list
4. Confidence threshold
5. Default action

So an allow-list match short-circuits before the deny list is consulted, and a deny match applies only after detection has already classified the request. The deny list is not a pre-detection fast path.

Next Steps