feat(authorization): align roles and permissions with the spec (PATCH, 409 conflicts, resource_type_slug) - #97
Conversation
Greptile SummaryThis PR aligns authorization role and permission behavior with the updated WorkOS specification.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains. No blocking failure remains. Important Files Changed
|
| return { | ||
| ...formatEntity(p), | ||
| system: false, | ||
| resource_type_slug: p.resource_type_slug ?? 'organization', |
There was a problem hiding this comment.
in the first commit, this was explicitly passing 'organization'; now allows supporting other resource type slugs
The `organization` fallback was spelled out independently at both persistence sites and again in the formatter, so changing it (or making it configurable) would have to land in three places. Review of #97 also found the new seed key undocumented and the empty-string rejection path untested; this closes those gaps in the same pass.
|
The reported failure belongs to superseded head The image behavior was unchanged; CI now allows enough time for pre-bind RSA key generation under variable runner load. |
|
Folded this check result into the active TARS task. |
|
Folded this check result into the active TARS task. |
|
Folded this check result into the active TARS task. |
|
Folded this check result into the active TARS task. |
This reverts commit 5cbb98c.
|
Folded this check result into the active TARS task. |
|
Folded this check result into the active TARS task. |
|
Folded this check result into the active TARS task. |
This reverts commit 1b211ef.
resource_type_slug
The pin had fallen 21 minor versions behind the published spec, so the committed event catalog knew nothing of the agent and resource-export events and SUPPORTED.md measured coverage against a stale endpoint list. 0.80 also retags the agents endpoints and adds IT contacts, waitlists, and platform teams; the support-matrix generator refuses unassigned tags, so those are mapped to features here.
The spec and every SDK update a permission with PATCH, but the emulator only registered PUT, so the Node SDK's updatePermission never reached the handler. Nothing outside the emulator ever sent PUT, so it is dropped rather than kept as an alias. A taken slug now answers 409 permission_slug_conflict as production does; the former 422 field error never carried the code clients key on.
A loop inside one `it` reports a bare mismatch without saying which input tripped; `it.each` names the failing value in the test title.
…se-shape # Conflicts: # SUPPORTED.md
Same divergence as permissions: the spec and the Node SDK update environment and organization roles with PATCH, so updateRole and updateOrganizationRole never reached the emulator's PUT handler. A taken slug now answers 409 with the spec's role_slug_conflict or organization_role_slug_conflict code instead of a 422 field error, which never carried the code clients key on.
|
Flagged: ARM64 failed only during the 10-second container health probe with repeated This matches the previously observed ARM runner/startup flake; there is no evidence here of a permission or image-build regression. Per the agreed scope, TARS is reporting it rather than modifying PR #97. |
The spec and the Node SDK replace a role's permissions with PUT and attach a single one with POST, both answering with the role, which production returns with its permission slugs inlined. The emulator gave POST replace-all semantics, had no PUT, and answered DELETE with an empty 204, so setEnvironmentRolePermissions had no handler and addEnvironmentRolePermission was rejected as malformed. Roles now carry `permissions` wherever they are formatted, which also closes that tracked gap in the response-shape ledger.
The matrix expanded registerRoleRoutes from a hand-kept mirror of the helper's routes, which had already drifted: it still listed PUT for role updates after the switch to PATCH, so SUPPORTED.md kept scoring FGA at 14/26 writes. Reading the registrations out of role-helpers.ts removes the second copy, and the generator now fails if it finds none rather than silently dropping every role endpoint.
The spec requires `resource_type_slug` on every role and on the role lifecycle events, and both create DTOs accept it, but the emulator had no notion of a role's scope and carried it as a tracked gap in the response-shape ledger. Roles now take the scope on create and in the seed file, default to `organization` as production does, and keep it through updates, which the update DTO cannot change. Resource types are still not modeled, so a scope is not checked against a registry and a role's permissions are not checked against its scope; production enforces both.
resource_type_slugProduction rejects a `resource_type_slug` that names no resource type and refuses permissions whose scope does not match the role's; the emulator accepts any non-empty slug and never cross-checks. That was stated only in code comments, so a reader of SUPPORTED.md had no way to know a scope typo passes here and fails against WorkOS.
The same optional-but-non-empty rule was spelled out at both create routes and both seed validators, so tightening it later (a registry, once resource types are modeled) would take four coordinated edits.
`PUT …/permissions` deleted the role's join rows and then inserted slug by slug, throwing 404 at the first unknown one, so a single typo left the role with a partial set. Production validates the whole list before writing, and this is the path the SDKs' setEnvironmentRolePermissions and setOrganizationRolePermissions call.
Production emits role.updated or organization_role.updated when a permission set actually changes through the permissions endpoints, without touching the role row; the emulator emitted nothing there, because only ws.roles.update fires the collection hook. Its role.deleted also never carries permissions while organization_role.deleted does, but the delete route cascaded the joins before the row, so the hook always saw an empty list. Both behaviors were read from the production roles service and the role-permissions controllers.
Summary
systemandresource_type_slugto every formatted permission response and eventorganizationTest plan
bun test src/workos/response-shapes.spec.ts src/workos/routes/authorization-permissions.spec.ts(42 passed)bun run typecheckbun run lintbun run fmt:checkRequested by @alidacodes