---
id: FAS-PFM-SEC-05
title: Staff Administration and Customer Entry acceptance
feature: FEAT-PFM-SEC-05
product_area: platform
module: security
revision: 2
status: proposed
product_intent: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
capabilities:
  - CAP-PFM-SEC-016
  - CAP-PFM-SEC-017
  - CAP-PFM-SEC-018
scenarios:
  - id: FAS-PFM-SEC-05-01
    title: HQ authority and requested customer entry stay separate
    kind: behaviour
    exercises:
      - CAP-PFM-SEC-016
      - CAP-PFM-SEC-017
      - CAP-PFM-SEC-018
    relies_on:
      - ATS-PFM-SEC-016-01
      - ATS-PFM-SEC-017-02
      - ATS-PFM-SEC-018-01
    preconditions: Prepare active staff-reader and administrator identities.
    steps:
      - do: >-
          Read staff and principal registers, submit a customer-entry request and inspect it before
          the customer decides.
        expect: >-
          HQ reads use the relevant staff keys; the pending request supplies no customer-entry
          authority.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
            administrator of a customer, holding every key at that customer, as 403
          - >-
            services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#refuses a
            request for more days than the maximum, 400
          - >-
            services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
            a staff reader 200 with every principal, this suite’s among them with its kind and
            status
    expected: >-
      HQ reads use the relevant staff keys; the pending request supplies no customer-entry
      authority.
    negative: true
    data_needs: >-
      Disposable customer, workspace and membership fixtures owned by the run; fixed clocks, failure
      controls or provider prerequisites as required by the case.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
        administrator of a customer, holding every key at that customer, as 403
      - >-
        services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#refuses a request
        for more days than the maximum, 400
      - >-
        services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
        a staff reader 200 with every principal, this suite’s among them with its kind and status
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#refuses a request
          for more days than the maximum, 400
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
          a staff reader 200 with every principal, this suite’s among them with its kind and status
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#refuses a request
          for more days than the maximum, 400
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
          a staff reader 200 with every principal, this suite’s among them with its kind and status
    execution_gap: FND-PFM-SEC-078
  - id: FAS-PFM-SEC-05-02
    title: Suspended staff cannot retain usable standing customer entry
    kind: interaction
    exercises:
      - CAP-PFM-SEC-016
      - CAP-PFM-SEC-017
    relies_on:
      - ATS-PFM-SEC-016-05
      - ATS-PFM-SEC-017-08
    preconditions: >-
      Prepare standing customer access for a staff member and a different authorized suspending
      administrator.
    steps:
      - do: >-
          Suspend the member, inspect staff-role and customer assignments and attempt fresh customer
          entry.
        expect: >-
          The suspended member cannot enter through standing access, including with retained browser
          state.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/tests/integration/services/invitations/delete-user.integration.spec.js#refuses
            the delete as the staff guard does, naming its machine code
          - >-
            services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
            each Rhythm Administrator one active customer-level standing grant in every customer but
            Rhythm’s own
    expected: >-
      The suspended member cannot enter through standing access, including with retained browser
      state.
    negative: true
    data_needs: >-
      Disposable customer, workspace and membership fixtures owned by the run; fixed clocks, failure
      controls or provider prerequisites as required by the case.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/integration/services/invitations/delete-user.integration.spec.js#refuses
        the delete as the staff guard does, naming its machine code
      - >-
        services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
        each Rhythm Administrator one active customer-level standing grant in every customer but
        Rhythm’s own
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/integration/services/invitations/delete-user.integration.spec.js#refuses
          the delete as the staff guard does, naming its machine code
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
          each Rhythm Administrator one active customer-level standing grant in every customer but
          Rhythm’s own
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/integration/services/invitations/delete-user.integration.spec.js#refuses
          the delete as the staff guard does, naming its machine code
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
          each Rhythm Administrator one active customer-level standing grant in every customer but
          Rhythm’s own
    execution_gap: FND-PFM-SEC-078
  - id: FAS-PFM-SEC-05-03
    title: Customer consent and withdrawal bound support work
    kind: lifecycle
    exercises:
      - CAP-PFM-SEC-016
      - CAP-PFM-SEC-017
    relies_on:
      - ATS-PFM-SEC-016-01
      - ATS-PFM-SEC-017-04
      - ATS-PFM-SEC-017-06
      - ATS-PFM-SEC-017-13
    preconditions: Prepare a request from identified staff awaiting a customer administrator’s decision.
    steps:
      - do: >-
          Approve within the requested duration, enter the workspace, revoke access and evaluate
          again after cache expiry.
        expect: >-
          The approved grant and assignment agree; withdrawal ends workspace work while retaining
          the known staff identity.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
            administrator of a customer, holding every key at that customer, as 403
          - >-
            services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#gives
            the two days that were asked for, not the thirty the approver named
          - >-
            services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#revokes
            the assignment the grant materialized, so the access is gone at once
          - >-
            services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#grants the
            staff member nothing while the request is waiting
    expected: >-
      The approved grant and assignment agree; withdrawal ends workspace work while retaining the
      known staff identity.
    negative: false
    data_needs: >-
      Disposable customer, workspace and membership fixtures owned by the run; fixed clocks, failure
      controls or provider prerequisites as required by the case.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
        administrator of a customer, holding every key at that customer, as 403
      - >-
        services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#gives
        the two days that were asked for, not the thirty the approver named
      - >-
        services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#revokes
        the assignment the grant materialized, so the access is gone at once
      - >-
        services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#grants the staff
        member nothing while the request is waiting
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#gives
          the two days that were asked for, not the thirty the approver named
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#revokes
          the assignment the grant materialized, so the access is gone at once
        - >-
          services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#grants the staff
          member nothing while the request is waiting
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#gives
          the two days that were asked for, not the thirty the approver named
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/approved-tenant-access.integration.spec.js#revokes
          the assignment the grant materialized, so the access is gone at once
        - >-
          services-platform:modules/security/tests/e2e/approved-access.e2e.spec.js#grants the staff
          member nothing while the request is waiting
    execution_gap: FND-PFM-SEC-078
  - id: FAS-PFM-SEC-05-04
    title: Staff status alone does not permit emergency or principal management
    kind: permission
    exercises:
      - CAP-PFM-SEC-016
      - CAP-PFM-SEC-017
      - CAP-PFM-SEC-018
    relies_on:
      - ATS-PFM-SEC-016-01
      - ATS-PFM-SEC-017-07
      - ATS-PFM-SEC-018-01
    preconditions: Prepare support and administrator identities with independently granted operation keys.
    steps:
      - do: Attempt emergency entry and principal suspension with each identity.
        expect: >-
          Each privileged action succeeds only with its own required key; staff membership alone
          supplies neither permission.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
            administrator of a customer, holding every key at that customer, as 403
          - >-
            services-platform:modules/security/tests/integration/services/staff-access/open-emergency-access.integration.spec.js#refuses
            a reason shorter than twenty characters
          - >-
            services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
            a staff reader 200 with every principal, this suite’s among them with its kind and
            status
    expected: >-
      Each privileged action succeeds only with its own required key; staff membership alone
      supplies neither permission.
    negative: false
    data_needs: >-
      Disposable customer, workspace and membership fixtures owned by the run; fixed clocks, failure
      controls or provider prerequisites as required by the case.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
        administrator of a customer, holding every key at that customer, as 403
      - >-
        services-platform:modules/security/tests/integration/services/staff-access/open-emergency-access.integration.spec.js#refuses
        a reason shorter than twenty characters
      - >-
        services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
        a staff reader 200 with every principal, this suite’s among them with its kind and status
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/open-emergency-access.integration.spec.js#refuses
          a reason shorter than twenty characters
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
          a staff reader 200 with every principal, this suite’s among them with its kind and status
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/hq-staff-and-roles.e2e.spec.js#refuses an
          administrator of a customer, holding every key at that customer, as 403
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/open-emergency-access.integration.spec.js#refuses
          a reason shorter than twenty characters
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#answers
          a staff reader 200 with every principal, this suite’s among them with its kind and status
    execution_gap: FND-PFM-SEC-078
  - id: FAS-PFM-SEC-05-05
    title: Deployment replay preserves deliberate suspension and withdrawal
    kind: regression
    exercises:
      - CAP-PFM-SEC-016
      - CAP-PFM-SEC-017
      - CAP-PFM-SEC-018
    relies_on:
      - ATS-PFM-SEC-016-07
      - ATS-PFM-SEC-017-08
      - ATS-PFM-SEC-018-02
      - ATS-PFM-SEC-018-05
    preconditions: >-
      Prepare a suspended founder, a manually revoked standing grant and a suspended service
      principal.
    steps:
      - do: Reconcile founders and principals twice and repeat the existing principal suspension.
        expect: >-
          Reconciliation preserves the deliberate restrictions, and an unchanged status adds no new
          transition event.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/tests/integration/services/provisioning/ensure-founding-staff.integration.spec.js#answers
            the first run as created
          - >-
            services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
            each Rhythm Administrator one active customer-level standing grant in every customer but
            Rhythm’s own
          - >-
            services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#records
            the suspension: the staff member, Rhythm’s customer, narrowing, from active to suspended
          - >-
            services-platform:modules/security/tests/integration/services/provisioning/ensure-service-principals.integration.spec.js#answers
            both as inserted, and none unchanged
    expected: >-
      Reconciliation preserves the deliberate restrictions, and an unchanged status adds no new
      transition event.
    negative: true
    data_needs: >-
      Disposable customer, workspace and membership fixtures owned by the run; fixed clocks, failure
      controls or provider prerequisites as required by the case.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/integration/services/provisioning/ensure-founding-staff.integration.spec.js#answers
        the first run as created
      - >-
        services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
        each Rhythm Administrator one active customer-level standing grant in every customer but
        Rhythm’s own
      - >-
        services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#records
        the suspension: the staff member, Rhythm’s customer, narrowing, from active to suspended
      - >-
        services-platform:modules/security/tests/integration/services/provisioning/ensure-service-principals.integration.spec.js#answers
        both as inserted, and none unchanged
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/integration/services/provisioning/ensure-founding-staff.integration.spec.js#answers
          the first run as created
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
          each Rhythm Administrator one active customer-level standing grant in every customer but
          Rhythm’s own
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#records
          the suspension: the staff member, Rhythm’s customer, narrowing, from active to suspended
        - >-
          services-platform:modules/security/tests/integration/services/provisioning/ensure-service-principals.integration.spec.js#answers
          both as inserted, and none unchanged
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/integration/services/provisioning/ensure-founding-staff.integration.spec.js#answers
          the first run as created
        - >-
          services-platform:modules/security/tests/integration/services/staff-access/rhythm-administrator-standing-access.integration.spec.js#gives
          each Rhythm Administrator one active customer-level standing grant in every customer but
          Rhythm’s own
        - >-
          services-platform:modules/security/tests/integration/services/service-principals/hq-service-principals-routes.integration.spec.js#records
          the suspension: the staff member, Rhythm’s customer, narrowing, from active to suspended
        - >-
          services-platform:modules/security/tests/integration/services/provisioning/ensure-service-principals.integration.spec.js#answers
          both as inserted, and none unchanged
    execution_gap: FND-PFM-SEC-078
