Getting Started - Ringspace Trusted Webrings: Protocol Specification

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# Getting Started

## Installation

Ringspace can be installed multiple ways. At present, installation relies on the `cargo` toolchain from the Rust language.

If you do not have Cargo/Rustup installed, visit here first.

### Build From Source

This is the recommended path, since it guarantees you have everything you need for Ringspace to run.

    git clone https://codeberg.org/mttaggart/ringspace
    cd ringspace
    cargo install --path ./

> Important

> When `ringspace` runs as a server, it should do so from the repo directory. The `static` and `template` folders must be accessible for the server homepage to function.

### Direct Installation via Cargo

The Ringspace binary can be installed using `cargo`.

    cargo install ringspace

> Warning

> This option will not install the `static` and `template` folders from the repository and is only recommended for site management.

> If you intend to manage servers and installed via this path, download the repo and copy the `static` and `template` folders to wherever `ringspace` runs from.

### Binary Download

Pre-compiled binaries are available on the releases. At present, builds for Linux x86_64 and ARM64 are available.

## Running a Server

`ringspace server` is the subcommand to initialize a server. It can be initialized for a specific Ring and on a specific port. See the CLI docs for more information.

This service should not be exposed directly to the internet. I recommend a reverse proxy such as Caddy as your internet-facing server.

If running Ringspace directly on a server, consider using Systemd or another method to manage it as a service.

## `.env`

Ringspace honors a `.env` file to set certain values. The repo’s `example.env` is represented here:

    # Database URL: See https://docs.rs/sqlx/latest/sqlx/sqlite/struct.SqliteConnectOptions.html
    RINGSPACE_DATABASE_URL="sqlite:///data/ringspace.db?mode=rwc"
    # Used for containerized deployments. Should almost always be 0.0.0.0
    RINGSPACE_LISTEN_ADDRESS="0.0.0.0"
    # HTTP port for containerized proxy
    RINGSPACE_HTTP_PORT=8080
    # HTTPS port for containerized proxy
    RINGSPACE_HTTPS_PORT=8443
    # Actual server listen address. Use this to change where the actual server listens
    RINGSPACE_ROCKET_ADDRESS="0.0.0.0"
    # Actual Server Listen Port
    RINGSPACE_ROCKET_PORT=8000
    # Startup Managed Ring details for containerized deployments
    RINGSPACE_RING_NAME="Example Ring"
    RINGSPACE_RING_URL="https://example.com"
    RINGSPACE_RING_DESCRIPTION="An example ring"

The server listen address and port can be set my command line as well with `ringspace server`. Precedence goes:

Command line options -> Enviroment variables -> Built-in defaults.

Even if it’s an empty file **Ringspace expects a `.env`, so at the very least, put a placeholder in your working directory.

    touch .env

## Docker/Podman Deployment

The repository contains everything you need to get up and running with a containerized deployment.

### Set `.env`.

    cp example.env .env

Set the values as desired. Confirm no listen port conflicts. The containerized app will set the managed ring defined by the environment variables as the default ring and serve it.

### Build Base Images

    docker compose build

### Set up Caddyfile

    cp Caddyfile.example Caddyfile

Set host information as desired. The upstream hostname (`ringspace`) must match the `container_name` in `docker-compose.yml`.

### Launch a Server

    docker compose up -d

### Interact

To run `ringspace` commands, you can use `exec` directly:

    docker container exec -it ringspace ringspace site add

Or you can initialize a shell:

    docker container exec -it ringspace /bin/bash
    ringspace ring add

## Rings

This section walks through ring management.

### Create a New Ring

In a folder of your choosing, run `ringspace ring add`. You can add the optional parameters, or let the wizard walk you through it. Use the `-f` option to set this as the default ring (you can manage multiple rings). You can run `ringspace ring set-default` later if you forget. When you’re done, a new `ringspace.db` Sqlite3 database will exist in this folder. This will hold all the information about your rings and sites. When you run the server, you must run it from a directory with this file!

### Launch the server

Run `ringspace server` to launch the server on port 8000 by default. Make sure the command is running from a directory with the `static` and `templates` folders from the repo present.

It would be a good idea to run this behind a reverse proxy of some kind. This process should also probably be managed by a Systemd Service or similar persistence mechanism

You can use the `-p` option to specify what port to run the server on, and `-r` to specify the Ring URL, if you’re managing multiple rings.

### Invite Sites

Identify a site you want to join the ring! It could be yours, or someone else’s. Once both parties have Ringspace installed, run `ringspace invite create -u https://new-site.com` to create a new invite code. This invite code will be what you share with the other party. When they’re ready, they will make a join request with that code. Be aware that by default, invite codes expire in 72 hours! You can alter that with the `---expiration-hrs` option on `ringspace invite create`.

### Fetch Votes

Sites will vote on each other, and you need to collect that data. Schedule a job to run `ringspace ring fetch-votes` to reach out to all member sites and collect new vote information. Your server will provide updated manifests on demand, but the vote information must be collected.

Site manifests store only the most recent vote for a given vote subject. This is to prevent creep in the manifests, and to represent that voters can change their minds. However, the Ring has a cooldown period. New votes will not be accepted within 24 hours of a previous vote.

## Sites

This section discusses site management from the perspective of a site owner, rather than a ring owner.

### Create a New Site

To make a site instead of a ring, run `ringspace site add`. Again, use the option flags or the wizard to walk through the creation. Use `-f` to mark a site a default on creation, or run `ringspace site set-default` later.

You can create as many sites as you like!

### Join a Ring

With an invite code in hand (see above), run `ringspace site join-ring -c invite-code-here`. Specify the site you’re joining to the ring as necessary with `-u`, otherwise the default site will be assumed. If successful, your database will be updated to show that site as a member of that ring, which will be reflected in new manifest creations.

### Create a Manifest

You create a new manifest any time you make a change to the site, including:

- Votes
- Key Rotation

`ringspace site manifest` (with an optional `-u` for non-default sites) will print the manifest JSON to the terminal. Place this in a file called `webrings.json` in a folder called `.well-known` underneath the web root of your site. So the full path to the manifest is `https://your-site.com/.well-known/webrings.json`.

### Vote on Sites

You can manually add a single vote with `ringspace site vote`, but the easier way to do this is `ringspace site vote-wizard`. The Vote Wizard fetches the ring manifest, looks for all current members, and prompts you for votes on all of them. This helps make sure everyone has votes for other members in their manifests!

### Rotate Keys

If you need to rotate your published keys, run `ringspace site rotate`. A new keypair will be generated and your joined rings will be queried with the new key data and a signature made with the old key. If any rings fail to update, this command will revert the change on all successes, guaranteeing that there are no discrepancies between rings and your keys. Only after a full remote rotation will your local keys be changed.

### Leave a Ring

If you want to depart a ring, it’s as simple as `ringspace site leave-ring -r https://ring-url.com`. The departure request will be processed on the ring server, and you’ll be marked as unenrolled. Your local membership record will be removed, but not the ring data itself (you might have other sites that are still members!).