Vow, uncensorable PDS written in Go
Go 96.4%
HTML 1.4%
Shell 0.8%
Makefile 0.8%
CSS 0.4%
Dockerfile 0.2%
145 1 36

Clone this repository

https://tangled.org/julien.rbrt.fr/vow https://tangled.org/did:plc:7kpq3n7brenbgyp2gx36hl6x/vow
git@knot.srv.rbrt.fr:julien.rbrt.fr/vow git@knot.srv.rbrt.fr:did:plc:7kpq3n7brenbgyp2gx36hl6x/vow

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

Vow#

WARNING

This is highly experimental software. Use with caution, especially during account migration.

Vow is a PDS (Personal Data Server) implementation in Go for the AT Protocol.

Quick Start with Docker Compose#

Prerequisites#

  • Docker and Docker Compose installed
  • A domain name pointing to your server
  • Ports 80 and 443 open

Installation#

  1. Clone the repository

    git clone https://pkg.rbrt.fr/vow.git
    cd vow
    
  2. Create your configuration file

    cp .env.example .env
    
  3. Edit .env with your settings

    VOW_DID="did:web:your-domain.com"
    VOW_HOSTNAME="your-domain.com"
    VOW_CONTACT_EMAIL="you@example.com"
    VOW_RELAYS="https://bsky.network"
    
    # Generate with: openssl rand -hex 16
    VOW_ADMIN_PASSWORD="your-secure-password"
    
    # Generate with: openssl rand -hex 32
    VOW_SESSION_SECRET="your-session-secret"
    
  4. Start the services

    docker-compose pull
    docker-compose up -d
    
  5. Get your invite code

    On first run, an invite code is automatically created. View it with:

    docker-compose logs create-invite
    

    Or check the saved file:

    cat keys/initial-invite-code.txt
    
  6. Monitor the services

    docker-compose logs -f
    

What Gets Set Up#

  • init-keys: Generates cryptographic keys (rotation key and JWK) on first run
  • vow: The main PDS service running on port 8080
  • create-invite: Creates an initial invite code on first run

Data Persistence#

  • ./keys/ — Cryptographic keys (generated automatically)
    • rotation.key — PDS rotation key
    • jwk.key — JWK private key
    • initial-invite-code.txt — Your first invite code (first run only)
  • ./data/ — SQLite database and blockstore

Configuration#

Database#

Vow uses SQLite by default. No additional setup required.

VOW_DB_NAME="/data/vow/vow.db"

SMTP Email#

VOW_SMTP_USER="your-smtp-username"
VOW_SMTP_PASS="your-smtp-password"
VOW_SMTP_HOST="smtp.example.com"
VOW_SMTP_PORT="587"
VOW_SMTP_EMAIL="noreply@example.com"
VOW_SMTP_NAME="Vow PDS"

IPFS Blob Storage#

By default blobs are stored in SQLite. Optionally, blobs can be stored on IPFS via a local Kubo node:

VOW_IPFS_BLOBSTORE_ENABLED=true

# URL of the local Kubo RPC API (default: http://127.0.0.1:5001)
VOW_IPFS_NODE_URL="http://127.0.0.1:5001"

# Optional: redirect getBlob to a public gateway instead of proxying
VOW_IPFS_GATEWAY_URL="https://ipfs.io"

# Optional: remote pinning service
VOW_IPFS_PINNING_SERVICE_URL="https://api.pinata.cloud/psa"
VOW_IPFS_PINNING_SERVICE_TOKEN="your-token"

Management Commands#

Create an invite code:

docker exec vow-pds /vow create-invite-code --uses 1

Reset a user's password:

docker exec vow-pds /vow reset-password --did "did:plc:xxx"

Updating#

docker-compose pull
docker-compose up -d

Implemented Endpoints#

NOTE

Just because something is implemented doesn't mean it is finished. Many endpoints still have rough edges around validation and error handling.

Identity#

  • com.atproto.identity.getRecommendedDidCredentials
  • com.atproto.identity.requestPlcOperationSignature
  • com.atproto.identity.resolveHandle
  • com.atproto.identity.signPlcOperation
  • com.atproto.identity.submitPlcOperation
  • com.atproto.identity.updateHandle

Repo#

  • com.atproto.repo.applyWrites
  • com.atproto.repo.createRecord
  • com.atproto.repo.putRecord
  • com.atproto.repo.deleteRecord
  • com.atproto.repo.describeRepo
  • com.atproto.repo.getRecord
  • com.atproto.repo.importRepo (Works "okay". Use with extreme caution.)
  • com.atproto.repo.listRecords
  • com.atproto.repo.listMissingBlobs

Server#

  • com.atproto.server.activateAccount
  • com.atproto.server.checkAccountStatus
  • com.atproto.server.confirmEmail
  • com.atproto.server.createAccount
  • com.atproto.server.createInviteCode
  • com.atproto.server.createInviteCodes
  • com.atproto.server.deactivateAccount
  • com.atproto.server.deleteAccount
  • com.atproto.server.deleteSession
  • com.atproto.server.describeServer
  • com.atproto.server.getAccountInviteCodes
  • com.atproto.server.getServiceAuth
  • com.atproto.server.refreshSession
  • com.atproto.server.requestAccountDelete
  • com.atproto.server.requestEmailConfirmation
  • com.atproto.server.requestEmailUpdate
  • com.atproto.server.requestPasswordReset
  • com.atproto.server.reserveSigningKey
  • com.atproto.server.resetPassword
  • com.atproto.server.updateEmail

Sync#

  • com.atproto.sync.getBlob
  • com.atproto.sync.getBlocks
  • com.atproto.sync.getLatestCommit
  • com.atproto.sync.getRecord
  • com.atproto.sync.getRepoStatus
  • com.atproto.sync.getRepo
  • com.atproto.sync.listBlobs
  • com.atproto.sync.listRepos
  • com.atproto.sync.requestCrawl
  • com.atproto.sync.subscribeRepos

Other#

  • com.atproto.label.queryLabels
  • com.atproto.moderation.createReport
  • app.bsky.actor.getPreferences
  • app.bsky.actor.putPreferences

License#

MIT. server/static/pico.css is also MIT licensed, available at https://github.com/picocss/pico/.