Part 02 — Multi-Device Identity Architecture

Reusable P2P Communication Platform

Status: Architecture specification
Part: 02 of 24
Primary language: Rust
Primary goals: multi-device accounts, cryptographic separation, secure linking, revocation, recovery, portability, reuse across messaging/files/emergency/ERP products


1. Purpose

The communication platform must not model a person, organization, or application identity as a single device key.

A modern user may have:

phone
laptop
desktop
tablet
secondary phone
headless node

and all of them may belong to the same logical identity.

The architecture must therefore distinguish:

Account Identity
Device Identity
Transport Identity
Session Identity
Application Profile

These are related, but they are not the same thing.

The multi-device identity system must support:

  • secure device linking
  • independent device keys
  • multiple active devices
  • device-specific transport addresses
  • device revocation
  • account recovery
  • key rotation
  • cross-device synchronization
  • sender-device attribution
  • per-device trust
  • per-device capabilities
  • offline pairing
  • QR/NFC bootstrap
  • enterprise/organization use
  • application namespaces
  • future headless nodes

The identity layer must remain reusable outside the messenger.


2. Fundamental Identity Model

The central model is:

Logical Identity
      │
      ├── Device A
      │     ├── identity key
      │     ├── transport identity
      │     └── session state
      │
      ├── Device B
      │     ├── identity key
      │     ├── transport identity
      │     └── session state
      │
      └── Device C
            ├── identity key
            ├── transport identity
            └── session state

Never model:

one user = one long-lived private key

That creates weak revocation and recovery semantics.


3. Identity Layers

The architecture should expose at least five layers.

3.1 Account Identity

Represents the long-lived logical principal.

Examples:

person
organization
service account
emergency authority
business unit

3.2 Device Identity

Represents one independently revocable device.

3.3 Transport Identity

Represents transport-specific addressing/cryptographic identity.

Example:

Iroh EndpointId

3.4 Session Identity

Represents ephemeral authenticated communication state.

3.5 Application Profile

Represents non-cryptographic user-facing data:

display name
avatar
status
organization role

Do not collapse these layers.


4. Strong Type Model

Recommended types:

#![allow(unused)]
fn main() {
pub struct AccountId([u8; 32]);
pub struct DeviceId([u8; 16]);
pub struct IdentityKeyId([u8; 32]);
pub struct TransportIdentityId([u8; 32]);
pub struct SessionId([u8; 16]);
pub struct DeviceCertificateId([u8; 32]);
}

Do not use:

#![allow(unused)]
fn main() {
String
}

for every identifier.

Strong types prevent accidental cross-use.


5. Account Identity

The account identity is the durable logical principal.

It should be stable across device replacement.

Conceptually:

#![allow(unused)]
fn main() {
pub struct AccountIdentity {
    pub account_id: AccountId,
    pub root_public_key: PublicKey,
    pub generation: u64,
}
}

The root private key should not necessarily be online continuously.

For stronger security, consider:

root identity key
    ↓
signs device certificates

rather than:

root key used for every message/session

6. Root Key Strategy

Recommended architecture:

Root Identity Key
        │
        ├── signs Device Certificate A
        ├── signs Device Certificate B
        └── signs Device Certificate C

The root key is used rarely.

Benefits:

  • easier device revocation
  • easier auditing
  • less exposure
  • better recovery
  • device independence

The root key may be:

hardware-protected
recovery-derived
offline-backed-up

depending on product mode.


7. Device Identity

Each device gets its own keypair.

#![allow(unused)]
fn main() {
pub struct DeviceIdentity {
    pub account_id: AccountId,
    pub device_id: DeviceId,
    pub signing_public_key: PublicKey,
    pub device_certificate: DeviceCertificate,
}
}

The device private key:

  • never leaves the device under normal operation
  • is stored in secure storage
  • can be revoked independently
  • signs device-level operations

8. Device Certificate

A device certificate binds:

Account
   ↓
Device
   ↓
Device public key

Conceptually:

#![allow(unused)]
fn main() {
pub struct DeviceCertificate {
    pub account_id: AccountId,
    pub device_id: DeviceId,
    pub device_public_key: PublicKey,
    pub issued_at: Timestamp,
    pub expires_at: Option<Timestamp>,
    pub capabilities: DeviceCapabilitySet,
    pub generation: u64,
    pub signature: Signature,
}
}

The signature is made by the account root or authorized linking authority.


9. Device Certificate Semantics

The certificate proves:

This device key belongs to this logical account.

It does not automatically prove:

this device is currently trusted
this device is not revoked
this device may perform every operation

Revocation and authorization are separate checks.


10. Transport Identity

Transport identities must not become account identity.

For Iroh:

EndpointId

should be treated as:

transport address/identity

not:

user identity

A device descriptor can bind them:

#![allow(unused)]
fn main() {
pub struct DeviceEndpoint {
    pub device_id: DeviceId,
    pub transport: TransportKind,
    pub transport_identity: TransportIdentity,
    pub expires_at: Option<Timestamp>,
    pub signature: Signature,
}
}

11. Why Transport Identity Must Be Separate

Transport identities may change because of:

  • reinstall
  • key rotation
  • migration
  • different transport implementation
  • temporary relay identity
  • privacy rotation

The account identity should remain stable.


12. Application Profile Separation

User profile:

#![allow(unused)]
fn main() {
pub struct AccountProfile {
    pub display_name: DisplayName,
    pub avatar: Option<BlobId>,
    pub status: Option<StatusText>,
}
}

must not define cryptographic identity.

Changing:

display name
avatar
status

must not rotate identity keys.


13. Device Metadata

Useful metadata:

#![allow(unused)]
fn main() {
pub struct DeviceMetadata {
    pub device_name: DeviceName,
    pub platform: PlatformKind,
    pub device_class: DeviceClass,
    pub capabilities: DeviceCapabilitySet,
    pub created_at: Timestamp,
    pub last_seen: Option<Timestamp>,
}
}

Device names are presentation data.

Never use:

"My Pixel"

as security identity.


14. Device Capability Set

Examples:

messaging
files
calls
AV1 hardware decode
AV1 hardware encode
H264 hardware
H265 hardware
Bluetooth
Wi-Fi Aware
DTN relay
headless node

Capabilities can change.

Therefore:

capabilities are signed state
not permanent identity

15. Linking a New Device

Core flow:

Existing trusted device
        ↓
Generate linking invitation
        ↓
New device scans/receives invitation
        ↓
Mutual authentication
        ↓
User verifies
        ↓
New device key generated
        ↓
Device certificate issued
        ↓
Device added to account state
        ↓
Other devices learn update

The linking process must not transmit existing device private keys.


16. Device Linking Invitation

A linking invitation should be:

#![allow(unused)]
fn main() {
pub struct DeviceLinkInvite {
    pub account_id: AccountId,
    pub inviter_device: DeviceId,
    pub ephemeral_link_key: PublicKey,
    pub expires_at: Timestamp,
    pub nonce: [u8; 16],
    pub signature: Signature,
}
}

It must be:

  • short-lived
  • one-time
  • authenticated
  • replay-resistant

17. QR Linking

QR is suitable for offline linking.

QR payload may include:

account id
inviting device id
ephemeral key
expiration
protocol version
short authentication code

The QR should not contain:

private keys
session keys
message history

18. NFC Linking

NFC can be an optional bootstrap mechanism.

Use it to exchange:

ephemeral linking material

not to bypass verification.

NFC proves proximity, not identity.


19. Numeric Verification

For high assurance:

New device shows 6–12 digit code
Existing device shows same code
User compares

The code is derived from the authenticated handshake transcript.

Do not generate an unrelated random code.


20. Linking Trust Decision

The existing device must explicitly approve:

Add "Tablet" to your account?

Show:

device type
platform
approximate time
link method
verification status

Avoid silent device addition.


21. New Device Key Generation

New device generates locally:

device signing key
transport key
session/bootstrap material
local database key

Private keys remain local.

The existing device signs only the new public identity information.


22. Device Addition Event

Represent device lifecycle as signed events.

Example:

#![allow(unused)]
fn main() {
pub enum DeviceEvent {
    Added(DeviceCertificate),
    Revoked(DeviceRevocation),
    Renamed(DeviceRename),
    CapabilityUpdated(DeviceCapabilityUpdate),
    TransportUpdated(DeviceTransportUpdate),
}
}

This creates a clear audit trail.


23. Account Device State

Current state is derived from:

ordered signed device events

or a signed snapshot plus events.

Do not maintain an unverified mutable map without provenance.


24. Device Generation Number

Each account state can include a monotonic generation.

Example:

generation 42

A new device update:

generation 43

This helps detect stale state.

Do not rely solely on wall-clock timestamps.


25. Device Revocation

Revocation is a first-class operation.

Flow:

Trusted device
   ↓
Revoke Device B
   ↓
signed revocation event
   ↓
generation increments
   ↓
sync to all devices
   ↓
future sessions reject Device B

26. Revocation Semantics

Revocation should prevent:

future session establishment
future group key delivery
future device synchronization
future account-authorized operations

It cannot guarantee deletion of data already copied to the revoked device.

Documentation and UI must state this accurately.


27. Immediate Local Revocation

As soon as Device A revokes Device B:

Device A

must immediately:

  • stop sending new data to B
  • stop trusting B
  • remove B from future fan-out
  • update local authorization

Do not wait for a server round trip.


28. Offline Revocation Propagation

If other devices are offline:

revocation event

must propagate later through:

  • direct sync
  • relay/mailbox
  • DTN
  • linked-device synchronization

Revocation state must therefore be durable.


29. Revocation Conflict Rules

Suppose:

Device A revokes B
Device C offline adds some state involving B

Security-sensitive state must prefer:

revocation

once authenticated.

Revoked devices cannot regain authority through stale sync.


30. Device Expiry

Optional device certificates may expire.

Useful for:

temporary device
shared terminal
emergency node
enterprise guest device

Expiration is not a replacement for revocation.


31. Device Rotation

Keys may rotate without changing logical DeviceId.

Flow:

Device key generation N
   ↓
rotation event
   ↓
generation N+1

Old keys become invalid for future authentication.


32. Rotation Reasons

Examples:

scheduled rotation
suspected compromise
secure-storage migration
algorithm upgrade
device OS migration

The system must support rotation before an emergency requires it.


33. Root Key Rotation

Root identity rotation is much more serious.

Architecture should support:

old root
  ↓ signs transition
new root

The transition event must be verifiable.

Never simply replace root key metadata locally.


34. Root Rotation Event

Conceptually:

#![allow(unused)]
fn main() {
pub struct RootRotation {
    pub account_id: AccountId,
    pub old_root: PublicKey,
    pub new_root: PublicKey,
    pub generation: u64,
    pub old_signature: Signature,
    pub new_signature: Signature,
}
}

This provides continuity.


35. Compromised Root Scenario

If the root private key itself is compromised, recovery requires a stronger mechanism.

Possible future strategies:

recovery quorum
trusted-device quorum
offline recovery secret
social recovery
organization authority

Do not claim that ordinary rotation solves a compromised root.


36. Recovery Architecture

Recovery should be designed from the beginning.

Possible modes:

Recovery key
Trusted device
Multi-device quorum
Organization-managed recovery
No recovery

Different products may choose different policies.


37. Recovery Policy Type

#![allow(unused)]
fn main() {
pub enum RecoveryPolicy {
    None,
    RecoverySecret,
    TrustedDeviceQuorum { threshold: u8 },
    OrganizationManaged,
}
}

The core identity system should support policy variation.


38. Recovery Secret

A recovery secret should not simply be:

password → private key

without strong KDF and policy.

Use a hardened derivation and authenticated recovery record.

The recovery secret should normally:

  • recreate account authority
  • not decrypt all past device-local storage automatically
  • require explicit new device issuance

39. Recovery Device Addition

Recovery path:

User loses all devices
   ↓
uses recovery mechanism
   ↓
reestablishes account authority
   ↓
creates new device identity
   ↓
revokes lost devices

Past message recovery is a separate backup problem.

Identity recovery and data backup must not be conflated.


40. Multi-Device Messaging Fan-Out

For 1:1 communication:

Alice Account
├── Phone
├── Laptop
└── Tablet

Bob Account
├── Phone
└── Laptop

When Alice sends to Bob:

Bob Phone
Bob Laptop
Alice's other devices

may each need the event.

The exact cryptographic fan-out mechanism can evolve, but the identity model must expose device membership.


41. Sender Attribution

A message should identify:

logical account
+
originating device

Example:

#![allow(unused)]
fn main() {
pub struct SenderIdentity {
    pub account_id: AccountId,
    pub device_id: DeviceId,
}
}

This enables:

  • auditing
  • compromised-device analysis
  • multi-device sync
  • device-specific receipts

42. Account-Level Presentation

UI can normally display:

Alice

not:

Alice / Pixel 9

Device attribution remains available in:

  • security details
  • diagnostics
  • enterprise audit
  • identity-change warnings

43. Device-Level Receipts

Delivery can occur per device.

Example:

Bob Phone → delivered
Bob Laptop → offline

Account-level UI may aggregate:

Delivered to Bob

according to product policy.

The core should retain device-level truth.


44. Sync Between User's Own Devices

Own-device sync must be explicit.

Examples:

sent messages
read state
contacts
group state
settings
drafts optionally

Do not treat own devices as automatically fully trusted for every application secret.

Per-data-class policy is useful.


45. Device Trust Classes

Possible:

#![allow(unused)]
fn main() {
pub enum DeviceTrustClass {
    Full,
    Limited,
    Temporary,
    Headless,
}
}

Examples:

Primary phone → Full
Laptop → Full
Public kiosk → Limited
Emergency relay → Headless

Applications can constrain synchronization accordingly.


46. Headless Devices

The identity architecture must support:

NAS
Raspberry Pi
home relay
enterprise gateway
emergency node

These may belong to:

user account
organization account
service identity

Do not assume every device has a screen.


47. Service Identities

Some applications need non-human principals.

Example:

school server
emergency authority
automation service
document relay

Use the same identity primitives.

Do not create a completely separate authentication model unless necessary.


48. Organization Identity

An organization may own:

Organization Account
├── server device
├── admin device
├── relay
└── automation node

Authorization is layered above identity.

Identity proves:

this device belongs to this organization principal

Authorization decides:

what it may do

49. Multiple Accounts on One Device

The core should allow:

personal
work
organization

identities on one physical device.

Each requires isolated:

keys
storage namespace
session state
trust graph
device membership

The application may choose whether to expose this feature.


50. Application Namespace

One physical device may run multiple applications using the communication SDK.

Therefore device state should include:

application namespace

where appropriate.

Do not automatically share:

contacts
message history
file access
session state

across applications.


51. Cross-Application Identity Reuse

This should be explicit, not automatic.

Possible modes:

Isolated identity per app
Shared identity with user consent
Organization-managed identity

The default should favor isolation.


52. Device Directory

Each account maintains a signed device directory.

Conceptually:

#![allow(unused)]
fn main() {
pub struct DeviceDirectory {
    pub account_id: AccountId,
    pub generation: u64,
    pub devices: Vec<DeviceDirectoryEntry>,
    pub signature: Signature,
}
}

This can be a compact snapshot derived from events.


53. Device Directory Entry

#![allow(unused)]
fn main() {
pub struct DeviceDirectoryEntry {
    pub device_id: DeviceId,
    pub certificate: DeviceCertificate,
    pub status: DeviceStatus,
    pub transport_endpoints: Vec<DeviceEndpoint>,
}
}

Status:

Active
Revoked
Expired

54. Device Directory Synchronization

A peer should not require a central server to learn device changes.

Possible paths:

direct peer
own-device sync
mailbox
relay
DTN
directory service

The directory is signed, so transport is not trusted for authenticity.


55. Stale Device Directory

A peer may have stale account state.

If a device presents:

newer signed generation

the peer can update.

If a device presents:

older generation

the peer should not roll back.


56. Rollback Protection

Maintain:

highest trusted generation per account

or stronger state continuity.

Never accept:

generation 17

after already trusting:

generation 22

unless a specific recovery protocol authorizes it.


57. Fork Detection

Two conflicting signed account states at the same generation may indicate:

bug
compromise
concurrent invalid update

The system should detect this.

Do not silently choose one.

Raise:

IdentityForkDetected

and require reconciliation/security handling.


58. Concurrent Device Changes

To avoid unnecessary forks, device-state updates should use a defined concurrency model.

Options:

single account authority
quorum
serialized event chain

For initial implementation:

serialized signed account-state chain

is easier to reason about.


59. Account State Chain

Each state event references:

previous_state_hash

Example:

#![allow(unused)]
fn main() {
pub struct AccountStateEvent {
    pub account_id: AccountId,
    pub generation: u64,
    pub prev_hash: StateHash,
    pub event: DeviceEvent,
    pub signature: Signature,
}
}

This creates tamper-evident continuity.


60. Device Linking Authority

Who may add a new device?

Possible policies:

root authority only
any full-trust device
threshold of trusted devices
organization admin

Make this configurable.


61. Default Consumer Policy

For a normal messenger:

existing verified full-trust device

can authorize a new device.

For enterprise:

organization policy

may require admin approval.


62. Link Approval Certificate

If device-to-device approval is allowed, the account architecture must define how a device gains delegation authority.

Example:

root certificate
   ↓
delegates device-link authority

Do not let any device arbitrarily add peers.


63. Device Roles

Possible device roles:

Primary
Standard
Limited
Relay
Recovery
Admin

These are account-level capabilities, not UI labels only.


64. Security Capabilities

A device certificate may include:

can_link_device
can_revoke_device
can_rotate_account_state
can_receive_messages
can_sync_history
can_relay

Use explicit capability semantics.


65. Principle of Least Authority

A headless relay should not need:

account root authority
message decryption keys
device linking authority

It should receive only the minimum credentials required.


66. Multi-Device File Transfer

A file may target:

account
specific device
device group

Examples:

Send to Bob's account
Send only to Bob's laptop
Sync file to all my devices

The identity layer must support device resolution.


67. Account Address vs Device Address

Define:

#![allow(unused)]
fn main() {
pub enum Destination {
    Account(AccountId),
    Device(DeviceId),
    Devices(Vec<DeviceId>),
}
}

The application can choose semantics.

Routing resolves account destinations into active authorized devices.


68. Device Resolution

Flow:

Destination Account
     ↓
Device Directory
     ↓
Active authorized devices
     ↓
Transport endpoints
     ↓
Routing

Do not make the application manually maintain endpoint lists.


69. Fan-Out Policy

Possible policies:

All active devices
Primary device only
Best reachable device
At least one device
Application-defined subset

Messaging may choose:

all relevant devices

Large files may choose:

specific device

70. Own-Device Synchronization Policy

Own-device sync may differ by data type.

Example:

messages → all full devices
settings → selected devices
large files → on demand
drafts → optional
emergency state → all full devices

This policy belongs above identity but uses device metadata.


71. Device Presence

Presence should be device-aware.

Example:

Account Alice:
Phone online
Laptop offline
Tablet nearby

Account-level presence can derive:

Alice reachable

without losing device-level detail internally.


72. Reachability vs Trust

A device may be:

trusted but unreachable
reachable but revoked
reachable but unknown

These are distinct states.

Never combine them into one boolean.


73. Device State Type

#![allow(unused)]
fn main() {
pub struct DeviceState {
    pub trust: DeviceTrustState,
    pub reachability: DeviceReachability,
    pub lifecycle: DeviceLifecycle,
}
}

This makes invalid assumptions harder.


74. Device Lifecycle

PendingLink
Active
Suspended
Revoked
Expired

Suspended can be useful for:

temporarily disabled device
enterprise policy
suspected compromise under investigation

75. Suspension vs Revocation

Suspension:

temporary
reversible

Revocation:

security-significant
normally permanent for that key generation

Do not use the same operation for both.


76. Lost Device Flow

User reports:

Phone lost

System should allow:

revoke lost device
rotate affected conversation/group state
invalidate device sessions
remove device from fan-out

The exact data-key rotation can occur asynchronously.


77. Compromised Device Flow

Stronger than simple loss.

Recommended response:

revoke device
rotate account-sensitive session material
rotate group membership keys
invalidate device tokens
trigger security warning

Do not assume revocation alone erases any keys already obtained.


78. Device Reinstallation

Reinstall should normally create:

new DeviceId
new device key

rather than silently resurrecting the previous device identity.

This makes security history clearer.


79. Device Migration

A deliberate migration can preserve user experience.

Flow:

Old device
   ↓
authenticated migration
   ↓
new device identity
   ↓
state transfer
   ↓
old device optionally revoked

Private device keys should still not be copied unless the architecture explicitly defines secure key migration.


80. Secure Storage

Private device material should use platform secure storage.

Android:

Android Keystore

Apple:

Keychain / Secure Enclave where appropriate

Desktop:

platform credential/key store
encrypted fallback

The identity crate should depend on a SecureStore abstraction.


81. Secure Store Trait

#![allow(unused)]
fn main() {
pub trait SecureStore {
    async fn store_secret(
        &self,
        key: SecretKeyId,
        secret: SecretBytes,
    ) -> Result<(), SecureStoreError>;

    async fn load_secret(
        &self,
        key: SecretKeyId,
    ) -> Result<SecretBytes, SecureStoreError>;
}
}

Avoid returning copyable secret types casually.


82. Secret Types

Use wrappers such as:

SecretBytes
Zeroizing
secrecy-style wrappers

to reduce accidental logging/copying.

Never derive:

#![allow(unused)]
fn main() {
Debug
}

for raw secret material.


83. Local Database Key

Each device may have a local database encryption key.

This key is distinct from:

account root key
device signing key
session key

Do not reuse one key for multiple purposes.


84. Key Separation

Use domain-separated derivation.

Conceptually:

root material
├── identity signing
├── device certification
├── recovery
└── other explicit domains

Never:

same key
for signing + encryption + database

85. Session Keys

Session keys are ephemeral or periodically renewed.

They should not become part of long-lived device directory state.

Identity authenticates session establishment.

Session cryptography protects current communication.


86. Prekeys / Offline Session Bootstrap

For asynchronous E2EE messaging, the architecture may require:

signed prekeys
one-time prekeys
device-specific prekey bundles

Each bundle belongs to a specific device.

The account directory helps discover which device bundles are valid.


87. Prekey Bundle Type

Conceptually:

#![allow(unused)]
fn main() {
pub struct DevicePrekeyBundle {
    pub account_id: AccountId,
    pub device_id: DeviceId,
    pub identity_key: PublicKey,
    pub signed_prekey: SignedPrekey,
    pub one_time_prekeys: Vec<OneTimePrekey>,
}
}

The exact cryptographic protocol should use a proven design.


88. Prekey Expiry

Prekeys must:

expire
rotate
replenish

Do not maintain indefinite prekey material.


89. Device Authentication During Session

Peer presents:

device certificate
device key proof
current account-state generation

The remote verifies:

certificate valid
device active
not revoked
account continuity valid

before application protocol becomes trusted.


90. Stale Peer Handling

If remote cannot verify current device status due to stale state:

Possible policy:

allow limited communication
request newer account state
delay sensitive operation

Do not silently trust stale high-risk identity information.


91. Offline Identity Verification

Two users without Internet can verify via:

QR
numeric code
NFC
manual fingerprint

The verification should bind:

account root identity

not just current transport endpoint.

This prevents re-verifying every transport change.


92. Contact Verification

A verified contact state should be tied to:

AccountId / root identity

with awareness of root rotation.

