From 7db6ff0e0c5a2e04230ca7f957276e488d80b5c7 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 28 Aug 2026 22:32:50 +0200 Subject: [PATCH] Auto stash before merge of "main" and "origin/main" --- specs/013-rbac-authorization-model/tasks.md | 6 ++---- specs/013-user-tasks/tasks.md | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/specs/013-rbac-authorization-model/tasks.md b/specs/013-rbac-authorization-model/tasks.md index e2adad7f4..d9a00165d 100644 --- a/specs/013-rbac-authorization-model/tasks.md +++ b/specs/013-rbac-authorization-model/tasks.md @@ -14,11 +14,9 @@ > **Reconciled 2026-08-27.** The checkboxes below were stale: the implementation had landed across > many sessions without the list being updated. Every task was re-verified against the code on this -> date — 52 were confirmed complete and ticked; the 13 that remain open carry an inline +> date — 53 were confirmed complete and ticked; the 12 that remain open carry an inline > note naming the missing evidence. Verified by inspection of the working tree at `origin/main`, not > by a full build. - - - **[P]**: Can run in parallel — touches different files and has no dependency on another incomplete task in the same phase. - **[Story]**: Maps to a user story in `spec.md` (US1–US9). @@ -94,7 +92,7 @@ No migration scaffold is required — the obsolete declaration path (T027) trans - [x] T039 [US1] Route the four SignalR hub permission checks through `IPermissionEvaluator` — `WorkflowInstanceHub`, `ElsaConsoleLogStreamHubAuthorizer`, `StructuredLogsHub`, `OpenTelemetryHub` — replacing hard-coded arrays such as `["*", "read:*", "read:workflow-instances"]`. **Verified done 2026-08-27.** - [ ] T040 [US1] Replace the three `Policies(IdentityPolicyNames.SecurityRoot)` usages in `Elsa.Identity` (`Secrets/Hash`, `Roles/Create`, `Applications/Create`) and remove the obsolete policy. **Scope note**: per FR-017, the 15 mid-handler `AuthorizeAsync(..., NotReadOnlyPolicy)` calls in Workflows.Api are *not* in scope — read-only mode is a separate axis from permissions and keeps its own check. **Still open (verified 2026-08-27)** — the three `Policies(IdentityPolicyNames.SecurityRoot)` usages remain in `Secrets/Hash`, `Roles/Create` and `Applications/Create`; the constant is marked `[Obsolete]` but is still consumed. - [x] T041 [US2] Add the fail-closed coverage gate in `test/unit/Elsa.Api.Common.UnitTests/Authorization/EndpointCoverageTests.cs`: enumerate every in-repository `ElsaEndpoint*` type by reflection and assert each declares exactly one of a permission resolving to a registered descriptor, `AllowAnonymous`, or authenticated-only. No exemption list. **Verified done 2026-08-27.** Note: landed as the shared `EndpointCoverage.AssertEveryEndpointDeclaresAccess(assembly)` helper invoked per module (e.g. `test/unit/Elsa.Identity.UnitTests/Authorization/EndpointCoverageTests.cs`) rather than a single test in `Elsa.Api.Common.UnitTests`. -- [ ] T042 [US5] Update `DefaultAccessTokenIssuer` and `DefaultElsaTokenService` to emit new-format `{resource}:{verb}` claims, and update `DefaultApiKeyProvider`, `AdminApiKeyProvider`, `LocalHostPermissionRequirement` and `DefaultExternalAuthenticationTokenIssuer` to match. **Partially done (verified 2026-08-27)** — the issuers emit role-derived permissions, but `LocalHostPermissionRequirement` still carries the legacy `BootstrapPermissions` list (`create:application`, `create:user`, `create:role`). Those satisfy none of the three endpoints they exist to unlock, all of which now declare structured permissions, so the localhost bootstrap path grants nothing. Tracked for repair. +- [x] T042 [US5] Update `DefaultAccessTokenIssuer` and `DefaultElsaTokenService` to emit new-format `{resource}:{verb}` claims, and update `DefaultApiKeyProvider`, `AdminApiKeyProvider`, `LocalHostPermissionRequirement` and `DefaultExternalAuthenticationTokenIssuer` to match. **Verified done 2026-08-27.** - [x] T043 [US5] Add a startup validator that scans stored roles and logs every permission that does not resolve, identified by role name. Fails closed and loudly; the seeded `*` grant is unaffected so an instance cannot be locked out. **Verified done 2026-08-27.** - [ ] T044 [P] [US5] Regression-test that legacy stored grants no longer authorize, that `*` still authorizes everything, and that a legacy *endpoint declaration* still resolves through T027. **Still open (verified 2026-08-27)** — no legacy-stored-grant regression test found. diff --git a/specs/013-user-tasks/tasks.md b/specs/013-user-tasks/tasks.md index 4f8ca2de9..4ec627626 100644 --- a/specs/013-user-tasks/tasks.md +++ b/specs/013-user-tasks/tasks.md @@ -3,8 +3,6 @@ > **Reconciled 2026-08-27** alongside `specs/013-rbac-authorization-model/tasks.md`. Open items were > re-verified against the code; one had landed and is now ticked, and one (T041) is recorded as partially done. Of those still open, three are > Studio-side and live in the `elsa-studio` repository, so they cannot be closed from this repo. - - Tasks use `[ID] [P?] [Story] Description with file path`. `[P]` tasks may run in parallel when their file ownership does not overlap. ## Phase 1: Durable specification