KB-4AC0
C2B1-R0 — Option A: Fast Containment (transitional machine identity) design
5 min read Revision 1
current-statec2b1-r0FAST_CONTAINMENToption-atransitional-identityunion-policyleast-privilegeSYNC_SECRETread-only2026-07-21
Option A — Fast Containment (transitional machine identity)
Concept
Create one transitional, non-admin machine identity whose policy is the union of every proven machine capability. Repoint all real consumers to it, prove machine-dependency-on-admin = 0, then rotate the exposed admin password+token. The broad identity is a bridge, decomposed later against a hard deadline.
Identity design (to be provisioned in S1-APPLY — NOT created in R0)
- User:
machine-transition@incomexsaigoncorp.vn(or reuse an existing non-admin shell). - Role/Policy: new policy
machine-transition-policywith:admin_access = FALSE,app_access = FALSE.- No access to
directus_users,directus_roles,directus_policies,directus_permissions,directus_access,directus_settings, and no schema/DDL. - Permission rows granting read+create+update on the union content collections:
workflows, the registry/discovery/transitive collections Nuxt reads,tasks,task_comments,knowledge_documents,system_issues, and the agent-data sync-target collections (+ delete on the agent-data sync targets only).
- Credential: one static token, stored parallel to the admin token; distinct value.
Exact permission rows are not designed in R0 (per mission §0). S1-DESIGN produces them.
Migration sequence (repoint one consumer at a time; each independently reversible)
- File/password consumers first (no restart, no lockout):
reconcile-tasks,reconcile-knowledge→ replaceDIRECTUS_PASSWORDin/etc/incomex/reconcile/directus-admin.envwith the transitional token auth (switch reconcile-*.py to Bearer token);dot-collection-health,dot-apr-health→ arm with the transitional token viaenvironment.sh/cron env. - agent-data → set the transitional token in
/etc/incomex/agent-data.env;docker savebackup ofagent-data-vps-prod:9acd...;docker compose up -d --no-deps --force-recreate agent-data. - Nuxt → BLOCKED until NUXT-IMG-H1. Then add
NUXT_SERVICE_TOKEN(= transitional token) todocker/.env, point compose L174 at it, recreate nuxt. - Hygiene (any time): remove the vestigial token export from
orphan-scanner/misclass-scannerand the vestigial password export fromdot-dot-health; decoupleSYNC_SECRETfrom the admin token. - C2B1-R1 proves zero machine dependency on admin → C2B1-X rotates admin password+token.
Rollback
Every step reverts by restoring the single changed file / compose line and (for containers) a recreate. The admin credential stays valid throughout until X, so any consumer can be pointed back.
Trade-off
- + Fewest identities to design → least design time.
- − One broad content-R/W token becomes a new long-lived secret in the same exposed
docker/.env; it is non-admin but over-privileged relative to any single consumer, and it MUST be decomposed later or it becomes permanent scope creep. - = Does not reach admin-rotation any faster than Option B, because both are gated by the same Nuxt recreate (NUXT-IMG-H1). Fast Containment's speed advantage does not materialize here.
Return values
FAST_CONTAINMENT_ETA_OPERATOR_HOURS = ~6h (identity 1.5h; file repoints 0.75h; agent-data 0.5h;
NUXT-IMG-H1 1.5h; nuxt repoint 0.5h; rotate 0.5h; verify 0.75h)
FAST_CONTAINMENT_ETA_ELAPSED_HOURS = ~24-48h (verification windows + cron cycles to confirm; cautious)
FAST_CONTAINMENT_RESTART_COUNT = 2 (agent-data, nuxt) — Directus NOT restarted
FAST_CONTAINMENT_RESIDUAL_RISK = MEDIUM:
- a broad non-admin token persists in docker/.env until a later decomposition pass (deadline required)
- new static token is plaintext in directus_users.token and rides nightly PG dump (now ENCRYPTED per C2B-PRE) — acceptable but note
- decomposition-deadline slippage = de-facto permanent over-privilege
- shares the Nuxt-image gate; no faster to actual containment than Option B