---
id: ATS-PFM-CSH-014
scope: CAP-PFM-CSH-014
product_area: platform
module: console-shell
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  rhythm-v2-docs: 25e253cb434aac6603ee294e3ca197ab6c4bfd0b
scenarios:
  - id: ATS-PFM-CSH-014-01
    title: Known context products enable only their mapped domains
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-01
    preconditions: Context fixtures list selected known products and an unknown product.
    steps: Derive entitlements and inspect application-to-domain coverage.
    expected: >-
      Known listed products enable their declared domains; the unknown product
      adds none and the mapping covers registered domains.
    negative: true
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#enables only the
      domains of the applications the context lists
    category: rule
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#enables only the
        domains of the applications the context lists
      - >-
        react-console:lib/security-context/entitlements.test.ts#switches nothing
        on for an application the console does not know
      - >-
        react-console:lib/security-context/entitlements.test.ts#covers every
        console domain
      - >-
        react-console:lib/security-context/entitlements.test.ts#names an
        existing domain for every application
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#enables only the
        domains of the applications the context lists
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#enables only the
        domains of the applications the context lists
  - id: ATS-PFM-CSH-014-02
    title: Staff wildcard authority cannot invent a product
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-03
    preconditions: The staff fixture grants wildcard actions and lists CRM alone.
    steps: Derive the enabled application domains.
    expected: CRM is enabled while unlisted product domains remain unavailable.
    negative: true
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#gives a staff
      wildcard no domain the applications did not give
    category: permission
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#gives a staff
        wildcard no domain the applications did not give
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#gives a staff
        wildcard no domain the applications did not give
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#gives a staff
        wildcard no domain the applications did not give
  - id: ATS-PFM-CSH-014-03
    title: Backend grants supply their console aliases
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-04
    preconditions: The context holds recognized backend permission keys.
    steps: 'Evaluate the corresponding console checks, including a one-to-many alias.'
    expected: >-
      Every mapped console check receives the authority supplied by its backend
      key.
    negative: false
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-017
      - TST-PFM-CSH-018
    provenance: test
    source: >-
      react-console:lib/authz/__tests__/authz.test.ts#maps aliases onto registry
      keys
    category: rule
    test_sources:
      - >-
        react-console:lib/authz/__tests__/authz.test.ts#maps aliases onto
        registry keys
      - >-
        react-console:lib/authz/__tests__/backend-aliases.test.ts#lets one
        backend key grant several console keys
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/authz.test.ts#maps aliases onto
        registry keys
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/authz.test.ts#maps aliases onto
        registry keys
  - id: ATS-PFM-CSH-014-04
    title: Synthetic keys depend on an enabled keyless domain
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-05
    preconditions: Fixtures enable or omit a keyless domain and deny one of its entries.
    steps: Derive keys for each fixture and compare a domain with backend aliases.
    expected: >-
      Enabled keyless items receive their synthetic keys except explicit
      denials; omitted domains receive none and aliased domains require backend
      grants.
    negative: false
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#grants a keyless
      domain's item keys when its application is enabled
    category: validation
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#grants a keyless
        domain's item keys when its application is enabled
      - >-
        react-console:lib/security-context/entitlements.test.ts#grants nothing
        of a keyless domain whose application is not listed
      - >-
        react-console:lib/security-context/entitlements.test.ts#lets a deny rule
        take one keyless key away
      - >-
        react-console:lib/security-context/entitlements.test.ts#leaves a domain
        with backend aliases needing its backend keys
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#grants a keyless
        domain's item keys when its application is enabled
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#grants a keyless
        domain's item keys when its application is enabled
  - id: ATS-PFM-CSH-014-05
    title: Normalized denial and unknown authority fail closed
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-07
      - BR-CAP-PFM-CSH-014-08
    preconditions: >-
      Fixtures supply exact and prefix grants, an explicit denial and absent
      entitlements.
    steps: Evaluate the matching permission and page decisions.
    expected: >-
      Denial prevails in normalized checks, prefixes cover descendants and
      absent authority does not satisfy a requested permission.
    negative: true
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-017
      - TST-PFM-CSH-023
      - TST-PFM-CSH-018
    provenance: test
    source: >-
      react-console:lib/authz/__tests__/authz.test.ts#grants exact keys and
      prefix wildcards, and denies win
    category: permission
    test_sources:
      - >-
        react-console:lib/authz/__tests__/authz.test.ts#grants exact keys and
        prefix wildcards, and denies win
      - >-
        react-console:lib/console/application-guard.test.ts#refuses a page that
        asks for something when there are no entitlements at all
      - >-
        react-console:lib/authz/__tests__/backend-aliases.test.ts#answers
        nothing for a key it does not cover, rather than guessing
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/authz.test.ts#grants exact keys and
        prefix wildcards, and denies win
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/authz.test.ts#grants exact keys and
        prefix wildcards, and denies win
  - id: ATS-PFM-CSH-014-06
    title: Removing a context product removes its domain
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-01
    preconditions: Two independent context fixtures differ only by CRM’s presence.
    steps: Derive each fixture’s enabled domains.
    expected: Only the fixture that lists CRM enables its domain.
    negative: true
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#takes an
      application away with the access key that named it
    category: transition
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#takes an
        application away with the access key that named it
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#takes an
        application away with the access key that named it
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#takes an
        application away with the access key that named it
  - id: ATS-PFM-CSH-014-07
    title: Scoped authority opens the surface but limits its records
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-10
    preconditions: Fixtures supply one custom-type scope and a separate workspace-wide grant.
    steps: 'Evaluate the surface, named type and another type under both fixtures.'
    expected: >-
      The scoped fixture permits its surface and named type only; the
      workspace-wide grant removes that type restriction.
    negative: true
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#holds the key on
      that object and nowhere else
    category: boundary
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#holds the key on
        that object and nowhere else
      - >-
        react-console:lib/security-context/entitlements.test.ts#keeps a key held
        tenant-wide as it is, whatever a scoped grant says
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#holds the key on
        that object and nowhere else
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#holds the key on
        that object and nowhere else
  - id: ATS-PFM-CSH-014-08
    title: Backend allowed authority survives a stale contrary rule
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-11
    preconditions: The context allows contact read and also contains a stale contrary denial.
    steps: Derive the allowed and denied console-key collections.
    expected: Contact view remains allowed and is excluded from the derived denial set.
    negative: false
    data_needs: Independent fixture inputs for the variants listed in this case.
    bound_to:
      - TST-PFM-CSH-018
    provenance: test
    source: >-
      react-console:lib/authz/__tests__/backend-aliases.test.ts#lets allowed win
      over a stale deny rule, because allowed is the authority
    category: invariant
    test_sources:
      - >-
        react-console:lib/authz/__tests__/backend-aliases.test.ts#lets allowed
        win over a stale deny rule, because allowed is the authority
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/backend-aliases.test.ts#lets allowed
        win over a stale deny rule, because allowed is the authority
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/authz/__tests__/backend-aliases.test.ts#lets allowed
        win over a stale deny rule, because allowed is the authority
  - id: ATS-PFM-CSH-014-09
    title: Product aliases and shared domains follow the context map
    category: rule
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-02
    preconditions: >-
      Contexts list Platform, Collect, Commerce, Events and each Publications
      provider separately.
    steps: Derive enabled domains from each context.
    expected: >-
      The output matches the declared product-to-domain mapping, including each
      provider of Publications.
    negative: false
    data_needs: Independent in-memory fixtures for each listed input.
    bound_to:
      - TST-PFM-CSH-033
    provenance: test
    source: >-
      react-console:lib/security-context/entitlements.test.ts#maps the
      applications whose Rhythm name is not the console's
    test_sources:
      - >-
        react-console:lib/security-context/entitlements.test.ts#maps the
        applications whose Rhythm name is not the console's
      - >-
        react-console:lib/security-context/entitlements.test.ts#lets any of
        several applications switch a shared domain on
      - >-
        react-console:lib/security-context/entitlements.test.ts#gives the
        platform application the console's own administration domains
    action_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#maps the
        applications whose Rhythm name is not the console's
    assertion_evidence:
      provenance: test
      source: >-
        react-console:lib/security-context/entitlements.test.ts#maps the
        applications whose Rhythm name is not the console's
  - id: ATS-PFM-CSH-014-10
    title: Derived frame access distinguishes staff and customer context
    category: permission
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-06
    preconditions: >-
      Context fixtures cover an empty application list, one application, staff
      identity and an explicit domain-access deny.
    steps: Derive normalized console keys for each fixture.
    expected: >-
      Frame access, staff access and domain-access results match the
      corresponding rule without a wildcard creating an unlisted product.
    negative: false
    data_needs: Independent in-memory fixtures for each listed input.
    bound_to: []
    provenance: proposed
    source: >-
      rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    test_sources: []
    action_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    assertion_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
  - id: ATS-PFM-CSH-014-11
    title: Feature values remain separate from domain availability
    category: invariant
    level: unit
    proves:
      - BR-CAP-PFM-CSH-014-09
      - INV-DOM-PFM-CSH-004-08
    preconditions: The context supplies one feature and omits another.
    steps: Derive entitlements and evaluate both feature keys.
    expected: >-
      Only the supplied feature is enabled; its presence supplies no additional
      product domain.
    negative: false
    data_needs: Independent in-memory fixtures for each listed input.
    bound_to: []
    provenance: proposed
    source: >-
      rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    test_sources: []
    action_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    assertion_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
  - id: ATS-PFM-CSH-014-12
    title: Application and task authority produce separate page decisions
    category: interaction
    level: browser
    proves:
      - BR-CAP-PFM-CSH-014-01
      - BR-CAP-PFM-CSH-015-01
      - BR-CAP-PFM-CSH-015-03
    preconditions: CRM availability and contact-view permission vary independently.
    steps: >-
      Derive the context entitlements and evaluate the contact page in each
      combination.
    expected: >-
      Only the enabled and permitted combination opens; application absence
      precedes task denial.
    negative: false
    data_needs: >-
      A fresh browser context, isolated account fixtures and controlled
      responses for the listed transitions.
    bound_to: []
    provenance: proposed
    source: >-
      rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    test_sources: []
    action_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
    assertion_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/console-shell/planning/capabilities/CAP-PFM-CSH-014-offer-exactly-the-applications-the-workspace-and-the-person.md
