feat(config): federated configuration sharing — engine + type registry + Flows (+ e2e)#2134
Merged
Merged
Conversation
…y + Flows (+ e2e) Builds the foundation of the fleet-wide federated-config standard (design in the carried openspec change; supersedes the design-only #2132). One OpenRegister- owned way for any app to share configuration over GitHub; Flows is the first consumer (the reframed #2065). - IShareableConfigType + RegisterShareableConfigTypesEvent + registry — the contribution seam, same idiom as flow nodes. Storage-agnostic: a type owns (de)serialisation, so app-specific storage (e.g. NL Design themes in IConfig) works too, not only OR objects. - FederatedConfigService — the engine: types(), bundle() (serialise a selection), install() (deserialise, gated by the org source allowlist), publish() (push to GitHub with the token supplied by the credential broker — Doriath's vault where installed, NC vault otherwise; the token never enters the service). Trust v1 = org allowlist (empty = not-yet-enforced) + version pinning + secret exclusion. - FlowShareableConfigType — flows as a type: serialise to a portable shape (no id/uuid/owner/organisation), install back into the flow store. - FederatedConfigController + routes (/api/federated-config/types|bundle|install), all #[NoCSRFRequired] so API/MCP clients can call them. Tests: 13 unit (registry event-once, service allowlist enforcement + prefix match, Flow type round-trip strips instance fields). Playwright e2e tests/e2e/api-direct/federated-config.spec.ts (4): types include Flows; a flow bundles → installs as a fresh flow → the installed flow RUNS to completion; unknown type = 404; the org allowlist refuses a non-allowlisted source (403) and allows an allowlisted one. phpcs clean. Live-verified on 8080: full round-trip (bundle a flow → install a fresh one → run it → {shared:true}). Follow-ups (per the design's phases 4-6): fold hermiq's duplicated GitHub sync onto this; roll out declared types per app (procest case types, shillinq payroll packs, opencatalogi publication types, docudesk, softwarecatalog, pipelinq, larpingapp, NL Design themes); the publish/discover UI; per-org RBAC beyond admin; signing.
Contributor
Quality Report — ConductionNL/openregister @
|
| 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-26 08:07 UTC
Download the full PDF report from the workflow artifacts.
This was referenced Jul 26, 2026
rubenvdlinde
added a commit
that referenced
this pull request
Jul 26, 2026
…iscovery, signing, per-org RBAC (#2147) Builds out the store surface on top of the sharing engine (#2134/#2135/#2140): - **Publish endpoint** `POST /api/federated-config/publish` — publishes a signed bundle to GitHub using the credential the USER selected (read from the `federated-config-credential` preference), never one passed by the caller. Refuses (400) when no store credential is selected. - **Discovery** `GET /api/federated-config/discover?topic=` — searches GitHub by a type's discovery topic (anonymous, or through the broker when the user has a credential). Backs a browse UI; never installs. - **Signing / verification** (`BundleSigner`, Ed25519 via libsodium) — publish signs the canonical bundle with the instance key (minted + stored once); install verifies. A tampered signature is always refused; unsigned/untrusted bundles are refused once the org populates a trusted-keys allowlist (empty = not-yet-enforced, the source-allowlist idiom). `GET /api/federated-config/ public-key` exposes the instance key for others to trust. - **Per-org RBAC** (`FederatedConfigAccess`) — publish/install gated by app-config group allowlists (`federated_config_publish_groups` / `_install_groups`); empty = any signed-in user, admins always allowed. 15 unit (BundleSigner round-trip/tamper/canonicalisation/enforcement; RBAC membership; install signing gate) + 6 Playwright e2e. Live-verified on 8080: public-key served; discover returned real GitHub repos; signing enforcement 403→ cleared 200 (after appconfig-cache restart); RBAC 403 for a non-admin gated user, 200 for admin; publish 400 with no credential selected. @SPEC openspec/changes/federated-config-sharing/specs/federated-config-sharing/spec.md
rubenvdlinde
added a commit
that referenced
this pull request
Jul 26, 2026
…tandard (#2154) The change captured only the initial design (5 requirements, most tasks open). It now reflects everything shipped and merged across the fleet: - 6 new requirements — schema-marker mechanism (REQ-FCS-006), Ed25519 signing + verification (007), per-org group RBAC (008), config sets (009), repo-creation + topic-tagging + fetch bridge (010), and installable config-set repositories / OpenBuild convergence (011). Each with scenarios; `openspec validate --strict` passes. - tasks.md updated to the shipped reality with PR references across openregister (#2134/#2135/#2140/#2147/#2148/#2149), nldesign #192, the 8 app markers, hermiq #126/#127, openbuild #181, nc-vue #242 — plus the real-GitHub end-to-end verification and the two external follow-ups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds the foundation of the fleet-wide federated configuration sharing standard (design carried in the openspec change; supersedes the design-only #2132). One OpenRegister-owned way for any app to share configuration over GitHub — Flows is the first consumer (the reframed #2065).
What
IShareableConfigType+RegisterShareableConfigTypesEvent+ registry — the contribution seam, same idiom as flow nodes. Storage-agnostic: a type owns (de)serialisation, so app-specific storage (e.g. NL Design themes inIConfig) works too, not only OR objects.FederatedConfigService— the engine:types(),bundle()(serialise a selection),install()(deserialise, gated by the org source allowlist),publish()(push to GitHub with the token supplied by the credential broker → Doriath's vault where installed, NC vault otherwise; the token never enters the service). Trust v1 = org allowlist (empty = not-yet-enforced) + version pinning + secret exclusion.FlowShareableConfigType— flows as a type: serialise to a portable shape (no id/uuid/owner/organisation), install back into the flow store.FederatedConfigController+ routes (/api/federated-config/types|bundle|install), all#[NoCSRFRequired].Verification
federated-config.spec.ts(4): types include Flows; a flow bundles → installs as a fresh flow → the installed flow RUNS to completion; unknown type → 404; the org allowlist refuses a non-allowlisted source (403) and allows an allowlisted one.{shared:true}.Design decisions baked in (from review)
OR service + type registry · GitHub credentials via Doriath (broker vault leaf) · trust v1 = org allowlist + pinning · sharing user/org-scoped · #2065 collapses to one flow-shaped consumer · no openconnector dependency.
Follow-ups (design phases 4–6)
Fold hermiq's duplicated GitHub sync onto this · roll out declared types per app (procest case types, shillinq payroll packs, opencatalogi publication types, docudesk, softwarecatalog, pipelinq, larpingapp, NL Design themes) · publish/discover UI · per-org RBAC beyond admin · signing.
🤖 Generated with Claude Code