Skip to content

ATS-PFM-SEC-010Assign roles within a controlled scope: Capability Test Specification

Markdown

ATS-PFM-SEC-010

Assign roles within a controlled scope: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaPlatformModuleSecurity, Customers and WorkspacesRevision3ExaminercodexExamined on2026-10-23

Read atservices-platform ad3f6a65react-console baf6dae3

Coverage

  • Rule covered
  • Transition covered
  • Validation gap: FND-PFM-SEC-067
  • Permission covered
  • Edge gap: FND-PFM-SEC-067
  • Failure gap: FND-PFM-SEC-067
  • Boundary covered
  • Concurrency covered
  • Invariant covered
  • Interaction covered

Test Scenarios

22 scenarios proving CAP-PFM-SEC-010; 13 bound to an existing test.

01 Role writes require management authoritypermissionapinegativetest
Proves
BR-CAP-PFM-SEC-010-01
Preconditions
Prepare a reader and an access manager.
Steps
Attempt the same grant with both identities.
Expected
The reader receives 403 without a write; the authorized manager succeeds.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses the reader’s attempt to grant as 403, and grants nothing
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#grants a role by its built-in key and answers the grant with the role it names
Source
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses the reader’s attempt to grant as 403, and grants nothing
02 Delegation keys, scopes and self-wideningpermissionapinegativetest
Proves
BR-CAP-PFM-SEC-010-02 INV-DOM-PFM-SEC-003-11
Preconditions
Prepare an administrator with limited workspace authority.
Steps
Grant within that authority, beyond its keys, at an unmanaged scope and to the administrator.
Expected
The permitted grant succeeds; failures identify missing authority or self-widening without creating grants.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a role that grants more than the caller may do there, and names what was missing
services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#refuses a scope the caller does not manage, and says which scope rather than which role
services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#lists every bad scope at once, so an administrator fixes the invitation in one go
services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#refuses an edit that reaches the editor's own grant, whatever they hold and whoever else holds it
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a role that grants more than the caller may do there, and names what was missing
03 Supported resource scopeboundaryapinegativetest
Proves
BR-CAP-PFM-SEC-010-03 INV-DOM-PFM-SEC-003-07
Preconditions
Prepare live, draft and archived custom record types.
Steps
Grant on those, an unsupported resource kind, a missing type and a different customer’s workspace.
Expected
Live and draft types accept grants; the remaining cases fail with no assignment written.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/resource-scopes.integration.spec.js#grants a role on a draft custom object, which is live though not yet active
services-platform:modules/security/tests/integration/services/membership/resource-scopes.integration.spec.js#refuses a resource type that is not on the allow-list, naming the field, and writes nothing
services-platform:modules/security/tests/integration/services/membership/resource-scopes.integration.spec.js#refuses an archived custom object, naming the object key, and writes nothing
services-platform:modules/security/tests/e2e/resource-scoped-grants.e2e.spec.js#refuses a tenant of another customer, naming it, and writes no grant
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses a scope the screens do not offer as 400
Source
services-platform:modules/security/tests/integration/services/membership/resource-scopes.integration.spec.js#grants a role on a draft custom object, which is live though not yet active
04 Customer security cannot amend staff authorityinvariantapinegativetest
Proves
BR-CAP-PFM-SEC-010-04 INV-DOM-PFM-SEC-003-07
Preconditions
Prepare platform and ordinary assignments.
Steps
Shorten, condition or move the platform assignment, then try promoting the ordinary assignment to platform.
Expected
Each attempt fails with HQ guidance and leaves the assignments unchanged.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a window that would have ended the staff grant, naming where such a change is made
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses the promotion, because granting staff authority is Rhythm HQ’s act
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#leaves the grant exactly as it was granted, so the authority is still in force
Source
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a window that would have ended the staff grant, naming where such a change is made
05 Membership and validity timingtransitionapitest
Proves
BR-CAP-PFM-SEC-010-05 INV-DOM-PFM-SEC-003-08
Preconditions
Prepare active and invited members.
Steps
Assign roles to both and another assignment beginning tomorrow.
Expected
Active membership receives an active grant, invited membership a pending grant, and the future window grants no current access.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#grants a role at customer scope, active at once for an active person, and audits it as widening
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#leaves a grant to somebody who has not accepted yet pending, so it begins when they do
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#answers a grant whose window opens tomorrow as scheduled, in the grant and in the list
Source
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#grants a role at customer scope, active at once for an active person, and audits it as widening
06 Duplicate assignment concurrencyconcurrencyapinegativetest
Proves
BR-CAP-PFM-SEC-010-06 INV-DOM-PFM-SEC-003-09
Preconditions
Prepare a member eligible for a role.
Steps
Grant the same role, scope and window sequentially and concurrently, then revoke and grant again.
Expected
Duplicates return already-assigned and preserve one live row; replacement after revocation succeeds.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses a second grant of the same role at the same scope, and writes no second row
services-platform:modules/security/tests/integration/services/membership/concurrent-grants.integration.spec.js#is granted, because a revoked row is history and leaves room for the grant
Source
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses a second grant of the same role at the same scope, and writes no second row
07 Withdrawal history and administrator protectioninvariantapinegativetest
Proves
BR-CAP-PFM-SEC-010-07
Preconditions
Prepare an ordinary grant and the last qualifying administrator.
Steps
Withdraw each grant.
Expected
The ordinary assignment is retained as revoked history; removing the last administrator is refused.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses the withdrawal that would leave the customer with no security administrator, and withdraws nothing
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#withdraws a grant, which the list then leaves out
Source
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#revokes the grant, keeps the row, and audits what was withdrawn
08 Atomic role-scope reconciliationtransitionapinegativetest
Proves
BR-CAP-PFM-SEC-010-08
Preconditions
Prepare a customer-wide Read Only assignment.
Steps
Select two workspaces, return to customer-wide scope and try an outside-customer workspace.
Expected
The expected two and then one scope rows remain; matching rows retain identity, revocation submits a flush request and the outside workspace fails.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/set-role-scope.integration.spec.js#turns the customer grant into one active grant per tenant asked for, revoking the customer grant
services-platform:modules/security/tests/integration/services/membership/set-role-scope.integration.spec.js#keeps a grant that already matches by its id, revoking only the tenant left out
services-platform:modules/security/tests/integration/services/membership/set-role-scope.integration.spec.js#submits an authorizer-cache flush naming the person after a change that revoked a grant
services-platform:modules/security/tests/integration/services/membership/resource-scopes.integration.spec.js#leaves a resource grant untouched, and out of the answer, when the role’s scope is set
Source
services-platform:modules/security/tests/integration/services/membership/set-role-scope.integration.spec.js#turns the customer grant into one active grant per tenant asked for, revoking the customer grant
09 Deny weakening uses widening checkspermissionapinegativetest
Proves
BR-CAP-PFM-SEC-010-09
Preconditions
Prepare a deny-bearing grant and an editor lacking the denied key.
Steps
Narrow or shorten the grant and add conditions, then extend it and remove a restriction.
Expected
The tested weakening operations fail and are recorded; the tested strengthening operations succeed.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a narrowing of the scope for an editor who is not allowed the key the grant was denying
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a validity window that would end a grant carrying a deny, for the same editor
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a condition added to a grant carrying a deny, for the same editor
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#allows an editor allowed nothing to extend the grant, because a grant that lasts longer denies for longer
Source
services-platform:modules/security/tests/integration/services/membership/amend-grant.integration.spec.js#refuses a narrowing of the scope for an editor who is not allowed the key the grant was denying
10 Effective-permission attributionruleapinegativetest
Proves
BR-CAP-PFM-SEC-010-11
Preconditions
Prepare a role with its own deny and a member without grants.
Steps
Explain both members’ access, then request explanation as a reader.
Expected
Allowed keys identify their assignment, role and policy; the denied key is absent, the grantless member has no permissions and the reader is refused.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/effective-permissions.integration.spec.js#answers the key the role allows, with the grant, the role and the policy that name it
services-platform:modules/security/tests/integration/services/membership/effective-permissions.integration.spec.js#leaves out a key the role's own deny takes back, although its policy still names it
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#answers nothing for somebody holding no grant, rather than failing
services-platform:modules/security/tests/e2e/console-users.e2e.spec.js#refuses the reader, who may read the person but not explain their access
Source
services-platform:modules/security/tests/integration/services/membership/effective-permissions.integration.spec.js#answers the key the role allows, with the grant, the role and the policy that name it
11 Staff-only and unknown roles are unavailableboundaryapinegativetest
Proves
BR-CAP-PFM-SEC-010-12
Preconditions
Prepare a customer membership.
Steps
Try staff-only roles by key and identifier and an unknown built-in key.
Expected
No grant is written; unavailable roles return not found and unknown-key refusal identifies the requested key.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses a staff-only role for a customer's user as not found, by its key or its id, and grants nothing
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses a built-in role key Rhythm does not have, naming it, and grants nothing
services-platform:modules/security/tests/e2e/definitions.e2e.spec.js#refuses to grant a staff-only role to a member, by its key or its id, and grants nothing
Source
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#refuses a staff-only role for a customer's user as not found, by its key or its id, and grants nothing
12 Membership and assignment historyinteractionapinegativetest
Proves
BR-CAP-PFM-SEC-010-13
Preconditions
Prepare a member.
Steps
Grant, move and withdraw a role, then inspect history.
Expected
Membership entries identify each changed assignment and assignment history carries the relevant widening classification.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/integration/services/membership/grant-history.integration.spec.js#lists the grant, the move and the withdrawal, each naming the grant it was about
Source
services-platform:modules/security/tests/integration/services/membership/grant-history.integration.spec.js#lists the grant, the move and the withdrawal, each naming the grant it was about
13 Grant presentation and role membershipinteractionbrowsertest
Proves
AS-JNY-PFM-SEC-003-02 AS-JNY-PFM-SEC-004-03
Preconditions
Prepare a security administrator and colleague.
Steps
Grant from the user page, inspect the role’s Members view and withdraw the grant.
Expected
Presentation names the grantor and lists the colleague while assigned; withdrawal removes that membership from the live view.
Data
Use the records described in the setup.
Bound to
react-console:e2e/security/users.spec.ts#gives a role, says who granted it, and takes it away again
react-console:e2e/security/roles.spec.ts#is given to a person, who then shows on its Members tab
Source
react-console:e2e/security/users.spec.ts#gives a role, says who granted it, and takes it away again
14 Role assignment: scheduled to livetransitionapiproposed
Proves
BR-CAP-PFM-SEC-010-05
Preconditions
Prepare a run-owned role assignment in scheduled state with the authority and inputs required by the cited transition.
Steps
[ { "do": "Advance the clock to the assignment’s start and read effective permissions.", "expect": "After the stated action, observe the role assignment in live state. This case does not require an additional history event unless the transition explicitly defines one.", "provenance": "proposed", "source": [ "services-platform:modules/security/db/security-assignments.table.ts (valid_from)", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
After the stated action, observe the role assignment in live state. This case does not require an additional history event unless the transition explicitly defines one.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/db/security-assignments.table.ts (valid_from),services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
15 Role assignment: live to endedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-010-05
Preconditions
Prepare a run-owned role assignment in live state with the authority and inputs required by the cited transition.
Steps
[ { "do": "Advance the clock to the assignment’s end and attempt the previously allowed operation.", "expect": "After the stated action, observe the role assignment in ended state. This case does not require an additional history event unless the transition explicitly defines one.", "provenance": "proposed", "source": [ "services-platform:modules/security/db/security-assignments.table.ts (valid_until)", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
After the stated action, observe the role assignment in ended state. This case does not require an additional history event unless the transition explicitly defines one.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/db/security-assignments.table.ts (valid_until),services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
16 Role assignment: live to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-010-07
Preconditions
Prepare a run-owned role assignment in live state with the authority and inputs required by the cited transition.
Steps
[ { "do": "Withdraw the active assignment and inspect its retained row and current access.", "expect": "After the stated action, observe the role assignment in revoked state. This case does not require an additional history event unless the transition explicitly defines one.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/assignments.ts:revokeAssignment", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
After the stated action, observe the role assignment in revoked state. This case does not require an additional history event unless the transition explicitly defines one.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/assignments.ts:revokeAssignment,services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
17 Role assignment: scheduled to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-010-07
Preconditions
Prepare a run-owned role assignment in scheduled state with the authority and inputs required by the cited transition.
Steps
[ { "do": "Withdraw a future assignment before its start and inspect the retained row.", "expect": "After the stated action, observe the role assignment in revoked state. This case does not require an additional history event unless the transition explicitly defines one.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/assignments.ts:revokeAssignment", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
After the stated action, observe the role assignment in revoked state. This case does not require an additional history event unless the transition explicitly defines one.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/assignments.ts:revokeAssignment,services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
18 Role assignment: live to livetransitionapiproposed
Proves
BR-CAP-PFM-SEC-010-09
Preconditions
Prepare a run-owned role assignment in live state with the authority and inputs required by the cited transition.
Steps
[ { "do": "Amend the assignment window within delegated authority and read its identity, version and history.", "expect": "After the stated action, observe the role assignment in live state. This case does not require an additional history event unless the transition explicitly defines one.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/assignments.ts:amendAssignment", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
After the stated action, observe the role assignment in live state. This case does not require an additional history event unless the transition explicitly defines one.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/assignments.ts:amendAssignment,services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
19 Assign roles within a controlled scope with offer and manage an invitationinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-008-05 BR-CAP-PFM-SEC-010-02
Preconditions
An access manager can delegate one role but lacks another role’s powers.
Steps
Invite with the permitted role, then attempt another invitation carrying the unavailable role.
Expected
The first creates pending assignments; the second creates neither invitation nor assignment.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a role that grants more than the caller may do there, and names what was missing,services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#refuses a scope the caller does not manage, and says which scope rather than which role
20 Assign roles within a controlled scope with maintain console membershipsinteractionapiproposed
Proves
BR-CAP-PFM-SEC-009-07 BR-CAP-PFM-SEC-010-07
Preconditions
Only one active qualifying customer administrator remains.
Steps
Try withdrawing the qualifying assignment and suspending its holder; read membership and assignments after each refusal.
Expected
Both operations leave the active administrator and qualifying assignment intact.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/services/membership/lockout.ts:assertNotLockedOut,services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#revokes the grant, keeps the row, and audits what was withdrawn
21 Assign roles within a controlled scope with model customer responsibilities with roles and policiesinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-010-07 BR-CAP-PFM-SEC-012-09
Preconditions
A custom role is assigned to an active member.
Steps
Try archiving the role, withdraw its assignment, and archive again.
Expected
The held role cannot be archived; after withdrawal it can leave the active list while history remains.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/integration/services/membership/manage-assignments.integration.spec.js#revokes the grant, keeps the row, and audits what was withdrawn,services-platform:modules/security/tests/integration/services/definitions/manage-roles.integration.spec.js#refuses to archive a role somebody still holds, names them, and leaves it active
22 Assign roles within a controlled scope with derive member access from appointments and eligibilityinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-010-08 BR-CAP-PFM-SEC-014-04
Preconditions
One member has a manual grant and a linked contact has source-owned access.
Steps
Change the manual role scope, try editing the derived assignment, then synchronize its source.
Expected
Manual scope changes preserve the derived row; direct derived editing is refused and source synchronization alone changes it.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/integration/services/membership/set-role-scope.integration.spec.js#turns the customer grant into one active grant per tenant asked for, revoking the customer grant,services-platform:modules/security/tests/integration/services/persistence/assignments.derived.integration.spec.js#refuses an amendment 409 derived_assignment, naming where to change it

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.