> For the complete documentation index, see [llms.txt](https://docs.abbey.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.abbey.io/reference/grant-kits/grant-workflows.md).

# Workflows

A Workflow, written natively in [Terraform](https://www.terraform.io/) using [HCL](https://developer.hashicorp.com/terraform/language/syntax/configuration), defines *how* someone should get access to a Resource.

## Workflow Spec

```hcl
workflow = {
    steps = [
        {
            reviewers = {
                # one_of = ["...", "...", ...]
                # all_of = ["...", "...", ...]
            },
            skip_if = [
                {
                    # bundle = "..."
                    # query = "..."
                }
            ]
        }
    ]
}
```

## Writing Workflows For Your Grant Kit

Workflows are written using the Grant Kit's Workflows DSL as native Terraform HCL code.

Writing Workflows consists of three steps:

1. [Add your steps](#add-your-steps).
2. [For each step, choose a Reviewer Constraint](#for-each-step-choose-a-reviewer-constraint).
3. [For each step, optionally add a Workflow Policy](#for-each-step-optionally-add-a-workflow-policy).

### Add Your Steps

Workflows can have one or more steps. Each step is an object that you configure in a list as defined in the [Workflow Spec](#workflow-spec).

<details>

<summary>Example Workflow Step Configurations</summary>

```hcl
// Workflow with a single step.
steps = [
    { ... }
]

// Workflow with 3 steps.
steps = [
    { ... },
    { ... },
    { ... }
]
```

</details>

{% hint style="info" %}
There's no practical limit to the number of Workflow Steps you can have.
{% endhint %}

### For Each Step, Choose a Reviewer Constraint

Each step must have a Reviewer Constraint that represents how many of the reviewers must approve an access request for the current step to be considered approved overall.

Abbey supports two types of Reviewer Constraints:

1. `one_of`: Require only one of the reviewers in the list of reviewers to approve.
2. `all_of`: Require all of the reviewers in the list of reviewers to approve.

<details>

<summary>Example Workflow Step Configurations with Reviewer Constraints</summary>

```hcl
# Workflow with multiple steps.
#
# The first step only requires one out of 3 reviewers to approve.
#
# The second step requires all reviewers (2 out of 2) to approve.
#
# The third step only requires one reviewer to approve, but
# effectively behaves like an `all_of` because there's only
# one reviewer in the list.
steps = [
    {
        reviewers = {
            one_of = ["alice@example.com", "bob@example.com", "carol@example.com"]
        }
    },
    {
        reviewers = {
            all_of = ["dan@example.com", "eve@example.com"]
        }
    },
    {
        reviewers = {
            one_of = ["frank@example.com"]
        }
    }
]
```

</details>

### For Each Step, Optionally Add a Workflow Policy

Each step may optionally have Workflow Policies attached to it. Workflow Policies define *when* or *if* someone should have their access revoked.

<details>

<summary>Example Workflow Step Configurations with Reviewer Constraints and Workflow Policies</summary>

```hcl
# Workflow with multiple steps.
#
# The first step has a single Workflow Policy attached.
# If the policy check passes, then the step will be skipped and
# none of the reviewers will be notified to review the access request.
#
# The second step has two Workflow Policies attached.
# Both of these policy checks must pass in order for the step to be skipped.
#
# The third step doesn't have a Workflow Policy.
# This means the step is required and will always be run.
steps = [
    {
        reviewers = {
            one_of = ["alice@example.com", "bob@example.com", "carol@example.com"]
        }
        skip_if = [
            { ... }
        ]
    },
    {
        reviewers = {
            all_of = ["dan@example.com", "eve@example.com"]
        }
        skip_if = [
            { ... },
            { ... }
        ]
    },
    {
        reviewers = {
            one_of = ["frank@example.com"]
        }
    }
]

```

</details>

For more information on how to add Workflow Policies, visit the [Policies](/reference/grant-kits/policies.md#configuring-policies-for-your-grant-kit) page.

## Workflow Step Evaluation

Abbey runs your Grant Kit Workflows using Abbey's distributed Workflow Engine. Workflows consist of a series of Workflow Steps you configure for an access request for access to be approved.

Workflow Steps are evaluated serially as shown in the following diagram:

<figure><img src="/files/PhIIer78K8crgbM8z5nW" alt="Workflow Step Evaluation"><figcaption><p>Workflow Step Evaluation.</p></figcaption></figure>

This diagram shows a Workflow with two Steps. For each Step, it will:

1. Evaluate Workflow Policies.
   * If the policies result in a `skip = true`, then this step will be skipped. As a result, none of the reviewers in the reviewer list will be notified to approve or deny the access request.
2. Notify reviewers.
   * Each Step must contain a list of reviewers. This is a list of strings that represent someone's [Primary Identity](/how-abbey-works/concepts.md#primary-identity).
   * Each reviewer may contain different notification channels, such as the Abbey App or Slack.
   * The Notification Router will notify reviewers on all of these channels.
3. Wait for the Reviewer Constraint to be met.
   * The list of reviewers are configured with a [Reviewer Constraint](#for-each-step-choose-a-reviewer-constraint), either `one_of` or `all_of`.
   * If using `one_of`, then only one reviewer from the list needs to approve for the Step to be considered approved. The Workflow Engine will then advance to the next step.
     * If no one has approved the access request yet and a deny is received from a reviewer, the Workflow Engine will auto-deny the step. This auto-deny will bubble up to the Workflow and result in access being denied overall.
   * If using `all_of`, then all reviewers from the list must approve for the Step to be considered approved. The Workflow Engine will advance to the next step only after this condition is met.
     * If some, but not all, approvals have been received, and a deny is received from a reviewer, the Workflow Engine will auto-deny the step.This auto-deny will bubble up to the Workflow and result in access being denied overall.

Once all Steps are approved, access will be granted.
