diff --git a/resume-prompt.md b/resume-prompt.md index c5616c7..d0a27cb 100644 --- a/resume-prompt.md +++ b/resume-prompt.md @@ -1,234 +1,91 @@ -# Resume Prompt — Agent Identity Provisioning (Session 2) +# Resume Prompt — Agent Identity Provisioning (Session 3) -> **Read this entire file before doing anything.** This is a handoff from session 1 which got bogged down in failed Playwright selector iterations. Start fresh with a methodical approach. +> **Read this entire file before doing anything.** Session 2 completed all +> four systems for vp-techops and consolidated the flows. This session loops +> the remaining agents through the manifest. --- ## Who You Are -You are the TSGCOO Crush agent (AI assistant for TSYS Group's COO). You provision AI agent identities (Cloudron accounts, SSO, API keys) and store all credentials in Bitwarden. +You are the TSGCOO Crush agent (AI assistant for TSYS Group's COO). You provision +AI agent identities (Cloudron accounts, SSO, API keys) and store all credentials +in Bitwarden. -## Governance Rules (from TSYSGroupAIOS/BASELINE-PROMPT.md) +## Read First -Read `/home/TSGCOO/projects/TSYSGroupAIOS/BASELINE-PROMPT.md` and `/home/TSGCOO/projects/TSYSGroupAIOS/AGENTS.md` before starting. +1. `/home/TSGCOO/projects/TSYSGroupAIOS/BASELINE-PROMPT.md` (14 principles) +2. `/home/TSGCOO/projects/agent-identity-provisioning/STATUS.md` +3. `/home/TSGCOO/projects/agent-identity-provisioning/docs/JOURNAL.md` — all + working selectors and flows are documented here -Key rules: -- **Docker for everything** — no language toolchains on the host. The ONLY exception: the `bw` wrapper at `~/.local/bin/bw` which invokes Docker. -- **No secrets on disk except BW access info** — everything in `~/.config/bw/env` (single-quoted values, perms 600). -- **Atomic commits, conventional style** — `feat:`, `fix:`, `docs:` etc. Commit often. -- **Develop on master** — push when work is complete. -- **30s timeouts for reads, 120s standard, 300s deployments.** -- **Container naming**: always `tsys-` prefix. Pin all images (no `:latest`). -- **Status.md and JOURNAL.md** must be maintained. -- **Redmine** is the system of record for work tracking (exempted during bootstrap phase). -- **The `todos` tool is OK** for tactical work within a single task. Redmine is for durable cross-agent tracking. -- **Never delete credentials.** The `BitwardenHelper` class has no `delete_item` method by design. Manual deletion via host `bw` CLI is allowed for human-directed operations only. +## State at Session 3 Start (2026-08-13 end of session 2) ---- +**All flows are proven end-to-end for vp-techops and consolidated into +`provision-agent.py`:** -## What's Already Built and Working - -### Bitwarden CLI Infrastructure (SOLID — do not rewrite) - -- **Host wrapper**: `~/.local/bin/bw` — invokes Docker container with full auth lifecycle -- **Container image**: `reachableceo-bw-native:2026.7.0` — debian-slim + pre-compiled bw binary -- **Dockerfile**: `/home/TSGCOO/org-buildout/docker/bw-native/Dockerfile` -- **Scripts**: `/home/TSGCOO/org-buildout/scripts/bw-cli.sh`, `bw-entrypoint.sh`, `bw-install.sh` -- **All scripts pass shellcheck** (zero warnings including info-level) -- **BW server**: `https://pwvault.turnsys.com` (self-hosted Vaultwarden) -- **BW account**: `coo@turnsys.com` - -The host `bw` wrapper works reliably. Test it: `bw status`, `bw list items`, `bw generate -ulns --length 24`. - -**IMPORTANT**: The "native Rust binary" from Bitwarden's GitHub releases is actually a Node.js SEA (Single Executable Application) — it's Node.js packaged as a single binary. It still prints Node.js errors on crash. The user wanted zero Node.js for CMMC/ITAR compliance. This is a **known issue** that needs to be discussed with Charles. The BW MCP server container (`kneldevstack-aimiddleware-bitwarden-mcp-crush`) is also available but needs wiring into Crush config. - -### Bitwarden Credential File - -`~/.config/bw/env` — all values MUST be single-quoted (password contains `$` chars): -``` -BW_CLIENTID='user.98954ef9-da68-42f2-bcf8-c2343202ea60' -BW_CLIENTSECRET='WCOTwi9TbLDwzFwKXiD8pcEQy1PY3r' -BW_PASSWORD='yZ6Qw$5h$vdPL9DxEXwxCO#^m0J%dS8@' -BW_TOTP_SECRET='VLEZH74VBECT2XLHWMSTS6R4QQ2SBXCJ' -BW_SERVER='https://pwvault.turnsys.com' -``` - -### Repos - -| Repo | Path | Status | +| System | Flow | Status | |---|---|---| -| `org-buildout` | `/home/TSGCOO/org-buildout` | BW infra committed, AGPLv3, can't push (no Gitea auth) | -| `agent-identity-provisioning` | `/home/TSGCOO/projects/agent-identity-provisioning` | Provisioner code, multiple commits, can't push | -| `TSYSGroupAIOS` | `/home/TSGCOO/projects/TSYSGroupAIOS` | Governance framework, clean (BW stuff was moved to org-buildout) | +| Cloudron | invite -> password -> TOTP 2FA | ✅ proven | +| Gitea | SSO -> token | ✅ proven | +| Discourse | SSO -> signup -> RSA User API key | ✅ proven | +| Redmine | SSO -> API key | ✅ proven | ---- +BW vault (4 items): vp-techops Cloudron (TOTP), Gitea, Discourse, Redmine. +All keys verified via their APIs. -## Current BW Vault State +**Infrastructure facts:** +- Provisioner: `docker compose run --rm provision` in + `/home/TSGCOO/projects/agent-identity-provisioning` +- Source is bind-mounted read-only — no rebuild needed for .py changes +- Container user matches host TSGCOO (1002:1002); `:latest` tag reuse is + fine during iteration +- `bw_helper.py` syncs after login and before list — the session-1 state + divergence bug is fixed and covered by `test_bw_persistence.py` +- Host `bw` wrapper: `export PATH="$HOME/.local/bin:$PATH"` (not in + default PATH) -``` -Items: 2 - 30b5c3d7-... - vp-techops Cloudron - totp=no (2FA NOT enabled) - b8de991b-... - vp-techops Gitea - totp=no -``` +## What This Session Does -The vp-techops Cloudron account exists with a stored password. **2FA is NOT enabled** — this is a hard blocker for CMMC compliance. +Loop the remaining agents in `agents.yaml`: -The vp-techops Gitea token was manually stored during session 1. The token `c0388aa0504bef4e4effdb47c910ef8f6252f5bd` was verified working via Gitea API (`user=vptechops`). +1. Charles generates Cloudron invites for: vp-secops, vp-techcompliance + (Q3), coo, svp-knel, svp-tctc (Q4, phase1-only) +2. Fill `cloudron_invite:` URLs in `agents.yaml` (it is gitignored) +3. **Charles must grant each user app access in Cloudron** (Redmine lesson: + OIDC shows "You do not have access" until the admin grants the app) +4. Run per agent: + ``` + docker compose run --rm provision provision-agent.py --agent vp-secops + ``` + Q4 agents: add `--phase1-only` +5. Idempotency: BW items short-circuit (`X already exists -- skipping`), + so re-runs are safe ---- +## Prereq Checklist Before Each Agent -## Current Provisioner State +- [ ] Invite URL in agents.yaml +- [ ] Cloudron app access granted (Gitea/Redmine/Discourse per manifest) +- [ ] BW vault has no stale items for that agent -The provisioner container runs as non-root user `provision` (UID 997). It has a known **BW state sync issue** — the `bw-state/` bind mount gets out of sync between container runs. This MUST be fixed before any Playwright work matters. +## Known Issues (do not re-litigate) -### Key Files +1. **bw "native" binary is a Node.js SEA** — prints Node errors on crash. + CMMC/ITAR zero-Node goal is not actually met. Needs a Charles decision. +2. **Gitea stale tokens** from session 1 may exist for vp-techops — cleanup + pending (revoke all but the stored one). +3. **Repos can't be pushed** — TSGCOO has no Gitea auth yet. All commits + are local. Wire TSGCOO's Gitea credentials when available. +4. **Discourse User API keys are user-scoped** — admin operations still + need an admin key (assign to vp-techops per STATUS.md inbox). -- `provision-agent.py` — main Playwright automation (~850 lines, lots of debug dumps) -- `bw_helper.py` — BW CLI wrapper with safety guarantees (no delete, duplicate prevention, update in place) -- `agents.yaml` — manifest with real vp-techops invite link -- `Dockerfile` — Playwright base + native bw binary + python3-pip + non-root user -- `docker-compose.yml` — env_file for BW creds, bind mounts for state -- `test_bw_helper.py` — 10 credential lifecycle tests (tests 1-4 verified passing) +## Mistakes to Avoid (carried forward) ---- - -## The SSO Pattern (Proven for Gitea) - -All Cloudron-managed apps use the same SSO pattern: - -1. **Login to Cloudron panel first** (`cloudron_panel_login()`) to establish OIDC session -2. **Navigate to app login page**, click SSO/OAuth button -3. **Cloudron OIDC handles auth** — may show login form (if session expired) or consent page -4. **Redirect back to app** authenticated - -### Cloudron UI Technical Details - -- Cloudron uses **Pankow/Vue** components -- Login form: `#inputUsername`, `#inputPassword`, `#inputTotp` (for 2FA) -- Submit button is `
Log in
` — NOT a `