Skip to content

docs(openspec): schedulable flows + app-declared credential providers - #2174

Merged
rubenvdlinde merged 1 commit into
developmentfrom
spec/or-followup-specs
Jul 28, 2026
Merged

docs(openspec): schedulable flows + app-declared credential providers#2174
rubenvdlinde merged 1 commit into
developmentfrom
spec/or-followup-specs

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Two follow-up specs named by the hydra-console chain.

apphost-schedule-flow-action

manifest.schedules[] can only ever run one thingScheduleActionAllowList::MAP has a single entry, openconnector:synchronization. So a virtual app cannot schedule a flow, even though the flow engine can now both call external APIs (#1067) and write objects (#2160).

Adds a flow-run action while keeping the closed allow-list — the point of that design is that an app cannot name an arbitrary class. Attribution is mandatory and fail-closed: a scheduled run has no session, so the owner comes from the schedule declaration and the action refuses rather than running ownerless.

Writing this spec found the same defect a fourth time in the adjacent scheduler (FlowScheduleService::fire() queued with no user) — fixed separately in #2173.

app-declared-credential-providers

The provider catalogue is runtime-immutable, so an app author cannot register the credentials their app needs. Two costs observed while building hydra-console: no codeberg/forgejo provider exists, and the github provider permitted no issue-label write — fixed in #2165 only because we could edit OpenRegister itself.

The design keeps the security boundary rather than removing it:

  • Narrowing lane — same host and auth scheme, provably-subset allow-rules → auto-admitted, because it grants strictly less than the base provider the app could already use. Anything not provably narrower is rejected outright, never escalated.
  • Novel lane — new host or path → pending, denied until an administrator approves. This is the lane that actually fixes Codeberg.
  • Approval pinned to a content digest, so an app that ships benign, gets approved, then widens is returned to pending. Without this the approval is theatre.
  • Always app-scoped and namespaced, so a declaration can neither shadow a reviewed entry nor be borrowed.
  • inject_only declarations rejected — a declared one would be unbounded secret egress authored by the app receiving the secret.

⚠️ Needs a PO decision

Whether the narrowing lane should really skip approval. Argument for: a strict subset grants less than the app already had, and click-fatigue on no-op approvals is itself a security regression. Argument against: it is the one path where something becomes usable with no human in the loop. Recorded as the first deferred question rather than buried in the design.

🤖 Generated with Claude Code

… credential providers

apphost-schedule-flow-action — manifest schedules[] can only ever run ONE thing:
ScheduleActionAllowList::MAP has a single entry, openconnector:synchronization.
A virtual app therefore cannot schedule a flow, even though the flow engine can
now both call external APIs (openconnector.source-call) and write objects
(openregister.object-write). Adds a flow-run action while keeping the closed
allow-list — the point of that design is that an app cannot name an arbitrary
class. Attribution is mandatory and fail-closed: a scheduled run has no session,
so the owner comes from the schedule declaration and the action refuses rather
than running ownerless.

Writing this spec found the same defect a fourth time in the adjacent scheduler
(FlowScheduleService::fire queued with no user) — fixed separately in #2173.

app-declared-credential-providers — the provider catalogue is runtime-immutable,
so an app author cannot register the credentials their app needs. Two costs
observed while building hydra-console: no codeberg/forgejo provider exists, and
the github provider permitted no issue-label write (fixed in #2165 only because
we could edit OpenRegister itself).

The design keeps the security boundary real rather than removing it. Two lanes:
a narrowing declaration (same host and auth scheme, provably-subset allow-rules)
is auto-admitted because it grants strictly less than the base provider the app
could already use; anything introducing a new host or path requires
administrator approval. Approval is pinned to a per-entry content digest, so an
app that ships benign, gets approved, then widens is returned to pending.
Declarations are always app-scoped and namespaced so they cannot shadow or be
borrowed from, and inject_only declarations are rejected outright — a declared
inject_only entry would be unbounded secret egress authored by the app receiving
the secret.

NEEDS PO CONFIRMATION: whether the narrowing lane should really skip approval.
Recorded as the first deferred question rather than buried in the design.
@rubenvdlinde
rubenvdlinde merged commit c84d2cc into development Jul 28, 2026
17 of 20 checks passed
@rubenvdlinde
rubenvdlinde deleted the spec/or-followup-specs branch July 28, 2026 05:56
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 3313310

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 174/174
npm ✅ 555/555
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-07-28 05:59 UTC

Download the full PDF report from the workflow artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant