Platform Tenant / Config / Credential — Current Source Refresh — 2026-08-10¶
- Status:
CURRENT SOURCE-RECONCILED DOCUMENTATION / NO IMPLEMENTATION ACTIVATION - Task:
CTC-CDOC-005 - Source baseline actually reviewed:
qa@8981a02f7b2a2fa256a7365d6921f3d7636f1fe2, thenmaster@f82a91f596e6d3ed636c102b458b3dd07d8475be - Source-owner baseline:
8981a02f7b2a2fa256a7365d6921f3d7636f1fe2;f82a91f...adds only CTC-CDOC-006 documentation and does not change the owner source reviewed here - Packet baseline:
qa@4f6165bc4c53a7d98b0c246392dd9ed5bd75c21c - Provider credential packet baseline:
qa@2163051c30380585f07b9541ccd15cbc28d7e7fe - Phase implementation:
USER HOLD - Effects: repository documentation only; no Runtime, DB, config, credential, role, menu, provider, Wiki, service or deployment effects
1. Authority And Concern Separation¶
Current source controls current implementation facts. Target reconstruction packets remain future design inputs only where explicitly labeled target.
Tenant identity
!= Operating Profile
!= Module enablement
!= Named process capability
!= Typed config value
!= Credential availability
!= Credential reveal/update authority
!= Menu/Page/API/Action/Record authorization
!= Provider effect authorization
No positive result in one concern grants another.
2. Baseline Drift And Current Owners¶
The platform packet baseline 4f6165... is an ancestor of the current source and is stale as a current owner baseline.
| Owner | Current finding |
|---|---|
app/platform/tenant/config_helper.php |
changed after packet baseline; now owns encrypted tenant-secret support, provider definitions, capability metadata and mixed cache behavior |
app/platform/tenant/capability_resolver.php |
current blob is unchanged from the packet baseline; typed decision semantics remain stable |
app/platform/tenant/CapabilityDefinitionRegistry.php |
current source present; absent from the old packet baseline |
app/platform/tenant/effective_capability_diagnostics.php |
current source present; returns safe effective-state diagnostics |
app/platform/tenant/module_guard.php |
current source has strict typed module resolution alongside legacy module/page/config decisions |
app/platform/tenant/api_strict_principal.php |
strict tenant context bridge into API scalar compatibility context |
app/platform/api_routes.php |
current managed credential and effective-capability API owner |
app/shared/api/logging.php |
current request-body redaction and sensitive-field masking owner |
frontend/pages/platform/admin-console/tenants.php |
current Admin Console consumer for tenant/config/credential/effective diagnostics |
The credential packet baseline 2163051... is also historical. Its managed reveal/replace/encrypted-storage contract remains represented in current source, with later capability-definition/diagnostics integration layered on top.
3. Plain Config, Secret Config And Managed Credential¶
Ordinary plain config¶
tenant_config_get() reads active T_TENANT_CONFIG by effective CLIENT_ID and CONFIG_KEY. Missing, stored-empty or source-error cases collapse to the caller default at the scalar boundary. Typed wrappers normalize bool/int values but still lose provenance and validity.
scalar config value
!= explicit configured policy
!= module/capability authorization
Secret-classified runtime config read¶
For a key classified secret, the helper considers both <KEY> and SECRET.<KEY> and prefers the managed SECRET.<KEY> row. Managed envelopes are decrypted for trusted Runtime consumers. Legacy plaintext <KEY> remains compatibility-read behavior.
This internal Runtime read is not credential reveal.
Managed credential storage¶
Preferred managed storage is:
T_TENANT_CONFIG.CONFIG_KEY = SECRET.<ORIGINAL_KEY>
Current source uses an enc:v1: AES-256-GCM envelope with key material derived from CTC_TENANT_SECRET_KEY, which must decode to 32 bytes.
No plaintext, ciphertext or key material was read in this task.
4. Credential Lifecycle¶
Managed credential operations are allowlisted by tenant_provider_config_definitions() entries with valueType = secret.
Reveal¶
Current source provides the explicit privileged reveal route documented as:
POST /platform/admin/tenants/{clientId}/credentials/{credentialKey}/reveal
It is separate from ordinary config/status reads and may return the decrypted credential only through that privileged response path. Source-level response controls include no-cache/no-store semantics.
Replace / rotate¶
Current source provides:
POST /platform/admin/tenants/{clientId}/credentials/{credentialKey}
The managed replacement contract:
- validates tenant/admin/key scope;
- rejects empty replacement values;
- checks
EXPECTED_UPDATED_ATwhen compatible revision metadata exists; - encrypts the replacement into
SECRET.<KEY>; - writes available value-type/module/update metadata;
- wipes and soft-deletes the active legacy plaintext
<KEY>row; - rereads/returns metadata rather than the credential value.
Revision conflict¶
Optimistic conflict protection depends on installed revision metadata. Source support does not prove UPDATED_AT exists in the target environment. If it is absent, equivalent optimistic concurrency is not established by the inspected source.
Removal¶
No managed remove/clear/revoke helper or route was located in the reviewed source set.
REVEAL: SOURCE PRESENT
REPLACE / ROTATE: SOURCE PRESENT
LEGACY PLAINTEXT RETIREMENT ON REPLACE: SOURCE PRESENT
REMOVE / CLEAR: NOT ESTABLISHED
Hide, Cancel, blank Save, provider disconnect, or plaintext retirement during replacement must not be mislabeled as credential removal.
5. Module / Profile / Capability Applicability¶
Current effective diagnostics explicitly keep the unresolved authorities unresolved:
Operating Profile: UNBOUND
Entitlement: UNKNOWN
Module: RESOLVED PER MODULE
Named capability: REGISTERED SUBSET
Role/Menu: EXTERNAL AUTHORITY
Provider effect authority: UNKNOWN
Legacy module behavior remains compatibility-oriented: explicit disable denies, while missing/source-error cases can allow under existing defaults.
Selected strict API paths instead use:
strict TenantExecutionContext
-> current row observation
-> CapabilityDefinitionRegistry
-> CapabilityResolver
-> safe typed resolution
The registered process-capability subset includes compatibility definitions such as MK_DOCUMENT_WORKFLOW_ENABLED and EXPORT_BROKERAGE_WORKFLOW_ENABLED. A compatibility default is not accepted Product entitlement or explicit tenant policy.
6. Strict Resolver Versus Legacy PHP/Scalar Callers¶
Current architecture is hybrid.
Strict selected API flow:
TenantExecutionContextAdapter
-> strict TenantExecutionContext
-> scalar bridge + safe serialized context
-> typed module/capability/config resolution where opted in
Legacy/current compatibility flow still exists through:
getClientId()
moduleGuardModuleDecision()
moduleGuardPageDecision()
moduleGuardConfigDecision()
isModuleEnabled()
tenant_config_get*()
Therefore:
typed foundation present
!= repository-wide typed execution
!= repository-wide profile/capability cutover
Caller-by-caller parity is still required before retirement of legacy behavior.
7. Current Cache Behavior¶
| Helper | Static cache partition |
|---|---|
tenant_config_get() |
DB object identity + tenant + config key |
tenant_config_get_many() |
tenant + config key; no DB object identity |
tenant_module_enabled() |
DB host/database + tenant + module key |
tenant_config_supports_metadata() |
one process-static capability result |
tenant_config_upsert() invalidates the shared menu cache, but no universal reset for all already-populated config static caches was located.
Evidence implications:
- same-process read-after-write freshness is not established;
- multi-read must not be assumed DB-object isolated;
- heterogeneous-schema multi-DB processes can make the metadata-support static result material;
- short-lived PHP requests may naturally discard static state, but that is Runtime evidence, not a source guarantee.
No Production incident is inferred.
8. Secret-Safe Diagnostics And Logging¶
tenant_effective_capability_diagnostics() internally reads configured rows but replaces secret content with a configured-presence marker before safe resolver serialization. Safe output may expose hasValue, source, validity, module/provider labels, fallback and reason; it is not secret reveal or provider validation.
Source inspection of app/shared/api/logging.php confirms:
- routes with
redactRequestBody = truestore an empty request body in API log context; apiLogMask()masks password/token/authorization/API-key/config-value/credential-value-like fields;- audit input summaries exclude sensitive categories.
No Runtime log was read and no credential route was executed.
9. Stale / Historical Findings¶
Original Tenant/Profile/Capability packet¶
The 4f6165... source baseline remains historical evidence but is no longer current for this owner set.
2026-08-09 dual-ref authority¶
PLATFORM_TENANT_CAPABILITY_DUAL_REF_CURRENT_AUTHORITY_2026-08-09.md accurately described a prior state where effective diagnostics were QA-only and absent from release master.
At this task's current reviewed refs, the diagnostics/registry source is present in both qa@8981a02... and master@f82a91f.... The prior QA-only/master-absent statement is therefore historical branch-status evidence, not current navigation.
master@f82a91f... differs from qa@8981a02... only because a parallel CTC-CDOC-006 documentation commit landed during this session; it does not change the Tenant/Config source-owner facts above.
Neither Git ref proves deployed Runtime identity.
10. Open Policy Questions¶
- What explicit lifecycle owns credential remove/revoke/clear?
- Should credential reveal require privileged-action reauthentication beyond current Admin Console/session authorization?
- Is credential administration allowed while the provider module is disabled for setup/recovery, or should a separate management capability gate it?
- What is the accepted tenant-to-operating-profile composition model?
- Which callers may retain missing/error compatibility fallback and which must become strict?
- What cache invalidation/version contract is required for same-process, long-running and multi-DB consumers?
- Does package/tier ever become entitlement authority?
No policy answer is invented here.
11. Runtime / Environment Evidence Still Required¶
Still NOT RUN:
- deployed source/config/schema identity;
- installed
T_TENANT_CONFIGcolumns/indexes and active-row metadata; - managed-secret versus legacy-row coexistence counts without values;
- Admin/super-admin/same-tenant/cross-tenant behavior;
- dedicated-deployment direct-route behavior;
- safe effective-diagnostics API/browser readback;
- runtime log-redaction observation with synthetic values;
- same-request/next-request/long-running cache freshness;
- multi-DB cache partition behavior;
- credential replacement provider consumption/validity;
- current Wiki content;
- complete strict-versus-legacy caller inventory.
Use RBR-TENANT-CONFIG-002-READONLY-PREFLIGHT.md only after separate environment-read authorization.
12. Disposition¶
Current source reconciliation: COMPLETE FOR CTC-CDOC-005
Plain config contract: SOURCE PRESENT
Managed encrypted credential storage: SOURCE PRESENT
Managed reveal: SOURCE PRESENT
Managed replace/rotate: SOURCE PRESENT
Legacy plaintext retirement on replace: SOURCE PRESENT
Managed removal: NOT ESTABLISHED
Request-body redaction: SOURCE PRESENT
Safe effective diagnostics: SOURCE PRESENT
Canonical profile binding: NOT ESTABLISHED
Repository-wide strict adoption: NOT ESTABLISHED
Runtime/environment evidence: NOT RUN
Phase impact: NONE
M3: NO
M4: NO
External effects: NONE
---¶
Source:
docs/reconstruction/PLATFORM_TENANT_CONFIG_CREDENTIAL_CURRENT_SOURCE_REFRESH_2026-08-10.md— ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.