Who has to sign off on a €30,000 vendor? An admin login to production? A 120-day exemption from the device-encryption policy? In most companies the honest answer is "ask around", and the evidence is a Slack thread.
ApprovalsHub makes each kind of request a form plus a routing policy. The requester answers the form; the policy turns the answers into a chain of approvers; each approver sees only what is waiting on them, with the evidence attached; overdue steps escalate; and every approval, rejection, exception and escalation is a searchable record.
The problem we started from
Approvals stall for three reasons: nobody is sure who should decide, the person who should decide does not know it is waiting on them, and when they finally decide there is no record of why. The fix is not another inbox. It is a policy that resolves the chain up front, and a record that keeps the reasons.
The answers on the form decide who signs. Not the requester's guess, not the loudest person in the thread.
A form plus a policy
A request type — spend, access, vendor onboarding, travel, policy exception, contract signature, headcount — has typed fields (text, number, select, yes/no, date, URL) and a list of rules. A rule says: when these conditions hold on the answers, then add these steps to the chain. A step is the requester's manager, a named person, or any member of a group, each with its own SLA.
Conditions on the answers
amount ≥ 25,000 adds the executive team. level = admin adds Security. handles personal data adds Security and Legal.
Deduplicated chains
Two rules that land on the same approver produce one step. Nobody signs twice.
Preview before you save
The designer shows the chain for sample answers — including rules you have not saved yet.
How routing works
On submit, every rule is evaluated in order against the answers. Matching rules contribute their steps; approvers are resolved — a manager becomes a person, a person on leave becomes their delegate, a group stays a group — and the first step becomes active with a due date. Steps run one after another. A resubmission after "changes requested" is re-routed: raise the amount and Finance joins the chain, drop to read access and Security leaves it. The history is kept either way.
Live routing preview shows who will sign before you press the button.
Rules → steps → resolved approvers, first step active with an SLA.
Only the eligible person can decide; the note goes on the record.
Chain, thread, evidence, exceptions, escalations — searchable forever.
Deciding
An approver's inbox lists the active steps they can decide — assigned directly, through a group, delegated to them, or escalated to them — with the request summary, the evidence count and how long it has been waiting. Approve moves the chain on; reject ends it; request changes sends it back to the requester with a note. Eligibility is enforced by the server: the wrong person gets a 403, not a quiet success.
Exceptions, escalation, delegation
- Exceptions. Sometimes the right answer is to approve outside policy — a 24-month term where the rule says 12. An approver can approve with an exception: a reason and an expiry. Exceptions live in a register with active / expired / revoked status, so nothing quietly becomes permanent.
- Escalation. A step past its SLA escalates to the approver's manager or the group's escalation contact — one at a time from the request, or all at once with the sweep. The escalation target can decide; the original approver still can too.
- Delegation. Out of office for a week? A delegation routes new steps to your cover and lets them decide the ones already waiting on you.
The record
Every request keeps its chain (who, when, within SLA or late), its thread (every action and comment), its evidence (links, files by name, notes) and its exceptions. The list is searchable by text, status, type, approver, escalation and exception. The dashboard shows cycle time, SLA compliance, approver load and exceptions about to expire — the questions an auditor and a COO both ask.
How it is built
House stack: a Go backend (standard-library routing, SQLite, no CGO) whose seed replays forty requests through the real routing and decision code, with tests for routing rules, the lifecycle, re-routing on resubmit, exceptions and delegation, the escalation sweep, validation and search; and a Next.js 16 / React 19 frontend on shadcn/ui and Tailwind v4 with a designer for fields and rules, a dynamic form with live routing preview, an inbox with an "acting as" picker, and the request page with its chain, thread and evidence. It signs in through the System32 control plane.
ApprovalsHub is available now in the System32 catalog. Ask us for a workspace and bring your messiest approval process.