Admin Control Plane · Runtime Phase 1 Preview · role registry · masking · assist · approval queue · audit event model

Runtime · Phase 1 + 2a + 2b
Models are LIVE (5 JSON files · validated · all fields grounded in B contracts). Phase 2a live: policy engine service wraps these models with an HTTP boundary → service.html (FastAPI · 7 endpoints · 24/24 example vectors pass · decision-only · dev-mode only). Phase 2b live: additive on top → phase-2b.html (Bearer JWT resolver · file-backed approval store · TTL enforcement · audit sink boundary) · parity 24/24 preserved · rationale at admin-control-plane-phase-2b.html.
Still not built: real JWKS/IdP verification · Postgres persistence · approval CRUD · Kafka audit producer · admin flip UI (Phase 2b+ infra / Phase 2c / Phase 3). Spec files: role_registry.json · access_policy.json · assist_model.json · approval_queue_model.json · audit_event_model.json · schema.json.

1. Role Registry 12 บทบาท · 4 หมวด · ตัวอย่าง masked_default

2. Masking Policy defaults + exceptions by field category

Mask by default · unmask only with explicit approval + TTL + audit. Sensitive-surface fields (biometric · health · minors · financial · minor-identity) require dual signers per approval_matrix.row-sensitive-override.

Field Category Default Platform-role unmask Superadmin break-glass Sensitive Self view

3. Assist + View-as-Tenant ต่างกันอย่างไร · ใช้เมื่อไร

View-as-Tenant

Read-only · implicit consent · max 60 min

เห็น UI/ข้อมูลเหมือนที่ tenant เห็น · debug + ช่วยเหลือ. ห้ามเขียนอะไร · ทุกปุ่ม action ถูก disable · banner เหลืองเตือนตลอด session.

ALLOWED:
  • view tenant's screens
  • navigate UI
  • see error states
FORBIDDEN:
  • write anything
  • click action buttons
  • export data
  • cross-tenant navigation

Assist Mode

Write with explicit tenant consent · max 120 min · every action audited under admin identity

ช่วย tenant ทำงานที่เขาขอช่วย · เขียนข้อมูลได้บางอย่าง. tenant ต้องกด 'Grant Assist' ก่อนเสมอ · banner แดงเตือน · ทุก action log เป็นชื่อ admin (ไม่ใช่ tenant).

ALLOWED:
  • edit within granted scope
  • complete forms on behalf
  • propose approvals
  • upload to workspace
FORBIDDEN:
  • sign approvals on behalf
  • change role assignments
  • modify PDPA agreements
  • export sensitive PII

Forbidden Patterns (both modes)

  • Silent impersonation · using tenant's JWT directly → never
  • Delegated approval · signing on behalf of tenant-admin → never
  • Permanent sessions · no TTL → never
  • Cross-tenant within session · scoped to exactly one tenant → never
  • Banner hiding · CSS override to remove banner → never
  • Audit disable · no path to turn off audit → never

4. Approval Queue Preview 6 แถว · phase 1 (sample_item_count = 0)

Queue shape + state machine ready. No items live yet — Phase 2 wires the submission + sign-off runtime.

Queues by approval_matrix row

Matrix Row
Required Signers
SLA
Items (live)

Queue state machine

pendingin_reviewsigned_partialsigned_fullapproved

Branches: any state → rejected / sent_back / withdrawn / expired. Sent-back re-enters pending after revision.

5. Audit Event Model 18 event types · WORM + hash-chain integrity

Planned integration with Kafka ptt.audit.trail (7yr retention · compress=none per CLAUDE.md). Hash chain detects tampering. 4 example events:

// view-as-tenant session start { "event_id": "aud-260418-a1b2c3d4", "event_type": "view_as.start", "actor": { "role_key": "support_success", "user_id": "U-support-007" }, "subject": { "type": "tenant", "id": "tenant-acme-001" }, "rationale": "Case CASE-260418-0042 · dashboard blank on login", "session_ref": "va-260418-001" }
// unmask granted { "event_type": "unmask.granted", "actor": { "role_key": "tenant_dpo", "tenant_id": "tenant-acme-001" }, "subject": { "type": "user", "id": "U-end-user-9901" }, "approval_refs": ["APP-260418-0099"], "mask_level_at_event": "unmasked-tenant", "honest_note_if_any": "TTL 30min · auto-expires 11:12" }
// approval signer { "event_type": "approval.sign", "actor": { "role_key": "platform_governance" }, "before_state": { "state": "in_review", "signers_count": 0 }, "after_state": { "state": "signed_partial", "signers_count": 1 }, "approval_refs": ["APP-260418-0100"] }
// governance break-glass (superadmin) { "event_type": "governance.break_glass", "actor": { "role_key": "superadmin" }, "action": "break_glass_unmask", "rationale": "P0 incident · tenant DB corruption · emergency · founder notified", "honest_note_if_any": "60min TTL · post-hoc written approval deadline +24h" }

6. Integration with Feature Flags งาน phase 1 ก่อนหน้า

Admin Control Plane + Feature Flags = upstream of every runtime. Feature flag admin.control_plane_v1 gates this plane; when flipped (Phase 2), the policy engine + approval service read from these JSON specs as contract.

Cross-pack dependencies

  • approval_matrix.row-* (B-owned) ← used by approval_queue_model.sample_queues_phase_1 (A)
  • approval_matrix.roles (B-owned) ← mirrored into role_registry.roles[].key where applicable (A)
  • sensitive_surface_markers (B) ← drives access_policy.masking_policy_rows[*].sensitive_escalation (A)
  • feature-flags/rollout_model.json#gates (A) ← references role_registry role keys · both A-owned
  • CLAUDE.md ptt.audit.trail (7yr WORM) ← audit_event_model.integrity_model.storage (A)

7. Honest Limits · What Phase 1 Does NOT Do ยังไม่ทำอะไรบ้าง

Phase 1 deliberately out of scope

  • No policy engine service (FastAPI) reading access_policy.json at request time
  • No approval submission UI · no kanban · no claim/sign endpoints
  • No audit log sink wired to Kafka · no WORM S3 bucket provisioned · no hash-chain verifier job
  • No assist/view-as session middleware · banner component · consent record table
  • No unmask TTL scheduler · no auto-revoke cron
  • No JWT issuance · no IdP integration · no MFA · no role admin UI
  • No tenant-admin kanban for pending approvals
  • No DEC seal workflow
  • No incident break-glass flow wired to founder notification
Admin Control Plane · Phase 1 · Session A · A-owned · spec live / enforcement not bound ← Planning spec · Feature Flags runtime ↗