evidence:
  - >-
    react-console at baf6dae:
    lib/security-context/{entitlements,entitlements.test}.ts,
    lib/authz/{evaluate,entitlements,backend-aliases}.ts,
    lib/authz/__tests__/{authz,backend-aliases}.test.ts,
    lib/console/application-guard.test.ts.
  - >-
    services-platform at ad3f6a6: modules/security/aws/api/access.routes.ts
    (getMySecurityContext, getMySecurityContextInTenant, getMyApplications),
    modules/security/services/access/security-context.ts (applications_of),
    docs/security/application-access.md, docs/licensing.md §2 and §9,
    docs/proposals/application-access-and-entitlements.md §6.4, §7.1, §10.1.
  - >-
    rhythm-v2-docs at 25e253cb434aac6603ee294e3ca197ab6c4bfd0b: capability,
    related capabilities, domain objects, client lifecycles, workflows and prior
    OpenAI examinations; continuation coverage limitations are recorded in
    FND-PFM-CSH-064.
coverage:
  rule: covered
  transition: covered
  validation: covered
  permission: 'gap: FND-PFM-CSH-064'
  edge: 'gap: FND-PFM-CSH-064'
  failure: 'gap: FND-PFM-CSH-064'
  boundary: covered
  concurrency: 'gap: FND-PFM-CSH-064'
  invariant: 'gap: FND-PFM-CSH-064'
  interaction: 'gap: FND-PFM-CSH-064'
