Skip to main content

The call

The first two arguments are positional: the grant, and the scope of what is being attempted. Everything after is keyword-only. By default authorize raises on a refusal. That is deliberate: the unsafe path is the one you have to write on purpose, rather than the one you get by forgetting to inspect a return value.

Handling the four refusals

Each maps to an exception, and they are different findings with different remedies. Collapsing them into one except throws away the diagnosis.
Exhausted and Gated both subclass Blocked, so order your except clauses from specific to general. A bare except Blocked first will swallow all three and you will lose the reason.

What comes back on success

policy_outcome is what the policy decided before the grant’s enforcement mode was applied, and enforcement_mode is the mode itself. In observe and shadow those two diverge, and the divergence is the entire value of running those rungs: it is what the control would have done. ledger_id is the handle for that decision in the record. Keep it if you need to settle later.

When Rotascale is unreachable

Capture fails open and enforcement fails closed. A recording problem must not cause an outage; an unreachable control plane must not silently permit an ungoverned action. Teams that cannot accept a closed failure set fail_open_enforcement and own that explicitly. The SDK logs at error level and the decision comes back with outcome="unavailable", so the choice is at least a recorded one rather than an accident.

Next

The six outcomes

What each one means and where it sends an operator.