Skip to content

Example: Provisioning Workflow with Role & Entitlement Lifecycle

A comprehensive workflow that invites a user to join a research program, collects required compliance documents, routes them through approval, and automatically provisions role-based access across multiple systems — with document-driven expiry that revokes access when certifications lapse.

Use Case

A compliance officer needs to onboard a researcher into the Genome Access Program. The researcher must:

  1. Accept an invitation to participate
  2. Submit a signed data use agreement (DUA) valid for one year
  3. Submit a current human subjects training certificate valid for two years
  4. Receive approval from a designated reviewer on both documents

Upon approval, the researcher is automatically granted the Genome Access Participant role, which provisions:

  • Membership in the genome-access Authifi group (grants SSO access to the genomics portal)
  • An Active Directory account in the RESEARCH\GenomeUsers OU (grants access to the secure file share)

When either document expires, the role is automatically revoked and both entitlements are deprovisioned.

Prerequisites

  1. Authifi connector configured with valid client credentials and the target tenant
  2. Test Active Directory connector configured (or a real AD connector in production)
  3. The genome-access group exists in Authifi
  4. Role Definition "Genome Access Participant" created with two entitlements:
  5. Authifi group membership (addToGroup / removeFromGroup / checkGroupMembership)
  6. AD account (createAccount / disableAccount / checkAccountExists)

Creating Entitlement Definitions

Entitlements are first-class, shared objects that can be linked to multiple roles. Create them via the Entitlements page (/entitlements) before building the role.

Entitlement 1: Authifi Group

  1. Click New Entitlement
  2. Fill in:
Field Value
Name Genomics Portal Access
Connector authifi
Provision Config { "command": "addToGroup", "groupId": "<genome-access-group-id>", "role": "member", "createIfMissing": true }
Deprovision Config { "command": "removeFromGroup", "groupId": "<genome-access-group-id>" }
Reconciliation Config { "command": "checkGroupMembership", "groupId": "<genome-access-group-id>" }

Entitlement 2: AD Account

  1. Click New Entitlement
  2. Fill in:
Field Value
Name Research File Share Access
Connector test-activedirectory
Provision Config { "command": "createAccount", "ou": "RESEARCH\\GenomeUsers", "groupName": "GenomeAccess" }
Deprovision Config { "command": "removeFromGroup", "groupName": "GenomeAccess" }
Reconciliation Config { "command": "checkGroupMembership", "groupName": "GenomeAccess" }

Creating the Role Definition

After creating the entitlement definitions, create the role and link them:

  1. Navigate to Role Definitions (/roles) and click New Role
  2. Fill in:
  3. Name: Genome Access Participant
  4. Description: Grants access to the genomics portal and secure file share
  5. Expires After (days): leave blank (expiry is driven by document lifecycle, not a fixed TTL)
  6. Save, then open the role detail page
  7. Click Link Entitlement and search for each entitlement created above:
  8. Link Genomics Portal Access
  9. Link Research File Share Access

Note the role definition ID after saving — you'll reference it in the role_grant step.

Workflow Settings

Field Value
Name Genome Access Provisioning
Category user
Subject Variable user (auto-created)
Error Strategy stop
Trigger manual

Context Variables

Name Type Required Description
user User yes The researcher being onboarded (auto-created, workflow subject)
reviewer User yes The compliance reviewer who approves the documents

Workflow Steps

# Step Name Type Purpose
1 Start start Entry point
2 Send Program Invitation notification Invites the researcher; pauses until accepted
3 Check Invitation condition Branches on acceptance
4 Request Data Use Agreement document_submission Collects the signed DUA (expires in 365 days)
5 Request Training Certificate document_submission Collects the human subjects certificate (expires in 730 days)
6 Grant Genome Access Role role_grant Provisions all entitlements via connectors
7 Send Access Granted Email notification Confirms provisioning to the researcher
8 Send DUA Rejected Email notification Notifies researcher of DUA rejection
9 Send Training Rejected Email notification Notifies researcher of training rejection
10 Send Declined Email notification Notifies researcher if they declined the invitation
11 End end Exit point