coverage_notes:
  rule:
    provenance: proposed
    source: >-
      ATS-PFM-CSH-014-01; ATS-PFM-CSH-014-02; ATS-PFM-CSH-014-03;
      ATS-PFM-CSH-014-04; ATS-PFM-CSH-014-05; ATS-PFM-CSH-014-06;
      ATS-PFM-CSH-014-07; ATS-PFM-CSH-014-08; ATS-PFM-CSH-014-09;
      ATS-PFM-CSH-014-10; ATS-PFM-CSH-014-12
    reason: >-
      Every mandatory rule has a proving scenario, including shared interaction
      cases; bindings identify execution separately.
  transition:
    provenance: proposed
    source: ATS-PFM-CSH-014-06
    reason: >-
      The listed scenarios specify this category; their bindings separately
      identify existing executable evidence.
  validation:
    provenance: proposed
    source: ATS-PFM-CSH-014-04
    reason: >-
      The listed scenarios specify this category; their bindings separately
      identify existing executable evidence.
  permission:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: >-
      The named permission keys still need a complete allowed, denied and scope
      matrix across their enforcement boundaries.
  edge:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: >-
      No dedicated scenario establishes this category; applicability and the
      required fixtures need review.
  failure:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: >-
      No dedicated scenario establishes this category; applicability and the
      required fixtures need review.
  boundary:
    provenance: proposed
    source: ATS-PFM-CSH-014-07
    reason: >-
      The listed scenarios specify this category; their bindings separately
      identify existing executable evidence.
  concurrency:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: >-
      No complete scenario matrix covers repeated events, overlapping reads or
      superseded answers for this capability.
  invariant:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: Associated object invariants remain without explicit proving scenarios.
  interaction:
    provenance: unknown
    source: FND-PFM-CSH-064
    reason: >-
      Related-capability combinations remain unspecified beyond the interactions
      listed.
