Runbooks/Approvals

Approvals

Group join requests, vault check-out requests and the workflow Approval step used to have three approval mechanisms with three pages. They now share one decision model and one Approvals page in the portal. Each kind keeps its own request record, its own audit trail and its own action after the decision: the membership is written, the check-out can be made, or the run continues. What is shared is who may decide, how many decisions are needed, escalation and timeout, the rule that the requester and the subject never decide, operator override, withdrawal, notifications, and one list to work from. Approvals need the Enterprise tier.

This runbook covers the shared page and the shared rules. Each kind also has its own runbook: the step’s fields are in Workflow approvals, the group policies are in Join policies, and the vault policies are in Check-out approvals.

The Approvals page

Approvals in the sidebar, its own entry directly below Mesh Objects, at /identity/approvals. There is one sidebar entry for all three kinds. It is visible to anyone who holds any of workflows.approve, groups.own or vault.approve. The subtitle reads “Workflow steps, group joins and vault checkouts waiting on a decision”. On a tier below Enterprise the page says “Approvals require the Enterprise tier”.

The old pages redirect here with the kind filter preset, so old links in emails and inbox notices keep working:

Old addressOpens with the kind
/identity/workflows/approvals, /workflows/approvalsWorkflow
/groups/approvals, /groups/approvals/adminGroup join
/vault/approvalsVault checkout

You can preset the filter yourself with ?kind=Workflow, ?kind=GroupJoin or ?kind=VaultCheckout on the address.

Tabs

TabShows
To decideOpen requests you may decide now. Empty: “Nothing is waiting for your decision.”
Decided by meRequests you have decided. Empty: “You have not decided any approvals yet.”
All openEvery open request of the kinds you may override, plus decided requests whose follow-up action is still owed. Only for holders of workflows.execute, groups.admin or vault.admin, each for their own kind. Empty: “No approvals are open.”
Completion failedDecided requests whose follow-up action failed or is still pending, for the same holders. Empty: “No completions have failed.”

The kind filter offers All, Workflow, Group join and Vault checkout.

Columns

ColumnShows
KindA badge: Workflow, Group join or Vault checkout.
TitleWhat is being asked. See the formats below.
SubjectThe object the request is about.
Requested byWho raised the request.
JustificationThe requester’s reason, truncated, with more and less to expand it.
StageThe stage, for two-stage requests.
OpenedWhen the request was opened.
Escalates / times outThe deadlines, or “none”.
Decisions so farApprovals so far of the number needed.

The title depends on the kind:

KindTitle
WorkflowThe Approval step’s Title.
Group join“Join group” for a request to join, or “Add person to group” when an owner adds someone.
Vault checkout“Check out account for N min”.

Deciding

Select Approve or Reject on the row. A dialog opens with a Reason (recorded in the audit trail) box. Confirm to record your decision.

On a vault row, the approve dialog also has Grant for (minutes). It is prefilled with the minutes the requester asked for. You can shorten it, from 1 up to the requested minutes, but you cannot lengthen it.

Your own request shows “Somebody else decides it (your request)” in place of the buttons.

A decision is refused when the request was already decided, when another decision landed first, or when the subject no longer exists. It is also refused when you are not permitted to decide it. Reload the page to see where the request stands.

Who can decide

The same rules apply to all three kinds.

Each kind decides who is asked in the first place:

KindWho is asked
WorkflowThe step’s Approvers, and Escalate to after escalation. See Who can approve.
Group joinThe group’s owners at stage 1. For a high-impact group, stage 2 is decided by a groups.admin holder who is not the stage-1 decider.
Vault checkoutThe members of the policy’s approver role. Deciding needs vault.approve and membership of that role. A policy with a blank approver role lets any vault.approve holder decide.

Escalation and timeout

When nobody has decided by the escalation time, the escalation set is told as well and can decide beside the first set. When nobody has decided by the timeout, the request times out.

KindWhere the timing comes fromWhat a timeout means
WorkflowThe step’s Escalate after and Time out after, unchanged.The step’s When timed out decides: the run ends, or continues into the next step.
Group joinConfigure → Groups: Join approval: escalate after (minutes) and Join approval: time out after (minutes). Both blank by default.A denial. The requester is told.
Vault checkoutThe vault policy: Escalate after (minutes), Escalation role and Time out after (minutes). All three blank by default.A denial. The requester is told.

Group and vault escalation and timeout are off until a policy sets them.

For group joins:

For vault check-outs, Escalation role names who an escalated request goes to. It is required when Escalate after is set.

Operator actions

