Workflow Tasks
Thand provides custom workflow tasks that extend the Serverless Workflow specification with access control operations. These tasks are invoked using the thand: keyword and handle the core functionality of the Thand Agent.
Task Overview
Custom Thand tasks handle the complete access control lifecycle:
| Task | Purpose | Phase |
|---|---|---|
validate | Validate access requests and user permissions | Pre-authorization |
approvals | Handle approval workflows with notifications | Authorization |
authorize | Grant temporary access to requested resources | Authorization |
monitor | Monitor usage and detect policy violations | Post-authorization |
revoke | Remove granted access | Post-authorization |
notify | Send notifications to users and administrators | Cross-cutting |
Task Syntax
All Thand tasks follow this syntax:
- step-name:
thand: task-name
with:
parameter1: value1
parameter2: value2
then: next-step
on:
condition1: target-step1
condition2: target-step2
validate
The validate task verifies that access requests are valid and that users have permission to request specific roles.
Syntax
- validate:
thand: validate
with:
validator: static|llm # Validation method (optional, defaults to "static")
then: next-step
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
validator | string | No | static | Validation method: static for rule-based, llm for AI-enhanced |
Validation Methods
Static Validation
Uses predefined rules to validate requests. This is the default validation method:
- validate:
thand: validate
with:
validator: static
then: approvals
The static validator:
- Validates that the user is provided
- Validates that the role is provided
- Validates that the reason is provided
- Validates that the duration format is correct (converts to ISO 8601)
- Validates that providers are specified
- Calls the provider’s role validation
LLM Validation
Uses AI to validate requests for enhanced validation:
- validate:
thand: validate
with:
validator: llm
model: gemini-2.5-pro # Optional model specification
then: approvals
Note: LLM validation is currently implemented but the functionality is limited to model specification.
Examples
Basic Static Validation
- validate-request:
thand: validate
then: approve-request
LLM Validation with Model
- intelligent-validate:
thand: validate
with:
validator: llm
model: gemini-2.5-pro
then: risk-assessment
approvals
The approvals task handles approval workflows by sending notifications to approvers and waiting for approval decisions.
Syntax
- approvals:
thand: approvals
with:
approvals: number # Required approvals
notifier: # Notification configuration
provider: string
to: string
message: string
on:
approved: target-step
denied: target-step
then: default-step
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
approvals | number | Yes | Number of approvals required |
notifier | object | Yes | Notification configuration |
Notifier Configuration
The notifier object configures how approval requests are sent:
notifier:
provider: slack # Notification provider
to: "C0123456789" # Channel ID or user ID
message: "Approval needed" # Custom message (supports templating)
Supported Providers
| Provider | Purpose | Target Format |
|---|---|---|
slack | Slack notifications | Channel ID: C0123456789 or User ID |
email | Email notifications | Email address |
Flow Control
The approvals task uses the on directive for conditional flow:
- approvals:
thand: approvals
with:
approvals: 2
notifier: { ... }
on:
approved: grant-access # If approved
denied: send-denial # If denied
then: timeout-handler # If insufficient approvals (loops back)
Approval Logic
The approvals task implements the following logic:
- Sends notifications using the specified notifier
- Listens for approval events (
com.thand.approval) - Collects approvals in the workflow context
- If any approval is
false(denied), routes to thedeniedstate - If the number of
trueapprovals meets the required count, routes to theapprovedstate - Otherwise, loops back to wait for more approvals
Examples
Basic Slack Approval
- manager-approval:
thand: approvals
with:
approvals: 1
notifier:
provider: slack
to: "C0123456789"
message: >
The user ${ .user.name } is requesting ${ .role.name } access.
Reason: ${ .reason }
on:
approved: grant-access
denied: deny-request
then: deny-request
Email Approval
- email-approval:
thand: approvals
with:
approvals: 1
notifier:
provider: email
to: "manager@company.com"
message: "Access request needs approval"
on:
approved: authorize
denied: denied
authorize
The authorize task grants temporary access to the requested role and resources.
Syntax
- authorize:
thand: authorize
with:
revocation: string # Optional revocation step name
then: next-step
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
revocation | string | No | Step to call for revocation |
Authorization Process
The authorize task:
- Validates the request is approved (checks workflow context)
- Creates temporary credentials/access across all specified providers
- Registers the session information
- Returns authorization details with timestamps
Authorization Context
The authorize task checks if the request has been approved by looking at the workflow context. If already approved, it returns basic model output with timestamps.
Examples
Basic Authorization
- grant-access:
thand: authorize
then: monitor-usage
Authorization with Revocation Step
- conditional-grant:
thand: authorize
with:
revocation: "emergency-revoke"
then: enhanced-monitoring
monitor
The monitor task tracks access usage and detects policy violations or suspicious activity.
Syntax
- monitor:
thand: monitor
with:
monitor: string # Monitoring method (optional)
threshold: number # Alert threshold (optional)
then: next-step
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
monitor | string | No | - | Monitoring method (currently not used in implementation) |
threshold | number | No | - | Alert threshold (currently not used in implementation) |
Monitoring Process
The monitor task:
- Requires Temporal workflow context (only works with Temporal)
- Listens for alert events of type
com.thand.alert - Evaluates alert level - if “critical”, handles the alert
- Loops back to continue monitoring for more alerts
Examples
Basic Monitoring
- track-usage:
thand: monitor
then: normal-completion
Monitoring with Parameters
- enhanced-monitor:
thand: monitor
with:
monitor: llm
threshold: 10
then: assessment-required
Note: The current implementation only supports basic alert listening. The monitor and threshold parameters are accepted but not actively used in the monitoring logic.
revoke
The revoke task removes granted access and cleans up temporary credentials.
Syntax
- revoke:
thand: revoke
with:
reason: string # Revocation reason (optional)
then: next-step
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
reason | string | No | "Access no longer needed" | Reason for revocation |
Revocation Process
The revoke task:
- Validates the elevate request from workflow context
- Iterates through all providers and identities
- Calls provider-specific revocation methods
- Logs revocation events
- Returns revocation status with timestamp
Examples
Standard Revocation
- end-session:
thand: revoke
with:
reason: "Access period completed"
then: cleanup-notifications
Default Revocation
- auto-revoke:
thand: revoke
then: end
notify
The notify task sends notifications to users, administrators, or external systems. This task is used internally by the approvals task but can also be used standalone.
Syntax
- notify:
thand: notify
with:
approvals: number # Number of approvals needed
notifier: # Notification configuration
provider: string
to: string
message: string
then: next-step
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
approvals | number | Yes | Number of approvals required (for approval notifications) |
notifier | object | Yes | Notification configuration |
Notification Process
The notify task:
- Validates the notification request
- Checks for matching notification providers
- Sends notifications via the specified provider
- Creates callback URLs for interactive approvals (Slack)
Supported Providers
- Slack: Sends rich notifications with approval buttons
- Email: Sends email notifications
Examples
Slack Notification
- slack-notify:
thand: notify
with:
approvals: 1
notifier:
provider: slack
to: "C0123456789"
message: "Access granted to user"
Note: The notify task is primarily used internally by the approvals task. For standalone notifications, consider using standard Serverless Workflow call tasks to external APIs.
Task Chaining and Flow Control
Sequential Execution
do:
- validate: { thand: validate, then: approve }
- approve: { thand: approvals, then: authorize }
- authorize: { thand: authorize, then: monitor }
- monitor: { thand: monitor, then: revoke }
- revoke: { thand: revoke, then: end }
Conditional Flow with Approvals
do:
- validate:
thand: validate
then: request-approval
- request-approval:
thand: approvals
with:
approvals: 1
notifier:
provider: slack
to: "C0123456789"
message: "Approval needed"
on:
approved: grant-access
denied: deny-access
then: deny-access
- grant-access: { thand: authorize, then: monitor }
- deny-access: { thand: revoke, then: end }
Error Handling
Use standard Serverless Workflow error handling:
do:
- safe-authorize:
try:
thand: authorize
catch:
- log-error:
call: logger.error
with:
message: "Authorization failed"
- cleanup: { thand: revoke }
Best Practices
1. Task Configuration
Always Use Validate First
# Correct flow
do:
- validate: { thand: validate }
- approve: { thand: approvals }
- authorize: { thand: authorize }
Use Appropriate Validation Method
# For standard validation
- validate:
thand: validate
with:
validator: static
# For AI-enhanced validation
- validate:
thand: validate
with:
validator: llm
2. Approval Configuration
Always Specify Both Approval States
- approvals:
thand: approvals
with:
approvals: 1
notifier: { ... }
on:
approved: grant-access # Required
denied: send-denial # Required
then: send-denial # Fallback for insufficient approvals
3. Monitoring
Monitor After Authorization
do:
- authorize: { thand: authorize, then: monitor }
- monitor: { thand: monitor, then: scheduled-revoke }
Note: Monitoring requires Temporal workflow context.
4. Revocation
Always End with Revocation
do:
- authorize: { thand: authorize, then: monitor }
- monitor: { thand: monitor, then: revoke }
- revoke: { thand: revoke, then: end }
Troubleshooting
Common Task Issues
1. Validation Errors
Error: role must be provided
Error: reason must be provided
Error: no providers specified in elevate request
Solution: Ensure the elevate request in workflow context contains all required fields.
2. Approval Configuration Errors
Error: both approved and denied states must be specified in the on block
Solution: Always specify both approved and denied states in the on block.
3. Authorization Failures
Error: authorization failed for user 'alice' role 'admin'
Solution: Verify the request has been properly approved and the user has permission to request the role.
4. Monitoring Limitations
Error: Monitoring is only supported with temporal
Solution: The monitor task only works within Temporal workflows. Use alternative monitoring approaches for other workflow engines.
Debugging Tasks
Enable task debugging in your workflow configuration:
logging:
level: debug
Check workflow context to understand task inputs and state.