A community based topic aggregation platform built on atproto
at main 4.4 kB view raw
1#!/bin/bash 2# Generate cryptographic keys for Coves did:web DID document 3# 4# This script generates a secp256k1 (K-256) key pair as required by atproto. 5# Reference: https://atproto.com/specs/cryptography 6# 7# Key format: 8# - Curve: secp256k1 (K-256) - same as Bitcoin/Ethereum 9# - Type: Multikey 10# - Encoding: publicKeyMultibase with base58btc ('z' prefix) 11# - Multicodec: 0xe7 for secp256k1 compressed public key 12# 13# Output: 14# - Private key (hex) for PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX 15# - Public key (multibase) for did.json publicKeyMultibase field 16# - Complete did.json file 17 18set -e 19 20SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 21PROJECT_DIR="$(dirname "$SCRIPT_DIR")" 22OUTPUT_DIR="$PROJECT_DIR/static/.well-known" 23 24# Colors 25GREEN='\033[0;32m' 26YELLOW='\033[1;33m' 27RED='\033[0;31m' 28NC='\033[0m' 29 30log() { echo -e "${GREEN}[KEYGEN]${NC} $1"; } 31warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } 32error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } 33 34# Check for required tools 35if ! command -v openssl &> /dev/null; then 36 error "openssl is required but not installed" 37fi 38 39if ! command -v python3 &> /dev/null; then 40 error "python3 is required for base58 encoding" 41fi 42 43# Check for base58 library 44if ! python3 -c "import base58" 2>/dev/null; then 45 warn "Installing base58 Python library..." 46 pip3 install base58 || error "Failed to install base58. Run: pip3 install base58" 47fi 48 49log "Generating secp256k1 key pair for did:web..." 50 51# Generate private key 52PRIVATE_KEY_PEM=$(mktemp) 53openssl ecparam -name secp256k1 -genkey -noout -out "$PRIVATE_KEY_PEM" 2>/dev/null 54 55# Extract private key as hex (for PDS config) 56PRIVATE_KEY_HEX=$(openssl ec -in "$PRIVATE_KEY_PEM" -text -noout 2>/dev/null | \ 57 grep -A 3 "priv:" | tail -n 3 | tr -d ' :\n' | tr -d '\r') 58 59# Extract public key as compressed format 60# OpenSSL outputs the public key, we need to get the compressed form 61PUBLIC_KEY_HEX=$(openssl ec -in "$PRIVATE_KEY_PEM" -pubout -conv_form compressed -outform DER 2>/dev/null | \ 62 tail -c 33 | xxd -p | tr -d '\n') 63 64# Clean up temp file 65rm -f "$PRIVATE_KEY_PEM" 66 67# Encode public key as multibase with multicodec 68# Multicodec 0xe7 = secp256k1 compressed public key 69# Then base58btc encode with 'z' prefix 70PUBLIC_KEY_MULTIBASE=$(python3 << EOF 71import base58 72 73# Compressed public key bytes 74pub_hex = "$PUBLIC_KEY_HEX" 75pub_bytes = bytes.fromhex(pub_hex) 76 77# Prepend multicodec 0xe7 for secp256k1-pub 78# 0xe7 as varint is just 0xe7 (single byte, < 128) 79multicodec = bytes([0xe7, 0x01]) # 0xe701 for secp256k1-pub compressed 80key_with_codec = multicodec + pub_bytes 81 82# Base58btc encode 83encoded = base58.b58encode(key_with_codec).decode('ascii') 84 85# Add 'z' prefix for multibase 86print('z' + encoded) 87EOF 88) 89 90log "Keys generated successfully!" 91echo "" 92echo "============================================" 93echo " PRIVATE KEY (keep secret!)" 94echo "============================================" 95echo "" 96echo "Add this to your .env.prod file:" 97echo "" 98echo "PDS_ROTATION_KEY=$PRIVATE_KEY_HEX" 99echo "" 100echo "============================================" 101echo " PUBLIC KEY (for did.json)" 102echo "============================================" 103echo "" 104echo "publicKeyMultibase: $PUBLIC_KEY_MULTIBASE" 105echo "" 106 107# Generate the did.json file 108log "Generating did.json..." 109 110mkdir -p "$OUTPUT_DIR" 111 112cat > "$OUTPUT_DIR/did.json" << EOF 113{ 114 "id": "did:web:coves.social", 115 "alsoKnownAs": ["at://coves.social"], 116 "verificationMethod": [ 117 { 118 "id": "did:web:coves.social#atproto", 119 "type": "Multikey", 120 "controller": "did:web:coves.social", 121 "publicKeyMultibase": "$PUBLIC_KEY_MULTIBASE" 122 } 123 ], 124 "service": [ 125 { 126 "id": "#atproto_pds", 127 "type": "AtprotoPersonalDataServer", 128 "serviceEndpoint": "https://coves.me" 129 } 130 ] 131} 132EOF 133 134log "Created: $OUTPUT_DIR/did.json" 135echo "" 136echo "============================================" 137echo " NEXT STEPS" 138echo "============================================" 139echo "" 140echo "1. Copy the PDS_ROTATION_KEY value to your .env.prod file" 141echo "" 142echo "2. Verify the did.json looks correct:" 143echo " cat $OUTPUT_DIR/did.json" 144echo "" 145echo "3. After deployment, verify it's accessible:" 146echo " curl https://coves.social/.well-known/did.json" 147echo "" 148warn "IMPORTANT: Keep the private key secret! Only share the public key." 149warn "The did.json file with the public key IS safe to commit to git."