A community based topic aggregation platform built on atproto
1# Coves Local Development Environment Configuration
2# This file contains all environment variables for the local atProto development stack
3# DO NOT commit secrets to version control in production!
4
5# =============================================================================
6# PostgreSQL Configuration (Development Database)
7# =============================================================================
8# Development database for Coves AppView (runs on port 5435)
9POSTGRES_HOST=localhost
10POSTGRES_PORT=5435
11POSTGRES_DB=coves_dev
12POSTGRES_USER=dev_user
13POSTGRES_PASSWORD=dev_password
14
15# =============================================================================
16# PDS (Personal Data Server) Configuration
17# =============================================================================
18# PDS runs on port 3001 (to avoid conflict with production PDS on :3000)
19PDS_HOSTNAME=localhost
20PDS_PORT=3001
21
22# PDS Service Endpoint for DIDs
23# This is the URL that goes in DID documents' atproto_pds service endpoint
24# Must match what the PDS thinks its public URL is (internal port 3000)
25# Development: http://localhost:3000 (PDS's internal view)
26# Production: https://pds.coves.social
27PDS_SERVICE_ENDPOINT=http://localhost:3000
28
29# DID PLC Directory for PDS
30# For local E2E testing: Use local PLC (requires --profile plc)
31# Note: Use container hostname for PDS to reach PLC within Docker network
32PDS_DID_PLC_URL=http://plc-directory:3000
33
34# JWT Secret (for signing tokens - change in production!)
35PDS_JWT_SECRET=local-dev-jwt-secret-change-in-production
36
37# Admin password for PDS management
38PDS_ADMIN_PASSWORD=admin
39
40# Handle domains (users will get handles like alice.local.coves.dev)
41# Communities will use c-{name}.coves.social (3-level format with c- prefix)
42PDS_SERVICE_HANDLE_DOMAINS=.local.coves.dev,.coves.social
43
44# PLC Rotation Key (k256 private key in hex format - for local dev only)
45# This is a randomly generated key for testing - DO NOT use in production
46PDS_PLC_ROTATION_KEY=af514fb84c4356241deed29feb392d1ee359f99c05a7b8f7bff2e5f2614f64b2
47
48# =============================================================================
49# AppView Configuration (Your Go Application)
50# =============================================================================
51# AppView runs on port 8081 (to avoid conflicts)
52APPVIEW_PORT=8081
53
54# PDS Firehose URL (WebSocket connection - direct to PDS, no relay)
55FIREHOSE_URL=ws://localhost:3001/xrpc/com.atproto.sync.subscribeRepos
56
57# PDS URL (for XRPC calls)
58PDS_URL=http://localhost:3001
59
60# =============================================================================
61# Test Database Configuration
62# =============================================================================
63# Test database runs on port 5434 (separate from dev on 5433)
64POSTGRES_TEST_DB=coves_test
65POSTGRES_TEST_USER=test_user
66POSTGRES_TEST_PASSWORD=test_password
67POSTGRES_TEST_PORT=5434
68
69# =============================================================================
70# Jetstream Configuration (Read-Forward User Indexing)
71# =============================================================================
72# Jetstream WebSocket URL for real-time atProto events
73#
74# Production: Use Bluesky's public Jetstream (indexes entire network)
75# JETSTREAM_URL=wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.actor.profile
76#
77# Local E2E Testing: Use local Jetstream (indexes only local PDS)
78# 1. Start local Jetstream: docker-compose --profile jetstream up pds jetstream
79# 2. Use this URL:
80JETSTREAM_URL=ws://localhost:6008/subscribe
81
82# Optional: Filter events to specific PDS
83# JETSTREAM_PDS_FILTER=http://localhost:3001
84
85# =============================================================================
86# Identity Resolution Configuration
87# =============================================================================
88# IMPORTANT: In dev mode (IS_DEV_ENV=true), identity resolution automatically
89# uses PLC_DIRECTORY_URL to ensure E2E tests stay local. In production, you
90# can optionally set IDENTITY_PLC_URL to use a different URL for read operations.
91#
92# For local dev: Leave IDENTITY_PLC_URL unset (uses PLC_DIRECTORY_URL)
93# For production: Optionally set IDENTITY_PLC_URL=https://plc.directory
94
95# Cache TTL for resolved identities (Go duration format: 24h, 1h30m, etc.)
96IDENTITY_CACHE_TTL=24h
97
98# =============================================================================
99# OAuth Configuration
100# =============================================================================
101# OAuth client private key (ES256 keypair - generate with: go run cmd/genjwks/main.go)
102# DO NOT commit this to version control in production!
103#
104# Supports two formats:
105# 1. Plain JSON (easier for local development):
106# OAUTH_PRIVATE_JWK={"alg":"ES256","crv":"P-256",...}
107#
108# 2. Base64 encoded (recommended for production to avoid shell escaping):
109# OAUTH_PRIVATE_JWK=base64:eyJhbGciOiJFUzI1NiIsImNydiI6IlAtMjU2Ii...
110# Generate with: echo '{"alg":...}' | base64 -w 0
111#
112OAUTH_PRIVATE_JWK={"alg":"ES256","crv":"P-256","d":"9tCMceYSgyZfO5KYOCm3rWEhXLqq2l4LjP7-PJtJKyk","kid":"oauth-client-key","kty":"EC","use":"sig","x":"EOYWEgZ2d-smTO6jh0f-9B7YSFYdlrvlryjuXTCrOjE","y":"_FR2jBcWNxoJl5cd1eq9sYtAs33No9AVtd42UyyWYi4"}
113
114# Cookie secret for session encryption (generate with: openssl rand -hex 32)
115# Also supports base64: prefix for consistency
116OAUTH_COOKIE_SECRET=f1132c01b1a625a865c6c455a75ee793572cedb059cebe0c4c1ae4c446598f7d
117
118# Seal secret for OAuth session tokens (AES-256-GCM encryption)
119# Generate with: openssl rand -base64 32
120# This must be 32 bytes when base64-decoded for AES-256
121# OAUTH_SEAL_SECRET=ryW6xNVxYhP6hCDA90NGCmK58Q2ONnkYXbHL0oZN2no=
122
123# AppView public URL (used for OAuth callback and client metadata)
124# Dev: http://127.0.0.1:8081 (use 127.0.0.1 instead of localhost per RFC 8252)
125# Prod: https://coves.social
126APPVIEW_PUBLIC_URL=http://127.0.0.1:8081
127
128# =============================================================================
129# Coves Instance PDS Authentication
130# =============================================================================
131# The Coves instance needs a PDS account to write community records
132# Create this account once: curl -X POST http://localhost:3001/xrpc/com.atproto.server.createAccount
133PDS_INSTANCE_HANDLE=testuser123.local.coves.dev
134PDS_INSTANCE_PASSWORD=test-password-123
135
136# Trusted Aggregator DIDs (bypasses community authorization check)
137# Comma-separated list of DIDs
138# - did:plc:yyf34padpfjknejyutxtionr = kagi-news.coves.social (production)
139# - did:plc:igjbg5cex7poojsniebvmafb = test-aggregator.local.coves.dev (dev)
140TRUSTED_AGGREGATOR_DIDS=did:plc:yyf34padpfjknejyutxtionr,did:plc:igjbg5cex7poojsniebvmafb
141
142# =============================================================================
143# Development Settings
144# =============================================================================
145# Environment
146ENV=development
147NODE_ENV=development
148# Always true for local development (use PLC_DIRECTORY_URL to control registration)
149IS_DEV_ENV=true
150
151# Security: Skip did:web domain verification for local development
152# IMPORTANT: Set to false in production to prevent domain spoofing attacks
153# When true, communities can claim any hostedByDID without verification
154# When false, hostedByDID must match the community handle domain
155SKIP_DID_WEB_VERIFICATION=true
156
157# Authentication: Skip JWT signature verification for local development (Phase 1)
158# IMPORTANT: Set to false in production for full signature verification
159# When true, only parses JWT without verifying signature (trusts any valid JWT format)
160# When false, verifies JWT signature against issuer's JWKS
161AUTH_SKIP_VERIFY=true
162
163# HS256 Issuers: PDSes allowed to use HS256 (shared secret) authentication
164# Must share PDS_JWT_SECRET with Coves instance. External PDSes use ES256 via DID resolution.
165# For local dev, allow the local PDS or turn AUTH_SKIP_VERIFY = true
166HS256_ISSUERS=http://localhost:3001
167
168# Logging
169LOG_LEVEL=debug
170LOG_ENABLED=true
171
172# =============================================================================
173# PLC Directory Configuration
174# =============================================================================
175# URL for PLC (Public Ledger of Credentials) directory
176#
177# For local E2E testing with registration: http://localhost:3002 (requires --profile plc)
178# - Registers DIDs with local PLC directory
179# - Safe for testing, won't pollute production plc.directory
180# - PDS must also be configured to use local PLC (see PDS_DID_PLC_URL)
181#
182# Production: https://plc.directory (currently Bluesky's, will transfer to third party)
183# - DO NOT use production PLC for testing!
184#
185PLC_DIRECTORY_URL=http://localhost:3002
186
187# =============================================================================
188# Dev Mode Quick Reference
189# =============================================================================
190# REQUIRED for local OAuth to work with local PDS:
191# IS_DEV_ENV=true # Master switch for dev mode
192# PDS_URL=http://localhost:3001 # Local PDS for handle resolution
193# PLC_DIRECTORY_URL=http://localhost:3002 # Local PLC directory
194# APPVIEW_PUBLIC_URL=http://127.0.0.1:8081 # Use IP not localhost (RFC 8252)
195#
196# BUILD TAGS:
197# make run - Runs with -tags dev (includes localhost OAuth resolvers)
198# make build - Production binary (no dev code)
199# make build-dev - Dev binary (includes dev code)
200#
201# Dev-only code (only compiled with -tags dev):
202# - internal/atproto/oauth/dev_resolver.go (handle resolution via local PDS)
203# - internal/atproto/oauth/dev_auth_resolver.go (localhost OAuth bypass)
204#
205# =============================================================================
206# Notes
207# =============================================================================
208# All local development configuration in one file!
209# - Dev PostgreSQL: port 5435
210# - Test PostgreSQL: port 5434 (via --profile test)
211# - PDS: port 3001 (avoids conflict with production on :3000)
212# - AppView: port 8081
213# - PDS is self-contained (SQLite + CAR files)
214# - PostgreSQL is only for Coves AppView indexing
215# - AppView subscribes directly to PDS firehose (no relay needed)
216# - PDS firehose: ws://localhost:3001/xrpc/com.atproto.sync.subscribeRepos