Phase 3 — Secure Remote Backend¶
Status: scaffold landed (2026-04-24, pccx-remote crate + OpenAPI draft); implementation kicks off in Phase 3 proper.
Scope: roadmap Weeks 10-13; milestones M3.1 - M3.6.
Target experience: “GitHub Codespaces, but 100% secure” — install pccx-remote on a workstation, connect from a laptop, session indistinguishable from local.
1. Threat model¶
Attack surface = auth layer + tunnel + session isolation. Three adversaries to model:
Adversary |
Capability |
Mitigation |
|---|---|---|
Network attacker (MITM) |
passive + active on any path between client & server |
mTLS-over-QUIC, hardware-bound device keys, no cleartext anywhere |
Compromised endpoint |
runs arbitrary code on one side |
OIDC + hardware 2FA, per-session sandbox, kill-switch |
Insider (same org) |
valid credentials, elevated intent |
per-project RBAC, append-only audit log replicated off-box |
STRIDE applied to each protocol message: spoofing countered by device
user dual auth; tampering by QUIC AEAD; repudiation by audit log; information disclosure by per-project encryption at rest; denial of service is rate-limited at the tunnel entrypoint; EoP gated by RBAC.
2. Tunnel¶
Default: WireGuard. Well-understood threat model, built-in key rotation, zero configuration surprise. Fallback: mTLS over QUIC (for networks that block UDP or require TCP egress).
Device keys are Curve25519, generated inside a hardware token (YubiKey / TPM 2.0) and never exported. Loss of the token = revocation via audit log.
Peer list authenticated by OIDC identity — WireGuard AllowedIPs tied to user + session, not to IP.
Keepalive 25s; idle sessions auto-terminate after 30 min (configurable).
3. Auth layer¶
3.1 OIDC + hardware 2FA¶
Client redirects to the configured OIDC provider (Google Workspace / Azure AD / Authentik).
JWT returned, then augmented with a WebAuthn challenge satisfied by the hardware token.
Session issued as a Ed25519-signed bearer token with a 12-hour hard expiry + 30-min sliding expiry.
3.2 RBAC¶
Three roles today:
owner,maintainer,viewer.Per-project scoping via the
projectsclaim in the session token.All reads/writes check
can(user, project, action)via a tiny Casbin-style policy table in pccx-remote.
4. Session isolation¶
Each session gets:
A process namespace (pid, net, mount) — systemd user scope.
An overlayfs sandbox rooted at
/var/lib/pccx-remote/sessions/<uuid>/. Reads fall through to the project tree; writes stay in the overlay and are squashed or discarded at session end.CPU + memory cgroup (configurable per project).
Network access defaults to deny-all — session opts in per tool (e.g.
cargo fetchrequires an explicit allow entry in project config).
Kill-switch: DELETE /v1/sessions/{id} or the audit log’s “revoke”
event yanks the namespace in ~100 ms.
5. REST + WebSocket surface¶
Already drafted in crates/remote/openapi.yaml. Five endpoint families:
Family |
Prefix |
Purpose |
|---|---|---|
Auth |
|
OIDC login kickoff + session refresh |
Sessions |
|
Open / list / kill sessions |
Traces |
|
Upload .pccx, stream verification verdict |
Reports |
|
Fetch rendered report |
Events |
|
WebSocket audit-log subscription |
All paths require the bearerAuth + deviceKey security combination.
6. Milestones¶
M3.1 — Daemon + tunnel (Week 10)¶
pccx-remotebinary skeleton (Tokio + Axum).WireGuard control plane via
boringtun-rs(userspace impl).Device-key registration flow; first end-to-end handshake.
M3.2 — Auth (Week 11)¶
OIDC redirect flow (via
oxide-authoropenidconnect).WebAuthn challenge + verification (via
webauthn-rs).RBAC policy table +
can(...)predicate.
M3.3 — Zero-trust posture (Week 11)¶
Every request signed; signature verified by the receiving side.
Append-only audit log (SQLite with FTS, replicated to S3-compatible store).
M3.4 — Session manager (Week 12)¶
overlayfs sandbox + cgroup v2 resource limits.
Multi-concurrent sessions per user.
Kill-switch latency SLA < 200 ms.
M3.5 — Web client (Week 12)¶
GATED on M3.1-M3.3 complete. No remote UI before the auth layer lands.
WASM build of pccx-ide’s data-plane surfaces (trace viewer, report panel) — full IDE feature parity deferred to Phase 4.
M3.6 — External pentest + STRIDE review (Week 13)¶
Hire an external auditor for a 1-week engagement.
STRIDE threat model delivered as a tracked doc.
Any CRITICAL / HIGH finding blocks Phase 3 close.
7. Crypto choices¶
No innovation. Only proven primitives.
WireGuard → ChaCha20-Poly1305 + Curve25519 + BLAKE2s (standard).
JWT → Ed25519 signatures.
At-rest per-project encryption → age (XChaCha20-Poly1305 + X25519).
TOTP deprecated in favour of WebAuthn (TOTP code interception has been exploited at scale).
8. Non-goals¶
Multi-tenant SaaS. pccx-remote is single-operator, self-hosted.
Streaming video of the remote session (RDP-style). The native Tauri client renders locally from typed IPC messages only.
Windows host. Linux primary, macOS best-effort; Windows sessions are client-only.
9. Open questions¶
YubiKey vs TPM for device keys: YubiKey is portable (one token works on multiple workstations); TPM is built-in but non-portable. Recommend: YubiKey default, TPM fallback behind config flag.
Audit log storage: SQLite WAL on the box + nightly S3 replication, vs. real-time shipping to S3. Real-time is more secure (insider can’t tamper in-flight) but adds an SPoF. Resolve at M3.3.