How approvals work
When a task reaches a gate, the run blocks and records anapproval_gate_blocked
event. A human resolves it:
RSTACK_USER)
— not a generic placeholder. Resolving from the Business Hub is also possible
(see the token below).
Enforce policy — .rstack/policy.json
Make selected stages require approval in every mode, including express runs:
required_approvals— task id → artifacts that must be approved before that task can run. Enforced in interactive and express mode.required_stage_approvals— canonical stage id (00-environment…14-cost-estimation) → artifacts that must be approved before any task entering that stage can run. No task ids needed. Enforced in every mode.approvals.every_stage— blanket human gate: every task must have astage-approval:<stage-id>artifact approved for each canonical stage it enters (e.g.sdlc_approve(artifact="stage-approval:07-code", ...)). Approving a stage once unblocks all tasks entering that stage for the rest of the run. Enforced in every mode.enforce_in_express— also apply the default interactive gates to express runs.managers— only these people may resolve approvals (see below).
Manager allow-list
When a manager list is configured (viapolicy.json managers[] or the
RSTACK_MANAGER_USERS env var, comma-separated), only those identities can
resolve a gate. Anyone else is rejected. With no list configured, any
identified user may approve.
Dashboard approval token
Approving from the browser requires a signed token so a manager’s identity can’t be spoofed from an unauthenticated request:- With the token set, the dashboard sends it as a header; approvals also
require a same-origin request and
Content-Type: application/json. - Without the token set, browser approvals are disabled (the secure
default) — approve via
sdlc_approveinstead. - Every dashboard approval records audit-proof actor evidence, not just a name.
The CLI path (
sdlc_approve) always enforces the manager allow-list. The
token specifically protects the dashboard endpoint from spoofed requests.Everyone gets paged when a gate blocks
A blocked gate fires a notification to every configured channel (webhooks) and pops a browser notification in the hub — so the manager doesn’t have to be watching the dashboard to know work is waiting.Email approval notifications
Register your team once and the right person gets an email the moment a gate blocks — the manager for guardrail overrides, the team lead for code-stage sign-offs, the release pair forrelease-readiness.json. Email is a
notification layer only: the claim gate stays the enforcement, and the
approval itself is always recorded through RStack’s audited, token-verified
path — never from the email.
Sending uses Azure Communication Services Email (REST + HMAC access-key
signing, implemented with Node built-ins — no new dependencies).
1. The secret stays in the environment — never in any .rstack/*.json
file (credential-shaped keys there are a hard validation error):
.rstack/notifications.json — sender
address, people, and routing:
guardrail-override:*,
stage-approval:*, destructive-action:*) → canonical stage id of the
blocked task. An artifact with no route falls back to the people named in
policy.json managers[] (matched by role, name, or email); if nobody
matches, the block is logged as “no email recipients resolved”. A route whose
roles don’t exist in recipients is flagged at config-validation time —
“this route resolves to nobody” — so a typo can’t silently mute approvals.
The channel activates only when both the environment connection string and
channels.email.sender are present (rstack-agents doctor reports exactly
which half is missing). Each resolved person gets their own email (To
only — recipient lists never leak) naming the run, task, blocked artifact, and
why, plus a deep link to the Business Hub approvals page
(http://localhost:3008/?page=approvals; port follows RSTACK_BUSINESS_PORT).
Why a deep link instead of Approve/Reject buttons in the email: Outlook
HTML approval buttons do not reliably return the approver’s identity —
only the selected option — so an email-button approval could not carry the
actor evidence RStack’s audit trail requires. Microsoft’s supported
identity-capturing path (Logic Apps / Power Automate Approvals) lives inside
M365, outside RStack’s audited approval records. v1 therefore links you to
the Business Hub approval card, where the existing token-verified path
records who approved. Signed one-time approval links are a v2 candidate.
