#!/bin/bash # scripts/generate-client-cert.sh # Flexible client certificate generation for any use case # Usage: ./scripts/generate-client-cert.sh [days-valid] set -e NAME=$1 OU=$2 DAYS_VALID=${3:-365} SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CERT_DIR="${SCRIPT_DIR}/../certs" if [ -z "$NAME" ] || [ -z "$OU" ]; then echo "Usage: $0 [days-valid]" echo "" echo "Examples:" echo " $0 payment-service automation # Service certificate (default 365 days)" echo " $0 jane-doe platform-team # Admin certificate" echo " $0 jira-plugin plugins # Plugin certificate" echo " $0 contractor-bob monitoring 30 # Temporary certificate (30 days)" echo "" echo "Common OU values:" echo " automation → service-writer role (create, read, update, list)" echo " platform-team → admin role (full access)" echo " monitoring → catalog-reader role (read, list only)" echo " plugins → plugin role (read, update annotations)" exit 1 fi # Ensure cert directory exists mkdir -p "$CERT_DIR" cd "$CERT_DIR" # Check if CA exists if [ ! -f "ca.pem" ] || [ ! -f "ca-key.pem" ]; then echo "❌ Error: CA not found!" echo " Run ./scripts/generate-dev-certs.sh first to create the CA" exit 1 fi echo "🔐 Generating certificate for: $NAME" echo " OU: $OU" echo " Organization: Company" echo " Valid for: $DAYS_VALID days" echo "" # Generate private key openssl genrsa -out "${NAME}-key.pem" 2048 2>/dev/null # Generate CSR openssl req -new \ -key "${NAME}-key.pem" \ -out "${NAME}.csr" \ -subj "/CN=${NAME}/OU=${OU}/O=Company/C=US" \ 2>/dev/null # Sign certificate openssl x509 -req \ -days ${DAYS_VALID} \ -in "${NAME}.csr" \ -CA ca.pem \ -CAkey ca-key.pem \ -CAcreateserial \ -out "${NAME}-cert.pem" \ -extfile <(echo "extendedKeyUsage=clientAuth") \ 2>/dev/null # Clean up CSR rm "${NAME}.csr" echo "✅ Certificate generated successfully!" echo "" echo "📋 Files created:" echo " ${CERT_DIR}/${NAME}-cert.pem" echo " ${CERT_DIR}/${NAME}-key.pem" echo "" echo "🔍 Certificate details:" openssl x509 -in "${NAME}-cert.pem" -noout -subject -dates echo "" echo "🎯 Role mapping (based on OU):" case $OU in "platform-team"|"admin") echo " Role: admin" echo " Permissions: Full access (entity:*)" ;; "automation"|"ci-cd") echo " Role: service-writer" echo " Permissions: create, read, update, list entities" ;; "platform"|"monitoring"|"dashboard") echo " Role: catalog-reader" echo " Permissions: read, list entities only" ;; "plugins") echo " Role: plugin" echo " Permissions: read, update annotations only" ;; *) echo " Role: Unknown - check security-config.yaml for mapping" echo " You may need to add a rule for OU=${OU}" ;; esac echo "" echo "📦 Distribute these files securely to the user:" echo " ${NAME}-cert.pem" echo " ${NAME}-key.pem" echo " ca.pem" echo "" echo "💡 Example distribution:" echo " # Copy to user's machine:" echo " scp ${NAME}-cert.pem ${NAME}-key.pem ca.pem user@host:~/.charybdis/" echo "" echo " # Or store in secrets manager:" echo " vault kv put secret/charybdis/${NAME} \\" echo " cert=@${NAME}-cert.pem \\" echo " key=@${NAME}-key.pem \\" echo " ca=@ca.pem" echo "" echo "🔒 Security reminder:" echo " - Keep private key (${NAME}-key.pem) secret!" echo " - Store securely (1Password, Vault, etc.)" echo " - Never commit to git" echo " - Valid for ${DAYS_VALID} days (expires $(date -v +${DAYS_VALID}d '+%Y-%m-%d' 2>/dev/null || date -d "+${DAYS_VALID} days" '+%Y-%m-%d' 2>/dev/null || echo 'N/A'))" echo ""