Skip to content

feat(pairing): add revocable paired access - #671

Merged
jamesbrink merged 1 commit into
mainfrom
feat/paired-host-access-management
Aug 3, 2026
Merged

feat(pairing): add revocable paired access#671
jamesbrink merged 1 commit into
mainfrom
feat/paired-host-access-management

Conversation

@jamesbrink

Copy link
Copy Markdown
Member

Summary

  • issue a distinct, digest-only persisted credential for every paired mobile client instead of copying the operator API key
  • add operator-only APIs and shared web/desktop Settings UI to list activity and revoke paired access with a two-step confirmation
  • scope grants to the exact persistent server instance, preserve them across restarts, and prevent paired clients from minting or managing other grants
  • identify iPhone/iPad claims and document the updated pairing contract

User impact

Operators can now see which devices are paired and revoke one device without rotating the server API key or disrupting other clients. Revocation blocks new authenticated requests; already-issued media links retain their existing 15-minute expiry.

Validation

  • nix flake check
  • bun run check:frontend
  • bun run build:mobile
  • cargo test -p mold-ai-db -p mold-ai-server (1,240 server tests passed before one existing queue timeout; the isolated timeout passed immediately)
  • focused database, pairing/auth authority, two-instance isolation, and frontend race tests
  • cargo clippy -p mold-ai-db -p mold-ai-server --all-targets -- -D warnings
  • live web UAT: pair, list, two-step revoke, revoked-key 401, restart persistence, responsive 390x844 layout
  • live shared-database UAT: paired key accepted only by its owning server instance, rejected by a sibling port, retained after owner restart, and rejected after revoke
  • independent subagent security/UX review and clean follow-up review

Copilot AI review requested due to automatic review settings August 3, 2026 02:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new pairing/auth model where each paired mobile client receives its own revocable credential (persisted by digest), plus operator-only APIs and shared Settings UI (web + desktop) to inspect and revoke paired access without rotating the operator API key.

Changes:

  • Server: mint per-client mold_pair_... credentials on claim, persist only SHA-256 digests in a new paired_clients table, and expose operator-only list/revoke endpoints.
  • UI: replace the old pairing card with a combined pairing + access-management panel (list + two-step revoke) in web and desktop Settings.
  • Mobile + docs: identify iPhone/iPad in pairing claims and document the updated pairing contract.

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
web/src/pages/SettingsPage.vue Swaps pairing UI to the new shared access-management panel.
web/src/pages/SettingsPage.test.ts Updates fetch stubs for the new /api/pairing/clients call.
studio/components/PairingAccessPanel.vue New shared panel combining pairing + client grant listing/revocation.
studio/components/PairingAccessPanel.test.ts Adds UI tests for listing, revoke confirmation, and race handling.
studio/components/MobilePairingCard.vue Emits sessionCreated so the parent can poll for new claims; tightens prop typing.
studio/api/pairing.ts Adds client identity to claim requests + operator APIs for list/revoke.
studio/api/pairing.test.ts Tests claim identity payload (and that the response key isn’t echoed back).
desktop/src/views/SettingsView.vue Swaps pairing UI to the new shared access-management panel.
desktop/src/views/SettingsView.test.ts Mocks the new panel component.
desktop/src/mobile/MobileApp.vue Sends iPhone vs iPad identity when redeeming pairing codes.
desktop/src/mobile/MobileApp.test.ts Updates expectations for the new claim arguments.
desktop/docs/server-api.md Documents per-client credentials and operator list/revoke endpoints.
crates/mold-server/src/routes.rs Adds new pairing management routes + request/response schema updates + tests.
crates/mold-server/src/lib.rs Loads API keys with access to metadata DB + instance id for paired-client persistence.
crates/mold-server/src/auth.rs Implements operator vs paired-client auth, minting, persistence, and revocation.
crates/mold-db/src/paired_clients.rs New DB helper for paired-client CRUD + activity touch + revoke.
crates/mold-db/src/migrations.rs Adds schema v16 creating the paired_clients table + index.
crates/mold-db/src/lib.rs Exposes the new paired_clients module.
bun.nix Formatting-only change.
apps/mobile/README.md Documents the new per-client credential behavior and operator revoke APIs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/mold-db/src/paired_clients.rs
Comment thread crates/mold-server/src/auth.rs
@jamesbrink
jamesbrink force-pushed the feat/paired-host-access-management branch from becac24 to d132e1c Compare August 3, 2026 02:26
@jamesbrink
jamesbrink enabled auto-merge (squash) August 3, 2026 02:26
@jamesbrink
jamesbrink merged commit 9beaf78 into main Aug 3, 2026
18 checks passed
@jamesbrink
jamesbrink deleted the feat/paired-host-access-management branch August 3, 2026 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants