woodglue.access¶
Grants, Roles, and the Caller of a request.
Authorization model: Grants, Roles, and the Caller of a request.
A Grant permits one action on the targets matching a glob pattern. Actions:
call: invoke methods of a namespace.read: see runs, run IO, and triggers of a namespace.trigger: fire, activate, and deactivate triggers of a namespace.view: open a UI; its targets areui:<name>.admin: manage Users, Role assignments, and tokens. Its pattern is ignored.
No action implies another. Grants are written as "<action> <pattern>" strings
in woodglue.yaml; a bare "admin" needs no pattern:
auth:
roles:
operator: ["call reports", "read *", "trigger reports"]
viewer: ["read *", "view ui:*"]
The admin Role is built in and holds every Grant.
A Caller is who a request runs as. It carries one or more Grant sets and is
allowed an action only if every set allows it, so a narrowed Personal Access
Token never exceeds its User's current Grants. current_caller holds the Caller
while a JSON-RPC call runs; it is unset for trusted in-process calls (tests,
wgl run), which check then allows.
NAMESPACE_ACTIONS = (Action.call, Action.read, Action.trigger)
module-attribute
¶
Actions whose targets are namespaces; any of them makes a namespace visible.
ANONYMOUS = Caller(user_id=None, grant_sets=(ALL_GRANTS,), name='anonymous')
module-attribute
¶
The Caller of every request when auth is disabled.
Grant
¶
Bases: BaseModel
Permission to perform action on targets matching the glob pattern.
>>> Grant.parse("call reports")
Grant(action=<Action.call: 'call'>, pattern='reports')
>>> str(Grant.parse("admin"))
'admin *'
Source code in src/woodglue/access.py
Caller
dataclass
¶
Who a request runs as. user_id is None only for the anonymous Caller
used when auth is disabled. credential_id and credential_kind name the
token or Session that authenticated the request.
Source code in src/woodglue/access.py
may_issue_credentials
property
¶
Whether this Caller may create tokens or Sessions. Only an unnarrowed Personal Access Token or a Session may: a narrowed token could mint one broader than itself, and a Delegated Token one that outlives its Session.
AccessDenied
¶
Bases: Exception
Raised by check when the current Caller lacks a Grant.
Source code in src/woodglue/access.py
allows(grants, action, target='')
¶
Whether any of grants permits action on target.
>>> gs = [Grant.parse("call rep*"), Grant.parse("view ui:*")]
>>> allows(gs, Action.call, "reports"), allows(gs, Action.call, "billing")
(True, False)
>>> allows(gs, Action.read, "reports")
False
>>> allows(gs, Action.view, "ui:billing")
True
Source code in src/woodglue/access.py
resolve_roles(roles)
¶
Parse Role definitions from config and add the built-in admin Role.
>>> r = resolve_roles({"viewer": ["read *"]})
>>> sorted(r), [str(g) for g in r["viewer"]]
(['admin', 'viewer'], ['read *'])
Source code in src/woodglue/access.py
check(action, target='')
¶
Raise AccessDenied unless the current Caller may perform action on target.
Source code in src/woodglue/access.py
visible(names)
¶
Filter namespace names to those the current Caller can see.