Holders of a kind’s override permission can settle a request of that kind without being an approver: workflows.execute for workflow requests, groups.admin for group joins and vault.admin for vault check-outs.

ActionWhereEffect
Approve as operator / Reject as operatorApprovals pageShown only when you are not an eligible approver on the row but hold the kind’s override permission. The decision settles the request alone. For a workflow request, the approvers are told it was decided by an administrator. For a group join or a vault check-out, the subject and the requester are told the outcome, as for any decision.
WithdrawPOST /api/approvals/{id}/withdrawWithdraws any open request of your kind. A workflow request is withdrawn only by cancelling its run.
Retry completionCompletion failed tabRuns the follow-up action of a decided request again. See After the decision.

Every operator action is recorded in the administrator audit trail as an operator decision, with who and the reason. An operator who is the requester or the subject of a request still cannot decide it.

Withdrawn requests

A request is withdrawn when:

The people asked are told when the request was still pending. Withdrawing an approved vault request nobody has used tells nobody, since nothing is asked of anyone.

Requesters withdraw from their own lists: Withdraw on /groups/requests (My Requests) for group joins, and Withdraw on the My requests tab of the Vault self-service page for vault requests.

After the decision

Each kind has its own follow-up action once a request is approved:

KindFollow-up action
WorkflowThe run continues. A workflow request has no follow-up action of its own, so it never appears on Completion failed.
Group joinThe membership is written.
Vault checkoutThe check-out can be made. The approved request shows the approval window left and a Check out button on the requester’s My requests tab.

A vault approval is valid for the policy’s Approval valid for (minutes), 1440 (24 hours) by default. An approved request nobody checks out within that window becomes Expired, the requester is told, and they must request again.

A decided request whose follow-up action is still owed stays on All open. The approval sweep retries the action after a 30 second grace from the decision, up to five attempts. After that the request is marked failed and stays on Completion failed until someone selects Retry completion.

Notifications

Every person asked gets an inbox notice under the bell. When email is set up under Settings → Email and their person object has an email address, they get an email as well. Who hears the outcome depends on the kind: a workflow request tells its approvers, because the decision is theirs to know; a group join or a vault check-out tells the person it is about and, when someone else asked, the requester, because the decision is an answer to them.

The subject reads “prefix title (phase)”. The prefix is “Approval:” for a workflow request, “Group join:” for a group join and “Vault request:” for a vault check-out.

PhaseWho is toldExample
needs your approvalthe approversGroup join: Join Finance (needs your approval)
escalated to youthe escalation setVault request: Check out svc-backup for 60 min (escalated to you)
approved / rejectedworkflow: the approvers; group join and vault: the subject and the requesterApproval: Enable account for Ada Lovelace (approved)
timed outthe approvers (nobody decided), and for a group join or a vault check-out also the subject and the requester (it is a denial)Group join: Join Finance (timed out)
withdrawnthe approversVault request: Check out svc-backup for 60 min (withdrawn)
expiredthe requester only, for a vault approval nobody usedVault request: Check out svc-backup for 60 min (expired)
no approver can be reached / waiting on an operatorvault only: the vault administrators, and the requesterVault request: Check out svc-backup for 60 min (no approver can be reached)

The body names the workflow for a workflow request, or reads “Request: group join” or “Request: vault checkout”. It continues with About: the subject and its type, Requested by: when the requester is not the subject, the justification, the approvals so far of the number needed, and, for a new request, when it escalates and times out in UTC.

The last line links to the page when the Portal URL is set under Settings → Email, Links:

Open: https://identitymesh.example.com/#/identity/approvals

Without a Portal URL, the email ends with:

Open the IdentityMesh portal and go to Approvals.

Enter the Portal URL as the plain address with no #. See Email.

Nothing is sent for a request that was approved automatically, such as a join to an open group or a check-out under a vault policy that does not require approval.

On a test install, every approval email can go to one mailbox instead of the real approvers and requesters. See Redirect for testing.

The approval sweep

A background pass in the Admin API runs every minute while the licence tier is Enterprise. It:

It keeps running when workflows are paused. It is not the workflow worker, and it has no setting to tune.

Operations card

The Approvals card on the Operations page shows:

The Workflows card still shows “N awaiting approval” for runs parked on an Approval step.

Permissions

