RBAC authorization plugin for the workflow engine using Casbin.
| 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 |
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"]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
}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 templateTemplate-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.
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 templatesTemplate-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.
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"]]
}make build # outputs bin/workflow-plugin-authz
make test # run tests with race detectormake install INSTALL_DIR=data/plugins/workflow-plugin-authz