diff --git a/PHASE5_RUNBOOK.md b/PHASE5_RUNBOOK.md index 08d415c..ead85d2 100644 --- a/PHASE5_RUNBOOK.md +++ b/PHASE5_RUNBOOK.md @@ -2,7 +2,7 @@ This runbook starts a minimal `k_server` + `k_proxy` prototype for session reuse testing. -Last updated: 2026-04-25 +Last updated: 2026-04-26 Related browser demo: @@ -218,37 +218,23 @@ Verified result on 2026-04-25: ## Current Limitation -- This uses card-presence probing, not a full WebAuthn assertion verification path. -- Intended as a Phase 5 starter for session semantics and proxy/server behavior. -- Session and counter state are currently process-local only; restart loses state. +- The stable deployed baseline still uses card-presence probing, not full assertion verification, for the default auth gate. +- Session and counter state are still process-local only; restart loses state. - Upstream trust still relies on a shared static `X-Proxy-Token`. -- Experimental direct FIDO2 mode now exists in `k_proxy_app.py` behind `--auth-mode fido2-direct`, but it is not the default runtime: - - direct registration on the current `k_proxy` card/library stack still fails with `No compatible PIN/UV protocols supported!` - - a CTAP1 fallback probe did not complete quickly enough to promote as the working path - - the deployed service was restored to default `probe` mode so the validated Phase 5 chain remains usable -- Raw CTAP debugging helper now exists at `/home/user/chromecard/raw_ctap_probe.py`: +- Experimental direct FIDO2 mode exists in `k_proxy_app.py` behind `--auth-mode fido2-direct`: + - direct `/enroll/register` now succeeds + - direct `/session/login` now succeeds and returns `auth_mode: "fido2_assertion"` + - direct `/session/status`, `/resource/counter`, and `/session/logout` also succeed end-to-end + - the mode remains optional for now; the deployed service was returned to default `probe` mode so the validated Phase 5 baseline stays reproducible +- Raw CTAP debugging helper exists at `/home/user/chromecard/raw_ctap_probe.py`: - use it on `k_proxy` to exercise low-level `makeCredential` / `getAssertion` - it logs keepalive callbacks and transport exceptions -- Current blocker before the next direct-auth attempt: - - `k_proxy` currently has no visible `/dev/hidraw*` - - `python3 /home/user/chromecard/fido2_probe.py --list` in `k_proxy` returns `No CTAP HID devices found.` - - restore card visibility first, then retry the raw CTAP probe and stop to tell the user when to press `yes` or `no` -- Latest retry after card reattach: - - `/dev/hidraw0` and `/dev/hidraw1` are visible in `k_proxy` again - - `/dev/hidraw0` opens successfully as the normal user, but `/dev/hidraw1` is still permission-denied - - raw `makeCredential` still shows no card prompt, so the hang is before the firmware confirmation UI - - hidraw inspection confirms `/dev/hidraw0` is the real FIDO interface and `/dev/hidraw1` is a separate vendor HID interface - - manual CTAPHID `INIT` written directly to `/dev/hidraw0` gets no reply at all within `3s` - - rerunning `webauthn_local_demo.py` inside `k_proxy` also shows no card prompt on register - - next step is to recover the USB/Qubes transport path before retrying direct auth - - after a full power cycle and reattach, manual CTAPHID `INIT` replies again and `webauthn_local_demo.py` registration succeeds again - - direct `raw_ctap_probe.py --device-path /dev/hidraw0 make-credential --rp-id localhost` also succeeds again after pressing `yes` on the card - - `k_proxy_app.py --auth-mode fido2-direct` was patched to use low-level CTAP2 and to auto-detect the working `/dev/hidraw*` node when the card re-enumerates - - after additional fixes for hidraw lifetime, VM-side `python-fido2` response mapping, and CTAP payload shape, `/enroll/register` now succeeds again for `directtest` - - `/session/login` for `directtest` now also succeeds after card confirmation and returns `auth_mode: "fido2_assertion"` - - `/session/status` succeeds - - protected `/resource/counter` succeeds again through `k_proxy -> k_server` - - `/session/logout` succeeds - - post-logout protected access returns `401` - - temporary direct-mode hidraw lifetime logging was removed again after diagnosis - - `phase5_chain_regression.sh` now supports card-interactive direct auth via `--interactive-card --expect-auth-mode fido2_assertion` +- `phase5_chain_regression.sh` now supports card-interactive direct auth via: + - `--interactive-card` + - `--expect-auth-mode fido2_assertion` + +## Current Focus + +- Keep the HTTPS split-VM chain reproducible in default `probe` mode. +- Decide whether `fido2-direct` is ready to become the default deployed auth path. +- Continue Phase 6.5 concurrency work; the active system limit is still higher-fan-out Qubes forwarding on the browser-facing path rather than basic Phase 5 functionality. diff --git a/Setup.md b/Setup.md index 2c062ef..b8eae2e 100644 --- a/Setup.md +++ b/Setup.md @@ -1,6 +1,6 @@ # Setup -Last updated: 2026-04-25 +Last updated: 2026-04-26 This is a living setup/status file for the local ChromeCard workspace at `/home/user/chromecard`. Update this file whenever environment status or verified behavior changes. @@ -611,6 +611,26 @@ Session note (2026-04-25, direct FIDO2 auth attempt): - the deployed `k_proxy` service was restored to default `probe` mode - verified `alice` login still works afterward, so the validated Phase 5 baseline remains intact +Session note (2026-04-26, markdown maintenance re-scan): +- Re-read the maintained workspace markdown set: + - `/home/user/chromecard/Setup.md` + - `/home/user/chromecard/Workplan.md` + - `/home/user/chromecard/PHASE5_RUNBOOK.md` +- Re-checked that the currently referenced runtime artifacts still exist in the workspace: + - `k_proxy_app.py` + - `k_server_app.py` + - `k_client_portal.py` + - `phase5_chain_regression.sh` + - `raw_ctap_probe.py` + - `generate_phase2_certs.py` + - `tls/phase2/ca.crt` + - `tls/phase2/k_proxy.crt` + - `tls/phase2/k_server.crt` +- Current documentation conclusion: + - the workspace still supports the HTTPS localhost-forwarded split-VM chain as the active baseline + - direct FIDO2 enrollment/login support exists in code and is documented as an optional follow-up path, not the default deployed runtime + - the main unresolved engineering limit is still the higher-fan-out Qubes forwarding ceiling on the browser-facing path, not basic chain bring-up + ## Known FIDO2 Transport Boundary - FIDO2 on this firmware is handled via USB HID (CTAPHID), not Wi-Fi/BLE/MQTT. diff --git a/Workplan.md b/Workplan.md index ded6c01..9c99a22 100644 --- a/Workplan.md +++ b/Workplan.md @@ -1,6 +1,6 @@ # Workplan -Last updated: 2026-04-25 +Last updated: 2026-04-26 This is the execution plan for making ChromeCard FIDO2 development and validation reproducible on this machine. @@ -299,8 +299,7 @@ Status (2026-04-25): - Browser traffic goes only to `k_proxy`. Immediate next action: -Immediate next action: -- Preserve the now-working direct auth path and record it as the current baseline. +- Preserve the now-working direct auth path as a tested option while keeping the default deployed baseline stable. - Verified end-to-end state: - direct `/enroll/register` succeeds for `directtest` - direct `/session/login` succeeds for `directtest` @@ -311,6 +310,7 @@ Immediate next action: - Next work should be cleanup/hardening: - decide whether to keep `directtest` enrollment - rerun `phase5_chain_regression.sh --interactive-card --expect-auth-mode fido2_assertion` against the current direct-auth baseline + - decide when `fido2-direct` should replace `probe` as the default deployed auth mode Exit criteria: - Enrollment and login both function end-to-end via `k_client -> k_proxy -> k_server`. @@ -549,11 +549,21 @@ Exit criteria: ## Current Next Step -- Resolve the direct-registration blocker for `--auth-mode fido2-direct` in `k_proxy`. -- Candidate directions: - - determine whether the current card can support the required PIN/UV path for direct CTAP2 registration from `python-fido2` - - or provide a different one-time enrollment route that yields persistent real credential material for later direct assertion verification -- Keep the new regression helper as the fast check that transport, session reuse, and counter semantics still hold after each change. +- Treat the default HTTPS split-VM chain as the stable baseline and keep validating it with `/home/user/chromecard/phase5_chain_regression.sh`. +- Push the next engineering cycle toward Phase 6.5 limits: + - reproduce and narrow the `~10` in-flight request ceiling on the browser-facing `k_client -> k_proxy` Qubes forward + - separate Qubes forwarding churn from app-level issues with targeted concurrency probes and log capture +- In parallel, decide whether `--auth-mode fido2-direct` is ready to become the default deployed path or should remain an optional/operator mode. +- Keep the regression helpers as the fast check that transport, auth, session reuse, and counter semantics still hold after each change. + +Status (2026-04-26, markdown maintenance): +- Re-scanned `Setup.md`, `Workplan.md`, and `PHASE5_RUNBOOK.md` against the current workspace files. +- Updated the plan to match the verified state: + - direct FIDO2 auth is no longer the primary blocker because register/login/logout already work in the experimental path + - the main open system limit is concurrency/fan-out on the Qubes-forwarded browser path + - the current planning split is now: + - baseline path: keep `probe` mode stable and reproducible + - follow-up path: decide whether to promote `fido2-direct` ## Inputs Expected During This Session