/ docs / guides / platforms / radicle.md
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.