Radicle Tor
In "A Cypherpunk's Manifesto" (1993), Eric Hughes eloquently states:
Privacy is the power to selectively reveal oneself to the world
When using the "private repository" feature on traditional centralized forges, the level of privacy is determined by the platform's Terms of Service agreement. Users have no choice but to trust that the platform's people won't abuse their access rights to view private data, or train their ML models on your private repos.
In contrast, Radicle's decentralized approach aims to put the power of privacy directly in the hands of users by leveraging public key cryptography and access control lists. The power to selectively reveal is at the core of Radicle's protocol design, striving to provide developers with a more secure and trustless collaboration environment.
When a private repository is created in Radicle, the data is accessible only to repository delegates and to collaborators or trusted seed nodes specified by the delegates. These are not encrypted at rest but rely on selective replication and are thus completely invisible to the rest of the network.
To further enhance privacy, Radicle nodes can be configured to run on the Tor network, allowing nodes to be represented by .onion addresses and also providing NAT traversal for free. These features enable users to take control of their privacy from a multidimensional perspective and collaborate on their own terms.
This article explores two approaches to distributing private repositories: using a trusted seed node or leveraging Tor. We'll start by setting up a private repository with a trusted seed node and then dive into the process of maintaining sovereignty and control over your data while collaborating with a trusted circle.
👻
Note that Radicle's codebase hasn't undergone formal security audits yet. While we are confident in its security, there might be undiscovered vulnerabilities. If you find any security issues, do report them to security@radicle.xyz
Radicle useful req and def
Definition 1: Radicle network is built of users. There are two kinds of users: radicle users, running radicle node, and git users, which do not run radicle node.
Requirement 2: Ordinary git users must be able to have an access to public git repositories hosted in the radicle network - and must not be able to access private repositories.
Prerequisites: Git users
- must have git installed locally;
- may be behind NAT;
- may or may not use Tor;
- must know radicle-specific project ID;
- must know IPv4 (what about IPv6) address of the radicle node seeding that repository; the node must be exposed to the public network;
- do not get access to issues, PRs, discussions etc.
Access to the repository for git users is performed by running:
git clone <protocol>://<seeding-radicle-node-ip>/<radicle-project-id>
How the ordinary git users discover radicle seed node IP address and project ID remains outside of the scope of radicle protocol design and feature requirements.
Requirement 3: Radicle users may run radicle nodes on a server or their workstations
Definition 4: A Radicle node is a seeding node if it is the primary source for at least one of the repositories for the network. Otherwise, it is called leecher.
Requirement 5: Radicle nodes may run behind Tor and/or NAT and still remain fully operational (except access by git users, as specified above in the claim 1 prerequisites).
Consequence 5.1: Seeding nodes must either:
- be using Tor and do not being accessible by ordinary git users;
- be behind NAT and do not being accessible by ordinary git users - but connect to bootstrap node to be accessible to other radicle nodes via NAT traversal mechanisms;
- be publicly available without NAT and Tor.
Consequence 5.2: Radicle nodes seeding repositories are required to be permanently online, i.e., run on private servers or in a cloud. So the rest of radicle nodes ("leechers") may go offline and can be run on a desktop sporadically all they want.
NAT, Tor?
NAT traversal involves techniques that establish and maintain Internet protocol connections across network address translation (NAT) gateways. This process allows devices on a private network with non-routable IP addresses to communicate with devices outside their network, overcoming the restrictions imposed by NAT.
Tor (The Onion Router) anonymizes a user's IP address and location by routing internet traffic through multiple relays, obscuring activities from surveillance. Like a VPN, Tor provides anonymity and bypasses restrictions, but it uses a decentralized network of relays for enhanced privacy, whereas VPNs route traffic through a single server.
Radicle F.A.Q
It's here.
Initializing a Private Data Enclave
Now, we, or Paxel return to a journey into the unknown, among the Intergalactic Union of the absolutists, where we are investigating the enigmatic dark star mystery with Calyx.
We've been decoding what was found in 897AF, cargo vessel. Data related to the dark star anomaly to better understand our universe, uploading our findings to the public dark-star repository.
However, recent analysis hints at the mind-bending possibility of multiple universes tightly intertwined with conscious thought. If accurate, widespread awareness of these findings could fundamentally alter our collective perception of reality, reshaping it in unpredictable ways. That is exciting but see, also concerning.
To ensure these revelations don't prematurely transform the spacetime continuum as we know it, we've initialized Git within a new project directory schrödingers-paradox, and decide to commit our data and analysis there:
$ cd schrödingers-paradox
$ cp /var/run/897af.log data/897af.log
$ git add data/
$ git add analysis/paxel-findings.md
$ git commit -m "Add mind-bending data from ship 897AF"
Schrödinger's paradox suggests that the act of observation influences the outcome of an experiment. Specifically, in the thought experiment involving a cat in a box, the observer's decision to check inside the box determines whether the cat's state is revealed as either dead or alive, resolving the uncertainty inherent in its quantum state.
Next, to be able to securely share this with our peers, like Calyx, we initialize a private repository in Radicle by passing the --private
flag with rad init
:
$ rad init --private
This command functions similarly to the public repository initialization process. It guides us through creating a new private repository, generates a repository identifier (RID), and creates a special Git remote named rad in our working copy.
The key difference is that setting the --private
flag automatically configures the visibility option to private. As a result, the repository remains unannounced and unpublished on the network, reflecting its private status 🥷.
$ rad init --private
Initializing private radicle 👾 repository in /home/paxel/src/schrödingers-paradox..
✓ Name schrödingers-paradox
✓ Description Recent data from research vessel 897AF has revealed peculiar patterns that, if verified, could have significant implications for our understanding of the universe.
✓ Default branch main
✓ Repository schrödingers-paradox created.
Your Repository ID (RID) is rad:z3jEQE4VMzkR1UVeSLiN9E8AMtV6a.
You can show it any time by running `rad .` from this directory.
You have created a private repository.
This repository will only be visible to you, and to peers you explicitly allow.
To make it public, run `rad publish`.
To push changes, run `git push`.
Curating the Allow List
Initially, the private schrödingers-paradox repository will only be accessible to us. But since we want to collaborate on these findings with others, we are going to configure its allow list to include the DIDs of Calyx, our trusted peer, and a [seed node][seeder] we manage that has a public DNS address.
🧠
Please note that NAT traversal is not yet implemented in Radicle. As a result, there are two approaches to distributing private repositories:
- Using a seed node with a public DNS address
- Using a user node or seed node that is enabled with a Tor .onion address
If you want to learn how to use Radicle with Tor, skip ahead to the Tor configuration section.
We can add both Calyx and our managed seed node to the allow list using a single rad id update
command by first providing a --title
and (optional) --description
for the update, then specifying each of their DIDs after an --allow
flag:
$ rad id update --title "Add Calyx and iui.darkstar.org to allow list" \
--description " " \
--allow did:key:z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap \
--allow did:key:z6MkqNZS9QWvC4wbZ8Vz4hQZ1FzN8q4XGj2KGmK9qNgQ8VWt
Since we are the only delegate on the repository, the update to the repository identity automatically is approved.
👻
It is possible to update a repository that is currently public to become private, by passing --visibility private
with a rad id update
command.
But you should understand that this does not necessarily delete your historic repository data from public seed nodes or other peers that had seeded or cloned your repository. It's just that future updates will only be announced and accessible to those explicitly defined in the allow list.
For more details on making updates to the repository identity, check out man rad-id.
With the allow list configured, Calyx and our seed node now have access to the schrödingers-paradox repository.
Seeding on a Managed Seed Node
Before cloning the repository to our managed seed node, we need to establish a connection between our local node and the seed node.
First, we SSH into our seed node and get its external address with rad node config --addresses
:
$ ssh iui.darkstar.org
$ rad node config --addresses
$ z6MkqNZS9QWvC4wbZ8Vz4hQZ1FzN8q4XGj2KGmK9qNgQ8VWt@iui.darkstar.org:8776
Next, we copy the external address and pass it into the rad node connect
command:
$ rad node connect z6MkqNZS9QWvC4wbZ8Vz4hQZ1FzN8q4XGj2KGmK9qNgQ8VWt@iui.darkstar.org:8776
With the connection established, we can now clone the schrödingers-paradox repository on our seed node. Since we're the only user with access to the repository currently, we'll pass in the --seed
flag along with our Node ID (NID):
$ ssh iui.darkstar.org
$ rad seed rad:z3jEQE4VMzkR1UVeSLiN9E8AMtV6a --seed z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C
By cloning the repository on our seed node, we ensure that it can serve as a reliable, authorized access point for other authorized peers to clone from.
👻
Please remember that private repositories are not encrypted at rest, so any seed node that you add to the allow list will have visibility to the
data and could potentially be accessed by anyone with access to that seed node.
The allow list should be limited to people or devices that you trust.
Cloning as a Trusted Peer
Finally, we turn to Calyx, our trusted collaborator. Calyx already has the Radicle CLI installed and an existing Radicle account, so we can share the private repository with her by providing the repository identifier (RID).
We tell Calyx that in order to clone the repository, she needs to first establish a connection with the seed node and then use the rad clone
command with the RID:
$ rad node connect z6MkqNZS9QWvC4wbZ8Vz4hQZ1FzN8q4XGj2KGmK9qNgQ8VWt@iui.darkstar.org:8776
$ rad clone rad:z3jEQE4VMzkR1UVeSLiN9E8AMtV6a
Since Calyx is on the allow list, she'll be able to successfully clone the repository from the seed node and begin collaborating with us on the schrödingers-paradox project.
Umbranx Infiltration
👻
Although we've taken every precaution to safeguard the private repository, something sinister is afoot. Our managed seed node, iui.darkstar.org, has been compromised by an unknown adversary.
Radicle's default behavior is to log all interactions with the node in a file named radicle.log in the user's home directory, but it is recommended to use more sophisticated log management tools and techniques to monitor and alert on suspicious activity.
The use of .onion addresses for increased privacy will help us regain our footing.
Embracing the Onion: Configuring Tor
Let's enable Tor on our local node and the seed node. To use Radicle with Tor, you must:
- Install Tor on your local machine and the seed node
- Configure Tor to run in hidden service mode
- Configure Radicle to use Tor
Let's start with our local machine.
Installing Tor
First, we install Tor and Tor Browser by following the instructions provided by the Tor Project for our specific operating system.
Once Tor is installed, we can run Tor Browser and check if it's working properly by visiting check.torproject.org.
Configuring Tor Hidden Service
Next, we configure Tor to run in hidden service mode by editing the torrc configuration file. We set up a hidden service to proxy Radicle's traffic:
$ sudo nano /etc/tor/torrc
# could be elsewhere
# e.g /opt/homebrew/etc/tor/torrc on OSX
We add the following lines:
HiddenServiceDir /var/lib/tor/radicle/
HiddenServicePort 8776 127.0.0.1:8776
We save and close the file,
Now we make sure make sure that folder exists and has the right permission, and owner
# this needs to be no more or less than 700 permission
$ sudo mkdir -p -m 700 /var/lib/tor/radicle
# this has to be owned by the same user that owns the tor service
$ sudo chown $(id -u):$(id -g) /var/lib/tor/radicle
These lines create a hidden service for Radicle, allowing traffic to be routed through Tor. We can then restart the Tor service:
$ sudo systemctl restart tor
# on OSX that would be /opt/homebrew/opt/tor/bin/tor
We can find our new .onion address by checking the hidden service directory:
$ cat /var/lib/tor/radicle/hostname
$ abcdefghijklmnopqrstuv.onion
Configuring Radicle to Use Tor
Finally, we configure Radicle to use Tor by updating the rad node configuration file.
Edit your radicle configuration file (~/.radicle/config.json) using rad config edit:
a. Set your externalAddresses to your .onion address with port 8776, e.g.:
"externalAddresses": [
"nryicotfm746kfvkoqjgrdffsohhv437m5aqpyv3rq546iddbsit3cid.onion:8776"
],
b. Set listen to:
"listen": [
"0.0.0.0:8776"
],
c. Add the following lines after the externalAddresses field:
"tor": {
"mode": "proxy",
"address": "127.0.0.1:9050"
},
We save and close the file, then restart Radicle:
$ rad node stop && rad node start
With Tor configured on both our local node and the seed node, we've successfully increased our privacy and can continue our research on the dark star mystery without (too much) fear of surveillance.
Tip
A container maybe?
Conclusion
We've covered a the journey of securing a private repository in Radicle, configuring an allow list, and using a managed seed node for authorized access. We also learned how to enhance privacy with Tor, ensuring sensitive data remains (more) secure.
By leveraging these tools and techniques, we've taken (some degree of) control of our data and privacy, collaborating on our terms and safeguarding our research from (some of the) prying eyes. As we continue to unravel the mysteries of the universe, we'll carry these principles with us, staying vigilant and protecting the integrity of our discoveries.