New devices signed under the verified account can inherit account-level trust according to policy.


93. New Device Notification

When a contact adds a device:

Alice added a new device.

The UI may show this as informational or security-significant depending on verification policy.

Do not silently hide device changes in high-security mode.


94. Identity Change Notification

If account root changes unexpectedly:

Security identity changed.

This is more serious than adding a device.

The distinction must be explicit.


95. Verification Modes

Possible:

#![allow(unused)]
fn main() {
pub enum VerificationPolicy {
    TrustAccountRoot,
    VerifyEveryDevice,
    HighSecurity,
}
}

Default messenger:

verify account root

Enterprise/high-security:

may require every device approval

96. Device Transparency Log

A future enhancement can provide:

append-only transparency log

for device additions/revocations.

This can help detect:

hidden unauthorized device additions

The core architecture should leave room for it.


97. Self-Hosted Transparency

Enterprise deployments may host:

organization device transparency service

without changing basic identity semantics.


98. No Mandatory Central Directory

The identity system must work:

P2P
offline
LAN-only
DTN

A directory server may improve discovery, but it is not the source of cryptographic truth.


99. Directory Service Role

Optional directory service can provide:

latest signed device directory
prekey bundles
transport hints

It must not be trusted to forge identities.

All state is verified cryptographically.


100. Device State Through DTN

Signed device-state updates can be transported through:

store-carry-forward

because authenticity does not depend on the relay.

This is important for disaster scenarios.


101. Emergency Identity

Emergency apps may need:

person identity
authority identity
responder identity
anonymous/limited identity

The identity layer should support different principal types without embedding emergency business rules.


102. Authority Identity

An authority account may certify:

Police Device
Hospital Device
Rescue Coordinator

The UI can display:

Verified Authority

only when cryptographic policy validates it.


103. Identity Claims

Keep optional claims separate from core identity.

Examples:

organization
role
department
emergency authority

Claims should be signed by an appropriate issuer.

Do not hard-code them into AccountId.


104. Claim Type

#![allow(unused)]
fn main() {
pub struct IdentityClaim {
    pub subject: AccountId,
    pub claim_type: ClaimType,
    pub value: ClaimValue,
    pub issuer: IssuerId,
    pub expires_at: Option<Timestamp>,
    pub signature: Signature,
}
}

Applications decide which issuers they trust.


105. Privacy

Device directories reveal metadata.

Minimize:

device names
exact platform
last seen
capabilities

to only what is necessary.

Some information can be shared only after authenticated contact/session establishment.


106. Public vs Private Device Metadata

Public:

device id
device key
required certificate fields

Private/authenticated:

friendly device name
platform detail
last-seen
capabilities

This reduces unnecessary metadata exposure.


107. Rotating Discovery Tokens

Nearby discovery must not advertise permanent:

AccountId
DeviceId

in plaintext.

Use rotating ephemeral discovery tokens.

Authenticated handshake resolves them to actual device identity.


108. Device Tracking Resistance

Avoid stable:

BLE identifiers
Wi-Fi service identifiers
transport advertisements

that allow passive tracking.

Transport discovery identity and cryptographic account identity should be separated.


109. Address Book Mapping

The messenger may map:

AccountId → Contact

but the identity SDK should not own:

phone-number address book
social graph
contact labels

Those are application concerns.


110. Device Audit Log

Each account should expose a local audit view:

Device added
Device revoked
Key rotated
Recovery used
Root changed

This is especially useful in enterprise and security-sensitive contexts.


111. Audit Event Type

#![allow(unused)]
fn main() {
pub enum IdentityAuditEvent {
    DeviceLinked,
    DeviceRevoked,
    DeviceSuspended,
    DeviceRotated,
    RootRotated,
    RecoveryUsed,
    ForkDetected,
}
}

Do not include secrets.


112. Notifications

Security-significant events may trigger:

local notification
cross-device notification
email/push optional

The identity layer emits events; the product decides presentation.


113. Cross-Device Consistency

Eventually all active trusted devices should converge on:

same account generation
same active device set
same revocation set

Temporary divergence is expected offline.

Security rules must remain conservative during divergence.


114. Reconciliation

When devices reconnect:

exchange generation
compare state hash
request missing events
verify chain
apply

Do not exchange entire history unnecessarily.


115. Merkle / Hash Chain Support

For many events, use:

state hash
event chain
Merkle summaries

to efficiently reconcile.

The first implementation can start with ordered signed events and later optimize.


116. Identity Storage

Suggested storage:

accounts
device_certificates
device_events
device_directory_snapshots
trust_state
verification_state
prekey_bundles
recovery_metadata
identity_audit

Secret material belongs in secure storage, not ordinary tables.


117. Storage Interface

#![allow(unused)]
fn main() {
pub trait IdentityStore {
    async fn account_state(...);
    async fn append_device_event(...);
    async fn device_certificate(...);
    async fn trust_state(...);
    async fn save_trust_state(...);
}
}

Keep secret store separate:

#![allow(unused)]
fn main() {
SecureStore
}

118. Transaction Boundaries

Device addition:

verify certificate
 ↓
append event
 ↓
update snapshot
 ↓
commit
 ↓
emit event

Never emit:

DeviceAdded

before durable persistence.


119. Idempotency

Receiving the same device event repeatedly should produce:

one logical state change

Use unique:

event id / hash

and generation constraints.


120. Replay Protection

Reject:

old device-add event
old transport endpoint
old revoked certificate

when newer state is known.

Use:

generation
state hash
certificate generation
expiry

121. Device-Specific Authorization

Applications may authorize per device.

Example:

Bob's laptop can receive 2 GB file
Bob's phone should receive only metadata

This can combine:

device capability
user policy
network policy

122. Enterprise Device Policy

An enterprise can require:

approved device
managed device
minimum app version
hardware-backed keys
device attestation

These should be optional policy layers.

Do not make attestation mandatory for the core protocol.


123. Platform Attestation

Android/iOS attestation can supplement identity.

It must not replace cryptographic identity.

Attestation answers:

