14.6Changes that wait for approval
Last updated
Why a change can wait
In SYNERGY Management Gateway, approval is a control on machine credentials, not on people. A person working in the console is never queued. An API key, however, is always a machine credential, so every change the node makes is checked against the key's supervision level:
| Level (console label) | The key waits for a person before |
|---|---|
| Unsupervised (Act without asking) | Nothing it does on its own account. |
| Guarded (Ask before destructive and security changes, the default) | Deleting anything; removing members or group memberships (Unassign, Clear); revoking a delegation; changes to access control lists, delegations, deletion protection, SPNs, password policies or password-retrieval principals; writing a privileged attribute; restoring a deleted object; enabling or disabling all the accounts in an organizational unit. |
| Supervised (Ask before every change) | Every change it makes. |
Under Guarded, everyday work runs straight away: creating and updating objects, enabling, disabling and unlocking accounts, password resets, moves, renames and adding members.
Some changes wait at every level, whatever the key's own:
- A change to an object Active Directory protects (
adminCount=1— members of Domain Admins and the other protected groups, and those groups themselves). - A change inside, or into, a protected container that an administrator set on the connection.
- An operation an administrator has pinned to "always ask agents" — unless the key has Skip the always-ask wait turned on.
- Any change once the key has made more than a set number of destructive changes in one rolling hour (20 by default). This volume brake then holds everything the key does until its count falls back under the threshold.
A change that would wait and carries a password — for example resetting the password of a protected account, or any password reset by a Supervised key — is refused outright with 403 Agent.ApprovalImpossible, because a queued request would have to store the password in clear text.
Supervision levels, protected containers and pins are set by administrators and are explained in Chapter 10, Operation policies, attribute policies and agent supervision. Approving and rejecting is described in Chapter 9, Operations log, approvals and waiting operations.
Tip: An integration that must run unattended, such as an overnight leavers job that deletes accounts, needs its API key set to Act without asking. Only a person who may approve operations can choose that level, and it holds only while the key's owner may approve operations. Even then, protected objects still wait for a person.
What the gateway answers
When a change has to wait, the gateway does not carry it out. It records it as an operation in the WaitingToApprove state and answers 202 Accepted with a handle: the operation ID, its status, when the request expires, and a URL to poll. The object you asked to create does not exist yet, so the node cannot return it.
The On Approval Required option
The node has an Options collection with On Approval Required; it matters for operations that change the directory. It decides what the node does with that answer:
| Choice | What happens |
|---|---|
| Error (default) | The item fails with "Operation requires approval". The error still carries the operation ID, so a workflow using Continue On Fail can pick it up. |
| Continue and Output Operation ID | The node emits an item with approvalRequired: true, operationId, code, status, message, displayName, expiresAt and pollUrl, and the workflow carries on. |
A queued change is never reported as a success. With Continue and Output Operation ID, the item that flows on is the approval handle, not { success: true }, so an IF node can branch on {{ $json.approvalRequired }}.
The approval handle does not say why the change is waiting. To find out, read the operation with Operation > Get By ID: its gateReason field explains the reason in plain text (for example "This agent asks before destructive and security changes."), and impactSummary, when present, says what the change would affect.
The Options collection is not offered on the Operation resource, whose operations never change the directory.
When Continue On Fail is on in the node settings and a request fails, the node emits an item with error (the message), errorCode (the gateway's error code, such as Operation.Disabled), httpCode, and — for a queued change — approvalRequired and operationId.
Waiting for the decision
The Wait for Approval operation of the Operation resource polls a queued operation until somebody decides it.
| Field | Default | Meaning |
|---|---|---|
| Operation ID | {{ $json.operationId }} | The operation to wait on. The default reads the ID from the approval handle emitted by the previous node. |
| Poll Interval (Seconds) | 30 | Time between status checks. At least 5. |
| Timeout (Seconds) | 3600 | Give up and fail the item after this long. 0 means "until the approval request expires". Never more than 7 days (604800 seconds). |
| Fail on Rejection | On | Fail the item when the operation is rejected, cancelled, expires undecided or fails when carried out. Turn off to receive the outcome as an item and decide in the workflow. |
The wait ends when the operation leaves WaitingToApprove. The emitted item is the operation record plus four fields:
status—Success,Failed,Rejected,CancelledorExpired.approved— true only when the status isSuccess.decided— true when the status is final.expired— true when the approval window closed without a decision.
An approval request expires after its window closes (72 hours by default). Approvers no longer see an expired request, so nobody can decide it. Wait for Approval then reports status: "Expired" (or fails the item, with Fail on Rejection on), so the workflow can submit the change again rather than wait forever. A request the requester withdraws in the console ends as Cancelled.
The result block
When an operation has been carried out, its record contains a result block:
entityId— the object'sobjectGUID. For a create, this is the new object.distinguishedName— the object's distinguished name.objectClass— its class.action— what was done, as a number:1for a create,2for an update,3for a delete (0for anything else).
result is missing while the operation is waiting, and for operations that never reached the directory (rejected, cancelled, blocked or failed early). So when result is present, the change happened and you can use what it produced, for example {{ $json.result.entityId }} in the next node.
Get By ID returns the same record without waiting, if you prefer to poll on your own schedule. Get Waiting lists everything your key's owner still has waiting.
Last updated
Thank you for your feedback.