Skip to content

This is an internal working record, not an everyday instruction. It was written while the system was being rebuilt, for whoever maintains it. If you are here to do today's work, use the everyday documents instead: Procedures · Processes · Runbooks · The working day, step by step

Platform Authorization And Access — Policy And Sequence Catalog

  • Status: SOURCE-RECONCILED PLATFORM POLICY/DIAGRAM INPUT / NO RUNTIME CHANGE
  • Current source baseline: qa/master@3c084671c034f8f5136b02dce990ecff6c66d107
  • Source authority: PLATFORM_AUTHORIZATION_ACCESS_SOURCE_AUTHORITY.md
  • Rebuild packet: PLATFORM_AUTHORIZATION_ACCESS_REBUILD_PACKET.md
  • Phase implementation: USER HOLD

1. Core Boundary

Menu
-> helps users discover work

Page guard
-> controls one page entry

API route guard
-> controls one transport entry

Action policy
-> controls one semantic command/query

Record predicate
-> controls one tenant/relationship record

State policy
-> controls whether the command is valid now

These layers cooperate but do not replace one another.


2. Current Page Request Sequence

sequenceDiagram
    actor User
    participant Shell as index.php
    participant Role as Menu/Page Role Helper
    participant Module as Module Guard
    participant Page as PHP Page
    participant API

    User->>Shell: /?page=route
    Shell->>Shell: normalize route + file exists
    alt physical super-admin
        Shell->>Role: super-admin/impersonation page decision
    else tenant user
        Shell->>Role: getPageRoleAccessDecision
    end
    Role-->>Shell: known/allowed
    Shell->>Module: moduleGuardPageDecision
    Module-->>Shell: allowed/known/reason
    alt denied or unavailable
        Shell-->>User: Access Denied / Feature Not Available
    else allowed
        Shell->>Page: include page
        Page->>API: initial queries/actions
        Note over API: API performs its own guards
    end

Page entry does not pre-authorize the page's APIs.


3. Current Menu/Page Fail-Open Paths

flowchart TD
    Req[Page/Menu decision] --> DB{Menu/Module source available?}
    DB -->|yes| Found{Matching explicit row?}
    Found -->|yes| Role{Role/module/config allow?}
    Role -->|yes| Allow[Allow]
    Role -->|no| Deny[Deny]
    Found -->|no page menu| Admin{Role 1 compatibility?}
    Admin -->|yes| CompatAdmin[Allow / known=false]
    Admin -->|no| Deny
    DB -->|menu DB error| CompatOpen[Allow / known=false]
    DB -->|missing tenant module| ModuleCompat[Module default allow]
    DB -->|module DB error| ModuleCompat

This diagram records current compatibility. It is not target policy.


4. Current API v2 Sequence

sequenceDiagram
    actor Client
    participant Router as API v2 Router
    participant Auth
    participant Tenant as Optional Strict Principal
    participant Module
    participant Menu
    participant Role
    participant Handler
    participant Repo

    Client->>Router: method + route
    Router->>Auth: authenticated?
    opt strictTenantPrincipal
        Router->>Tenant: build strict actor/subject/tenant context
    end
    Router->>Module: moduleKey
    Router->>Menu: requiredMenuRoutes
    Router->>Role: requiredRoleIds
    Router->>Handler: request context/body
    Handler->>Repo: tenant/record/state-specific query or mutation
    Repo-->>Handler: result
    Handler-->>Client: response

The router does not prove record ownership/state by itself.


5. Current Legacy TYPE/ACTION Sequence

sequenceDiagram
    actor Client
    participant Endpoint as Legacy post/query endpoint
    participant Auth
    participant Module
    participant Menu
    participant Handler as TYPE/ACTION Handler
    participant DB

    Client->>Endpoint: TYPE + ACTION + DATA
    Endpoint->>Auth: session login check
    Endpoint->>Module: TYPE/ACTION module mapping
    opt selected endpoint/caller
        Endpoint->>Menu: owning menu route
    end
    Endpoint->>Handler: effective scalar user/client/advancedOperations
    Handler->>DB: handler-owned role/tenant/state logic
    DB-->>Handler: result
    Handler-->>Client: legacy response envelope