Flow Diagram

Start
Send Program Invitation (notification, requiresAcceptance)
Check Invitation (condition: acceptance_status == "accepted")
  ├── true ──► Request Data Use Agreement (document_submission, expiresAfterDays: 365)
  │              │
  │              ├── success ──► Request Training Certificate (document_submission, expiresAfterDays: 730)
  │              │                  │
  │              │                  ├── success ──► Grant Genome Access Role (role_grant)
  │              │                  │                  │
  │              │                  │                  └──► Send Access Granted Email ──► End
  │              │                  │
  │              │                  └── error ──► Send Training Rejected Email ──► End
  │              │
  │              └── error ──► Send DUA Rejected Email ──► End
  └── false ──► Send Declined Email ──► End

Step-by-Step Configuration

Step 2: Send Program Invitation

Config Field Value
Type notification
Recipient Type Internal User
Recipient User {{user.id}}
Subject Override Invitation to the Genome Access Program
Custom Body You have been invited to join the Genome Access Program. Participation requires submission and approval of a Data Use Agreement and a current Human Subjects Training Certificate. Click the link below to accept this invitation and begin the enrollment process.
Require User Acceptance Checked (true)
Acceptance Expiry (hours) 168 (7 days)

The workflow pauses at waiting_acceptance. The researcher receives an email with an accept/reject link. If they don't respond within 7 days, the acceptance expires and the condition evaluates to the false branch.

Step 3: Check Invitation

Config Field Value
Type condition
Expression acceptance_status == "accepted"
True → Go To Request Data Use Agreement
False → Go To Send Declined Email

Step 4: Request Data Use Agreement

Config Field Value
Type document_submission
Document Label Signed Data Use Agreement
Instructions Download the Data Use Agreement template, read it carefully, sign it, and upload the signed copy as a PDF. This agreement is valid for one year from the date of approval.
Template ID (select your DUA template from the dropdown, if uploaded)
Submitter Email {{user.email}}
Submitter User ID {{user.id}}
Allowed MIME Types application/pdf
Max File Size 10485760 (10 MB)
Approvers {{reviewer.id}}
Notify Submitter Checked
Notify Approvers Checked
Expires After (days) 365
Success → Go To Request Training Certificate
Error → Go To Send DUA Rejected Email

The expiresAfterDays: 365 setting automatically stamps each uploaded document with an expires_at date one year from upload. The hourly document-expiry-check job monitors this expiry and triggers revocation of any linked role assignments when the document lapses.

Step 5: Request Training Certificate

