objective categorical abstract machine language personal data server
at main 157 lines 6.0 kB view raw view rendered
1# pegasus 2 3is an [atproto PDS](https://atproto.com/guides/glossary#pds-personal-data-server), along with an assortment of atproto-relevant libraries, written in OCaml. 4 5## table of contents 6 7- [Running It](#running-it) 8- [Environment](#environment) 9 - [SMTP](#smtp) 10 - [S3](#s3) 11- [Development](#development) 12- [Libraries](#libraries) 13 - [ipld](#ipld) - IPLD implementation (CIDs, CAR, DAG-CBOR) 14 - [kleidos](#kleidos) - Cryptographic key management 15 - [mist](#mist) - Merkle Search Tree implementation 16 - [hermes](#hermes) - XRPC client 17 - [frontend](#frontend) - Web interface 18 - [pegasus](#pegasus-library) - PDS implementation 19 20## running it 21 22After cloning this repo, start by running 23 24``` 25docker compose pull 26``` 27 28to pull the latest image, or 29 30``` 31docker compose build 32``` 33 34to build from source. 35 36Next, run 37 38``` 39docker compose run --rm --entrypoint gen-keys pds 40``` 41 42to generate some of the environment variables you'll need. 43 44Copy [`.env.example`](.env.example) to `.env` and fill in the environment variables marked as required. See [Environment](#environment) for further details on configuration. 45 46After that, run 47 48``` 49docker compose up -d 50``` 51 52to start the PDS, then navigate to `https://{PDS_HOSTNAME}/admin` to log in with the admin password you specified and create an invite code or a new account on the PDS. 53 54## environment 55 56Documentation for most environment variables can be found in [`.env.example`](.env.example). There are two optional categories of environment variables that add functionality: 57 58### SMTP 59 60The PDS can email users for password changes, identity updates, and account deletion. If these environment variables are not set, emails will instead be logged to the process' stdout. 61 62- `PDS_SMTP_AUTH_URI` — The URI to connect to the mail server. This should look like `smtp[s]://user:pass@host[:port]`. 63- `PDS_SMTP_STARTTLS=false` — Whether to use STARTTLS when connecting to the mail server. Defaults to false. If true, the connection will default to port 587. If false, the connection will default to port 465. Setting a port in `PDS_SMTP_AUTH_URI` will override either one. 64- `PDS_SMTP_SENDER` — The identity to send emails as. Can be an email address (`e@mail.com`) or a mailbox (`Name <e@mail.com>`). 65 66### S3 67 68The PDS can be configured to back up server data to and/or store blobs in S3(-compatible storage). 69 70- `PDS_S3_BLOBS_ENABLED=false` — Whether to store blobs in S3. By default, blobs are stored locally in `{PDS_DATA_DIR}/blobs/[did]/`. 71- `PDS_S3_BACKUPS_ENABLED=false` — Whether to back up data to S3. 72- `PDS_S3_BACKUP_INTERVAL_S=3600` — How often to back up to S3, in seconds. 73- `PDS_S3_ENDPOINT`, `PDS_S3_REGION`, `PDS_S3_BUCKET`, `PDS_S3_ACCESS_KEY`, `PDS_S3_SECRET_KEY` — S3 configuration. 74- `PDS_S3_CDN_URL` — You may optionally set this to redirect `getBlob` requests to `{PDS_S3_CDN_URL}/blobs/{did}/{cid}`. When unset, blobs will be fetched either from local storage or from S3, depending on `PDS_S3_BLOBS_ENABLED`. 75 76## libraries 77 78This repo contains several libraries in addition to the `pegasus` PDS. Each library has its own README with detailed documentation. 79 80### <a id="ipld"></a>[ipld](ipld/README.md) 81 82A mostly [DASL-compliant](https://dasl.ing/) implementation of [CIDs](https://dasl.ing/cid.html), [CAR](https://dasl.ing/car.html), and [DAG-CBOR](https://dasl.ing/drisl.html). 83 84Provides content addressing primitives for IPLD: Content Identifiers (CIDs), Content Addressable aRchives (CAR), and deterministic CBOR encoding. 85 86### <a id="kleidos"></a>[kleidos](kleidos/README.md) 87 88An atproto-valid interface for secp256k1 and secp256r1 key management, signing/verifying, and encoding/decoding. 89 90Handles cryptographic operations for both K-256 and P-256 elliptic curves with multikey encoding and did:ket generation. 91 92### <a id="mist"></a>[mist](mist/README.md) 93 94A [Merkle Search Tree](https://atproto.com/specs/repository#mst-structure) implementation for data repository purposes with a swappable storage backend. 95 96### <a id="hermes"></a>[hermes](hermes/README.md) 97 98An XRPC client for atproto with three components: 99 100- **hermes** - Core XRPC client library 101- **hermes_ppx** - PPX extension for ergonomic API calls 102- **hermes-cli** - CLI to generate OCaml types from atproto lexicons 103 104### <a id="frontend"></a>[frontend](frontend/README.md) 105 106The PDS frontend, containing the admin dashboard and account page. 107 108### <a id="pegasus-library"></a>[pegasus](pegasus/README.md) 109 110The PDS implementation. 111 112## development 113 114To start developing, you'll need: 115 116- [`opam`](https://opam.ocaml.org/doc/Install.html), the OCaml Package Manager 117- and the following packages, or their equivalents on your operating system: `cmake git libev-dev libffi-dev libgmp-dev libssl-dev libsqlite3-dev libpcre3-dev pkg-config` 118 119Start by creating an opam switch; similar to a Python virtual environment, storing the dependencies for this project and a specific compiler version. After that, install [`dune`](https://dune.build), the build system/package manager pegasus uses. 120 121``` 122opam switch create . 5.2.1 --no-install 123opam install dune 124``` 125 126You may need to run `eval $(opam env)` for this to work. Next, run 127 128``` 129dune pkg lock 130``` 131 132to solve dependencies. 133 134Set the required environment variables (see [Environment](#environment)), noting that the program won't automatically read from `.env`, then either run 135 136``` 137dune exec pegasus 138``` 139 140to run the program directly, or 141 142``` 143dune build 144``` 145 146to produce an executable that you'll likely find in `_build/default/bin`. 147 148For development, you'll also want to run 149 150``` 151dune tools exec ocamlformat 152dune tools exec ocamllsp 153``` 154 155to download the formatter and LSP services. You can run `dune fmt` to format the project. 156 157The [frontend](frontend/) and [email templates](pegasus/lib/emails/) are written in [MLX](https://github.com/ocaml-mlx/mlx), a JSX-ish OCaml dialect. To format them, you'll need to `opam install ocamlformat-mlx`, then `ocamlformat-mlx -i ./{frontend,pegasus}/**/*.mlx`.