Module: Hecks::Runtime::CommandRules::Authorization
- Included in:
- Hecks::Runtime::CommandRules
- Defined in:
- lib/hecks/runtime/command_rules/authorization.rb
Overview
Whether the caller may run this command at all — a role mismatch,
the one check that runs before any domain-state work, alongside the
argument gate rather than after it.
TWO CHECKS, NOT A REPLACEMENT — ADR 0025 §9's own caution against
"silently downgrading role to documentation" cuts both ways: a
caller who never named WHO they are (every caller before this) is
checked exactly the way it always has been, string equality
against the command's own role. Only a caller that ALSO binds an
actor_id (Hecks.as_caller(role:, actor_id:)) reaches the
real check — a live Governance::RoleAssignment lookup through
Ports::Authorization, once the command's domain declares
uses_framework "Governance" (HecksagonBuilder refuses any
domain that declares a role and does not, at build time — see
its own refuse_ungoverned_roles!). An identified caller is never
let back through the string fallback: a real identity that holds
no matching grant is refused, not waved through because it also
happens to type the right word.
Instance Method Summary collapse
-
#refuse_role_mismatch(command, domain) ⇒ Object
OPT-IN, on BOTH sides.
Instance Method Details
#refuse_role_mismatch(command, domain) ⇒ Object
OPT-IN, on BOTH sides. No caller bound: unchecked, exactly as
today. No role declared: unchecked too — role is genuinely
optional in this language (roughly a third of banking's own
commands declare none), so a command that never named a role has
nothing to check a caller against.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/hecks/runtime/command_rules/authorization.rb', line 33 def refuse_role_mismatch(command, domain) caller = Caller.current return unless caller return if command.role.to_s.empty? = if caller.actor_id && governance_attached?(domain) Ports::Authorization.holds_role?(registry, actor_id: caller.actor_id, role: command.role) else caller.role == command.role end return if raise Unauthorized, RefusalWording.render("Unauthorized", "role_mismatch", command: command.hecks_name, role: command.role, caller_role: caller.role) end |