Skip to content

Platform Identity / Session / Impersonation — Current Consumer Refresh — 2026-08-09

  • Status: CURRENT STATIC SOURCE REFRESH COMPLETE / ENVIRONMENT AND SESSION EVIDENCE REQUIRED
  • Previous source-authority baseline: qa/master@3c084671c034f8f5136b02dce990ecff6c66d107
  • Current review ref: qa/master@40fb4020e2993347eb7cde9cb24ee9f6201cd806
  • Previous authority: PLATFORM_IDENTITY_SESSION_IMPERSONATION_SOURCE_AUTHORITY.md
  • Consumer matrix: PLATFORM_IDENTITY_CURRENT_CONSUMER_MATRIX_2026-08-09.md
  • Evidence package: RBR-IDENTITY-001-READONLY-CURRENT-SURFACE-PREFLIGHT.md
  • Phase implementation: USER HOLD
  • Effects: source inspection and documentation only

1. Purpose

The original Identity packet remains the semantic owner for login, PHP session, actor/subject, tenant context, password handling and impersonation. This refresh answers a narrower current-source question:

Did the core Identity implementation change?
Which new or expanded current consumers rely on the existing Identity contract?
Where does a high-impact consumer use scalar session identity instead of a
complete typed Actor / Subject / Tenant context?
What evidence is required before changing current session or impersonation
behavior?

It does not authorize login/session changes, password changes, impersonation, credential reveal, role changes or a PHP/Next.js identity migration.


2. Refresh Result

2.1 Core Identity source is unchanged

The following core source files were not changed between the previous Identity baseline and the current review ref. Current blob identities are recorded below.

Source Current blob Current responsibility
login.php bd73f23524e34e9daf85ecb0eb4fbe77a7afdfa4 username/password authentication, rehash, session issue
config/session.php c2fb4d252bf910fe2507308a767a72398e919b37 PHP session and cookie parameters
config/config.php b49bdf04441c2fe09ba1b53bd7cccc576f260d00 scalar tenant/user/role and super-admin compatibility helpers
app/platform/auth/account_post_helper.php 8baed69a47a058c13120973617f49980338a7409 own-password change
app/platform/audit/super_admin_post_helper.php 76c9bef4d77f4cc8856c3d2fa92998713968eab8 impersonation start and password reset
admin-console.php 1fe62af36ff750cd3de358f7f05e00f0264af027 Admin Console session entry, tenant-only impersonation and end
app/platform/tenant/tenant_execution_context_adapter.php 0ffa6657aeabd117ddfc78c5bd2303ac022119bf typed Actor/Subject/Tenant construction
app/shared/api/runtime.php 54675d2f0c363fb68959a7d79b97ceb8686e4b25 API authentication and scalar/strict request context

Therefore the original current-source conclusions remain valid:

login lookup is username-only
one 20-hour PHP session TTL is used
login regenerates the session ID
impersonation start/end do not visibly regenerate the session ID
password update does not revoke other sessions
scalar helpers can replace actor identity with the effective subject
strict typed principal remains route opt-in

2.2 Consumer surface changed

The principal current Identity drift is not a new session engine. It is the addition or expansion of high-impact consumers that rely on the existing session and scalar context.

The most important new consumer is tenant provider-credential management:

POST /platform/admin/tenants/{clientId}/credentials/{credentialKey}/reveal
POST /platform/admin/tenants/{clientId}/credentials/{credentialKey}

Additional operational consumers introduced or expanded after the original Identity baseline include Loader Work Assignment, Final Loading Review, Street Turn, Billing/QBO, document email and provider operations. Their detailed Action/Record authorization is owned by the current Access and Integration refreshes. This document owns only the identity context they consume.

Current classification:

core Identity source: STATICALLY CURRENT
consumer surface: EXPANDED
current environment/session evidence: REQUIRED
accepted target Identity policy: OPEN / PARTIAL
M3: NO
M4: NO

3. Current Credential Reveal / Replacement Consumer

3.1 Route contract

Current route registration uses:

method = POST
moduleKey = null
redactRequestBody = true

The route is not registered with a strict tenant principal, a dedicated named credential capability or a privileged-reauth requirement.

The handler calls:

platformApiAssertAdminConsoleAccess()

Current Admin Console access is:

physical Super Admin
OR
effective role ID 1

For a non-Super-Admin actor, the requested clientId must equal getClientId(). A physical Super Admin is not limited by that same-tenant condition.

3.2 Identity context used by the credential helper

After access checks, the current credential helper receives only:

['clientId' => target client]

The helper does not receive the complete typed context containing:

physical actor
effective subject
impersonation mode
tenant provenance
authorization reference
privileged reauthentication state

Those facts may exist elsewhere in the request/session/log context, but they are not part of the credential repository call contract.

3.3 Reveal

Current reveal behavior:

allowlisted secret key
+ authorized Admin Console session
+ selected tenant
-> decrypt one stored credential
-> return plaintext in one response

Current transport protections include:

Cache-Control: no-store, private
Pragma: no-cache
request-body redaction metadata
ordinary provider-list response remains masked

The current source does not establish:

  • privileged password reauthentication before reveal;
  • MFA before reveal;
  • an explicit reason/ticket field;
  • an explicit prohibition while impersonating;
  • a separate short-lived reveal grant;
  • a durable reveal audit record containing actor and subject separately;
  • automatic invalidation of already-rendered plaintext on server-side session change.

These are current policy/evidence gaps. They are not authorization to disable or alter the feature broadly.

3.4 Replacement

Current replacement uses:

new non-empty value
+ optional EXPECTED_UPDATED_AT
-> optimistic revision check
-> encrypted SECRET.<CONFIG_KEY> storage
-> legacy plaintext row retirement/wipe

Replacement does not imply:

provider authentication succeeded
provider connectivity succeeded
module/capability is enabled
current actor may call the provider
other sessions no longer know the old value

3.5 Impersonation interaction

isSuperAdmin() continues to inspect the original session fields. Therefore a physical Super Admin remains a Super Admin while user- or tenant-impersonating. The current credential route does not explicitly reject that condition.

Safe current documentation must therefore distinguish:

physical Super Admin selecting a tenant in Admin Console
!= tenant-only impersonation acceptance
!= target-user role acceptance
!= privileged reauthentication

The actual current browser behavior and accepted policy require controlled evidence before any guard change.


4. Login And Session Contract Revalidation

4.1 Login

The current login query remains:

SELECT ...
FROM T_USER
WHERE USERNAME = ?
  AND DELETED_AT IS NULL
LIMIT 1

No tenant/realm identifier is submitted. Current data must prove one of:

active usernames are globally unique
or
an accepted login realm exists outside this query

The source alone cannot prove that active duplicate usernames do not exist.

4.2 Password verification and rehash

modern hash -> password_verify
legacy 128-hex hash -> SHA-512 compatibility verifier
successful login with rehash required -> compare-and-set password update

Login updates LAST_LOGIN after session issue. A login evidence run is therefore not read-only at the database level and must be treated as an authorized authentication scenario, not part of the read-only preflight.

4.3 Session issue

Successful login performs:

session_regenerate_id(true)
-> write original session tenant/user/role fields
-> update LAST_LOGIN
-> redirect to default page

4.4 Current cookie/session settings

TTL = 20 hours
strict mode = on
cookies only = on
HttpOnly = on
SameSite = Lax
Secure = HTTPS or X-Forwarded-Proto=https
cookie lifetime = TTL
gc lifetime = TTL

The current source still does not separate idle, absolute, impersonation or privileged-action timeouts.


5. Actor / Subject / Tenant Revalidation

5.1 Scalar compatibility context

Current scalar helpers remain:

getClientId()
getSessionUserId()
getSessionUsername()
getEffectiveRoleIds()
isSuperAdmin()

During user impersonation:

getSessionUserId / getSessionUsername / getClientId
-> effective subject / target tenant

isSuperAdmin
-> original physical session

A caller that stores only the scalar username can lose the physical actor. A caller that stores only the original session username can lose the effective subject. Evidence and future typed contracts must preserve both.

5.2 Typed context

The typed adapter still supports:

direct WEB/API user
user impersonation
tenant-only impersonation
allowlisted API tenant override
explicit CLI/INTEGRATION binding
legacy CLI compatibility

However API strict principal construction remains route opt-in. A route using apiRouteLegacyContext() is not automatically proven to preserve complete Actor/Subject/Tenant provenance.

5.3 Page/API telemetry

Current API logging keeps request-body redaction for marked routes. Diagnostic entries use the original session username for the displayed actor while API request context can use the effective scalar username and tenant.

This can preserve useful physical-actor evidence, but a complete support trace still needs both identities explicitly connected by request/correlation data.

physical actor in diagnostic event
+ effective subject/tenant in request context
!= one durable typed identity audit unless connected and readable

6. Current Impersonation Consumers

6.1 User impersonation start

Current action:

IMPERSONATE_START

Current sequence:

Super Admin endpoint authorization
-> validate target tenant/user
-> clear direct-page grant
-> store IMPERSONATE session object
-> invalidate menu cache
-> redirect

No session ID regeneration is visible in this sequence.

6.2 Tenant-only impersonation

Admin Console main_open can store:

TARGET_USER_ID = 0
TARGET_CLIENT_ID = selected tenant

This selects tenant context but does not represent a real tenant user.

6.3 End

/admin-console?action=impersonate_end unsets the session impersonation object and redirects. It is currently a GET action and does not visibly regenerate the session ID.

6.4 Current sensitive consumers to classify

The following actions require explicit evidence under direct, user-impersonated and tenant-only-impersonated conditions:

