---
id: CAP-PFM-CSH-010
title: Enter the workspace named by a link
feature: FEAT-PFM-CSH-03
product_area: platform
module: console-shell
revision: 2
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
intent_sources:
  - >-
    react-console:docs/url-architecture.md#2.2 The context of the URL's tenant (decided by Andrew
    2026-10-14; final acceptance 2026-10-15)
  - >-
    react-console:docs/url-architecture.md#6. Tenant from the URL (decided by Andrew 2026-10-14;
    final acceptance 2026-10-15)
purpose: >-
  A workspace link renders its destination only after that workspace’s access context is
  established.
outcomes:
  - Destination pages use the workspace named by the address.
  - 'Refusals distinguish missing, inaccessible and unavailable workspaces.'
concepts:
  - CON-PFM-CSH-003
actors:
  - ACT-PFM-001
  - ACT-PFM-002
surfaces:
  - console
preconditions: []
postconditions: []
permissions:
  - key: platform.security-self.read
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-CSH-010-01
    proved_by: [ATS-PFM-CSH-010-01, ATS-PFM-CSH-010-06, ATS-PFM-CSH-010-09, TST-PFM-CSH-034]
    statement: >-
      Workspace content waits until the access context matches the address workspace exactly, and an
      answer naming a different workspace fails entry.
    kind: invariant
    enforced_at:
      - console
    must_prove: true
    provenance: documented
    source: 'react-console:docs/url-architecture.md#2.2 The context of the URL''s tenant'
    origin: >-
      react-console:docs/url-architecture.md#2.2 The context of the URL's tenant (decided by Andrew
      2026-10-14; final acceptance 2026-10-15)
  - id: BR-CAP-PFM-CSH-010-02
    proved_by: [ATS-PFM-CSH-010-02, TST-PFM-CSH-009, TST-PFM-CSH-014]
    statement: An unknown workspace identifier produces the workspace not-found presentation.
    kind: validation
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: 'react-console:e2e/mock/url-architecture.mock.spec.ts#an id no tenant has shows not found'
    origin: >-
      react-console:docs/url-architecture.md#6. Tenant from the URL (decided by Andrew 2026-10-14;
      final acceptance 2026-10-15)
  - id: BR-CAP-PFM-CSH-010-03
    proved_by: [ATS-PFM-CSH-010-03, TST-PFM-CSH-003]
    statement: >-
      A non-staff person who cannot reach the named workspace remains on the access-denied
      presentation.
    kind: permission
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: >-
      react-console:components/console/__tests__/tenant-id-gate.test.tsx#leaves anyone else on the
      access-denied page
    origin: >-
      react-console:docs/url-architecture.md#6. Tenant from the URL (decided by Andrew 2026-10-14;
      final acceptance 2026-10-15)
  - id: BR-CAP-PFM-CSH-010-04
    proved_by: [ATS-PFM-CSH-010-03, TST-PFM-CSH-003]
    statement: >-
      A denied destination links back to the current workspace, otherwise the first other reachable
      workspace, and offers no return workspace when none is available.
    kind: calculation
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: >-
      react-console:components/console/__tests__/tenant-id-gate.test.tsx#leads to another tenant
      they can reach when they are in none, never the refused one
    origin: >-
      react-console:docs/url-architecture.md#6. Tenant from the URL (DEF-CRM-0545) (decided by
      Andrew 2026-10-14; final acceptance 2026-10-15)
  - id: BR-CAP-PFM-CSH-010-05
    proved_by: [ATS-PFM-CSH-010-04, TST-PFM-CSH-003]
    statement: >-
      An out-of-service workspace uses the unavailable presentation, offering HQ to staff or another
      reachable workspace to other users.
    kind: validation
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: >-
      react-console:components/console/__tests__/tenant-id-gate.test.tsx#says the workspace is
      unavailable, never no access, with the way back for staff
    origin: none
  - id: BR-CAP-PFM-CSH-010-06
    proved_by: []
    statement: >-
      The gate retains its last refusal for ten seconds across remounts and can request access again
      on a later visit.
    kind: lifecycle
    enforced_at:
      - console
    must_prove: false
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:rememberedRefusal'
    origin: none
  - id: BR-CAP-PFM-CSH-010-07
    proved_by: []
    statement: >-
      Immediately after leaving for HQ, entry to the workspace just left waits six seconds before
      retrying if its address remains active.
    kind: lifecycle
    enforced_at:
      - console
    must_prove: false
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
    origin: none
  - id: BR-CAP-PFM-CSH-010-08
    proved_by: [ATS-PFM-CSH-010-07]
    statement: An entry failure outside the recognized refusal cases displays the failure message.
    kind: validation
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
    origin: none
  - id: BR-CAP-PFM-CSH-010-09
    proved_by: [ATS-PFM-CSH-010-05]
    statement: >-
      A fresh direct load reuses the boot request’s answer for the address workspace rather than
      issuing a second gate request.
    kind: policy
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:pendingUrlAnswer, openTenantId'
    origin: >-
      react-console:docs/url-architecture.md#6. Tenant from the URL (decided by Andrew 2026-10-14;
      final acceptance 2026-10-15)
  - id: BR-CAP-PFM-CSH-010-10
    proved_by: [ATS-PFM-CSH-010-08]
    statement: The gate decodes the workspace identifier and compares its lowercase value.
    kind: validation
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
    origin: none
