raxit
security.yaml reference

The tests: block

The tests: block -- asserting policy behavior before you ship it.

tests: is how you assert "sensitive tool defers," "unknown tool denies," and similar invariants directly in security.yaml, so a policy edit that silently breaks one is caught before it ships — not discovered live.

Shape

tests:
  - name: calc is permitted
    action: calc
    expect: permit
  - name: stripe/refund defers (sensitive tool)
    action: stripe/refund
    expect: defer
  - name: stripe/payouts is denied (forbidden)
    action: stripe/payouts
    expect: deny
  - name: unknown_tool is denied (default-deny)
    action: unknown_tool
    expect: deny
FieldRequiredNotes
nameyesunique within the document
principalnodefaults to the document's agent:
actionyesthe resource under test
argsnoscalar args, projected into Cedar context
contextnoextra context fields (e.g. phase)
expectyesexactly one of permit, defer, deny
expect_reasonnoexpected ReasonCode string; unset = not checked
expect_typenoone of ALLOW, DENY, MODIFY, STEP_UP, DEFER

expect is a coarse 3-value check. expect_type is a finer, 5-value projection of the same outcome, never a replacement — pairing expect: permit with expect_type: MODIFY asserts "this permits, and specifically via a modify rule." A review rule's test correctly expects defer (coarse) or STEP_UP (fine) — both are correct, at different resolution.

Errors: security.yaml: tests[0].name is required, security.yaml: tests: duplicate test name "x", security.yaml: tests[0].action is required, security.yaml: tests[0].expect "x" must be one of permit, defer, deny, security.yaml: tests[0].expect_type "x" must be one of ALLOW, DENY, MODIFY, STEP_UP, DEFER.

What tests: evaluates against

raxit test runs each case against the pure Cedar policy decision — not the full stateful governor pipeline. Warrant upgrades, session taint, budgets, and other runtime governors are excluded by design: a review rule's test correctly expects defer regardless of whether a warrant would upgrade it to permit at runtime.

raxit test output

$ raxit test
ok  1 - calc is permitted
ok  2 - unknown_tool is denied (default-deny)

2/2 passed

A failing case:

$ raxit test
FAIL 1 - calc should be denied but rule says allow (intentional failure): got "permit", want "deny"

0/1 passed, 1 failed: calc should be denied but rule says allow (intentional failure)
raxit test: 1 test case(s) failed

Exit code 1 on any failure — this is what makes tests: usable as a CI gate, not just a manual sanity check.

apply runs this gate — but only apply

raxit apply's pipeline is validate → run tests: → push to the daemon. A policy that fails its own tests: block is never applied:

$ raxit apply
FAIL 1 - calc should be denied but rule says allow (intentional failure): got "permit", want "deny"

0/1 passed, 1 failed: calc should be denied but rule says allow (intentional failure)
apply refused (tests): raxit test: 1 test case(s) failed
(no changes made; the last-applied policy is still enforced)

The tests: gate is enforced client-side, inside raxit apply. A bare authenticated POST /v1/reload against a running daemon (bypassing apply) loads and validates Cedar syntax, but does not run tests: — it's possible to activate a policy directly against the daemon that would have failed its own declared tests. Always ship policy changes through raxit apply, not a raw reload call.

On this page