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.