scenarios:
  - id: SC-CAP-PFM-CSH-010-01
    given: The address names an unknown workspace.
    when: Workspace entry is attempted.
    then: The gate displays not found.
    provenance: test
    source: 'react-console:e2e/mock/url-architecture.mock.spec.ts#an id no tenant has shows not found'
  - id: SC-CAP-PFM-CSH-010-02
    given: A customer user cannot reach the requested workspace but can reach another.
    when: The gate evaluates the refusal.
    then: Access is denied with a return route to the reachable workspace.
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate, deniedReturnTenant'
  - id: SC-CAP-PFM-CSH-010-03
    given: The destination workspace is out of service.
    when: Entry is attempted.
    then: The gate explains unavailability rather than missing authority.
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-CSH-011
  - CAP-PFM-CSH-013
  - CAP-PFM-CSH-009
journeys:
  - JNY-PFM-CSH-003
  - JNY-PFM-CSH-004
open_questions: []
evidence:
  - >-
    react-console at baf6dae: components/console/tenant-id-gate.tsx,
    components/console/__tests__/tenant-id-gate.test.tsx,
    lib/security-context/{tenant-id,left-tenant,boot}.ts, docs/url-architecture.md §2.2, §6, §11,
    e2e/mock/url-architecture.mock.spec.ts, e2e/dev/{url-architecture,initialisation}.dev.spec.ts.
  - >-
    services-platform at ad3f6a6: modules/security/aws/api/access.routes.ts (getMySecurityContext
    with tenant_id and preferred_tenant_id, getMySecurityContextInTenant; MOD-PFM-SEC).
controls: [TC-AVL-001, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-004, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-CSH-03-01, FAS-PFM-CSH-03-02, FAS-PFM-CSH-03-03, FAS-PFM-CSH-03-04]
suites: [TST-PFM-CSH-003, TST-PFM-CSH-009, TST-PFM-CSH-014, TST-PFM-CSH-034]
---
# Enter the workspace named by a link

## Purpose

A workspace link renders its destination only after that workspace’s access context is established.

## How It Works

The person follows a workspace link. The access provider asks for that workspace and the gate evaluates the result. Content becomes available only in the matching context. Recognized refusals provide different explanations and return destinations. Staff access denial returns the person to HQ through the existing staff handling. The product should verify context mismatch, remount timing and unavailable recovery in browser tests.

## Relationships

- Security owns the strict workspace-access answer.
- Console addresses identify the destination workspace.
- Workspace switching uses the same gate for its chosen destination.
