Document Phase 2.5 ownership and concurrency
This commit is contained in:
parent
4b0b126bf9
commit
46fb878f8d
|
|
@ -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`.
|
||||||
|
|
|
||||||
27
Setup.md
27
Setup.md
|
|
@ -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:
|
||||||
|
|
|
||||||
19
Workplan.md
19
Workplan.md
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue