A collection of microservices for the Speakeasy platform enabling Bluesky users to share posts with trusted followers only, built with post-quantum encryption and user convenience in mind.
You will need Docker installed
# First time
pnpm install
pnpm build
pnpm dev:setup
# Launch dev environment
pnpm dev
# Or to launch just one service
pnpm dev:private-sessions
To add an invite code in prod:
SSH into spkeasy_services_prod
docker exec -it <container-id> npm run invite:add -- <code> <key> [value] [totalUses]If you've borked your database pnpm dev:setup will wipe and reinitialise it
/
├── packages/ # Shared packages/libraries
│ ├── common/ # Shared code, types, and utilities
│ │ ├── src/
│ │ │ ├── types/ # Shared TypeScript interfaces
│ │ │ ├── constants/ # Shared constants
│ │ │ └── utils/ # Shared utility functions
│ └── crypto/ # Shared cryptographic operations
│ ├── src/
│ │ ├── kyber/ # CRYSTALS-Kyber implementation
│ │ ├── aes/ # AES-256-GCM operations
│ │ └── dilithium/ # CRYSTALS-Dilithium signatures
├── services/ # Individual microservices
│ ├── user-profiles/ # User profile and preferences management
│ ├── user-keys/ # User encryption key management
│ ├── trusted-users/ # Trust relationship management
│ ├── private-sessions/ # Encryption session and private post management
│ ├── group-sessions/ # (Future)
│ └── group-members/ # (Future)
├── docker/ # Docker configuration
│ ├── development/
│ └── production/
├── scripts/ # Build and deployment scripts
├── tests/ # Integration tests
├── .github/ # GitHub Actions workflows
├── package.json # Root package.json for workspace
├── tsconfig.json # Base TypeScript configuration
└── docker-compose.yml # Local development setup
A set of microservices handling:
- User profiles and preferences (user-profiles)
- User encryption keys (user-keys)
- Trust relationships (trusted-users)
- Encryption sessions and private posts (private-sessions)
- TypeScript
- XRPC (@atproto/xrpc-server)
- PostgreSQL with Prisma ORM
- Authentication using AT Protocol JWT tokens
- Post-quantum encryption (CRYSTALS-Kyber)
- Symmetric encryption (AES-256-GCM)
- Completely out-of-band from Bluesky PDS
- No modifications to user's Bluesky data
- Staff access for moderation
- Multi-device support
- Key rotation and revocation
- Forward secrecy through session management
The services are built as a collection of microservices that share a common development environment. Each service has its own:
- Database schema
- API endpoints
- Job processing (via PgBoss)
- Prisma models and migrations
-
User Profiles Service
- Manages user keys and profiles
- Schema:
user_profiles - Port: 3001
-
Private Sessions Service
- Handles private session creation and management
- Schema:
private_sessions - Port: 3002
- Processes session-related jobs
-
Trusted Users Service
- Manages trusted user relationships
- Schema:
trusted_users - Port: 3003
- Schedules session recipient additions
-
PostgreSQL Database
- Single database instance
- Separate schemas for each service
- Shared PgBoss schema for job processing
- Environment-based database names:
- Development:
speakeasydatabase - Test:
speakeasy_testdatabase - Production: Uses production database URLs
- Development:
- Default credentials:
- User: speakeasy
- Password: speakeasy
- Database: speakeasy (development) or speakeasy_test (test)
-
PgBoss
- Centralized job processing
- Single schema (
pgboss) - Job names partition processing by service
- Web UI available at http://localhost:8080
- Node.js (v18 or later)
- Docker and Docker Compose
- pnpm
-
Install dependencies:
pnpm install
-
Start the development environment:
pnpm dev:setup
This will:
- Create a
.envfile from.env.exampleif it doesn't exist - Replace placeholder Stripe API secret key (Test environment!) in
.envif relevant to your work - Start all services in Docker
- Run database migrations
- Build and start the services
- Create a
The application supports multiple environments:
- Development (default): Uses
speakeasydatabase - Test: Uses
speakeasy_testdatabase
# Default development setup
pnpm dev:setup
# Or explicitly set environment
NODE_ENV=development pnpm dev:setup# Test environment setup
pnpm test:setup
# Or explicitly set environment
NODE_ENV=test pnpm dev:setupThe environment is determined by the NODE_ENV environment variable:
NODE_ENV=development(or unset) → usesspeakeasydatabaseNODE_ENV=test→ usesspeakeasy_testdatabase (or modifies existing environment variables to use test database)NODE_ENV=production→ requires explicit service-specific environment variables (e.g.,PRIVATE_SESSIONS_DATABASE_URL,TRUSTED_USERS_DATABASE_URL, etc.)
If you see errors about database migrations:
- Check that your
.envfile has the correct database URLs - Each service has its own database URL (e.g.
PRIVATE_SESSIONS_DATABASE_URL,TRUSTED_USERS_DATABASE_URL) - The main
DATABASE_URLis used for migrations - Database URLs are automatically derived based on
NODE_ENV:- Development:
postgresql://speakeasy:speakeasy@localhost:5496/speakeasy?schema=<service_schema> - Test:
postgresql://speakeasy:speakeasy@localhost:5496/speakeasy_test?schema=<service_schema>(or modifies existing environment variables to use test database) - Production: Requires explicit service-specific environment variables (e.g.,
PRIVATE_SESSIONS_DATABASE_URL,TRUSTED_USERS_DATABASE_URL, etc.)
- Development:
If you see TypeScript errors:
- Make sure all dependencies are installed
- Check that the common package is built
- Run
pnpm buildin the common package if needed
Services depend on each other in this order:
user-keys- Provides key managementtrusted-users- Manages trust relationshipsprivate-sessions- Handles private sessionsprivate-posts- Manages private posts
If a service fails to start, check its dependencies are running first.
- Make changes to the code
- Run
pnpm buildto rebuild affected packages - Restart services as needed with
pnpm dev
Run tests with:
pnpm test- Create a new branch for your feature
- Make your changes
- Run tests and ensure everything builds
- Submit a pull request
[License details here]
See REFERENCE.md for detailed technical documentation.