网页 综合 更新时间 2026-11-14 05:13:17

Rules — Claw Patrol Docs

自动蜘蛛 clawpatrol.dev 正文约 6000 字
Rules — Claw Patrol Docs
Rules are how an operator decides what happens to a request: forward it, reject it, or route it through one or more approvers — a human acting from the dashboard or Slack, an LLM judging against a policy, or both in sequence (every approver must allow). Each rule is a block in gateway.hcl that targets one or more endpoints, describes which requests it applies to (the condition CEL expression), and declares the outcome (verdict = "allow" / "deny", or approve = [...]).
There is one rule kind. The rule's protocol family — http, sql, or k8s — is inferred from its endpoint(s) at load time and pins the set of CEL variables the condition may reference. An https endpoint exposes http.method / http.path / …; a postgres or clickhouse endpoint exposes sql.verb / sql.tables / …; a kubernetes endpoint exposes k8s.verb / k8s.resource / …. A rule whose endpoints = [...] mixes families is a load error.
This page covers the operator's view: how to write a rule, what each facet does, and how rules behave in different situations.
For the surrounding picture see Architecture — request flow, where matching fits, how endpoints claim requests.
Each endpoint claims requests and emits actions of a specific family. Each action carries the family's facets, and rules match against those facets via a CEL condition expression. See Architecture for how endpoints claim requests in the first place.
Bound to https endpoints. The condition is evaluated against the parsed HTTP request before it is forwarded upstream, after MITM has terminated TLS.
Example: require approval for a specific resource mutation.
CEL variables (all optional in any given condition):
Bound to sql endpoints (postgres, clickhouse_https, clickhouse_native). The condition runs against every parsed SQL statement the agent sends.
Example: block filesystem-reaching Postgres functions.
verb, tables, and functions are extracted by a best-effort lexer over a lower-cased copy of the statement — see Case sensitivity below.
A statement that carries another statement inside it is evaluated twice: once on its own verb, and once per statement it runs. A WITH x AS (DELETE …) SELECT … is a select that also runs a delete; EXPLAIN ANALYZE …, PREPARE … AS …, DECLARE … CURSOR FOR …, COPY (…) TO … and a DO block body are the same shape. A deny on the inner statement denies the whole query, so a rule keyed on sql.verb == 'delete' fires on every one of those without being written for each wrapper. Plain EXPLAIN only plans its statement, so it carries no inner statement to judge.
tables and functions are multi-valued facets: a single statement can name several tables (SELECT ... FROM a JOIN b) and call several functions. Use CEL's in operator for a single name ('secrets' in sql.tables) or sets.intersects(...) for an overlap test against a list. To require every extracted name be covered, write the condition against sql.statement with a regex (sql.statement.matches(...)).
Bound to kubernetes endpoints. The condition sees the (verb, resource, namespace, name, params) tuple Claw Patrol parses out of the kubernetes API path.
Example: deny Kubernetes Secret reads.
proxy is its own verb because those paths proxy an arbitrary HTTP request at a pod or — for /api/v1/proxy/nodes/<node>/… — at the node's kubelet. A reads allow-list written as k8s.verb in ['get', 'list', 'watch'] does not cover them. The <resource>/proxy subresource form (…/pods/<name>/proxy/<path>) keeps the verb its HTTP method implies, so gate it on the resource.
A path shape the gateway can't decompose into that tuple — including an HTTP method the apiserver derives no verb from — has no tuple at all, so every k8s.* condition on it is unevaluable and fails closed.
A rule bound to https endpoints sees http.* only; a rule bound to kubernetes endpoints sees k8s.* only. Mixing families across a rule's endpoints = [...] is a load error.
Bound to ssh endpoints. The condition runs against each channel action the agent issues over an established SSH session — a terminal request (pty), a command (exec), the default login shell (shell), a subsystem open (sftp, …), or a direct-tcpip port forward — evaluated at the moment the action crosses the gateway, before it is forwarded upstream. A denied action refuses that one channel (the agent sees a request failure or a rejected forward); the rest of the SSH connection stays up, so other allowed actions still work.
Example: block interactive terminal sessions but allow commands.
ssh.verb is lower-cased at rule-load time (so ssh.verb == 'Pty' still matches). ssh.command, ssh.subsystem, ssh.forward_host, and ssh.stdin are matched as sent (case-sensitive).
Blocking interactive sessions. Deny ssh.verb == 'pty', not ssh.verb == 'shell'. The shell verb is only the default login shell request — an agent gets an equally interactive session via an exec'd shell (ssh host bash, ssh -t host sh), which a shell-only rule sails straight past. The pty (pseudo-terminal) request is the wire signal that a session wants a terminal; denying it tears the session channel down before any shell or exec runs, so both ssh host and ssh -t host bash are refused. (A no-terminal exec like ssh host bash without -t reads stdin as a dumb shell and isn't a pty — gate that with an ssh.command rule or an exec allowlist if your threat model needs it.)
Inspecting session stdin. ssh.stdin exposes the bytes a session pipes to a remote shell — the body of ssh build-host < deploy.sh or ssh build-host 'bash -s' < script. A rule reading it (a CEL match like ssh.stdin.contains(...), or an approve = [<judge>] chain that hands the script to an LLM) pre-gates: the gateway buffers the stdin and withholds it from the upstream shell until the verdict, so a denied script never executes — the remote read() blocks until allow. Key properties:
Scope — beyond ssh.stdin, the facet gates the channel envelope, not arbitrary channel contents. A rule sees what kind of action and which command / subsystem / forward target / piped stdin, but not
访问原文 返回搜索 https://clawpatrol.dev/docs/rules/
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。