API v2 and legacy endpoint evidence must be tested separately until caller-zero.


6. UI Visibility Versus Backend Authorization

sequenceDiagram
    actor User
    participant ReactOrPHP as UI
    participant Access as Visibility Query
    participant API as Backend Command
    participant Policy

    ReactOrPHP->>Access: GetVisibleActions
    Access-->>ReactOrPHP: show/hide/disabled hints
    User->>API: direct or UI command request
    API->>Policy: AuthorizeCommand again
    alt denied
        API-->>User: stable denial
    else allowed
        API-->>User: command result
    end

Required rule:

UI hidden is not a security boundary.

7. Record Authorization

sequenceDiagram
    participant Adapter as Page/API Adapter
    participant Access as Access Policy
    participant Repo as Owning Repository
    participant App as Application Command

    Adapter->>Access: actor/subject/tenant + action + record ref
    Access->>Repo: minimal tenant/relation projection
    alt missing/foreign/wrong relation
        Repo-->>Access: denied/not-found disposition
        Access-->>Adapter: stable safe denial
    else record belongs to context
        Repo-->>Access: authorized record projection + state/version
        Access->>App: permission context
        App->>App: validate domain state transition
        App-->>Adapter: result or record-state denial
    end

Authorization does not duplicate the application's transition rules.


8. Physical Super-Admin And Impersonation

flowchart TD
    Actor[Physical Super Admin?] -->|no| Normal[Normal role/action policy]
    Actor -->|yes| Mode{Access mode}
    Mode -->|Admin diagnostic override| Allowlist[Require allowlisted resource + authorization ref]
    Mode -->|User impersonation| Subject[Evaluate target subject role/action + actor restrictions]
    Mode -->|Tenant-only impersonation| Support[Evaluate explicit support/diagnostic capabilities]
    Mode -->|No tenant target| Console[Platform admin surfaces only]

Target rule:

Original super-admin status remains audit lineage.
It is not an automatic permit for every impersonated business action.

9. Target Access Decision Sequence

sequenceDiagram
    actor User
    participant UI as React UI
    participant Next as Next.js Adapter
    participant Identity
    participant Platform as Module/Capability/Config
    participant Access
    participant Repo
    participant App
    participant Audit

    User->>UI: open/act
    UI->>Next: request
    Next->>Identity: actor/subject/tenant
    Identity-->>Next: strict context
    Next->>Platform: resolve availability/prerequisites
    Platform-->>Next: module/capability/config/credential results
    Next->>Access: evaluate action + record reference
    Access->>Repo: tenant/relation projection
    Repo-->>Access: minimal record/state/version
    Access-->>Next: ALLOW/DENY/UNAVAILABLE/UNKNOWN
    alt ALLOW
        Next->>App: execute owning command/query
        App->>Audit: transition/result evidence
        App-->>UI: exact result/readback
    else not allowed
        Next->>Audit: safe decision evidence
        Next-->>UI: stable safe reason/recovery
    end

10. Target Access Decision State

stateDiagram-v2
    [*] --> Unknown
    Unknown --> Allow: every required check PASS
    Unknown --> Deny: actor/action/record not permitted
    Unknown --> Unavailable: module/capability/config/credential unavailable
    Allow --> Deny: policy/role/record changes before command
    Allow --> Unavailable: prerequisite changes before command
    Allow --> Unknown: policy/source cannot be reread

    note right of Unknown
      Consequential writes do not execute.
      Existing compatibility migrates by cohort.
    end note

11. Selected Strict-Rollout Sequence

sequenceDiagram
    participant Current as Current Decision
    participant Target as Target Read Shadow
    participant Matrix as Role/API/Record Matrix
    participant Release

    Current->>Target: same request inputs
    Target-->>Matrix: shadow decision + reasons
    Current-->>Matrix: current observed decision
    Matrix->>Matrix: compare allow/deny/unavailable and negative cases
    alt accepted parity
        Matrix->>Release: select one route/action cohort
        Release->>Target: target authoritative
    else mismatch
        Matrix->>Current: keep current authority
    end

No global switch.


12. Rollback Sequence

sequenceDiagram
    participant Operator
    participant Router
    participant Current as Previous Decision Owner
    participant Target as New Decision Owner
    participant Audit

    Operator->>Router: rollback selected cohort
    Router->>Target: stop authoritative decisions
    Router->>Current: restore previous accepted decision
    Router->>Audit: record rollback version/reason
    Operator->>Router: run allow/deny/foreign/state smoke
    Router-->>Operator: exact parity readback

Rollback does not reopen unrelated access.


13. Policy Decisions

ID Decision Status
ACC-POL-010 unknown consequential write TARGET DENY / CURRENT MIGRATION REQUIRED
ACC-POL-020 unknown read CALLER-SPECIFIC OPEN
ACC-POL-030 missing tenant-module row PARITY SEED BEFORE STRICT
ACC-POL-040 module source error OPEN
ACC-POL-050 unmapped page INVENTORY REQUIRED
ACC-POL-060 unregistered role-1 page access OPEN
ACC-POL-070 super-admin bypass categories OPEN
ACC-POL-080 impersonation action policy REQUIRED
ACC-POL-090 tenant-only support mode actions OPEN / DIAGNOSTIC PREFERRED
ACC-POL-100 record 403/404 disclosure OPEN
ACC-POL-110 menu prerequisite in target COMPATIBILITY INPUT ONLY
ACC-POL-120 numeric roles to semantic capabilities REQUIRED FOR TARGET
ACC-POL-130 virtual menu policies OPEN OWNER MIGRATION
ACC-POL-140 UI visible actions SAME INPUTS / BACKEND RECHECK
ACC-POL-150 print/direct page aliases OPEN
ACC-POL-160 legacy TYPE/ACTION retirement REQUIRED BY CALLER-ZERO
ACC-POL-170 redacted access diagnostics RECOMMENDED
ACC-POL-180 Client 1 broad guard rollout PROHIBITED WITHOUT FULL EVIDENCE

14. Stable Decision Reasons

Suggested target reason families:

authentication_required
session_invalid
tenant_context_required
tenant_forbidden
module_disabled
module_unknown
capability_disabled
capability_unavailable
config_unavailable
credential_unavailable
menu_required
page_forbidden
api_forbidden
role_denied
action_denied
record_not_found_or_denied
record_relation_denied
record_state_denied
override_forbidden
impersonation_restricted
policy_stale
policy_source_error
unknown

Current reasons are mapped, not silently replaced, during read shadow.


15. Support Decision Tree

flowchart TD
    Start[User cannot see/use action] --> Auth{Authenticated?}
    Auth -->|no| Login[Resolve session/login]
    Auth -->|yes| Tenant{Correct tenant/subject?}
    Tenant -->|no| Context[End/fix impersonation or target]
    Tenant -->|yes| Module{Module/capability/config available?}
    Module -->|no| Owner[Escalate to platform/config owner]
    Module -->|yes| Page{Menu/page/API allowed?}
    Page -->|no| Role[Review role/action policy]
    Page -->|yes| Record{Record belongs and relation valid?}
    Record -->|no| Deny[Safe denied/not-found]
    Record -->|yes| State{Record state valid?}
    State -->|no| Process[Escalate to process owner]
    State -->|yes| Unknown[Collect request ID and decision trace]

16. Update Triggers

Update this catalog when any accepted change affects:

  • authentication/session/tenant inputs;
  • menu/role/page helpers;
  • module/config availability;
  • API route metadata;
  • legacy endpoint guard;
  • semantic action capability;
  • record tenant/relation predicate;
  • state-transition owner;
  • super-admin/impersonation behavior;
  • direct page/print aliases;
  • UI action visibility;
  • stable access errors/reasons;
  • read-shadow/cutover/rollback;
  • Client 1/Client 2 role matrix.

Diagrams explain contracts; they do not activate access-policy changes.

---

Source: docs/processes/PLATFORM_AUTHORIZATION_ACCESS_POLICY_AND_SEQUENCE.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.