Feature: Device Sub-Keys #15
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#15
Original Author: @icub3d
Original Date: 2026-04-15T14:15:39Z
Feature: Device Sub-Keys
Overview
Device sub-keys allow a user to authenticate from multiple devices without sharing their master private key. Each device generates its own Ed25519 key pair and receives a delegation certificate signed by the master key. Servers verify the delegation chain to accept device-key-signed operations. Devices can be listed and individually revoked without affecting the user's identity.
Background
The identity design doc (
docs/design/identity.md, "Multiple Devices" section) defines the device key model. A device key is authorized by a delegation certificate signed by the master key:The server accepts operations signed by a device key if it can verify the delegation chain back to the trusted master public key. This means the master key can stay offline after initial setup, and a compromised device key has limited blast radius.
Phase 1 identity (#4) and auth (#5) established master key generation and challenge-response authentication. This feature extends that to support device keys alongside master keys.
Requirements
Design
API / Interface Changes
REST endpoints (all under
/api/v1/):/devices/devices/devices/:device_pubkeyPOST
/devicesrequest body:Modified auth flow: The
POST /auth/verifyendpoint accepts an additional optional field:If
delegation_certificateis present, the server verifies the chain instead of requiring the pubkey to match a known master key directly.Gateway events:
DEVICE_ADD— new device registered (sent to the user's other sessions)DEVICE_REVOKE— device revoked (sent to all sessions; revoked device's session is terminated)Tauri IPC commands:
generate_device_key— generate a new Ed25519 key pair for this device and store in keychaincreate_delegation_certificate— sign a delegation cert with the master key (requires master key to be available on this device)sign_with_device_key— sign a challenge with the device's keyget_device_pubkey— return this device's public keyData Model Changes
New table:
Component Changes
Server (
server/):server/src/models/device_key.rs— DeviceKey, DelegationCertificate structs; canonical serialization format for signingserver/src/services/delegation.rs— Delegation certificate verification logic: parse cert, verify master signature, check expiry, check revocationserver/src/store/device_key_store.rs—DeviceKeyStoretraitserver/src/store/sqlite/device_key_store.rs— SQLite implementationserver/src/routes/devices.rs— REST handlers for device registration, listing, revocationserver/src/routes/auth.rs— Extend challenge-response to accept device key + delegation certificateserver/src/middleware/auth.rs— Session tokens issued to device keys carry the user's identity (master pubkey) as the principalserver/src/gateway/mod.rs— On device revocation, terminate any active sessions for that device keyShared types (
shared/):shared/src/delegation.rs— DelegationCertificate struct and canonical serialization shared between server and client Rust codeClient (Tauri core,
client/src-tauri/):client/src-tauri/src/commands/device_key.rs— Tauri IPC commands for device key generation, delegation cert creation, device signingclient/src-tauri/src/commands/auth.rs— Support auth flow with device key: sign challenge with device key, attach delegation certificateClient (React,
client/src/):client/src/api/devices.ts— API client functions for device endpointsclient/src/components/settings/DeviceList.tsx— List of registered devices with revoke buttonclient/src/components/settings/AddDevice.tsx— Flow for registering the current device (generate key, create cert, submit to server)Database migrations:
server/migrations/NNNN_create_device_keys.sqlTask List
Shared
shared/src/delegation.rsServer
DeviceKeyStoretrait to the storage trait hierarchydevice_keystableDeviceKeyStorefor the SQLite backend/deviceshandler: validate cert signature, store delegation/deviceshandler: list active (non-revoked, non-expired) device keys for the authenticated user/devices/:device_pubkeyhandler: mark as revoked (requires master key auth)/auth/challengeto accept device pubkeys (challenge issued per pubkey, works for any key)/auth/verifyto accept device key signature + delegation certificate; verify chain before issuing session tokensend_to_user)Client (Tauri core)
generate_device_keyIPC command: generate Ed25519 key pair, store in OS keychaincreate_delegation_certificateIPC command: construct cert struct, sign with master key, return signed certsign_with_device_keyIPC command: sign arbitrary bytes with the device keyget_device_pubkeyIPC commandClient (React)
Test List
Open Questions