What environment is this device running in?

Identity answers:

Which logical device/account is this?

124. Device Health Claims

Optional:

OS version
app version
secure storage available
hardware key support

These are claims/capabilities, not identity itself.


125. Version Compatibility

Device directory schema must be versioned.

Wire state:

DeviceCertificateV1
DeviceEventV1

Internal Rust structs may evolve independently.


126. Serialization

Use explicit protocol-safe types.

Avoid:

#![allow(unused)]
fn main() {
usize
SystemTime internals
platform enums
}

on wire.

Prefer:

u16
u32
u64
fixed arrays
bounded bytes
explicit timestamps

127. Input Limits

Limit:

max devices per account
max endpoints per device
max claims
max metadata length
max device name length
max event chain batch

Do not let an attacker force unbounded device-directory allocation.


128. Device Count Policy

Default normal account:

small bounded number

Enterprise may configure larger limits.

The core should not assume:

exactly 5 devices

but must still enforce resource limits.


129. Session Cache

Maintain device-authenticated session cache:

AccountId
DeviceId
AccountGeneration
SessionId
LastAuthenticated

Invalidate when:

device revoked
root changed
certificate rotated

130. Revocation Cache

Fast path:

revoked device set

for session validation.

This must be derived from durable authenticated state.


131. Device Identity API

Recommended public clients:

#![allow(unused)]
fn main() {
IdentityClient
DeviceClient
TrustClient
RecoveryClient
}

Keep public API small.


132. Example API

#![allow(unused)]
fn main() {
let identity = client.identity();

let invite = identity
    .create_device_link_invite(LinkPolicy::default())
    .await?;

let result = identity
    .approve_device_link(link_request)
    .await?;
}

Application should not directly construct signed device certificates.


133. Revoke API

#![allow(unused)]
fn main() {
identity
    .revoke_device(
        device_id,
        RevocationReason::Lost,
    )
    .await?;
}

The library handles:

signed event
generation
persistence
sync notification
session invalidation

134. Recovery API

#![allow(unused)]
fn main() {
let recovery = identity
    .begin_recovery(recovery_material)
    .await?;
}

Recovery should be a guided state machine, not one monolithic call.


135. State Machine for Linking

Created
 ↓
InviteShared
 ↓
PeerConnected
 ↓
Verified
 ↓
Approved
 ↓
CertificateIssued
 ↓
Committed
 ↓
Completed

Failure states:

Expired
Rejected
VerificationFailed
Cancelled

136. State Machine for Recovery

Started
 ↓
RecoveryMaterialVerified
 ↓
AuthorityRestored
 ↓
NewDeviceCreated
 ↓
OldDevicesReviewed
 ↓
RevocationsCommitted
 ↓
Completed

Persist progress safely where appropriate.


137. UI Boundary

Dioxus receives view models:

DeviceListVm
DeviceLinkVm
SecurityIdentityVm
RecoveryVm

It never receives:

root private key
device private key
session key

138. Android Kotlin Boundary

Kotlin may handle:

Android Keystore
biometric confirmation
QR camera
NFC
system notifications

Rust owns:

identity state
certificate logic
linking protocol
revocation
recovery policy

139. iOS Boundary

Equivalent pattern:

Keychain/Secure Enclave
camera
NFC where available
system authentication

through platform adapter.

No identity business logic should be duplicated in Swift.


140. Headless Linking

Headless nodes can link through:

CLI approval
QR rendered elsewhere
one-time token
admin-issued certificate

The same identity semantics apply.


141. File-Only Product Reuse

A file-transfer app may use:

AccountId
DeviceId
DeviceDirectory
device pairing
device revocation

without:

contacts
message history
conversation model

This proves identity is reusable.


142. ERP Reuse

ERP can map:

EmployeeId
   ↓
AccountId

or maintain its own mapping.

The communication SDK should not know what an employee is.


143. Emergency Reuse

Emergency application can link:

Responder Account
├── phone
├── radio gateway
└── vehicle node

without changing identity semantics.


144. Service-to-Service Reuse

Headless services can use:

organization identity
device certificate
transport identity

for secure automated communication.


145. Privacy-Preserving Device Names

Friendly names may stay local.

Remote peers do not need to know:

"Irshad's Bedroom PC"

unless user explicitly shares it.

Use generic capability descriptors by default.


146. Device Removal UX Semantics

UI should distinguish:

Remove device

from:

Revoke compromised device

If both map to revocation technically, presentation should explain consequences.


147. Device History Retention

Keep historical records:

revoked device id
revocation time
certificate fingerprint
reason

without retaining unnecessary sensitive metadata forever.

This helps security audits.


148. Key Compromise Warnings

If a formerly revoked device appears:

reject authentication
log security event
optional user warning

Do not silently reconnect.


149. Root Trust Cache

For verified contacts, store:

trusted root fingerprint
verification time
verification method

Root changes require explicit policy.


150. Verification Methods

Possible:

QR
numeric code
manual fingerprint
organization certificate
trusted directory

Record method for audit.


151. Device Linking Over Existing Secure Session

Preferred when possible:

existing trusted device
    ↓
authenticated channel
    ↓
link negotiation

QR/NFC supplies bootstrap proof.

The actual certificate transfer uses the secure channel.


152. Device Linking Without Internet

Must work:

Bluetooth
Wi-Fi Direct
LAN
QR bootstrap

No central service is required.

This is essential for emergency/disaster use.


153. Device Linking With Internet

Internet can simplify:

rendezvous
push
directory update

but cryptographic authority remains local/account-controlled.


154. Recovery Without Internet

If recovery policy supports offline secret/quorum:

recovery

must not require a cloud server.

This is valuable for resilient communication.


155. Backup Relationship

Identity backup should contain:

recovery material
public account state
encrypted necessary metadata

not blindly copy:

all active session state
all device private keys

unless explicitly designed.


156. New Device History Bootstrap

After linking, a new device may request:

conversation history
files
contacts
settings

This is a synchronization problem layered above identity.

Identity only establishes:

this device is authorized to participate

157. History Authorization

A linked device may not automatically receive all old data.

Policy examples:

new device gets full history
new device gets future messages only
new device gets selected history

This belongs to product/data policy.


158. Device Removal and Backups

Revoking a device does not erase:

backups
exports
screenshots
copied files

The system must not claim otherwise.


159. Threat Model

Protect against:

stolen device
malicious linking attempt
replayed linking invite
stale directory rollback
rogue transport endpoint
revoked device reconnect
identity fork
device key theft
root key rotation attack
directory server compromise
relay compromise

The design must assume network infrastructure is untrusted.


160. Trust Assumptions

The core trusts:

cryptographic verification
configured authorization policy
secure storage to its documented guarantees

It does not trust:

relay
LAN
Bluetooth peer name
IP address
server database
device display name

161. Security Invariants

  1. A device cannot become account-authorized without valid authority.
  2. Revoked devices cannot establish future trusted sessions.
  3. Old account state cannot roll back newer trusted state.
  4. Transport identity cannot substitute for account identity.
  5. Application profile changes cannot change identity.
  6. Private device keys do not leave device under normal operation.
  7. New devices receive only data authorized by product policy.
  8. Device linking is replay-resistant.
  9. Account root changes are explicitly verifiable.
  10. Identity state is usable without a central server.

162. Testing Strategy

Unit tests:

certificate verification
generation ordering
revocation
rotation
linking invite expiry
capability enforcement

Integration tests:

link device
sync directory
revoke device
attempt reconnect

Fault tests:

duplicate events
out-of-order events
stale directory
conflicting generation
process death during linking

163. Property Tests

Examples:

revoked device never becomes active after reconciliation
higher generation never rolls back
duplicate event is idempotent
valid event chain verifies
tampered chain fails

164. Fuzz Targets

Fuzz:

device certificate parser
device event parser
directory snapshot
link invite
recovery record
identity claim

All input sizes must be bounded.


165. Simulated Multi-Device Tests

Topology:

Alice:
A1 Phone
A2 Laptop
A3 Tablet

Bob:
B1 Phone
B2 Laptop

Test:

A1 adds A3
A2 offline
A3 sends
A2 reconnects
A1 revokes A3
Bob receives updated directory
A3 reconnect attempt rejected

166. Disaster Test

A1 no Internet
A2 nearby via BLE
A3 reachable through DTN

Device-state update:

A1 revokes A3

must eventually propagate through:

A2
DTN
gateway

and remain cryptographically valid.


167. Performance Goals

Identity operations are not usually hot-path data-plane operations.

Prioritize:

correctness
security
small metadata
incremental sync
bounded directories

Avoid repeatedly verifying full account history for every message.

Use validated cached state.


168. Cache Strategy

Cache:

verified device certificate
active device set
revocation set
highest generation
transport endpoints

Invalidate on signed state update.


169. Device Directory Size

Do not transmit full history unnecessarily.

Normal handshake can send:

account id
device certificate
generation
state hash

Then request:

missing state

only if needed.


170. Protocol Extension Integration

Part 01 defined protocol extensions.

Identity participates before application extensions become trusted.

Handshake:

Core transport
 ↓
Identity binding
 ↓
Account/device verification
 ↓
Extension negotiation
 ↓
Messaging/files/etc.

Identity is therefore foundational.


171. Capability Negotiation Integration

Device capabilities advertise:

which extensions
which media
which transports

but capabilities must be bound to authenticated device identity.

Do not trust anonymous capability advertisements for authorization.


172. Routing Integration

Routing uses:

DeviceDirectory

to resolve:

AccountId
   ↓
active devices
   ↓
transport endpoints

Routing cannot send account-level traffic correctly without identity resolution.


173. DTN Integration

DTN destinations can use opaque identifiers derived from:

AccountId
DeviceId
routing capability

Relay peers do not need full account metadata.


174. File Integration

File transfer target can be:

account
device
selected devices

This allows:

send to laptop only

without creating a fake conversation.


175. Messaging Integration

Messaging can fan out to:

recipient devices
sender's other devices

using authenticated device membership.

This allows consistent multi-device history.


176. Call Integration

Call invitation may target:

account

and ring:

all eligible devices

First device to accept can establish call ownership.

Other devices receive:

call answered elsewhere

177. Call Ring Arbitration

Need deterministic state:

Ringing
AcceptedBy(DeviceId)
Cancelled
Expired

This avoids simultaneous multi-device answers.

Identity provides the device list; call protocol handles arbitration.


178. Notification Integration

Push targets are device-specific.

Maintain:

DeviceId → push endpoint

as application/platform metadata.

Push token is not identity.


179. Device Endpoint Privacy

Transport/push endpoints should be:

rotatable
expiring
scoped

where possible.

Do not expose them permanently in public profile data.


180. Device Link Rate Limits

Protect against link spam.

Limit:

active invites
attempts per time window
failed verification attempts

and require user confirmation.


181. Recovery Rate Limits

Recovery attempts should be rate-limited where infrastructure participates.

Offline recovery should use strong local cryptographic proof rather than relying solely on rate limits.


182. UX States

Device management UI:

This device
Other devices
Recently revoked
Security alerts

Each row:

name
platform
last active
trust status
role

Sensitive actions require confirmation.


183. New Device UX

Flow:

Settings
 ↓
Linked Devices
 ↓
Link New Device
 ↓
Show/Scan QR
 ↓
Verify
 ↓
Approve
 ↓
Sync

Do not mix this with ordinary contact pairing.


184. Contact Pairing vs Device Linking

These are distinct.

Contact pairing:

Alice ↔ Bob

Device linking:

Alice Phone ↔ Alice Laptop

They must use different protocol states and UI language.


185. Device Name Validation

Device display names should be:

bounded
sanitized
localizable
non-authoritative

Do not permit device name to influence security policy.


186. Audit Export

Support exporting:

device list
security fingerprints
revocation history
identity generation

without exporting private keys.

Useful for enterprise/security support.


187. API Surface

Suggested modules:

