Skip to content
Ironflow is pre-1.0: APIs can change between releases. Pin a version. What is ready →

ironflow policy

Manage the Rego policy set of an organization (authorization Layer 2).

Terminal window
ironflow policy <subcommand> [flags]

RBAC roles (Layer 1) grant capabilities. The policy set can only deny on top of them. A new set starts in monitor mode: it records what it would deny and blocks nothing. See Authorization policy sets for the model and Author a policy set for a walkthrough.

The commands work on the set of your organization. Add --platform to address the platform organization’s set. That needs platform credentials. Policy writes need the orgs:manage action (platform:policies:manage for --platform).

Layer 2 applies only when the server runs with spec.auth.policyEnforcement: true. When it is off, pull prints a warning, and the set is stored but not enforced.

These flags exist on every subcommand except force-monitor, which has only --server.

FlagShortTypeDefaultDescription
--server-sstringIRONFLOW_SERVER_URL or http://localhost:9123Server URL.
--platformboolfalseAddress the platform organization’s set.

Write the active policy set, the IRN library and the input schema to a directory.

Terminal window
ironflow policy pull <dir> [flags]

Arguments:

ArgumentRequiredDescription
dirYesThe directory to write. Ironflow creates it if needed.

Flags:

FlagTypeDefaultDescription
--pruneboolfalseDelete local .rego files that are not in the server’s set. Other files are kept.

pull writes:

  • the files of the set, with their names,
  • .ironflow/lib/irn.rego, the IRN library,
  • .ironflow/input.schema.json, the schema of input,
  • .ironflow-policy.json, with version, decision and mode.

If <dir> holds .rego files that the server does not have, pull stops and lists them. --prune deletes exactly those files, and never .ironflow/. pull refuses to write through a symlink, and refuses a file name that is not a path inside <dir>.

Output:

Pulled version 4 (3 files, mode monitor) into ./policies

Replace the active policy set with the .rego files in a directory.

Terminal window
ironflow policy push <dir> [flags]

push reads every .rego file under <dir>, except .ironflow/ and .git/. It skips symlinks with a warning. The write is conditional. It sends the version from .ironflow-policy.json (written by pull) as If-Match, or the value of --if-version. If another admin wrote first, the server answers 412. Pull, merge and push again.

Flags:

FlagTypeDefaultDescription
--if-versionintThe expected current version. Pass it when <dir> has no .ironflow-policy.json. Then the decision rule and mode are not read from the file, and the CLI warns that the decision rule is cleared unless you pass --decision.
--modestringkeep the current modeenforce or monitor. A new set starts in monitor.
--decisionstringfrom .ironflow-policy.jsonThe decision rule path, for example data.envoy.authz.allow.
--bypass-self-lockout-preflightboolfalseSkip the self-lockout preflight. Break-glass.
--bypass-reasonstringRequired with the bypass flag. The CLI cuts it to 200 bytes.

Output:

Pushed version 5 (3 files, mode monitor)

If the server answers 503 policy_set_not_propagated, the set is saved but not yet active on every node. The CLI writes the saved version to .ironflow-policy.json and tells you to run the same push again.

Check the .rego files in a directory without saving them. The server compiles the set and applies every write rule.

Terminal window
ironflow policy validate <dir> [flags]

Flags:

FlagTypeDefaultDescription
--modestringenforce or monitor.
--decisionstringfrom .ironflow-policy.jsonThe decision rule path.

Output:

valid: 3 files

A failure prints one line for each problem, as file:line:col: message, and exits with an error.

Evaluate a policy set for one input. Nothing is stored.

Terminal window
ironflow policy dry-run [dir] --input <file> [flags]

With <dir>, the command evaluates the files on disk as a candidate set. Without it, the command evaluates the active set on the server.

Flags:

FlagTypeDefaultDescription
--inputstringRequired. A JSON file with request and subject, and optionally attributes for the Envoy view.
--decisionstringfrom .ironflow-policy.jsonThe decision rule path for a directory dry-run.
--explainboolfalsePrint the trace notes. Add trace("...") calls to your rules.

The decision rule is evaluated only when the input has an attributes key.

Output:

decision: deny (set mode: monitor)
denied by: deny
- members cannot delete runs

decision is the verdict of the set, also for a monitor set. A line evaluation error: <class> shows when the set failed. See Debug a deny.

List the versions of the set, newest first. Ironflow keeps the newest 100.

Terminal window
ironflow policy versions [flags]

Output:

VERSION MODE CREATED BY DECISION
4 enforce 2026-10-12T08:00:00.000000Z user_ann
3 monitor 2026-10-11T09:11:48.000000Z user_ann

Make an earlier version’s files and decision rule the active set, as a new version. History never changes.

Terminal window
ironflow policy rollback <version> [flags]

Arguments:

ArgumentRequiredDescription
versionYesThe version to restore. A positive integer.

The active mode stays. A rollback does not switch enforcement on or off. The CLI does not change local files. Run ironflow policy pull <dir> afterward.

Flags:

FlagTypeDefaultDescription
--dirstring.A pulled directory. Its .ironflow-policy.json gives the current version.
--if-versionintThe expected current version, instead of --dir.
--bypass-self-lockout-preflightboolfalseSkip the self-lockout preflight. Break-glass.
--bypass-reasonstringRequired with the bypass flag.

Output:

rolled back to version 3 as version 6; run `ironflow policy pull <dir>` to get the restored files

If the server answers 503 policy_set_not_propagated, run the same rollback again with --if-version set to the saved version that the message names.

Break-glass for platform operators. Switch the policy set of an organization to monitor mode.

Terminal window
ironflow policy force-monitor <org> --reason "<text>" [flags]

Use it when a set in enforce mode denies the policy-set routes, or when a stored set no longer compiles. The command writes a new version of the same files in monitor mode. It does not compile the set. The request is evaluated against the platform set, never against the set of the organization. It needs platform credentials.

Arguments:

ArgumentRequiredDescription
orgYesThe organization ID.

Flags:

FlagShortTypeDefaultDescription
--reasonstringRequired. 1 to 200 bytes. Recorded in the audit log.
--server-sstringServer URL.

Output:

Organization org_acme policy set is in monitor mode (version 5)

See Recover from a lockout.

Terminal window
# Start a policy repository from the server
ironflow policy pull ./policies
# Test locally, then check on the server
opa test ./policies
ironflow policy validate ./policies
ironflow policy dry-run ./policies --input request.json --explain
# Push in monitor mode, then switch to enforce
ironflow policy push ./policies
ironflow policy push ./policies --mode enforce
# Push a set for an Envoy policy
ironflow policy push ./policies --decision data.envoy.authz.allow
# Versions and rollback
ironflow policy versions
ironflow policy rollback 3 --dir ./policies
ironflow policy pull ./policies
# Platform organization's set
ironflow policy pull ./platform-policies --platform
# Break-glass for a bricked organization set
ironflow policy force-monitor org_acme --reason "enforce set denies policy routes, ticket 4412"
# Break-glass for a refused corrective push (needs an API key)
ironflow policy push ./policies \
--bypass-self-lockout-preflight \
--bypass-reason "incident-217 emergency lockout recovery"