workflow-plugin-authz
RBAC authorization plugin for the workflow engine using Casbin.
Capabilities
| Type |
Name |
| Module |
authz.casbin |
| Step |
step.authz_check_casbin |
| Step |
step.authz_add_policy |
| Step |
step.authz_remove_policy |
| Step |
step.authz_role_assign |
authz.casbin module
Loads a Casbin PERM model and policy from inline YAML config. The enforcer is thread-safe and shared with all step.authz_check_casbin steps that reference the module by name.
modules:
- name: authz
type: authz.casbin
config:
model: |
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
policies:
- ["admin", "/*", "*"]
- ["editor", "/api/*", "GET"]
- ["editor", "/api/*", "POST"]
- ["viewer", "/api/*", "GET"]
roleAssignments:
- ["alice", "admin"]
- ["bob", "editor"]
- ["carol", "viewer"]
step.authz_check_casbin pipeline step
Checks whether the authenticated user (injected by step.auth_required) has permission to perform the configured action on the configured object. Returns HTTP 403 and stops the pipeline on denial.
steps:
- type: step.auth_required # sets auth_user_id in output
config: {}
- type: step.authz_check_casbin
config:
module: authz # authz.casbin module name (default: "authz")
subject_key: auth_user_id # step output key for the subject (default: "auth_user_id")
object: "/api/v1/tenants" # static path, or Go template: "{{.request_path}}"
action: "POST" # static method, or Go template: "{{.request_method}}"
On success the step outputs:
{
"authz_subject": "alice",
"authz_object": "/api/v1/tenants",
"authz_action": "POST",
"authz_allowed": true
}
On denial (HTTP 403):
{
"response_status": 403,
"response_body": "{\"error\":\"forbidden: bob is not permitted to POST /api/v1/tenants\"}",
"response_headers": {"Content-Type": "application/json"},
"authz_allowed": false
}
step.authz_add_policy pipeline step
Adds a policy rule to the Casbin enforcer at runtime; when the rule actually changes the policy (that is, it is newly added), the step saves the updated policy via the module's configured Casbin adapter (file/GORM adapters persist to their backing store, while the in-memory adapter keeps changes for the lifetime of the process). Each element of rule may be a static string or a Go template rendered against the merged pipeline context (trigger data, prior step outputs, and current context).
steps:
- type: step.authz_add_policy
config:
module: authz # authz.casbin module name (default: "authz")
rule: ["editor", "/api/posts", "POST"] # policy rule; each element may be a Go template
Template-based rule (values resolved from the pipeline context at runtime):
steps:
- type: step.authz_add_policy
config:
module: authz
rule: ["{{.role}}", "{{.resource}}", "{{.method}}"]
On success the step outputs:
{
"authz_policy_added": true,
"authz_rule": ["editor", "/api/posts", "POST"]
}
authz_policy_added is false when the rule already existed in the enforcer.
step.authz_remove_policy pipeline step
Removes a policy rule from the Casbin enforcer at runtime. Mirrors step.authz_add_policy in configuration; each element of rule may be a static string or a Go template.
steps:
- type: step.authz_remove_policy
config:
module: authz # authz.casbin module name (default: "authz")
rule: ["editor", "/api/posts", "POST"] # policy rule to remove; elements may be Go templates
Template-based rule:
steps:
- type: step.authz_remove_policy
config:
module: authz
rule: ["{{.role}}", "{{.resource}}", "{{.method}}"]
On success the step outputs:
{
"authz_policy_removed": true,
"authz_rule": ["editor", "/api/posts", "POST"]
}
authz_policy_removed is false when the rule did not exist in the enforcer.
step.authz_role_assign pipeline step
Adds or removes role mappings (grouping policies) in the Casbin enforcer at runtime. Useful for provisioning authorization when new users or tenants are onboarded.
| Config field |
Type |
Default |
Description |
module |
string |
"authz" |
Name of the authz.casbin module |
action |
string |
"add" |
"add" to assign a role, "remove" to revoke it |
assignments |
list of grouping policy rows |
— |
One or more grouping policy rows, each with at least [user, role]; each value may be a Go template |
Assign roles (static):
steps:
- type: step.authz_role_assign
config:
module: authz
action: add # "add" (default) or "remove"
assignments:
- ["alice", "admin"]
- ["bob", "editor"]
Assign a role using templates (values resolved from the pipeline context at runtime):
steps:
- type: step.authz_role_assign
config:
module: authz
action: add
assignments:
- ["{{.new_user_id}}", "{{.tenant_role}}"]
Revoke a role:
steps:
- type: step.authz_role_assign
config:
module: authz
action: remove
assignments:
- ["bob", "editor"]
On success the step outputs:
{
"authz_role_action": "add",
"authz_role_assignments": [["alice", "admin"], ["bob", "editor"]]
}
Build
make build # outputs bin/workflow-plugin-authz
make test # run tests with race detector
Install
make install INSTALL_DIR=data/plugins/workflow-plugin-authz