provider credential reveal/replacement
own-password change
user password reset
role/menu/module/config administration
provider send or synchronization
record mutation through operational pages

Do not infer accepted policy from the fact that a route currently succeeds.


7. Password Consumer Revalidation

7.1 Own-password change

The helper uses:

getSessionUserId()
getClientId()
current password verification

Under user impersonation these scalar values can resolve to the target user and tenant. Current policy on invoking “change own password” during impersonation is not explicitly owned by the helper.

7.2 Super Admin reset

The reset command uses explicit target user and tenant IDs and writes a modern password hash.

7.3 Session non-implications

Neither current password path establishes:

current session rotation
other-session revocation
impersonation termination
provider-token revocation
user notification

8. Current Consumer Families

Consumer Identity inputs Current concern
Credential reveal/replacement physical Super Admin or role 1, effective tenant, selected client ID high-impact plaintext reveal without typed actor/subject contract or privileged reauth
Admin tenant config/module original/effective Admin Console session and selected tenant selected tenant and impersonation mode must remain explicit
Work Assignment effective user/roles plus assigned Loader identity UI numeric roles and handler role/self checks differ; Access packet owns authorization
Final Loading Review effective tenant and roles Client 1 numeric role compatibility; Access packet owns action decision
Street Turn effective tenant, module, record state no dedicated action role in source; Access packet owns authorization
QBO/Gmail/Telegram/APMT/AI Voice tenant binding, local actor/system identity, credential owner Integration packet owns provider effect; Identity owns actor/tenant provenance
Callback/webhook explicit or configured tenant/provider binding provider identity is not automatically a local actor
CLI/scheduler explicit tenant binding or legacy fallback new write must not rely on compatibility-only tenant context
Page/API telemetry original session actor plus effective request tenant/context actor/subject connection must remain reconstructable

9. Current Gap Register

ID Current fact Required disposition
IDN-CUR-010 core Identity files unchanged from previous baseline preserve original source authority
IDN-CUR-020 credential reveal/replacement consumes scalar Admin session context record direct/impersonated behavior and accepted policy
IDN-CUR-030 credential repository call receives only target clientId future typed command must preserve actor/subject/authorization reference
IDN-CUR-040 reveal has no privileged reauth/MFA in reviewed source policy and controlled evidence required
IDN-CUR-050 impersonation start/end do not visibly rotate session ID evidence and policy required before change
IDN-CUR-060 impersonation end/logout are GET actions browser and request-integrity policy remains open
IDN-CUR-070 own-password change uses effective scalar subject impersonation behavior must be tested and accepted
IDN-CUR-080 password update does not revoke other sessions revocation policy and current session-store inventory required
IDN-CUR-090 logging may preserve actor while request context uses subject correlation/readability evidence required
IDN-CUR-100 provider/service identities remain adapter-specific explicit system/integration binding required per family
IDN-CUR-110 current PHP session remains the only implemented web session authority PHP/Next.js coexistence cannot invent a second independent session truth

10. Target Continuity

The accepted target direction remains:

one authoritative session decision
+ typed Actor / Subject / Tenant context
+ explicit impersonation delegation
+ separate authorization decision
+ durable identity/security evidence
+ PHP and Next.js adapters during coexistence

The current refresh does not select a session library, add a session table or start migration work.

10.1 Required target command boundaries

AuthenticateUser
ChangeOwnPassword
ResetUserPassword
StartImpersonation
EndImpersonation
ReauthenticatePrivilegedAction
InvalidateSession
InvalidateUserSessions

10.2 Sensitive credential consumer boundary

A future credential command must receive, at minimum:

physical actor
effective subject
target tenant
access mode
credential key
privileged authorization / reauth reference
request ID
expected revision

This target requirement does not invalidate current source; it defines the rebuild contract.


11. Evidence Required

Current Identity evidence owner:

RBR-IDENTITY-001

Required classes:

  • schema/data evidence for username uniqueness and password-hash population;
  • server/session evidence for save handler, cookie attributes and expiry;
  • direct user, user-impersonation and tenant-only context evidence;
  • controlled role and password scenarios;
  • credential reveal/replacement identity evidence without capturing secrets;
  • actor/subject/request correlation evidence;
  • current logout/reset and cross-session behavior;
  • Client 1 and selected Client 2 non-regression;
  • current Wiki/admin guidance.

The accompanying read-only package defines only safe metadata and GET-only observation. Login, impersonation, password and credential commands require a separate exact authorization.


12. Current Disposition

core Identity source freshness:
CONFIRMED

current high-impact consumer inventory:
REFRESHED

credential identity boundary:
DOCUMENTED / POLICY PARTIAL

read-only evidence package:
DEFINED

current environment/session/account evidence:
NOT RUN

privileged action evidence:
NOT RUN

M3:
NO

M4:
NO

Phase progress:
NONE

---

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