Rego — 18 Operations for AI Agents

Rego is policy as code: OPA admission control, authorization decisions, compliance gates across Kubernetes and CI. act101 lets agents navigate policies structurally, finding the rule that allowed or denied a request without re-reading the bundle.

This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Rego code through the act MCP server. 18 operations available: 0 refactor, 18 query, 0 analysis. Each operation is callable from Claude Code, Cursor, Codex, OpenCode, or any MCP-compatible agent host. Click any operation for a stable anchor link suitable for citation.

18Query

Worked Rego examples

act101 reads a Rego file's package declaration, each import statement, and every rule definition as declarations. The skeleton tags the package a module, named for its dotted path; tags each rule clause function, named for the rule — a rule with more than one clause, like a default value alongside its full body, reports one function declaration per clause, all sharing the rule's name; and tags each import statement import, but names it literally "import" in every case, since the rule captures only the bare import keyword and never reaches for the sibling node holding the actual imported path. symbols covers the package and every rule clause but has no rule for import at all, so it drops the import entirely rather than repeating its useless name. The unit of structure in this grammar is the top-level statement: neither query descends into a rule's own body conditions. Each example below is the verbatim output of the command shown, run against the file shown. Query outputs are pretty-printed with the timing block omitted.

Read the badge-access policy's package, import, and rules as a skeleton

badge-access.rego declares the physical.badge_access package, imports future.keywords.in, and defines allow (a default clause plus a full clause), after_hours, and deny_reason.

$ act query skeleton badge-access.rego

Before

package physical.badge_access

import future.keywords.in

default allow := false

allow if {
	input.employee.clearance_level >= input.door.required_level
	input.employee.department in input.door.allowed_departments
}

after_hours if {
	input.request_time.hour < 6
}

deny_reason contains "outside authorized hours" if {
	after_hours
	not input.employee.on_call
}

Output

{
    "type": "Skeleton",
    "declarations": [
        {
            "kind": "module",
            "name": "physical.badge_access",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 1,
                    "column": 1,
                    "byte_offset": 0
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 19,
                    "column": 2,
                    "byte_offset": 362
                }
            },
            "name_range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 1,
                    "column": 9,
                    "byte_offset": 8
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 1,
                    "column": 30,
                    "byte_offset": 29
                }
            }
        },
        {
            "kind": "import",
            "name": "import",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 3,
                    "column": 1,
                    "byte_offset": 31
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 3,
                    "column": 7,
                    "byte_offset": 37
                }
            }
        },
        {
            "kind": "function",
            "name": "allow",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 1,
                    "byte_offset": 58
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 23,
                    "byte_offset": 80
                }
            },
            "name_range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 9,
                    "byte_offset": 66
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 14,
                    "byte_offset": 71
                }
            }
        },
        {
            "kind": "function",
            "name": "allow",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 7,
                    "column": 1,
                    "byte_offset": 82
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 10,
                    "column": 2,
                    "byte_offset": 216
                }
            },
            "name_range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 7,
                    "column": 1,
                    "byte_offset": 82
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 7,
                    "column": 6,
                    "byte_offset": 87
                }
            }
        },
        {
            "kind": "function",
            "name": "after_hours",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 12,
                    "column": 1,
                    "byte_offset": 218
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 14,
                    "column": 2,
                    "byte_offset": 265
                }
            },
            "name_range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 12,
                    "column": 1,
                    "byte_offset": 218
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 12,
                    "column": 12,
                    "byte_offset": 229
                }
            }
        },
        {
            "kind": "function",
            "name": "deny_reason",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 16,
                    "column": 1,
                    "byte_offset": 267
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 19,
                    "column": 2,
                    "byte_offset": 362
                }
            },
            "name_range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 16,
                    "column": 1,
                    "byte_offset": 267
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 16,
                    "column": 12,
                    "byte_offset": 278
                }
            }
        }
    ]
}

The skeleton reports six declarations: the package as module, the import as import named literally "import" rather than future.keywords.in, allow twice — once for its default clause and once for its full if clause — and after_hours and deny_reason once each, all function.

List the package and rule clauses as symbols

The same file has one package and four rule clauses; the import statement is not a rule.

$ act query symbols badge-access.rego

Before

package physical.badge_access

import future.keywords.in

default allow := false

allow if {
	input.employee.clearance_level >= input.door.required_level
	input.employee.department in input.door.allowed_departments
}

after_hours if {
	input.request_time.hour < 6
}

deny_reason contains "outside authorized hours" if {
	after_hours
	not input.employee.on_call
}

Output

{
    "type": "Symbols",
    "symbols": [
        {
            "name": "physical.badge_access",
            "kind": "module",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 1,
                    "column": 9,
                    "byte_offset": 8
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 1,
                    "column": 30,
                    "byte_offset": 29
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "allow",
            "kind": "function",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 9,
                    "byte_offset": 66
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 5,
                    "column": 14,
                    "byte_offset": 71
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "allow",
            "kind": "function",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 7,
                    "column": 1,
                    "byte_offset": 82
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 7,
                    "column": 6,
                    "byte_offset": 87
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "after_hours",
            "kind": "function",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 12,
                    "column": 1,
                    "byte_offset": 218
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 12,
                    "column": 12,
                    "byte_offset": 229
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "deny_reason",
            "kind": "function",
            "range": {
                "start": {
                    "file": "badge-access.rego",
                    "line": 16,
                    "column": 1,
                    "byte_offset": 267
                },
                "end": {
                    "file": "badge-access.rego",
                    "line": 16,
                    "column": 12,
                    "byte_offset": 278
                }
            },
            "visibility": "unknown"
        }
    ]
}

symbols reports five entries — physical.badge_access as module and the same four rule clauses as function — dropping the import that skeleton listed.

Query

18 query tools, the same on every supported language. Descriptions live in the shared reference: /docs/query-tools.

callers control_flow data_flow definition diagnostics effect_closure effect_summary fix_auto get_type graph import_organize interface mutations references repo_outline skeleton symbols symbols_batch

← RazorReScript →