AI Adoption GuideProcurementApprove
DoA compliance enforcement
AI cross-checks each approver against the delegation-of-authority matrix and flags unauthorized approvals before they post.
Procurement processRequestApproveSourceEvaluateSelectOrderReceiveReview
By Don, DoneThat’s AI coach · updated
Hold the click if the named person is not on the live matrix
DoA enforcement is a hard gate on the person who clicked, not a warning in the queue. Join that identity to the live delegation-of-authority matrix on amount, legal entity, and category. If they are over their limit, in the wrong entity, or missing from the row that covers this request, hold the approval and route it to the person the matrix actually names.
The matrix is the source of truth. Workflow defaults, manager chains, and "who usually signs this" are not. An unauthorized click that posts is a control failure even when the spend is real and the supplier is allowed.
This check runs at approve, after intake. Policy pre-check at intake can confirm supplier, catalog, and category rules. That pass does not prove the person about to click is authorized.
SAP, Coupa, Workday, and ServiceNow all host approval chains. The control is the same wherever the click happens: the named identity must match a live matrix row before the approval posts.
Match amount, entity, and category, not the org chart
Read three fields from the request and one identity from the click, then look up one matrix row.
- Amount. Use the value DoA is written against, usually the PO or requisition total with the tax treatment your policy names. Approving a line without the header total will miss a limit.
- Legal entity. Company code, not cost center, not plant nickname. A controller authorized in DE01 is not authorized in DE02 because they still sit in the same building.
- Category. Capex versus opex, inventory versus services, or whichever axis your matrix actually uses. A $200,000 inventory limit does not authorize $200,000 of professional services.
- Named identity. The person who clicked, as a stable HR or identity ID, not a display name and not a shared inbox.
If the row exists and the person is inside all three limits, the approval may post. If any axis fails, hold. Show the limit that failed and the named delegate on that row. If the row has no person, hold and send it to the DoA owner. Do not pick a manager from the org chart to keep the queue moving.
Self-approval is a separate hold: the requester cannot satisfy DoA by approving their own request, even when their limit would cover the amount.
Risk-based approval routing may add reviewers or skip courtesy layers. It cannot skip a matrix row or substitute a cheaper path when the amount requires a higher delegate.
A plant controller still in the default chain after a split
The walkthrough is illustrative, not a measured result.
A European manufacturing group splits one German company code into two: the original plant (DE01) and a new legal entity for a recently acquired warehouse (DE02). The plant controller, Anna, used to cover both sites on paper. Finance published a new matrix: Anna remains the DE01 maintenance-capex delegate up to €50,000. Above that, and for all DE02 spend in that category, the row names the regional finance director.
A €180,000 roof-repair PO is raised against DE02. The buying tool still defaults Anna as approver because her HR record still lists her as plant controller for Germany and the approval chain was copied from DE01. She clicks.
Join her identity to the live matrix: amount €180,000, entity DE02, category maintenance capex. She is over the DE01 cap even if the entity were right, and she has no DE02 row. Hold. Do not post. Route to the regional finance director named on the DE02 row. Put the failed axes on the hold reason: entity and amount, and show the €50,000 DE01 cap.
If the DE02 row is blank because finance has not named anyone yet, still hold. Queue it to the matrix owner. Filling the gap with Anna's skip-level, or with the next manager in the HR file, invents a delegate the board never authorized.
Stale HR data is the usual failure
Most false holds, and most unauthorized posts you catch in audit, come from a matrix that does not match the organization that exists this week.
Job changes, legal-entity splits, and acting cover during leave move faster than the spreadsheet or the workflow table. HR still shows last quarter's title. The buying tool still has last year's default chain. Enforcement will block legitimate work, or it will let the old controller keep signing, until those files agree.
Reconcile before you enforce:
- Every matrix row has a person ID that still exists, a limit, an entity, a category, and an effective date.
- Acting delegations have a start and an end. Cover during leave is a dated row, not a forwarded inbox.
- When HR records a manager change, the matrix owner gets a work item. Do not wait for the annual policy refresh.
- Run detection against recent approvals before you switch to blocking. The mismatches tell you whether the matrix or the org file is wrong.
If the same cost center or entity keeps failing, the threshold or the entity mapping is probably wrong. Fix the row. Do not widen the check to any director in the function.
Approval anomaly flagging will still catch unusual amounts and odd suppliers in a queue that is otherwise authorized. It is not a substitute for a missing matrix join. A familiar amount on a familiar supplier can still be an unauthorized click.
A policy pre-check pass is not DoA
Intake can be clean and the click can still be unauthorized.
Policy pre-check answers whether this supplier, channel, and category are allowed. DoA answers whether this person is allowed to bind the company for this amount in this entity. A request that passed intake still needs the matrix join at approve.
Keep the two reasons separate in the hold message. Mixing them trains requesters to argue policy when the problem is identity, and trains approvers to treat a green intake banner as permission to click.
The same separation applies to risk-based routing. Risk can add a category lead or skip a rubber-stamp layer. It cannot drop the matrix delegate or treat a low score as a license to post without a named, in-limit person.
If you auto-approve a low-risk band, that posting identity still needs a DoA row. A rule that says "under $5,000, no human" without one is an unauthorized posting with a nicer name.
Enforcement is finished when a held click shows the failed axis, names the live delegate or the matrix owner, and does not invent a person to keep the PO moving.
Is this worth automating for you?
Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.
DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.
Measure the baseline first