a simple rust terminal ui (tui) for setting up alternative plc rotation keys driven by: secure enclave hardware (not synced) or software-based keys (synced to icloud)
plc secure-enclave touchid icloud atproto
Rust 97.7%
Shell 2.3%
3 1 0

Clone this repository

https://tangled.org/saewitz.com/plc-touch https://tangled.org/did:plc:pppqzcp436xpufbu6luy5ysh/plc-touch
git@tangled.org:saewitz.com/plc-touch git@tangled.org:did:plc:pppqzcp436xpufbu6luy5ysh/plc-touch

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

plc-touch#

Please Touch. Secure enclave based keys for ATProto PLC rotation keys.

Named after the Please Touch Museum

A Rust TUI for managing AT Protocol (Bluesky) did:plc rotation keys with macOS Secure Enclave and Touch ID.

Take sovereign control of your DID PLC identity by generating hardware-backed P-256 keys and using them to directly sign and submit PLC operations — without needing your PDS to sign on your behalf.

Features#

  • Key Management — Generate P-256 keys in the Secure Enclave (device-only, hardware-backed) or as software keys (synced via iCloud Keychain across Apple devices)
  • Touch ID Signing — Every PLC operation signing triggers biometric authentication
  • DID Inspection — View your DID document, rotation keys, verification methods, and services
  • PLC Operations — Add/remove rotation keys, with diff preview before signing
  • Audit Log — Browse the full PLC operation history for any DID
  • PDS Login — Authenticate with your PDS for operations that require it (initial key addition via email token flow)
  • Test Posts — Send posts to Bluesky from the TUI

Screenshots#

┌─plc-touch──did:plc:abc...xyz──🔑 mykey ● PDS─┐
│ 1 Keys  │ 2 Identity │ 3 Sign │ 4 Audit │ ...│
├───────────────────────────────────────────────┤
│ ┌ Secure Enclave Keys ───────────────────────┐│
│ │  ▸ mykey *                                 ││
│ │    did:key:zDnae...                        ││
│ │    iCloud Keychain (synced)  Touch ID      ││
│ └────────────────────────────────────────────┘│
│ q quit  ? help  1-6 tabs  n new  d del  s set │
└───────────────────────────────────────────────┘

Requirements#

  • macOS 13+ (Ventura or later)
  • Rust toolchain
  • Apple Developer account (for Secure Enclave entitlements)
  • Provisioning profile with keychain-access-groups entitlement

Setup#

  1. Clone and configure:
git clone https://github.com/yourusername/plc-touch.git
cd plc-touch
cp .env.example .env
  1. Edit .env with your Apple Developer signing details:
CODESIGN_IDENTITY="Apple Development: Your Name (XXXXXXXXXX)"
BUNDLE_ID="com.yourcompany.plc-touch"
TEAM_ID="XXXXXXXXXX"
  1. Create a provisioning profile on developer.apple.com:

    • Register your Mac's Provisioning UDID (find it in System Settings > General > About, or system_profiler SPHardwareDataType | grep "Provisioning UDID")
    • Create a macOS App ID with your bundle ID
    • Create a macOS Development provisioning profile
    • Download and save as embedded.provisionprofile in the project root
  2. Build and sign:

./build.sh
  1. Run:
target/release/plc-touch.app/Contents/MacOS/plc-touch

Usage#

Tabs#

Tab Key Description
Keys 1 Manage Secure Enclave / iCloud Keychain keys
Identity 2 Inspect DID document, rotation keys, verification methods
Sign 3 Review and sign staged PLC operations
Audit 4 Browse PLC operation audit log
Post 5 Send a test post to Bluesky
Login 6 Authenticate with your PDS

Key Bindings#

Global:

  • 1-6 — Switch tabs
  • ? — Help
  • q — Quit

Keys tab:

  • n — Generate new key (choose syncable or device-only)
  • d — Delete selected key
  • s — Set as active signing key
  • Enter — Copy did:key to clipboard

Identity tab:

  • e — Enter/change DID
  • r — Refresh from PLC directory
  • a — Add active key to rotation keys
  • x — Remove selected rotation key
  • m — Move rotation key (change priority)

Sign tab:

  • s — Sign operation with Touch ID
  • j — Toggle JSON view

Audit tab:

  • j/Enter — Expand/collapse entry

Key Types#

When generating a key (n), you can toggle sync with Tab:

  • Syncable [Y] — Software P-256 key stored in iCloud Keychain. Available on all your Apple devices. Touch ID enforced at app level before signing.
  • Device-only [n] — Hardware-backed Secure Enclave key. Never leaves the chip. Touch ID enforced by hardware during signing. Only works on this device.

Typical Flow#

  1. Generate a key — Tab 1, press n, enter a label, press Enter
  2. Set it active — Press s on the key
  3. Log in to your PDS — Tab 6, enter handle and app password
  4. Enter your DID — Tab 2, press e, enter your did:plc:...
  5. Add key to rotation — Tab 2, press a on your key
  6. Sign the operation — Tab 3, press s, authenticate with Touch ID
  7. Submit — Confirm submission to PLC directory

Architecture#

src/
├── main.rs          # Entry point, terminal setup/teardown
├── app.rs           # Application state, event loop, async task dispatch
├── enclave.rs       # Secure Enclave + iCloud Keychain key management
├── didkey.rs        # did:key encoding/decoding (P-256)
├── plc.rs           # PLC operations, DAG-CBOR serialization, CID computation
├── sign.rs          # DER→raw signature conversion, low-S normalization
├── directory.rs     # PLC directory HTTP client
├── atproto.rs       # AT Protocol XRPC client (session, posts)
├── event.rs         # Async message types
└── ui/
    ├── mod.rs       # Top-level layout, tab bar, modals
    ├── keys.rs      # Key list and management
    ├── identity.rs  # DID document display
    ├── operations.rs# Operation signing and diff view
    ├── audit.rs     # Audit log browser
    ├── login.rs     # PDS authentication
    ├── post.rs      # Post composer
    └── components.rs# Shared widgets

Signing Flow#

PLC Operation (JSON)
  → serialize_for_signing() (DAG-CBOR, canonical key ordering)
  → sign_operation()
    → SE key: SecKeyCreateSignature (hardware Touch ID)
    → Software key: LAContext biometric check → SecKeyCreateSignature
  → DER → raw r||s (64 bytes)
  → low-S normalization
  → base64url encode → sig field
  → compute CID → submit to plc.directory

Development#

# Run tests (no hardware required)
cargo test

# Build without signing (for development)
cargo build

# Build + codesign (required for Secure Enclave access)
./build.sh

License#

MIT