Document Phase 2.5 ownership and concurrency

This commit is contained in:
Morten V. Christiansen 2026-04-25 01:33:16 +02:00
parent 4b0b126bf9
commit 46fb878f8d
3 changed files with 65 additions and 7 deletions

View File

@ -88,6 +88,17 @@ Notes:
- Use `--cacert /home/user/chromecard/tls/phase2/ca.crt` for TLS verification in `curl`-based checks. - Use `--cacert /home/user/chromecard/tls/phase2/ca.crt` for TLS verification in `curl`-based checks.
- Raw VM-IP routing is not the validated path for the current prototype. - Raw VM-IP routing is not the validated path for the current prototype.
## Ownership And Concurrency
- `k_proxy` is authoritative for session state.
- `k_server` is authoritative for the protected counter state.
- Sessions are in-memory only in `k_proxy` and are lost on proxy restart.
- The protected counter is in-memory only in `k_server` and resets on server restart.
- Both services use `ThreadingHTTPServer`.
- `k_proxy` guards its session store with a single process-local lock.
- `k_server` guards counter increments with a single process-local lock.
- Qubes localhost forwarders are transport plumbing only; they are not a source of state authority.
## Test Flow ## Test Flow
Use the proxy port that matches the mode you started: Use the proxy port that matches the mode you started:
@ -98,7 +109,7 @@ Use the proxy port that matches the mode you started:
Create a session (runs auth gate once): Create a session (runs auth gate once):
```bash ```bash
curl -sS -X POST http://127.0.0.1:<proxy-port>/session/login \ curl -sS --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/session/login \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{"username":"alice"}' -d '{"username":"alice"}'
``` ```
@ -112,30 +123,30 @@ TOKEN='<paste-token>'
Check session: Check session:
```bash ```bash
curl -sS -X POST http://127.0.0.1:<proxy-port>/session/status \ curl -sS --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/session/status \
-H "Authorization: Bearer $TOKEN" -H "Authorization: Bearer $TOKEN"
``` ```
Call protected resource multiple times (should not require new login): Call protected resource multiple times (should not require new login):
```bash ```bash
curl -sS -X POST http://127.0.0.1:<proxy-port>/resource/counter \ curl -sS --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/resource/counter \
-H "Authorization: Bearer $TOKEN" -H "Authorization: Bearer $TOKEN"
curl -sS -X POST http://127.0.0.1:<proxy-port>/resource/counter \ curl -sS --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/resource/counter \
-H "Authorization: Bearer $TOKEN" -H "Authorization: Bearer $TOKEN"
``` ```
Logout/invalidate: Logout/invalidate:
```bash ```bash
curl -sS -X POST http://127.0.0.1:<proxy-port>/session/logout \ curl -sS --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/session/logout \
-H "Authorization: Bearer $TOKEN" -H "Authorization: Bearer $TOKEN"
``` ```
Re-check after logout (should fail with 401): Re-check after logout (should fail with 401):
```bash ```bash
curl -i -X POST http://127.0.0.1:<proxy-port>/resource/counter \ curl -i --cacert /home/user/chromecard/tls/phase2/ca.crt -X POST https://127.0.0.1:<proxy-port>/resource/counter \
-H "Authorization: Bearer $TOKEN" -H "Authorization: Bearer $TOKEN"
``` ```
@ -143,4 +154,5 @@ curl -i -X POST http://127.0.0.1:<proxy-port>/resource/counter \
- This uses card-presence probing, not a full WebAuthn assertion verification path. - 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. - Intended as a Phase 5 starter for session semantics and proxy/server behavior.
- For the split-VM chain, the current blocker is not the Python prototype logic; it is refused `qubes.ConnectTCP` forwarding for the chain ports. - Session and counter state are currently process-local only; restart loses state.
- Upstream trust still relies on a shared static `X-Proxy-Token`.

View File

@ -277,6 +277,33 @@ Session note (2026-04-25, Phase 2 HTTPS bring-up):
- second protected counter call returned value `2` - second protected counter call returned value `2`
- session status remained valid after reuse - session status remained valid after reuse
Session note (2026-04-25, Phase 2.5 ownership and concurrency):
- Current prototype state ownership is now explicit:
- `k_proxy` is authoritative for session state
- `k_server` is authoritative for protected resource state
- `k_client` is not authoritative for either session validity or counter/resource state
- Current session model in `k_proxy`:
- server-side in-memory session store only
- opaque bearer token generated by `secrets.token_urlsafe(32)`
- per-session fields are `username` and `expires_at`
- expiry is enforced in `k_proxy`; `k_server` does not validate client sessions directly
- Current resource model in `k_server`:
- in-memory monotonic counter guarded by a lock
- access allowed only when request arrives from `k_proxy` with the expected `X-Proxy-Token`
- Current concurrency model in code:
- both services use `ThreadingHTTPServer`
- `k_proxy` protects session-map mutations and garbage collection with a single lock
- `k_server` protects counter increments with a single lock
- TLS verification and upstream fetches happen outside the session lock in `k_proxy`
- Current runtime assumptions and limits:
- Qubes localhost forwarders are treated as transport plumbing, not as state authorities
- if `k_proxy` restarts, in-memory sessions are lost
- if `k_server` restarts, the in-memory counter resets
- the current shared `X-Proxy-Token` is a prototype trust mechanism, not a final authorization design
- Practical meaning:
- race-free behavior is currently defined for session CRUD and counter increments inside one process per VM
- persistence, distributed session authority, and multi-proxy/multi-server coordination are not implemented yet
Session note (2026-04-25, in-VM forwarding test): Session note (2026-04-25, in-VM forwarding test):
- Tested the intended in-VM forwarding path with `qvm-connect-tcp` instead of host-side `qrexec-client-vm`. - Tested the intended in-VM forwarding path with `qvm-connect-tcp` instead of host-side `qrexec-client-vm`.
- Forwarders start and bind locally: - Forwarders start and bind locally:

View File

@ -130,6 +130,25 @@ Next action (2026-04-25):
- localhost Qubes forwarders are part of the active runtime model for the two TLS hops - localhost Qubes forwarders are part of the active runtime model for the two TLS hops
- define concurrency assumptions and limits around session store, forwarders, and counter access - define concurrency assumptions and limits around session store, forwarders, and counter access
Status (2026-04-25):
- Current ownership model is now explicit:
- `k_proxy` is authoritative for session creation, expiry, lookup, and logout
- `k_server` is authoritative for the protected monotonic counter
- `k_client` is a client only; it holds bearer tokens but is not a state authority
- Current validation boundary is explicit:
- `k_proxy` validates bearer tokens against its in-memory session store
- `k_server` trusts only requests that arrive with the configured `X-Proxy-Token`
- `k_server` does not currently validate end-user session tokens directly
- Current concurrency strategy is explicit:
- `k_proxy` uses `ThreadingHTTPServer` plus one lock around the in-memory session map
- `k_server` uses `ThreadingHTTPServer` plus one lock around counter increments
- upstream HTTPS calls from `k_proxy` are made outside the session-store lock
- Current runtime limits are explicit:
- sessions are process-local and disappear on `k_proxy` restart
- counter state is process-local and resets on `k_server` restart
- transport relies on Qubes localhost forwarders `9771` and `9780`
- Phase 2.5 is complete for the current prototype shape.
## Phase 3: Recover Basic Device Visibility on `k_proxy` (Blocking) ## Phase 3: Recover Basic Device Visibility on `k_proxy` (Blocking)
1. Verify physical + USB enumeration path. 1. Verify physical + USB enumeration path.