Config Field Value
Type document_submission
Document Label Human Subjects Training Certificate
Instructions Complete the required human subjects protection training and upload your certificate of completion. Certificates are valid for two years.
Template URL https://training.example.com/human-subjects
Submitter Email {{user.email}}
Submitter User ID {{user.id}}
Allowed MIME Types application/pdf, image/*
Max File Size 5242880 (5 MB)
Approvers {{reviewer.id}}
Notify Submitter Checked
Notify Approvers Checked
Expires After (days) 730
Success → Go To Grant Genome Access Role
Error → Go To Send Training Rejected Email

Step 6: Grant Genome Access Role

Config Field Value
Type role_grant
Role Definition ID (UUID of "Genome Access Participant" — paste or use variable)
User ID {{user.id}}
Fail on Partial Unchecked (false)
Next Step Send Access Granted Email

This step calls RoleService.grantRole(), which:

  1. Creates a role_assignment record linked to this workflow run
  2. For each entitlement definition on the role:
  3. Creates an entitlement_instance with status pending
  4. Executes the connector command from provision_config
  5. Updates the instance to provisioned (or failed)
  6. Sets the assignment status to active (or partially_provisioned if any entitlement failed)

The step produces output variables (roleAssignmentId, roleProvisioned, provisionedCount, failedCount) that can be referenced by subsequent steps.

With failOnPartial unchecked, the workflow continues even if one entitlement fails to provision. The failed entitlement can be reprovisioned later from the Role Assignments page.

Step 7: Send Access Granted Email

Config Field Value
Type notification
Recipient Type Internal User
Recipient User {{user.id}}
Subject Override Genome Access Program — Access Granted
Custom Body Your documents have been approved and your access has been provisioned. You now have access to the Genomics Portal and the Research File Share. Your Data Use Agreement expires in 1 year and your Training Certificate expires in 2 years — you will need to renew them before expiry to maintain access.
Require User Acceptance Unchecked (false)

Step 8: Send DUA Rejected Email

Config Field Value
Type notification
Recipient Type Internal User
Recipient User {{user.id}}
Subject Override Data Use Agreement not approved
Custom Body Your submitted Data Use Agreement for the Genome Access Program was not approved. Please review the reviewer's feedback, make corrections, and contact the compliance office for next steps.
Require User Acceptance Unchecked (false)

Step 9: Send Training Rejected Email

Config Field Value
Type notification
Recipient Type Internal User
Recipient User {{user.id}}
Subject Override Training certificate not approved
Custom Body Your Human Subjects Training Certificate was not approved. Please verify that you completed the correct training course and that the certificate is current. Contact the compliance office if you need assistance.
Require User Acceptance Unchecked (false)

Step 10: Send Declined Email

Config Field Value
Type notification
Recipient Type Internal User
Recipient User {{user.id}}
Subject Override Genome Access Program invitation declined
Custom Body We received your response declining the invitation to the Genome Access Program. If this was a mistake or you change your mind, please contact the compliance office to receive a new invitation.
Require User Acceptance Unchecked (false)

Wiring the Graph

Connect the steps in the graph editor:

  1. StartSend Program Invitation
  2. Send Program InvitationCheck Invitation
  3. Check Invitation → true → Request Data Use Agreement
  4. Check Invitation → false → Send Declined Email
  5. Request Data Use Agreement → success → Request Training Certificate
  6. Request Data Use Agreement → error → Send DUA Rejected Email
  7. Request Training Certificate → success → Grant Genome Access Role
  8. Request Training Certificate → error → Send Training Rejected Email
  9. Grant Genome Access RoleSend Access Granted Email
  10. Send Access Granted EmailEnd
  11. Send DUA Rejected EmailEnd
  12. Send Training Rejected EmailEnd
  13. Send Declined EmailEnd

Starting a Run

Start the workflow manually from the workflow detail page or via API:

POST /api/workflows/:id/start
{
  "variables": {
    "user": "uuid-of-researcher",
    "reviewer": "uuid-of-compliance-reviewer"
  }
}

For user-type variables, supply the user's UUID; the engine resolves it to a full user object (with id, email, displayName, etc.) before execution begins.

If the researcher doesn't have an account yet, pre-provision one:

POST /api/users
{ "email": "researcher@university.edu", "displayName": "Dr. Jane Smith" }
# → { "id": "newly-created-uuid", ... }

Runtime Walkthrough

Happy Path

  1. Invitation sent — The engine sends an email to researcher@university.edu with an accept/reject link. The run pauses at waiting_acceptance.

  2. Researcher accepts — Dr. Smith clicks the link and accepts. The engine resumes and evaluates the condition → true.

  3. DUA requested — The engine creates a task in Dr. Smith's inbox asking her to download the DUA template, sign it, and upload it. The run pauses at waiting_submission.

  4. DUA uploaded — Dr. Smith uploads the signed PDF. The document is stored with expires_at set to 365 days from now and subject_user_id set to her user ID. The run transitions to waiting_approval and the reviewer is notified.

  5. DUA approved — The reviewer downloads the DUA, verifies the signature, and clicks Approve. The engine resumes and moves to the next document.

  6. Training certificate requested — Another task appears in Dr. Smith's inbox. She completes the training at the linked URL, downloads her certificate, and uploads it. This document gets expires_at set to 730 days.

  7. Training approved — The reviewer approves the certificate.

  8. Role granted — The role_grant step executes:

  9. Creates a role_assignment record for "Genome Access Participant" linked to this run
  10. Calls the Authifi connector's addToGroup → Dr. Smith is added to genome-access group
  11. Calls the AD connector's createAccount → an AD account is created in the GenomeUsers OU
  12. Both entitlement_instance records are marked provisioned
  13. The assignment status is set to active

  14. Confirmation sent — Dr. Smith receives an email confirming her access. The run completes.

Rejection Paths

  • If Dr. Smith declines the invitation, she receives a "declined" email and the workflow ends without any document collection or provisioning.
  • If the DUA is rejected, she receives a rejection email. The workflow ends — the training certificate is never requested and no access is provisioned.
  • If the training certificate is rejected, she receives a rejection email. Even though the DUA was approved, no role is granted because the workflow requires both documents.

Automatic Lifecycle Management

After the workflow completes and access is provisioned, three automated systems monitor the ongoing lifecycle:

Document Expiry

The document-expiry-check scheduled job runs hourly. When Dr. Smith's DUA expires (1 year after upload):

  1. The job detects expires_at < now() for the approved DUA
  2. The document status is updated to expired
  3. The job finds the role assignment linked to the same workflow run via granted_by_run_id
  4. RoleService.revokeRole() is called, which:
  5. Calls Authifi removeFromGroup → Dr. Smith is removed from genome-access
  6. Calls AD removeFromGroup → her AD group membership is removed
  7. The role assignment status is set to revoked

The same would happen if the training certificate expires first (at the 2-year mark). Either document expiring triggers full revocation because the role is linked to the workflow run that collected both documents.

Entitlement Reconciliation

The entitlement-reconciliation job runs daily at 02:00 UTC. For each active entitlement instance with a reconciliation_config:

  1. Calls Authifi checkGroupMembership → verifies Dr. Smith is still in genome-access
  2. Calls AD checkGroupMembership → verifies her AD group membership

If an entitlement is found to be missing (e.g., an Authifi admin manually removed her from the group):

  • The entitlement instance is marked orphaned
  • An administrator can view orphaned entitlements on the Role Assignments page and choose to reprovision (re-add to group) or revoke (remove the entire role)

Webhook Events

If the Authifi system supports outbound webhooks, it can notify Floh directly when group membership changes:

POST /api/entitlements/webhook/authifi-connector-id
{
  "action": "removed",
  "resourceId": "genome-access-group-membership-id"
}

The system correlates the resourceId with the external_id stored on the entitlement instance and marks it as orphaned immediately, without waiting for the next reconciliation cycle.

Renewal

When a document is approaching expiry, administrators can see it in the Documents page (/documents) with an amber "expiring soon" badge. To renew access:

  1. Start a new run of the same workflow (or a dedicated renewal workflow) for the same user
  2. The researcher submits a new, current document
  3. Upon approval, a new role_grant step provisions fresh entitlements (or the existing assignment is still active if the old document hasn't expired yet)

The expired document from the previous run does not affect the new assignment — each workflow run creates its own independent role assignment.

Monitoring Access

Documents Page

Navigate to Documents (/documents) to see all documents across users:

  • Filter by Expiring Soon to see documents expiring within 30 days
  • Filter by User to see all documents for a specific researcher
  • Each document shows its linked role assignments and their status

Role Assignments Page

Navigate to Role Assignments (/role-assignments) to see all active, expired, and revoked assignments:

  • Filter by Status to find active, partially_provisioned, or revoked assignments
  • Click an assignment to see individual entitlement instance statuses and reconciliation history
  • Use Revoke to manually remove access, or Reprovision to fix failed/orphaned entitlements