Join our Newsletter — 33% off our NHI Course

What breaks when approval systems treat pending, denied, and executed as if they were the same state?

Confusing those states causes clients and agents to misread transport success as tool execution, or to treat a waiting request as if it already passed review. That can trigger false completion messages, duplicated requests, or unsafe retries. A sound design keeps pending, approved, denied, expired, and executed separate, with explicit transitions and reconciliation against the downstream operation record.

When state labels collapse, control flow collapses too

The core problem is not only a bad label, it is a broken contract between the caller, the approval layer, and the executor. If pending, denied, and executed are all treated as “done,” systems can no longer tell whether a request is waiting for review, explicitly rejected, or already consumed downstream. That makes every follow-on decision less trustworthy, from retry logic to user messaging.

A clean approval model needs state to carry meaning. Pending means no downstream action yet; approved means permission exists; denied means the request must not proceed; executed means the action already happened; expired means the approval window closed without use. Those distinctions let clients reconcile intent with outcome instead of guessing from a single success response.

In practice, the state machine matters as much as the decision itself. If a workflow can move from pending to approved and later to executed, then each transition should be explicit, monotonic where appropriate, and auditable so that a later observer can determine whether a transport call, an approval decision, or an actual side effect occurred.

Why transport success is not the same as action completion

Many systems confuse message acceptance with business completion. A gateway, queue, or API can return success because it accepted the request, not because the underlying operation passed review or finished executing. If a client interprets transport-level acknowledgement as tool execution, it may emit false completion, hide an outstanding approval, or skip a necessary reconciliation step.

This is especially dangerous when approvals are asynchronous. The safe pattern is to bind each request to a durable operation record, then compare the approval state with the downstream execution record before declaring success. That prevents a transient network response from being mistaken for a final security or business decision.

It also reduces duplicate action risk. When callers do not know whether a request was merely accepted, approved, denied, or already executed, they tend to retry conservatively. Without idempotency keys, deduplication, and clear terminal states, those retries can create repeated side effects even when the original action already completed.

What explicit transitions and reconciliation must preserve

The most reliable design is one that makes state transitions visible and impossible to blur. A request should have a distinct lifecycle, with pending, approved, denied, expired, and executed treated as separate outcomes rather than variants of one generic terminal condition. The execution layer should publish its own record so the approval layer can reconcile what was authorized with what actually happened.

That separation matters because the approval decision and the downstream action are different facts. A request can be approved but not yet executed, denied but still visible in logs, or executed after approval expires if the implementation is weak. A good model records both the decision and the effect, then surfaces mismatches as exceptions rather than normalizing them away.

For practitioners, the useful test is simple: can an operator answer “was this approved, denied, or actually executed?” from the records alone. If the answer depends on inference from status text or client behavior, the state model is too weak for dependable automation.

Risk and Threat Considerations

Collapsing approval states creates integrity risk because downstream systems may act on a false assumption about authority or completion. It also creates an abuse path for duplicate execution, unsafe retries, and confused-deputy behavior when an agent or client treats a waiting request as already authorised.

Failure mechanism: A caller misreads acceptance as execution, retries after an unclear response, or marks a denied request as complete, which breaks idempotency and allows state drift between the approval record and the real-world side effect.

Impact: Teams can trigger duplicate actions, suppress required review, or miss a denial entirely, which is especially damaging when the downstream operation is irreversible, costly, or security-sensitive.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP API Security Top 10 addresses the attack and risk surface, while NIST SP 800-53 Rev 5 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
NIST SP 800-53 Rev 5 AC-1 — Access Control Policy and Procedures Approval state handling is an access decision workflow that needs defined policy and transition rules.
AU-2 — Event Logging Distinct approval and execution states require records that preserve who decided and what actually happened.
IA-5 — Authenticator Management Misread approvals often stem from ambiguous request tokens, retries, or lifecycle handling of credentials tied to action.
Recommendation — Define explicit approval-state policy and enforce separate pending, denied, and executed transitions. Log approval decisions and downstream execution as separate events. Use strong request correlation and lifecycle controls for action-bearing tokens and credentials.
NIST CSF 2.0 PR.AA-05 — Identity Management, Authentication, and Access Control The subject depends on separating authorization from execution and preserving access decisions accurately.
Recommendation — Separate authorization decisions from execution outcomes and verify each before completion.
OWASP API Security Top 10 API6 — Unrestricted Access to Sensitive Business Flows Ambiguous approval states can let clients repeat or bypass sensitive workflow steps.
Recommendation — Protect sensitive workflow states with explicit server-side authorization and idempotency checks.

Practitioner Guidance

What to verify: Check that every terminal state is mutually exclusive and backed by a separate downstream record. If approval and execution share the same status code or timestamp model, the design is too ambiguous for safe automation.

Decision rule: If the request can cause a real side effect, require a durable operation identifier, explicit idempotency handling, and a reconciliation step before any client is allowed to announce completion.

Practitioner takeaway: The safest approval system is not the one with the fewest states, but the one that makes permission, waiting, denial, expiration, and execution impossible to confuse.