evidence:
  - >-
    specs/platform/security/planning/capabilities/CAP-PFM-SEC-016-run-rhythm-s-own-staff-accounts-and-hq-roles.md
  - >-
    specs/platform/security/planning/capabilities/CAP-PFM-SEC-017-let-rhythm-staff-into-a-customer-s-workspace-only-by-consent.md
  - >-
    specs/platform/security/planning/capabilities/CAP-PFM-SEC-018-stop-and-restart-another-service-s-calls-into-rhythm.md
  - >-
    Capability test scenario references identify the outcomes this suite relies on. The complete
    feature chains remain proposed until a suite executes every step.
examiner: codex
examined_at: '2026-10-23'
final_text: OpenAI
---
# Staff Administration and Customer Entry acceptance: Feature Acceptance Suite

## What the Feature Must Do as a Whole

The suite connects staff administration with customer-approved support entry and service-principal management. It checks which authority each privileged action requires and how membership or grant changes end access.

## Interactions Between Capabilities

A staff account supplies HQ identity while a separate grant permits customer entry. Suspension, revocation and deployment replay must be checked together so administrative reconciliation cannot silently reverse a deliberate access decision. The referenced capability scenarios supply detailed observations. These ordered feature cases remain proposed until a registered suite executes the whole chain and its result is retained.

## Regression Record

| Revision | Change | Scenario | Why |
|---|---|---|---|
| 1 | initial | all | Establish the feature’s cumulative acceptance baseline. |
| 2 | testing examination continuation | all | Verify references, write final feature text and keep execution gaps explicit. |