design_obligations: []
interactions:
  - capability: CAP-PFM-CSH-006
    provenance: unknown
    source: FND-PFM-CSH-064
  - capability: CAP-PFM-CSH-015
    provenance: proposed
    source: ATS-PFM-CSH-014-12
  - capability: CAP-PFM-CSH-016
    provenance: unknown
    source: FND-PFM-CSH-064
workflow_obligations:
  - artifact: WF-PFM-CSH-005
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/platform/console-shell/design/workflows/WF-PFM-CSH-005-refresh-the-application-list.md
    disposition: 'gap: FND-PFM-CSH-064'
    note: >-
      Review every hop, branch, failure and race with the cited capability
      scenarios; unexecuted combinations remain in the coverage finding.
  - artifact: WF-PFM-CSH-007
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/platform/console-shell/design/workflows/WF-PFM-CSH-007-assemble-the-navigation-menu.md
    disposition: 'gap: FND-PFM-CSH-064'
    note: >-
      Review every hop, branch, failure and race with the cited capability
      scenarios; unexecuted combinations remain in the coverage finding.
---

# Apply the workspace and person’s application access: Capability Test Specification

## Coverage

The coverage map describes specified proof, not a passing run. Each mandatory rule below has a scenario or an explicit finding; a proposed scenario remains an execution obligation even when its expected outcome follows the pinned implementation.

| Mandatory Rule | Scenarios or Finding |
|---|---|
| `BR-CAP-PFM-CSH-014-01` | `ATS-PFM-CSH-014-01`, `ATS-PFM-CSH-014-06`, `ATS-PFM-CSH-014-12` |
| `BR-CAP-PFM-CSH-014-02` | `ATS-PFM-CSH-014-09` |
| `BR-CAP-PFM-CSH-014-03` | `ATS-PFM-CSH-014-02` |
| `BR-CAP-PFM-CSH-014-04` | `ATS-PFM-CSH-014-03` |
| `BR-CAP-PFM-CSH-014-05` | `ATS-PFM-CSH-014-04` |
| `BR-CAP-PFM-CSH-014-06` | `ATS-PFM-CSH-014-10` |
| `BR-CAP-PFM-CSH-014-07` | `ATS-PFM-CSH-014-05` |
| `BR-CAP-PFM-CSH-014-08` | `ATS-PFM-CSH-014-05` |
| `BR-CAP-PFM-CSH-014-10` | `ATS-PFM-CSH-014-07` |
| `BR-CAP-PFM-CSH-014-11` | `ATS-PFM-CSH-014-08` |

Context derivation needs all product aliases, shared domains, synthetic keys, explicit denies, scoped grants and feature separation. Permission derivation tests do not establish that each service operation enforces its access key.

## Interactions With Related Capabilities

Only the enabled and permitted combination opens; application absence precedes task denial.

The interaction rows cite the contracts they exercise. Related combinations without a complete case remain in the coverage finding, together with cross-capability workflows and permission boundaries. A helper assertion is bound only for its stated outcome; the full browser handoff remains proposed until a suite checks it.


Pinned source and exact test anchors are recorded in frontmatter. Test bindings record static assertion review and use the executable-suite register; no product test result is inferred from that review. The prior planning and design examinations supply context, while this continuation records the remaining proof obligations explicitly.
