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
at main 189 lines 6.8 kB view raw view rendered
1# plc-touch 2 3Please Touch. Secure enclave based keys for ATProto PLC rotation keys. 4 5> Named after the [Please Touch Museum](https://www.pleasetouchmuseum.org/) 6 7A Rust TUI for managing AT Protocol (Bluesky) `did:plc` rotation keys with macOS Secure Enclave and Touch ID. 8 9Take 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. 10 11## Features 12 13- **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) 14- **Touch ID Signing** — Every PLC operation signing triggers biometric authentication 15- **DID Inspection** — View your DID document, rotation keys, verification methods, and services 16- **PLC Operations** — Add/remove rotation keys, with diff preview before signing 17- **Audit Log** — Browse the full PLC operation history for any DID 18- **PDS Login** — Authenticate with your PDS for operations that require it (initial key addition via email token flow) 19- **Test Posts** — Send posts to Bluesky from the TUI 20 21## Screenshots 22 23``` 24┌─plc-touch──did:plc:abc...xyz──🔑 mykey ● PDS─┐ 25│ 1 Keys │ 2 Identity │ 3 Sign │ 4 Audit │ ...│ 26├───────────────────────────────────────────────┤ 27│ ┌ Secure Enclave Keys ───────────────────────┐│ 28│ │ ▸ mykey * ││ 29│ │ did:key:zDnae... ││ 30│ │ iCloud Keychain (synced) Touch ID ││ 31│ └────────────────────────────────────────────┘│ 32│ q quit ? help 1-6 tabs n new d del s set │ 33└───────────────────────────────────────────────┘ 34``` 35 36## Requirements 37 38- macOS 13+ (Ventura or later) 39- Rust toolchain 40- Apple Developer account (for Secure Enclave entitlements) 41- Provisioning profile with `keychain-access-groups` entitlement 42 43## Setup 44 451. **Clone and configure:** 46 47```bash 48git clone https://github.com/yourusername/plc-touch.git 49cd plc-touch 50cp .env.example .env 51``` 52 532. **Edit `.env`** with your Apple Developer signing details: 54 55``` 56CODESIGN_IDENTITY="Apple Development: Your Name (XXXXXXXXXX)" 57BUNDLE_ID="com.yourcompany.plc-touch" 58TEAM_ID="XXXXXXXXXX" 59``` 60 613. **Create a provisioning profile** on [developer.apple.com](https://developer.apple.com): 62 - Register your Mac's Provisioning UDID (find it in System Settings > General > About, or `system_profiler SPHardwareDataType | grep "Provisioning UDID"`) 63 - Create a macOS App ID with your bundle ID 64 - Create a macOS Development provisioning profile 65 - Download and save as `embedded.provisionprofile` in the project root 66 674. **Build and sign:** 68 69```bash 70./build.sh 71``` 72 735. **Run:** 74 75```bash 76target/release/plc-touch.app/Contents/MacOS/plc-touch 77``` 78 79## Usage 80 81### Tabs 82 83| Tab | Key | Description | 84|-----|-----|-------------| 85| Keys | `1` | Manage Secure Enclave / iCloud Keychain keys | 86| Identity | `2` | Inspect DID document, rotation keys, verification methods | 87| Sign | `3` | Review and sign staged PLC operations | 88| Audit | `4` | Browse PLC operation audit log | 89| Post | `5` | Send a test post to Bluesky | 90| Login | `6` | Authenticate with your PDS | 91 92### Key Bindings 93 94**Global:** 95- `1`-`6` — Switch tabs 96- `?` — Help 97- `q` — Quit 98 99**Keys tab:** 100- `n` — Generate new key (choose syncable or device-only) 101- `d` — Delete selected key 102- `s` — Set as active signing key 103- `Enter` — Copy `did:key` to clipboard 104 105**Identity tab:** 106- `e` — Enter/change DID 107- `r` — Refresh from PLC directory 108- `a` — Add active key to rotation keys 109- `x` — Remove selected rotation key 110- `m` — Move rotation key (change priority) 111 112**Sign tab:** 113- `s` — Sign operation with Touch ID 114- `j` — Toggle JSON view 115 116**Audit tab:** 117- `j`/`Enter` — Expand/collapse entry 118 119### Key Types 120 121When generating a key (`n`), you can toggle sync with `Tab`: 122 123- **Syncable `[Y]`** — Software P-256 key stored in iCloud Keychain. Available on all your Apple devices. Touch ID enforced at app level before signing. 124- **Device-only `[n]`** — Hardware-backed Secure Enclave key. Never leaves the chip. Touch ID enforced by hardware during signing. Only works on this device. 125 126### Typical Flow 127 1281. **Generate a key** — Tab 1, press `n`, enter a label, press `Enter` 1292. **Set it active** — Press `s` on the key 1303. **Log in to your PDS** — Tab 6, enter handle and app password 1314. **Enter your DID** — Tab 2, press `e`, enter your `did:plc:...` 1325. **Add key to rotation** — Tab 2, press `a` on your key 1336. **Sign the operation** — Tab 3, press `s`, authenticate with Touch ID 1347. **Submit** — Confirm submission to PLC directory 135 136## Architecture 137 138``` 139src/ 140├── main.rs # Entry point, terminal setup/teardown 141├── app.rs # Application state, event loop, async task dispatch 142├── enclave.rs # Secure Enclave + iCloud Keychain key management 143├── didkey.rs # did:key encoding/decoding (P-256) 144├── plc.rs # PLC operations, DAG-CBOR serialization, CID computation 145├── sign.rs # DER→raw signature conversion, low-S normalization 146├── directory.rs # PLC directory HTTP client 147├── atproto.rs # AT Protocol XRPC client (session, posts) 148├── event.rs # Async message types 149└── ui/ 150 ├── mod.rs # Top-level layout, tab bar, modals 151 ├── keys.rs # Key list and management 152 ├── identity.rs # DID document display 153 ├── operations.rs# Operation signing and diff view 154 ├── audit.rs # Audit log browser 155 ├── login.rs # PDS authentication 156 ├── post.rs # Post composer 157 └── components.rs# Shared widgets 158``` 159 160### Signing Flow 161 162``` 163PLC Operation (JSON) 164 → serialize_for_signing() (DAG-CBOR, canonical key ordering) 165 → sign_operation() 166 → SE key: SecKeyCreateSignature (hardware Touch ID) 167 → Software key: LAContext biometric check → SecKeyCreateSignature 168 → DER → raw r||s (64 bytes) 169 → low-S normalization 170 → base64url encode → sig field 171 → compute CID → submit to plc.directory 172``` 173 174## Development 175 176```bash 177# Run tests (no hardware required) 178cargo test 179 180# Build without signing (for development) 181cargo build 182 183# Build + codesign (required for Secure Enclave access) 184./build.sh 185``` 186 187## License 188 189MIT