Skip to content

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:

config/workflows.yaml
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:

config/workflows.yaml (continued)
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

config/workflows.yaml (continued)
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

  1. Navigate to Reviews → Pending.
  2. Use the filter sidebar to narrow by risk level, platform, or department.
  3. Select reviews using the checkbox column.
  4. Click Bulk Action → choose Approve, Revoke, or Reassign.
  5. 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:

reviews:
  bulk:
    max_per_operation: 200
    require_justification: true
    allowed_roles: [admin, reviewer]

5 — Custom Review Templates

Review templates determine what information is presented to the reviewer. Create custom templates for different platforms or risk levels:

config/review-templates/high-risk.yaml
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.

config/integrations/servicenow.yaml
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
config/integrations/jira.yaml
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