Skip to content

Platform Provider Credential Management — Current Source — 2026-08-08

  • Status: CURRENT SOURCE CONTRACT / ENVIRONMENT AND ROLE EVIDENCE REQUIRED
  • Current review ref: qa@2163051c30380585f07b9541ccd15cbc28d7e7fe
  • Owning source change: feat: allow admin provider credential reveal
  • Integration refresh: PLATFORM_INTEGRATION_PROVIDER_CURRENT_SOURCE_REFRESH_2026-08-08.md
  • Read-only evidence package: RBR-CREDENTIAL-001-READONLY-CURRENT-STATE-PREFLIGHT.md
  • Current Admin Runbook: PLATFORM_TENANT_CONFIGURATION_ADMIN_SUPPORT_RUNBOOK.md
  • Phase implementation: USER HOLD

1. Purpose

This document records the current source contract for Provider Settings credential reveal and replacement.

It separates:

credential definition
credential storage
credential availability metadata
credential reveal
credential replacement
provider authentication
provider effect authorization
provider effect result

These are not interchangeable.


2. Current Actors

Super administrator

Can select a tenant in Admin Console and invoke the managed credential routes for that explicit tenant.

Tenant administrator

Current server access requires Admin Console access and restricts a non-super-admin actor to:

requested clientId == effective getClientId()

The current Admin Console access helper accepts super-admin or effective numeric role 1.

Other roles

No current managed credential access is intended through these routes. The source rechecks the Admin Console predicate server-side.

Important distinction

Tenant administrator may reveal/update an allowlisted tenant credential
!= tenant administrator may call every provider operation

Module, capability, action, record and provider-effect authorization remain separate.


3. Credential Allowlist

A key is manageable only when:

tenant_provider_config_definitions()[KEY] exists
AND valueType == secret

Current families represented in the allowlist include:

  • Gemini and legacy image-provider credentials;
  • Telegram bot/webhook/cron secrets;
  • Gmail credential and operation secrets;
  • QuickBooks Time OAuth/client/setup secrets;
  • QuickBooks Online OAuth/client secrets;
  • APMT consumer/authorization keys;
  • Twilio auth and AI Voice secrets.

Non-secret provider settings such as model, URL, timeout, mailbox name or enabled flag are not revealable through this credential endpoint.

Arbitrary config keys and environment-variable names are rejected.


4. Storage Authority

4.1 Preferred row

T_TENANT_CONFIG.CONFIG_KEY = SECRET.<ORIGINAL_KEY>

4.2 Envelope

enc:v1:<base64(nonce + GCM tag + ciphertext)>

Encryption key source:

CTC_TENANT_SECRET_KEY

Required key shape:

base64-encoded 32-byte key

4.3 Legacy compatibility

Read supports either:

SECRET.<KEY>
OR
<KEY>

and prefers the encrypted companion row.

This means a legacy plaintext row may still be readable until a managed replacement retires it.

4.4 Replacement migration

Managed replacement:

  1. reads current source/revision;
  2. encrypts the replacement;
  3. updates or inserts SECRET.<KEY>;
  4. records VALUE_TYPE='secret' when schema supports it;
  5. associates module metadata when schema supports it;
  6. wipes and soft-deletes the active legacy plaintext <KEY> row;
  7. rereads the stored credential metadata.

4.5 Schema compatibility

Current helper adapts to presence/absence of:

VALUE_TYPE
UPDATED_AT
MODULE_ID

Therefore source support does not prove which metadata is installed in the current environment.


5. Safe List/Status Read

The ordinary tenant-config/provider-list query:

  • removes SECRET.* rows from the response;
  • returns the public original key;
  • reports whether an encrypted row has a value;
  • reports last-updated metadata when available;
  • keeps CONFIG_VALUE empty for secret fields.

Safe status output may include:

credential key
provider
label
module key
configured / not configured
updatedAt

It must not include the credential value.


6. Reveal Command

Current route:

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

Preconditions

  • authenticated session;
  • Admin Console access;
  • same-tenant restriction for non-super-admin;
  • allowlisted secret key;
  • readable/decryptable stored value.

Result

credentialKey
configured
value
updatedAt

The current result intentionally contains the decrypted credential value.

Response controls

Cache-Control: no-store, private
Pragma: no-cache

UI controls

The current page:

  • requests one credential only;
  • uses password input by default;
  • toggles Show/Hide;
  • clears the displayed value when another credential is revealed;
  • clears credential fields on page exit;
  • provides accessible show/hide labels.

Non-implications

Reveal succeeded
!= credential is valid at provider
!= module/capability enabled
!= provider effect authorized
!= provider connection healthy

7. Replacement Command

Current route:

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

Body semantics:

VALUE
EXPECTED_UPDATED_AT optional

Current behavior

  • empty VALUE is rejected;
  • key must remain allowlisted;
  • tenant/admin checks are repeated;
  • revision conflict is returned when expected metadata differs;
  • encrypted row is written;
  • legacy plaintext row is retired;
  • response returns updated metadata, not plaintext.