PermissionOn the Approvals page
workflows.approveOpen the page. Decide workflow requests that name you.
groups.ownOpen the page. Decide group join requests for groups you own. Ownership is still per group.
vault.approveOpen the page. Decide vault check-out requests for policies whose approver role you hold.
workflows.executeAll open and Completion failed for workflow requests. Decide any workflow request as an operator, withdraw, retry.
groups.adminThe same for group joins, and stage 2 of high-impact joins.
vault.adminThe same for vault check-outs. Override the approver-role rule, which is recorded. Check in anyone’s session.
groups.request, vault.requestWithdraw your own request.

No new permission was added. Every decision, override, withdrawal and retry is recorded in the administrator audit trail with who, whether as approver or as operator, and the reason. The group and vault hash-chained audit trails keep their own rows (Requested, Approved, Denied, Cancelled, Expired, and so on) exactly as before.

API

The /api/approvals routes need the Enterprise tier. Below it every route is refused with “Enterprise tier required”.

MethodRouteDoesPermission
GET/api/approvals?tab=todo|mine|all|failed&kind=Workflow|GroupJoin|VaultCheckoutList. todo (the default) is the open requests the caller may decide now. mine is the requests the caller decided. all is every open request of the kinds the caller may override, plus decided ones whose action is still owed. failed is decided requests whose action is Pending or Failed. all and failed answer 403 when the caller may override none of the kinds.any of workflows.approve, groups.own, vault.approve, workflows.execute, groups.admin, vault.admin
GET/api/approvals/{id}One request with its approvers, decisions and deadlines. Readable by the people asked, the requester, whoever decided it and operators of its kind.same
POST/api/approvals/{id}/approveBody { reason, asOperator, payload: { grantedDurationMinutes } }. Needs the kind’s decide permission and eligibility, or asOperator: true with the kind’s override permission. A vault check-out may carry payload.grantedDurationMinutes, from 1 to the requested minutes (400 outside that). 409 when already decided, when another decision landed first, or when the subject no longer exists. 403 when not permitted.same
POST/api/approvals/{id}/rejectSame body and rules. Any eligible rejection settles the request.same
POST/api/approvals/{id}/withdrawBody { reason }. The requester (a vault check-out also while approved and unused), or a holder of the kind’s override permission while the request is open. A workflow request closes with its run (409).the above, plus groups.request, vault.request
POST/api/approvals/{id}/retry-completionRuns the follow-up action again for a request whose completion is Failed or Pending.the kind’s override permission
GET/api/vault/checkouts/mineThe caller’s own vault requests, newest first, with approvedExpiresUtc.vault.request

Each list row carries the id, kind, stage, title, subject, requester, justification, when it opened, the escalation and timeout times, the decisions so far and the number needed, the status, who decided and as what (Approver or Operator), the completion status, the requested duration in minutes for a vault row, and whether the caller can decide it.

GET /api/workflows/status and the operations posture carry pendingApprovals { workflow, groupJoin, vaultCheckout }, completionFailedApprovals and policiesWithoutReachableApprover.

Deprecated routes

These routes are kept for one release as wrappers over the new ones. Move integrations to /api/approvals.

Retention and erasure

Workflow requests still age out with their runs, under run-history retention. See Retention. Group join and vault request records are removed when their request rows are purged, never on their own.

Erasing a person under DSAR and right to erasure blanks the title, subject name, message, justification and requester name on every request about them or raised by them, of every kind. Who decided, and how, stays on the record.

Upgrading

See Upgrades for the release’s full list.

Troubleshooting

What you seeCause and fix
The page says “Approvals require the Enterprise tier”The licence tier is below Enterprise. Approvals, and the approval sweep, need Enterprise.
A request you expect is missing from To decideEligibility is checked when you decide, so you may no longer be an owner or in the approver role. You may be the requester or the subject, who never decide. Or the kind filter is set to another kind; set it to All.
A vault row is refused as not permittedDeciding a check-out needs vault.approve and membership of the policy’s approver role. Add yourself to the role under Settings → User Role Assignments, or have a vault.admin holder decide as operator.
An old link or bookmark lands on the Approvals page with a kind already selectedThe old pages redirect to the shared page with the kind preset. Update the bookmark to /identity/approvals.
A decided request is still on All openIts follow-up action is still owed. The sweep retries it after a 30 second grace.
A decided request is on Completion failedThe follow-up action failed five times, or is still pending. Fix the cause, then select Retry completion.
The Operations card or the event log says a vault policy’s role “reaches nobody in the mesh”No member of the approver role resolves to a mesh person, so only a vault.admin operator can decide its requests. Set the policy’s approver role to a role people hold, and make sure those people have mesh objects that match their sign-in.
The email ends with “Open the IdentityMesh portal and go to Approvals.”Portal URL is empty. Set it under Settings → Email, Links. See Email.