identity/
├── account.rs
├── device.rs
├── certificate.rs
├── directory.rs
├── event.rs
├── trust.rs
├── linking.rs
├── recovery.rs
├── claims.rs
├── audit.rs
└── error.rs

188. Crate Split

Recommended:

comm-identity-types
comm-identity
comm-identity-protocol
comm-identity-storage

Keep split only if complexity justifies it.

Initially:

comm-identity

with internal modules may be sufficient.


189. Error Types

#![allow(unused)]
fn main() {
pub enum IdentityError {
    InvalidCertificate,
    RevokedDevice,
    ExpiredDevice,
    StaleGeneration,
    ForkDetected,
    LinkExpired,
    LinkRejected,
    VerificationFailed,
    Unauthorized,
    RecoveryFailed,
    Storage,
    Crypto,
}
}

Do not collapse into:

Identity failed

190. No anyhow in Public Domain API

Use typed errors for reusable library boundaries.

anyhow can be used in:

CLI
application bootstrap
top-level integration

but not as the identity protocol contract.


191. Migration Strategy

Persistent identity schema must support migrations.

Never rewrite identity state destructively without backup/recovery strategy.

Migration tests should include:

old device directory
old certificates
old trust state
old recovery metadata

192. Algorithm Agility

Do not hard-code one cryptographic algorithm into every type name.

Use:

AlgorithmId
KeyType
SignatureScheme

where future migration matters.

But avoid needless generic abstraction in the first implementation.


193. Algorithm Downgrade Protection

A peer must not force:

old weak algorithm

if policy requires stronger.

Negotiation chooses:

mutually supported
∩
locally allowed

194. Root Key Backup

If user chooses recovery backup:

encrypted export

must be:

  • authenticated
  • strongly derived
  • versioned
  • integrity-protected

Never export raw private key in plaintext.


195. Backup Import

Import must verify:

format version
integrity
account identity
recovery policy

before replacing local state.


196. Identity Reset

Resetting identity means:

new account identity

not:

clear app cache

UI must explain:

contacts may see you as a new identity
old encrypted relationships may not carry over

197. Account Deletion

Account deletion in a P2P system cannot erase all copies everywhere.

It can:

revoke devices
publish tombstone/state
delete local secrets
request server cleanup

but must not promise impossible remote deletion.


198. Organization Offboarding

Enterprise example:

employee leaves
 ↓
revoke organization device/capability
 ↓
remove from future keys
 ↓
block future sessions

Personal identity may remain unaffected if separated properly.


199. Multi-Tenant Safety

If platform is embedded in a multi-tenant app:

Tenant A
Tenant B

must have isolated:

identity namespaces
device directories
trust graphs
storage

Never key solely by AccountId if tenant context is required.


200. Recommended Initial Implementation

For the first production version, implement:

AccountId
DeviceId
root identity key
device signing key
device certificate
signed device directory
device add
device revoke
device transport endpoint binding
QR link
numeric verification
account generation
rollback protection
device-level session authentication
secure storage abstraction

Defer initially:

social recovery
transparency log
complex quorum recovery
attestation enforcement
multi-root organizations

but leave extension points.


201. Implementation Phases

Phase 1 — Types

Implement:

AccountId
DeviceId
DeviceCertificate
DeviceStatus
DeviceDirectory

Phase 2 — Local Identity

root key generation
device key generation
secure storage
certificate issuance

Phase 3 — Linking

invite
QR
ephemeral handshake
numeric verification
approval
certificate commit

Phase 4 — Revocation

signed revocation
generation
session invalidation
fan-out update

Phase 5 — Directory Sync

hash
generation exchange
incremental events

Phase 6 — Recovery

basic recovery secret or trusted-device policy

Phase 7 — Hardening

fuzzing
fault injection
rollback tests
fork tests
migration tests

202. Definition of Done

Part 02 is complete when:

  • one account can contain multiple devices
  • every device has independent keys
  • transport identity is separate from account identity
  • devices can be linked without Internet
  • linking is authenticated and replay-resistant
  • user confirmation is required
  • device revocation is durable
  • revoked devices cannot create future trusted sessions
  • device state cannot roll back
  • stale directories are detected
  • account generation is monotonic
  • own-device sync can discover active devices
  • file transfer can target specific devices
  • messaging can fan out across devices
  • Dioxus does not receive secret keys
  • Kotlin/Swift do not own identity logic
  • secure storage is abstracted
  • identity works without a central server
  • device-state updates can travel through DTN
  • the system supports headless/service devices
  • file-only products can reuse the identity layer
  • fuzz/property/integration tests exist

203. Relationship to Other Architecture Parts

Part 02 feeds directly into:

03 — Transport & Routing Policy Engine
04 — Offline Event Log
05 — Robust File / Blob Subsystem
06 — DTN / Store-Carry-Forward
07 — Capability Negotiation Expansion
11 — Relay / Self-Hosted Infrastructure
14 — Proximity Abstraction
15 — QR / NFC Bootstrap Pairing
16 — Daemon & Headless Runtime
17 — Emergency Priority Architecture
19 — C ABI / FFI
20 — Embedded Linux Node
23 — External Interoperability Suite

Transport needs device resolution.

Messaging needs device fan-out.

Files need specific-device targeting.

DTN needs authenticated destination identities.

Emergency systems need device-independent principal identity.


204. Final Principle

The platform should treat a logical person or organization as a cryptographic account containing independently revocable devices, not as a single device key.

The correct model is:

Account
  │
  ├── Device A
  ├── Device B
  ├── Device C
  └── Revoked Device D

with:

Account identity
≠
Device identity
≠
Transport identity
≠
Session identity
≠
User profile

That separation gives the platform:

  • secure multi-device operation
  • device replacement
  • device revocation
  • offline linking
  • headless-node support
  • reusable identity for messaging/files/ERP/emergency products
  • future recovery mechanisms
  • transport independence
  • better long-term protocol stability

This identity architecture should be implemented before higher-level multi-device messaging or file synchronization is considered production-ready.