Concurrency

When UPDATED_AT metadata is installed and supplied, the update uses a conditional revision check.

When the environment does not support UPDATED_AT, the same optimistic concurrency protection is not available in the inspected helper.

Removal

Current helper text says removal is a separate explicit action. No managed credential removal helper or route was located in the inspected source.

Current classification:

REVEAL: PRESENT
REPLACE: PRESENT
REMOVE: NOT ESTABLISHED

Do not describe blank Save, Cancel or Hide as credential removal.


8. Logging And Evidence

Current routes declare:

redactRequestBody = true

Current API logging:

  • replaces the request body with an empty structure in route log context;
  • masks names matching credential/config/token/secret patterns in ordinary masking;
  • does not use the credential response as normal request-log content.

Current static test asserts these boundaries.

No credential-domain immutable event was located for:

REVEAL
REPLACE
FAILED REVEAL
FAILED REPLACE

Current request diagnostics may establish actor, route, time, request ID and result metadata, but request diagnostics are not a business/security approval ledger.

Required future evidence should distinguish:

request observed
credential row changed
provider later consumed the credential
provider operation succeeded

9. Dedicated Deployment Boundary

Current Admin Console page presents tenant management as read-only in a dedicated deployment.

The inspected credential route/helper does not contain an explicit dedicated-deployment guard.

Current classification:

UI read-only intent: PRESENT
Direct credential route deployment guard: NOT LOCATED
Current deployed behavior: NOT VERIFIED

Do not infer server denial from disabled/hidden UI controls.


10. Cache And Consumer Boundary

Current tenant-config readers use process-local static caches.

Managed replacement invalidates the shared menu cache, but the inspected helper does not expose a general reset for every already-loaded tenant-config static cache in the same long-lived process.

Typical request-scoped PHP execution may naturally discard static state at request end, but that is an environment/runtime fact, not a portable contract.

Evidence must establish:

  • PHP execution model;
  • long-running CLI or worker consumers;
  • next-request readback;
  • provider adapter effective source;
  • whether service restart/reload is needed for any non-PHP consumer.

11. Provider Definition And Module Boundary

Every allowlisted provider definition carries a module key, but current credential access is registered with:

moduleKey = null

The Admin route relies on Admin Console authorization and tenant/key allowlist rather than provider module enablement at route dispatch.

Therefore:

Provider module disabled
!= credential reveal/update route necessarily unavailable

The Admin Runbook says a credential does not authorize or enable provider use. Current environment evidence must determine whether disabled-module credential management is intended for setup/recovery or should be limited by a separate accepted policy.

No policy change is authorized by this document.


12. Current Error/Conflict Classes

Source-observed classes include:

FORBIDDEN
  actor lacks Admin Console access or targets another tenant

NOT_FOUND
  key is not an allowlisted provider secret

INVALID
  missing/empty replacement value

CONFLICT
  expected updatedAt differs

UNAVAILABLE
  encryption key absent, envelope invalid or decrypt/store failed

User-visible errors should not include the credential value or cryptographic material.


13. Read-Only Evidence Requirements

RBR-CREDENTIAL-001 must establish without revealing values:

  • current T_TENANT_CONFIG schema and indexes;
  • configured provider-secret keys by tenant;
  • encrypted companion versus legacy plaintext row counts;
  • enc:v1: envelope classification using safe prefix/length expressions only;
  • duplicate active rows;
  • metadata/revision availability;
  • allowlist/provider/module mapping;
  • Admin role/account/menu/page source;
  • request-log redaction configuration;
  • dedicated deployment behavior;
  • current caller effective source after replacement;
  • no plaintext copied into evidence.

14. Target Reconstruction Inputs

Future architecture should preserve:

credential definition registry
credential owner tenant
credential storage reference/version
availability metadata
separate privileged reveal
separate replacement/rotation
explicit removal/retirement
actor/subject/request correlation
provider consumer read
provider effect authorization

It should not require copying plaintext credential values into:

  • React state beyond the explicit reveal field;
  • ordinary Next.js server logs;
  • business tables;
  • provider attempt payloads;
  • Wiki, Task or incident documents;
  • generic analytics.

A future external secret store may replace encrypted DB storage, but the application contract should continue to return safe availability/reference metadata by default and plaintext only through a separately authorized reveal operation when the product requires it.


15. Current Disposition

Allowlisted secret definition:
SOURCE PRESENT

Encrypted tenant storage:
SOURCE PRESENT

Legacy plaintext compatibility read:
SOURCE PRESENT

Reveal route/UI:
SOURCE PRESENT

Replacement route/UI:
SOURCE PRESENT

Request-body redaction:
SOURCE PRESENT

Credential-specific immutable audit:
NOT LOCATED

Managed removal route:
NOT LOCATED

Dedicated direct-route enforcement:
NOT LOCATED

Current DB rows/metadata:
NOT READ

Current role/account behavior:
NOT RUN

Current credential values:
NOT READ

Provider validity after replacement:
NOT VERIFIED

M3:
NO

M4:
NO

---

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