Module: Magik::Policy
- Defined in:
- lib/magik/policy.rb
Overview
Authorization: one rule per resource verb, evaluated identically in every surface that projects from a declaration — screens, actions, API resources, channels, jobs and the admin panel.
Implements: Phase 2 — Rendering & Actions of docs/idea/00-build-spec.md
(architecture decision 13, added by amendment on 2026-08-26).
Planned DSL surface, copied from the spec:
policy :Name do default :deny; can :verb do |actor, record| ... end endscreen/action/channel/job/api ..., policy: %i[Name verb]roles/staff_roleson the app composition root
Two decisions carried from the audit that found this gap
(docs/idea/10-saas-coverage.md), both load-bearing:
- Phase 2, not Phase 7. Adding a
policy:argument to six constructs after those constructs exist is the retrofit the spec itself calls unsurvivable when it says it abouttenant_id. - Tier 1, not tier 3 beside Auth. Render and
Realtime sit at tier 2 and must evaluate policies, and imports
go strictly down a tier. So the evaluator takes the actor as an opaque
value — exactly as Router takes a path without knowing what a
screen is — and
authat tier 3 supplies it.
Authorization is deliberately not a swap point: a second backend is a second authorization system, which is how frameworks of this shape die.
Status: Not implemented — spec only. Every entry point below raises NotImplementedError.
Constant Summary collapse
- SPEC_PHASE =
The build-spec phase this subsystem implements.
"Phase 2 — Rendering & Actions"- DSL_SURFACE =
The DSL this subsystem will expose, verbatim from the spec.
[ "policy :Name do default :deny; can :verb do |actor, record| ... end end", "screen/action/channel/job/api ..., policy: %i[Name verb]", "roles :owner, :admin, :member, :viewer, default: :member", "staff_roles :support, :support_lead — a separate axis from tenant membership" ].freeze
- STATUS =
Implementation status of this subsystem.
"Not implemented — spec only"
Class Method Summary collapse
-
.define(*_args, **_options) ⇒ void
Entry point for the Policy DSL.
Class Method Details
.define(*_args, **_options) ⇒ void
This method returns an undefined value.
Entry point for the Policy DSL.
61 62 63 |
# File 'lib/magik/policy.rb', line 61 def self.define(*_args, **) raise NotImplementedError, "Magik::Policy is spec-only; see docs/idea/00-build-spec.md" end |