radicle.md
1 # Radicle Integration 2 3 Use Auths with [Radicle](https://radicle.xyz) for sovereign code forge identity. The `auths-radicle` crate provides an adapter layer that bridges Radicle's peer-to-peer Git collaboration with Auths' policy-based authorization, without introducing any new signature formats. 4 5 ## Architecture 6 7 The integration follows a **zero new crypto** principle: 8 9 - **Radicle handles all cryptographic signature verification** (Ed25519). 10 - **Auths provides authorization** through its policy engine (is this key allowed to sign for this identity?). 11 - The `auths-radicle` adapter bridges the two. 12 13 Radicle identifies peers with `did:key:z6Mk...` identifiers (Ed25519 multicodec format). The adapter maps these to Auths device DIDs and evaluates device attestations against the Auths policy engine. 14 15 ### Verification flow 16 17 1. Radicle verifies the Ed25519 signature on a commit (cryptographic proof). 18 2. The adapter converts the signer's public key to a `did:key` device DID. 19 3. The adapter loads the identity and device attestation from storage. 20 4. The Auths policy engine evaluates the attestation (not revoked, not expired). 21 5. The result is mapped: `Allow` becomes `Verified`, `Deny` becomes `Rejected`, `Indeterminate` becomes `Warn`. 22 23 ## Storage layout 24 25 The default Auths layout uses the RIP-X (Radicle) convention: 26 27 | Ref | Path | 28 |---|---| 29 | Identity | `refs/rad/id` | 30 | Identity blob | `radicle-identity.json` | 31 | Attestation prefix | `refs/keys` | 32 | Attestation blob | `link-attestation.json` | 33 34 ## Setup 35 36 ### 1. Create an identity 37 38 First, create a metadata file for your Radicle identity: 39 40 ```bash 41 cat > ~/radicle_meta.json << 'EOF' 42 { 43 "xyz.radicle.agent": {"alias": "my_rad_alias", "controller": ""}, 44 "profile": {"name": "Radicle User"} 45 } 46 EOF 47 ``` 48 49 Then initialize your identity: 50 51 ```bash 52 auths id create \ 53 --metadata-file ~/radicle_meta.json \ 54 --local-key-alias radicle_id_key 55 ``` 56 57 ### 2. View identity details 58 59 ```bash 60 auths id show --repo "$RAD_REPO_PATH" 61 ``` 62 63 ### 3. Link a device 64 65 Import a device key and link it to your identity: 66 67 ```bash 68 CONTROLLER_DID=$(auths id show --repo "$RAD_REPO_PATH" \ 69 | grep 'Controller DID:' | awk -F': ' '{print $2}') 70 71 auths key import \ 72 --alias rad_device_key \ 73 --seed-file ~/rad_device.seed \ 74 --controller-did "$CONTROLLER_DID" 75 ``` 76 77 Then link the device: 78 79 ```bash 80 auths device link \ 81 --repo "$RAD_REPO_PATH" \ 82 --identity-key-alias radicle_id_key \ 83 --device-key-alias rad_device_key \ 84 --device-did "$DEVICE_DID" \ 85 --note "Radicle Laptop Key" 86 ``` 87 88 ### 4. Verify linked devices 89 90 ```bash 91 auths device list --repo "$RAD_REPO_PATH" 92 ``` 93 94 ## Threshold identities 95 96 Radicle supports threshold identities (e.g., 2-of-3 delegates must sign). The `auths-radicle` crate provides `verify_multiple_signers` and `meets_threshold` functions for evaluating multi-signer commits against Auths policy: 97 98 ```rust 99 use auths_radicle::{DefaultBridge, verify_multiple_signers, meets_threshold}; 100 101 let bridge = DefaultBridge::with_storage(storage); 102 103 let signer_keys: Vec<[u8; 32]> = /* collect from Radicle commit */; 104 let results = verify_multiple_signers(&bridge, &signer_keys, "repo-id", now); 105 106 if meets_threshold(&results, identity.document.threshold as usize) { 107 println!("Commit authorized by threshold quorum"); 108 } 109 ``` 110 111 ## Radicle identity documents 112 113 The adapter reads Radicle identity documents from `refs/rad/id`. These documents contain a list of delegate DIDs and a threshold: 114 115 ```json 116 { 117 "delegates": [ 118 "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi" 119 ], 120 "threshold": 1, 121 "payload": { 122 "name": "my-project" 123 } 124 } 125 ``` 126 127 The adapter extracts the Ed25519 public key from each delegate's `did:key` (base58btc-encoded with the `0xED01` multicodec prefix) and uses it for policy evaluation.