Manage Review Workflows¶
Goal¶
Customise Verity's review workflow engine to match your organisation's governance model — from SLA targets and escalation chains to bulk review handling and external ticketing integration.
Prerequisites¶
| Requirement | Details |
|---|---|
| Verity environment | All core services + Temporal running |
| Admin role | Verity admin RBAC role for configuration changes |
| Familiarity | Review Lifecycle concept |
Review Workflow Lifecycle¶
Every access-decay review follows a Temporal-powered state machine:
stateDiagram-v2
[*] --> PENDING : Score ≥ threshold
PENDING --> IN_REVIEW : Assigned reviewer opens packet
IN_REVIEW --> DECIDED : Reviewer submits decision
DECIDED --> EXECUTING : Remediation workflow triggered
EXECUTING --> COMPLETED : Remediation confirmed
COMPLETED --> [*]
PENDING --> ESCALATED : SLA breached (Level 1)
IN_REVIEW --> ESCALATED : SLA breached (Level 2)
ESCALATED --> IN_REVIEW : Escalation assignee accepts
DECIDED --> FAILED : Remediation error
FAILED --> DECIDED : Retry
Temporal durability
The workflow state is durable — if a Verity service restarts, reviews resume exactly where they left off. SLA timers continue to count even across restarts.
1 — Configure SLA Thresholds¶
SLA targets determine how long a review can remain unresolved before escalation. Configure them per risk level in the workflow settings:
reviews:
sla:
critical:
response_time: 4h # reviewer must open within 4 hours
resolution_time: 24h # decision must be submitted within 24 hours
high:
response_time: 8h
resolution_time: 48h
medium:
response_time: 24h
resolution_time: 5d
low:
response_time: 48h
resolution_time: 14d
reminders:
- at: 50% # 50 % of SLA elapsed
channel: email
- at: 80% # 80 % of SLA elapsed
channel: [email, slack]
- at: 100% # SLA breached → escalate
action: escalate
Risk levels are assigned automatically based on the grant's decay score:
| Decay Score | Risk Level |
|---|---|
| 90 – 100 | Critical |
| 75 – 89 | High |
| 50 – 74 | Medium |
| 30 – 49 | Low |
2 — Set Up Escalation Chains¶
Define who receives escalated reviews when an SLA is breached:
reviews:
escalation:
levels:
- name: Level 1 — Resource Owner
assignee_source: grant_owner
sla_multiplier: 1.0 # uses base SLA
- name: Level 2 — Team Lead
assignee_source: team_lead
sla_multiplier: 0.5 # half the base SLA
- name: Level 3 — Security Team
assignee_source: group:security-team
sla_multiplier: 0.5
- name: Level 4 — CISO
assignee_source: role:admin
sla_multiplier: 0 # immediate action required
notification: [pagerduty, email]
max_escalations: 4
final_action: auto_suspend # suspend grant if all levels exhausted
flowchart LR
Owner["Resource Owner<br/>SLA: 1×"] -->|breached| Lead["Team Lead<br/>SLA: 0.5×"]
Lead -->|breached| Sec["Security Team<br/>SLA: 0.5×"]
Sec -->|breached| CISO["CISO<br/>Immediate"]
CISO -->|breached| Auto["Auto-Suspend<br/>Grant"]
style Auto fill:#e74c3c,color:#fff
Auto-suspend
The auto_suspend final action will disable the access grant via the
Remediation service. Enable this only after thorough testing with your
identity provider's revocation API.
3 — Delegation and Reassignment¶
Reviewers can delegate reviews to a colleague or back to their manager.
API¶
# Delegate review to another user
curl -X POST http://localhost:8000/api/v1/reviews/REV-001/delegate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"delegate_to": "bob@example.com",
"reason": "On leave — Bob has context on this service account."
}'
Delegation Rules¶
reviews:
delegation:
allow_self_delegation: false
max_delegations_per_review: 2
allowed_targets:
- same_team # same team as the original assignee
- direct_reports # manager can delegate down
- security_team # always available
require_reason: true
Audit trail
Every delegation is recorded in the audit log with the delegator, delegate, timestamp, and reason. See Audit for query options.
4 — Bulk Review Handling¶
When a certification campaign generates hundreds of reviews, bulk operations speed up the process.
Bulk Approve / Revoke via API¶
# Bulk approve reviews matching a filter
curl -X POST http://localhost:8000/api/v1/reviews/bulk \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "approve",
"filter": {
"risk_level": "low",
"principal_type": "service_account",
"last_used_within_days": 7
},
"justification": "Service accounts actively used within 7 days — bulk approved per policy P-042."
}'
Bulk Review in the Dashboard¶
- Navigate to Reviews → Pending.
- Use the filter sidebar to narrow by risk level, platform, or department.
- Select reviews using the checkbox column.
- Click Bulk Action → choose Approve, Revoke, or Reassign.
- Provide a justification (required for audit).
Bulk review limits
By default, bulk actions are limited to 50 reviews per operation. An
admin can increase this in config/workflows.yaml:
5 — Custom Review Templates¶
Review templates determine what information is presented to the reviewer. Create custom templates for different platforms or risk levels:
template:
name: high-risk-review
applies_to:
risk_levels: [critical, high]
sections:
- title: Grant Summary
fields: [principal, asset, privilege, grant_mechanism, granted_date]
- title: Decay Evidence
fields: [decay_score, last_used_at, usage_trend_30d, peer_comparison]
- title: Risk Context
fields: [data_classification, compliance_frameworks, open_incidents]
- title: Recommended Action
auto_suggest: true # AI-generated recommendation
fields: [suggested_action, confidence_score, similar_decisions]
decision_options:
- value: approve
label: "Approve — Access is still needed"
require_justification: false
- value: reduce
label: "Reduce — Downgrade to lower privilege"
require_justification: true
- value: revoke
label: "Revoke — Remove access"
require_justification: false
- value: defer
label: "Defer — Need more information"
require_justification: true
max_defer_days: 14
6 — Ticketing Integration¶
Connect reviews to your existing ITSM tools so remediation actions create trackable tickets.
integrations:
servicenow:
enabled: true
instance_url: https://company.service-now.com
auth:
type: oauth2
client_id: ${SNOW_CLIENT_ID}
client_secret: ${SNOW_CLIENT_SECRET}
mapping:
review_decided_revoke:
table: incident
fields:
short_description: "Verity: Revoke access — {{ principal }} → {{ asset }}"
category: Security
subcategory: Access Management
urgency: "{{ risk_level_to_snow_urgency }}"
assignment_group: Identity & Access Management
integrations:
jira:
enabled: true
base_url: https://company.atlassian.net
auth:
type: api_token
email: ${JIRA_EMAIL}
token: ${JIRA_API_TOKEN}
mapping:
review_decided_revoke:
project: IAM
issue_type: Task
summary: "Verity: Revoke {{ privilege }} on {{ asset }} for {{ principal }}"
labels: [verity, access-revocation]
priority: "{{ risk_level_to_jira_priority }}"
Verify Integration¶
# Trigger a test ticket
curl -X POST http://localhost:8000/api/v1/integrations/test \
-H "Authorization: Bearer $TOKEN" \
-d '{"integration": "servicenow", "dry_run": true}'
Configuration Reference¶
All workflow settings live under the reviews key in config/workflows.yaml:
| Setting | Type | Default | Description |
|---|---|---|---|
sla.<level>.response_time |
duration | varies | Time to first open |
sla.<level>.resolution_time |
duration | varies | Time to decision |
escalation.levels |
list | 4 levels | Escalation chain definition |
escalation.final_action |
string | notify |
Action when all levels exhausted |
delegation.max_delegations_per_review |
int | 2 |
Max delegation hops |
bulk.max_per_operation |
int | 50 |
Reviews per bulk action |
bulk.require_justification |
bool | true |
Mandate reason for bulk actions |
Next Steps¶
- Read the Review Lifecycle concept for deeper background
- Configure Alerting for SLA breach notifications
- Set up SSO to ensure reviewers authenticate via your IdP
- Explore the Workflow Engine service docs