Skip to content

Decide whether POST /api/v1/automation/:name/toggle belongs in the manage_metadata write set — it mutates flow enablement with no authoring capability #10243

Description

@os-elon

Split out of #10145 rather than folded into it, because it is a decision, not the measured defect that card fixes.

What #10145 settled, and what it deliberately did not

#10145 gates the automation-domain definition writesPOST /automation, PUT /automation/:name, DELETE /automation/:name — on manage_metadata. It deliberately left every other mutating route on the domain alone, on the rule that authoring and executing are different questions:

POST /automation/:name/toggle sits between the two classes and is the one that needs a ruling.

The question

toggleFlow(name, enabled) mutates whether a registered flow is enabled and bound to its trigger. Today it is reachable by any authenticated caller (behind the domain's anonymous floor, and nothing else).

Reading it as execution state: the domain's own _status route comment separates the two explicitly — "persisted status is metadata, but whether a flow is actually enabled + bound to its trigger is engine state". On that reading toggle is operator tooling, not authoring, and gating it on manage_metadata would be the same over-block mistake #7968 records for the paused-run screen read.

Reading it as authoring: disabling a shipped flow is functionally equivalent to deleting it for as long as it stays off — and DELETE /automation/:name is now gated. On a walled multi-organization deployment the blast radius is identical to the one #10145 measured: flow enablement is environment-scoped, so one tenant switching a flow off switches it off for every organization on the deployment. That is the same cross-tenant shape, one verb over.

⚠️ The second reading has not been measured over HTTP. This card is the request to measure it and rule, not a claim that it reproduces.

What a fix would look like if the ruling goes that way

One line: add the toggle arm to isFlowAuthoringWrite in packages/runtime/src/domains/automation.ts, which is already the single predicate for this policy. The audit block in packages/runtime/src/domains/automation-write-capability-gate.test.ts currently pins toggle as ungated, deliberately and in the open, so that pin is where the ruling would land:

it('POST /:name/toggle stays ungated — enablement is engine state, not a definition write', …)

If the ruling goes the other way, that pin stays and this card closes as not planned with the reasoning recorded — which is also a useful outcome, because right now the verdict is implicit.

Related: #10145 (the write gate this splits from), #7020 (whether the read and write capability cohorts should align).

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions