Platform Authorization And Access — Capability Rebuild Packet¶
- Packet status:
DETAILED SOURCE-RECONCILED PLATFORM INPUT / NO IMPLEMENTATION ACTIVATION - Source authority:
PLATFORM_AUTHORIZATION_ACCESS_SOURCE_AUTHORITY.md - Identity input:
PLATFORM_IDENTITY_SESSION_IMPERSONATION_REBUILD_PACKET.md - Tenant/config input:
PLATFORM_TENANT_PROFILE_CAPABILITY_CONFIGURATION_REBUILD_PACKET.md - Current source baseline:
qa/master@3c084671c034f8f5136b02dce990ecff6c66d107 - Target stack: React visibility + Next.js route adapters + framework-independent TypeScript policy/application contracts
- Phase implementation:
USER HOLD - Effects: documentation only
1. Required Platform Outcome¶
For every protected query or command, the system returns one explicit, explainable decision.
Authenticated Actor/Subject
+ Strict Tenant Context
+ Product/Module Availability
+ Named Capability
+ Page/API/Action Policy
+ Record Ownership/Relation
+ Record-State Eligibility
+ Config/Credential Prerequisite
= Access Decision
1.1 Decision values¶
ALLOW
DENY
UNAVAILABLE
UNKNOWN
ALLOW: all required checks are satisfied.DENY: actor/subject is not permitted.UNAVAILABLE: owning product/module/capability/config/provider is not available.UNKNOWN: authority cannot determine a safe result.
Consequential writes treat UNKNOWN as not authorized. Existing live compatibility is migrated caller-by-caller rather than changed globally by this packet.
1.2 Administrator/support result¶
An authorized support user can inspect a redacted decision trace:
- physical actor and effective subject type;
- tenant provenance;
- page/API/action key;
- module/capability/config availability;
- role/action decision;
- record predicate category;
- record-state predicate category;
- result and stable reason;
- current source/release version;
- compatibility fallback used;
- owner for correction.
The trace never returns secret values or unauthorized record content.
1.3 Non-goals¶
Do not create:
- one monolithic
isAllowed()business engine; - page/menu visibility as final authorization;
- generalized workflow state inside access policy;
- a new permission table without accepted data model;
- a customer-specific role fork;
- universal fail-closed rollout under this documentation wave;
- frontend-only access control;
- automatic super-admin bypass of every business command;
- a second tenant/module/capability authority.
2. Access Decision Contract¶
interface AccessDecision {
decision: 'ALLOW' | 'DENY' | 'UNAVAILABLE' | 'UNKNOWN'
reasonCode: string
requestId: string
policyVersion: string
sourceRevision?: string
actor: { type: string; id: string }
subject?: { type: 'USER'; id: string } | null
tenant: {
localTenantId: number
globalTenantId?: string
provenance: string
}
resource: {
pageKey?: string
apiRouteKey?: string
actionKey: string
recordType?: string
recordId?: string
}
checks: {
authentication: CheckResult
tenant: CheckResult
module?: CheckResult
capability?: CheckResult
menuPage?: CheckResult
roleAction?: CheckResult
record?: CheckResult
recordState?: CheckResult
config?: CheckResult
credential?: CheckResult
}
compatibilityFallbacks: string[]
safeUserMessage: string
correctionOwner?: string
}
interface CheckResult {
state: 'PASS' | 'FAIL' | 'NOT_APPLICABLE' | 'UNKNOWN'
reasonCode: string
source?: string
}
The client receives a safe subset. Protected support tooling may receive the redacted full trace.
3. Target Evaluation Order¶
1. Authenticate physical actor
2. Resolve effective subject and strict tenant
3. Resolve owning product/module/capability
4. Resolve page/API adapter availability
5. Resolve semantic action permission
6. Load record through tenant-scoped repository predicate
7. Validate parent/child relation
8. Validate record-state eligibility in owning application command
9. Validate required config/credential
10. Return decision and execute query/command only on ALLOW
3.1 Why record state stays with the application owner¶
Authorization may ask whether the state check passed, but the owning command defines the rule.
Examples:
May user invoke Reverse Allocation?
= access policy
Is this Allocation reversible after downstream Scale/Delivery?
= Allocation application/domain policy
Do not duplicate state-transition rules in a generic access registry.
4. Semantic Queries¶
4.1 EvaluatePageAccess¶
Input:
- actor/subject/tenant context;
- page key and query variant;
- requested mode.
Returns module/capability/menu/role availability and safe route result.
4.2 EvaluateApiAccess¶
Input:
- request method/route key;
- actor/subject/tenant;
- owning module/capability/action.
Does not load or reveal protected record content.
4.3 EvaluateActionAccess¶
Evaluates semantic action permission independent of UI placement.
mk.allocation.apply
mk.scale.reverse
ctc.final-review.confirm
platform.impersonation.start
These names are semantic inputs; registry implementation remains a later decision.
4.4 EvaluateRecordAccess¶
Loads a minimal tenant/ownership/relation projection through the owning repository.
Returns either:
- allowed record reference;
- denied/not-found according to disclosure policy;
- relation/state owner for next check.
4.5 GetVisibleActions¶
Returns UI action hints derived from the same accepted policy inputs. It never replaces backend checks.
4.6 GetAccessDecisionTrace¶
Read-only administrator/support query. Requires a privileged diagnostic capability and returns redacted reasons, not protected record data.
4.7 GetAccessMatrixForTenantRole¶
Produces a review matrix for one tenant/profile/role and selected page/API/action set. Used for P2-style acceptance, not request-time authorization.
5. Semantic Commands¶
5.1 AuthorizeCommand¶
Application adapter invokes this with:
- strict actor/subject/tenant context;
- action key;
- record reference if any;
- expected record state/version;
- request/correlation ID.
ALLOW is required before the owning command executes.
5.2 GrantTemporaryAdminDiagnosticAccess¶
Optional future command for a narrow diagnostic page/action, not general business mutation.
Required:
- physical super-admin;
- target tenant;
- exact diagnostic resource;
- reason/authorization reference;
- short expiry;
- audit;
- no secret exposure.
5.3 RevokeTemporaryAdminDiagnosticAccess¶
Ends the diagnostic grant and records the result.
5.4 PublishRoleActionPolicy¶
Target control-plane command only if a versioned role/action policy model is accepted. Current T_MENU/role state must not be silently rewritten by documentation.
6. Stable Error Contract¶
ACCESS_UNAUTHENTICATED
ACCESS_SESSION_INVALID
ACCESS_TENANT_CONTEXT_REQUIRED
ACCESS_TENANT_FORBIDDEN
ACCESS_MODULE_DISABLED
ACCESS_MODULE_UNKNOWN
ACCESS_CAPABILITY_DISABLED
ACCESS_CAPABILITY_UNAVAILABLE
ACCESS_CONFIG_UNAVAILABLE
ACCESS_CREDENTIAL_UNAVAILABLE
ACCESS_MENU_REQUIRED
ACCESS_PAGE_FORBIDDEN
ACCESS_API_FORBIDDEN
ACCESS_ROLE_DENIED
ACCESS_ACTION_DENIED
ACCESS_RECORD_NOT_FOUND_OR_DENIED
ACCESS_RECORD_RELATION_DENIED
ACCESS_RECORD_STATE_DENIED
ACCESS_OVERRIDE_FORBIDDEN
ACCESS_IMPERSONATION_RESTRICTED
ACCESS_POLICY_STALE
ACCESS_POLICY_SOURCE_ERROR
ACCESS_UNKNOWN
ACCESS_UNEXPECTED_ERROR
Disclosure policy decides when a missing/foreign record uses one combined not-found/denied response.
7. Role And Capability Model¶
7.1 Current compatibility¶
Current roles are numeric IDs and can be stored as comma-separated values.
Representative compatibility labels:
1 Administrator
2 Office Manager
3 Dispatch Manager
4 Forklift Operator
5 Truck Operator
6 Yard Truck Driver
Current special policies and onboarding seeds use these IDs directly.
7.2 Target semantic capability¶
Target action permission uses stable semantic keys, for example:
platform.users.manage
platform.impersonation.start
ctc.inbound.assign-loader
ctc.loader.complete
ctc.final-review.confirm
mk.commercial.update
mk.booking.update
mk.allocation.apply
mk.scale.reverse
A role is a named bundle of capabilities for one profile/tenant. The bundle does not become record ownership or state eligibility.
7.3 Migration rule¶
numeric role decision
-> read-shadow semantic capability decision
-> compare expected allow/deny
-> selected route/action cutover
-> rollback
-> numeric-role caller-zero for that action
Do not rename numeric roles and call the migration complete.
8. Record Authorization Contract¶
Every consequential record query/command defines:
record type
primary ID / UUID
owning tenant field
parent/child tenant relationship
soft-delete predicate
profile applicability
actor/subject ownership if applicable
required related record
current state/version
safe denial response
8.1 Required repository pattern¶
FindAuthorizedRecordForAction(
tenant,
recordId,
action,
expectedVersion
)
The repository returns only the minimal projection needed for authorization/application validation.
8.2 Prohibited patterns¶
- load by ID without tenant and check later in UI;
- accept
CLIENT_IDfrom body as authority; - infer record access from parent page visibility;
- return foreign record metadata in a denial;
- treat super-admin actor as automatic owner while impersonating;
- duplicate record-state logic in menu/page policy.
9. Page/API/UI Parity Matrix¶
For every selected action:
| Dimension | Required evidence |
|---|---|
| Menu | expected visibility for each role/profile |
| Page | direct URL allow/deny |
| Initial query | page can/cannot load data |
| Action UI | button/control visible or hidden |
| API | direct request allow/deny independent of UI |
| Record | own tenant, foreign tenant, missing and wrong relation |
| State | valid and invalid current state |
| Impersonation | direct actor, user subject and tenant-only support mode |
| Module/config | enabled, disabled, missing and source-error compatibility |
| Result | stable error and no data leak |
P2-007 or its future accepted successor owns live role acceptance. This packet supplies the matrix structure only.
10. Policy Decision Matrix¶
| ID | Decision | Current evidence | Recommended target | Status |
|---|---|---|---|---|
ACC-POL-010 |
Unknown write decision | current fail-open exists in some layers | deny selected consequential writes | REQUIRED FOR TARGET |
ACC-POL-020 |
Unknown read decision | compatibility varies | caller-specific explicit policy | OPEN |
ACC-POL-030 |
Missing module assignment | current allow | seed parity before strict cutover | RECOMMENDED |
ACC-POL-040 |
Module source error | current allow in core helper | expose unavailable/compatibility reason; migrate by caller | OPEN |
ACC-POL-050 |
Unmapped page | current allow/unknown | inventory and explicit ownership before strict | REQUIRED BEFORE CUTOVER |
ACC-POL-060 |
Unregistered page admin entry | role 1 compatibility | explicit diagnostic/owner route or retire | OPEN |
ACC-POL-070 |
Super-admin bypass | broad in some layers | action-specific privileged capability | OPEN |
ACC-POL-080 |
Impersonation permission | actor and subject semantics mixed in callers | explicit actor/subject policy | REQUIRED |
ACC-POL-090 |
Tenant-only impersonation | current support mode | diagnostics/support only unless action explicitly allowed | RECOMMENDED |
ACC-POL-100 |
Record denial response | handler-specific | stable 403/404 disclosure policy | OPEN |
ACC-POL-110 |
Menu as API prerequisite | current API supports required menu routes | keep as compatibility input, not sole target action authority | RECOMMENDED |
ACC-POL-120 |
Numeric roles | current primary access input | semantic capability migration by action | REQUIRED FOR TARGET |
ACC-POL-130 |
Virtual menu roles | current compatibility | move accepted behavior to profile/capability owner | OPEN |
ACC-POL-140 |
UI visibility source | multiple JS/PHP hints | derive from same policy inputs; backend always rechecks | REQUIRED |
ACC-POL-150 |
Direct page aliases | selected print-page aliases | explicit owner/action mapping | OPEN |
ACC-POL-160 |
Legacy TYPE/ACTION routes | separate guard architecture | adapter or retirement after caller-zero | REQUIRED FOR P12 |
ACC-POL-170 |
Access diagnostic trace | not universal | redacted support query | RECOMMENDED |
ACC-POL-180 |
Client 1 broad guard rollout | prior outage risk | no global conversion without full caller/role evidence | FIXED SAFETY RULE |
11. Target Component Architecture¶
flowchart TB
React[React Pages and Action Hints]
Next[Next.js Page/API Adapters]
PHP[Legacy PHP Adapters]
Identity[Actor + Tenant Context]
Platform[Module / Capability / Config]
Access[TypeScript Access Policy]
App[Owning Application Command / Query]
Repo[Tenant-scoped Repository]
DB[(MySQL)]
Audit[Decision / Transition Evidence]
React --> Next
Next --> Identity
PHP --> Identity
Identity --> Platform
Platform --> Access
Access --> App
App --> Repo
Repo --> DB
Access --> Audit
App --> Audit
The access policy does not execute business SQL or provider calls.
12. Migration Waves¶
ACC-W0 Full selected page/API/action/record caller inventory
ACC-W1 Redacted read-only access decision trace
ACC-W2 Semantic action definition for one low-risk query
ACC-W3 UI/backend parity for one read-only page
ACC-W4 One strict API read cohort
ACC-W5 One bounded write action read-shadow
ACC-W6 One authoritative semantic action cutover
ACC-W7 Record/state denial parity and rollback
ACC-W8 Impersonation/super-admin decision parity
ACC-W9 Legacy TYPE/ACTION adapter or retirement
ACC-W10 Target-role and Client 1/2 stabilization
ACC-W11 Current Wiki/admin diagnostics publication
ACC-W12 Numeric role/menu-only caller-zero for selected scope
ACC-W13 Shared/Dedicated parity
ACC-W14 PostgreSQL later
No wave is activated by this document.
13. Rollback¶
Rollback restores the previous accepted decision owner for the selected route/action. It preserves:
- current role/menu/module rows;
- record data;
- audit/decision evidence;
- current URL/API compatibility;
- actor/subject/tenant lineage;
- explicit denial fixes already accepted.
Rollback does not:
- dual-authorize old and new decisions indefinitely;
- convert an unknown result into allow;
- expose previously denied record data;
- remove audit/history;
- revert business records changed by an already-committed command;
- broadly reopen a disabled module.
14. Stable Acceptance Scenarios¶
Page and menu¶
ACC-SCN-010 expected menu and page allow
ACC-SCN-020 hidden menu / direct page denied
ACC-SCN-030 query-specific menu route
ACC-SCN-040 unregistered page compatibility
ACC-SCN-050 page registry inactive/error
ACC-SCN-060 module disabled/missing/error
ACC-SCN-070 config prerequisite disabled/error
API and action¶
ACC-SCN-110 authenticated API allow
ACC-SCN-120 unauthenticated API
ACC-SCN-130 menu prerequisite denied
ACC-SCN-140 numeric role denied
ACC-SCN-150 UI hidden / direct API denied
ACC-SCN-160 legacy TYPE/ACTION parity
ACC-SCN-170 unknown decision on write
Record and state¶
ACC-SCN-210 own-tenant record allow
ACC-SCN-220 foreign-tenant record denied without leak
ACC-SCN-230 missing record
ACC-SCN-240 wrong parent/child relation
ACC-SCN-250 invalid record state
ACC-SCN-260 stale version
ACC-SCN-270 provider/config prerequisite unavailable
Privileged and migration¶
ACC-SCN-310 non-impersonating super-admin diagnostic
ACC-SCN-320 user impersonation subject decision
ACC-SCN-330 tenant-only support decision
ACC-SCN-340 admin override allowlisted/unauthorized
ACC-MIG-SCN-010 old/new read parity
ACC-MIG-SCN-020 semantic action one-decision cutover
ACC-MIG-SCN-030 rollback without access widening
ACC-MIG-SCN-040 Client 1 non-regression
ACC-MIG-SCN-050 Client 2 expected behavior
ACC-MIG-SCN-060 legacy caller-zero
ACC-MIG-SCN-070 Shared/Dedicated parity
ACC-MIG-SCN-080 PostgreSQL parity
15. Definition Of Ready For Implementation Review¶
- selected pages/APIs/actions/records and callers are fully inventoried;
- current role/menu/module/config rows are read for the target environment;
- actor/subject/tenant semantics are accepted;
- semantic action and record predicate are explicit;
- record-state owner is identified;
- unknown/fail-open compatibility is documented for the selected cohort;
- UI/API direct-call parity scenarios exist;
- Client 1 non-regression and rollback are explicit;
- no unrelated broad guard conversion is required;
- remaining unknowns cannot change live access for the selected wave.
16. Definition Of Complete¶
A selected authorization migration wave is complete only after:
- current and target decisions match accepted policy;
- target-role browser and direct API tests pass;
- foreign record and wrong-state negatives pass;
- UI visibility and backend authorization agree;
- impersonation and super-admin cases are verified;
- one authoritative decision is active for the cohort;
- rollback is rehearsed;
- current support/Wiki guidance is published and read back;
- old route/role/menu-only decision callers reach zero for the selected scope;
- observation/stabilization passes.
Documentation alone does not satisfy these criteria.
---¶
Source:
docs/reconstruction/PLATFORM_AUTHORIZATION_ACCESS_REBUILD_PACKET.md— ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.