A third party ATProto appview
at main 2.8 kB view raw
1#!/bin/bash 2 3# A pure Bash script to generate a standalone oauth-keyset.json file 4# using a P-256 (prime256v1) key for ES256, suitable for AT Protocol OAuth client authentication. 5# 6# NOTE: ES256 (P-256) is required for private_key_jwt client authentication in ATProto OAuth. 7# ES256K (secp256k1) is used for other ATProto operations, but NOT for OAuth client auth. 8# 9# Dependencies: openssl, jq, xxd 10 11set -e 12 13echo "🔐 OAuth Keyset Generator" 14echo "===========================" 15echo "" 16 17# --- Dependency Check --- 18for cmd in openssl jq xxd; do 19 if ! command -v $cmd &> /dev/null; then 20 echo "❌ Missing required dependency: $cmd" 21 exit 1 22 fi 23done 24 25# --- Key Generation --- 26echo "🔑 Generating P-256 (ES256) key pair for OAuth client authentication..." 27# 1. Generate a P-256 (prime256v1) private key in the legacy format 28openssl ecparam -name prime256v1 -genkey -noout -out private-legacy.pem 29 30# 2. Convert the legacy key to the required PKCS#8 format 31openssl pkcs8 -topk8 -nocrypt -in private-legacy.pem -out private-pkcs8.pem 32 33# 3. Generate the corresponding public key 34openssl ec -in private-legacy.pem -pubout -out public.pem 2>/dev/null 35 36# Read PEM file contents into variables (using the corrected PKCS#8 private key) 37PRIVATE_KEY_PEM=$(cat private-pkcs8.pem) 38PUBLIC_KEY_PEM=$(cat public.pem) 39 40echo "⚙️ Formatting key into JWK format..." 41# Extract components from the original key for JWK 42KEY_COMPONENTS_HEX=$(openssl ec -in private-legacy.pem -text -noout) 43 44# Isolate and clean up each component 45PRIV_HEX=$(echo "$KEY_COMPONENTS_HEX" | grep priv -A 3 | tail -n +2 | tr -d ' \n:') 46PUB_HEX=$(echo "$KEY_COMPONENTS_HEX" | grep pub -A 5 | tail -n +2 | tr -d ' \n:') 47X_HEX=$(echo "$PUB_HEX" | cut -c 3-66) 48Y_HEX=$(echo "$PUB_HEX" | cut -c 67-130) 49 50# Convert hex components to base64url for the JWK 51D_B64URL=$(echo -n "$PRIV_HEX" | xxd -r -p | base64 | tr '/+' '_-' | tr -d '=') 52X_B64URL=$(echo -n "$X_HEX" | xxd -r -p | base64 | tr '/+' '_-' | tr -d '=') 53Y_B64URL=$(echo -n "$Y_HEX" | xxd -r -p | base64 | tr '/+' '_-' | tr -d '=') 54 55# Generate a unique Key ID (kid) 56KID="$(date +%s)-$(openssl rand -hex 4)" 57 58# --- File Creation --- 59echo "📄 Creating oauth-keyset.json file..." 60jq -n \ 61 --arg kid "$KID" \ 62 --arg pkpem "$PRIVATE_KEY_PEM" \ 63 --arg pubpem "$PUBLIC_KEY_PEM" \ 64 --arg d "$D_B64URL" \ 65 --arg x "$X_B64URL" \ 66 --arg y "$Y_B64URL" \ 67 '{ 68 kid: $kid, 69 privateKeyPem: $pkpem, 70 publicKeyPem: $pubpem, 71 jwk: { 72 kid: $kid, 73 kty: "EC", 74 crv: "P-256", 75 alg: "ES256", 76 use: "sig", 77 d: $d, 78 x: $x, 79 y: $y 80 } 81 }' > oauth-keyset.json 82 83# --- Cleanup --- 84rm private-legacy.pem private-pkcs8.pem public.pem 85 86echo "" 87echo "✅ Success! oauth-keyset.json generated with ES256 (P-256) key for OAuth client authentication." 88echo ""