Skip to content

Enterprise AI platform · Medium, 5.9 of 10 · patched

The human sign-off an AI agent never needed

Archestra calls itself the all-in-one open-source enterprise AI platform. One of its guardrails lets an operator require a human to approve an AI agent’s risky tool call before it runs. We found that the guardrail could silently fail to fire for any call that also matched a narrow exception. Whether it did depended on the order the operator had added two policies in, and the approval policy stayed on screen the whole time, looking enforced. It is public as GHSA-mr62-rhg7-9m4v, rated Medium at 5.9 of 10, fixed in platform-v1.3.73, and credited to RIA Labs.

Patched

Read this part first

If you run Archestra, read the advisory. Every platform release from platform-v1.0.48 up to, but not including, platform-v1.3.73 is affected. The fix shipped in platform-v1.3.73 on 14 October 2026. Update to it or a later 1.3 release. Our own reading, not the advisory’s: the 1.4.0 pre-releases, beta.1 through beta.13 and rc.14 through rc.35, carry the same logic. From rc.36 that code is gone. On any of those, update past rc.35.

Until you can, our own suggestion, not the advisory’s: list every tool that has a specific require-approval policy and also another specific policy that can match the same call. Treat that gate as unreliable, whatever order the policies were added in. Remove the exception, or narrow it so no call can match both. Keep the gate. Do not test it by calling a live tool that can delete, send or pay.

The rest of this is about the pattern. There is no exploit code below.

How bad it is

The record rates it Medium, 5.9 of 10: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N. The vector reads: network, no privileges, no user interaction. The score is held down by AC:H. Our report’s reason is a condition we state plainly: two specific policies have to match the same call, and an operator has to have created both. Integrity is I:H because the thing that fails is the control that stops an agent acting without a person.

We filed 7.5 in the score field too, with a scope change and a low confidentiality impact, and the advisory text, which is our report, still carries it. The record was published at 5.9, with neither, and does not say why. Both vectors keep AC:H, and our report gives the reason. The record’s number is the one we print.

Why an AI platform makes this worse

A human-approval gate puts a person between an AI agent and an action. The agent reads text nobody vetted, decides what to do with it, and then calls a tool that has real effects. We do not know what any operator chose to gate. Where the gate exists, the person in the middle is often the last control.

The rules that decide whether a tool call needs that person can match on the call’s own arguments. Those arguments are filled in by the agent, which is the party the gate is meant to govern. So the side that can be steered by hostile text also influences which rules apply to the call. That is normal and fine for a working gate. It is how a broken one gets reached.

And a gate that is off while it looks on is worse than no gate. An operator who never configured approval knows it is missing. An operator who did configure it, and can see it in the screen, stops worrying.

The clue was the order

Each tool can carry several policies. Some match any call, and some match only calls with particular arguments. When more than one specific policy matches, the code fetched them from the database with no ordering at all, walked down the list, and let the first match decide. If that match was anything other than “require approval”, it stopped looking. A require-approval policy further down the list was never read.

No clever trick was needed to put it there. In our test the rows came back in the order the operator added them, which is the order the Add Policy button produces. Write the narrow exception first and the broad gate second, and the gate did not fire for a call that matched both. The database promises no order here. In practice it repeats the same order until the rows change. So on an affected deployment, we expect matching calls to skip approval on every try, not now and then. What varies is which deployments are broken, not which requests get through.

Three alibis that did not hold

“That is how precedence is meant to work.” Three other places in the same file settle a multi-match safely. The evaluator that blocks calls is order-independent: any matching block wins wherever it sits. The check for whether a tool has a blocking policy asks only whether one exists. And the lookup for the tool itself, a few lines above the faulty one, is explicitly sorted, with a comment explaining that a duplicate must resolve to the same row every time rather than an arbitrary one. The same file shows the hazard was understood. It was not applied here.

“Something further down the line catches it.” Nothing we found does. The blocking evaluator files “require approval” alongside “allow” and leaves the decision to the approval check. Every path we found that asks for approval asks that one check and acts on its answer alone.

“The tests would have shown it.” The test file covers a specific policy beating a default one, and that case works. When we looked, it had no test with two specific policies on one tool. The fix added one. The product defined what happens between specific and default. It defined nothing between specific and specific.

How we know

A description is not a finding. We added one test file to the project’s own suite and ran it against the Postgres build that suite already uses, so the row order was real database behaviour and not a mock’s array. First the control: their eight existing approval tests, unmodified, all passed.

Then one tool with two specific policies, both matching a single call: a broad gate requiring approval, and a narrow exception allowing it. The gate alone required approval. The exception alone did not. With the gate added first, approval was required. With the exception added first, it was not. We asserted the security property itself, that if any matching policy says a human must approve then a human must approve, and only the last case failed.

What we did not do is stand up the whole platform and drive a tool call through its gateway end to end. The advisory says so and so do we. We read every path that runs a tool and found no second approval check. The record credits RIA Labs as the only reporter, and carries no CVE identifier. We reported it privately and published nothing until the fix and the advisory were out.

Three questions for any AI platform with a policy engine

None of this is unique to one product. If rules decide what an AI agent may do, these are worth asking about whatever enforces them.

  1. What happens when two rules match the same call? If the answer is “the first one wins”, find out which one is first, and whether anyone chose that.
  2. Can the agent choose which rules apply? If rules can match on arguments the agent supplies, then whoever steers the agent steers which rules match.
  3. Is the safety property tested across orderings? A test that passes for the order you thought of says little about the order your operator used.

None of it needs exotic tooling. It needs the property written down as a sentence, then checked every way the rows can be arranged.

What it proves, and what it doesn’t

It proves we test the control plane of an AI platform, the rules and gates around the model, and not only the prompts that go through it. A guardrail is code like any other, and it can be wrong in ways the demo never shows.

It does not prove anyone got past an approval on a live deployment. It needs two overlapping policies that an operator created, and we do not know how many deployments had them. We did not show hostile text steering an agent into arguments that match two policies. It does not show the whole platform failing end to end, only the decision function the platform relies on. And it says nothing about how Archestra compares with other platforms. We did not compare them.

If you build or run an AI platform, an agent framework or an MCP gateway, we’ll read it. Nominate a target and the first scan costs nothing.

Published 14 October 2026. GHSA-mr62-rhg7-9m4v · CVSS 3.1 base score 5.9 on the record (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N) · CWE-863 (Incorrect Authorization) · credited to RIA Labs as reporter, published by the Archestra maintainers. Status as of 19 October 2026. Corrections, or an AI platform you maintain and want looked at: info@ria-labs.com.

See what a scan turns up

Nominate a target. The first scan costs nothing, and we’ll walk you through it.