#!/usr/bin/env bash ############################################################################### # KISC MCPF - Install VeriTrust-Issued Credential # # Installs the VeriTrust-signed MCP Server Credential and validates it # # Usage: ./install-credential.sh ############################################################################### set -euo pipefail CREDENTIAL_FILE="${1:-}" DEPLOY_DIR="/opt/kisc-llm/poc/deploy" TARGET="$DEPLOY_DIR/.well-known/credentials/mcp-server.json" # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # ============================================================================= # Validation # ============================================================================= if [[ -z "$CREDENTIAL_FILE" ]]; then log_error "Usage: $0 " echo "" echo "Example:" echo " $0 /tmp/veritrust-credential.json" exit 1 fi if [[ ! -f "$CREDENTIAL_FILE" ]]; then log_error "File not found: $CREDENTIAL_FILE" exit 1 fi if [[ ! -d "$DEPLOY_DIR" ]]; then log_error "Deploy directory not found: $DEPLOY_DIR" exit 1 fi echo "============================================" echo "Install VeriTrust Credential" echo "============================================" echo "Source: $CREDENTIAL_FILE" echo "Target: $TARGET" echo "" # ============================================================================= # Validate Credential Format # ============================================================================= log_info "Step 1: Validating credential format..." # Check if valid JSON if ! jq empty "$CREDENTIAL_FILE" 2>/dev/null; then log_error "Invalid JSON in credential file" exit 1 fi # Check required fields REQUIRED_FIELDS=( "@context" "type" "issuer.id" "credentialSubject.id" "proof.type" "proof.proofValue" ) for field in "${REQUIRED_FIELDS[@]}"; do if ! jq -e ".$field" "$CREDENTIAL_FILE" >/dev/null 2>&1; then log_error "Missing required field: $field" exit 1 fi done # Verify issuer is VeriTrust ISSUER=$(jq -r '.issuer.id' "$CREDENTIAL_FILE") if [[ "$ISSUER" != "did:web:veritrust.vc" ]]; then log_error "Invalid issuer: $ISSUER (expected: did:web:veritrust.vc)" exit 1 fi # Verify subject is KISC MCP server SUBJECT=$(jq -r '.credentialSubject.id' "$CREDENTIAL_FILE") if [[ "$SUBJECT" != "did:web:llm.kis.gov.lv#mcp-server" ]]; then log_warn "Subject mismatch: $SUBJECT (expected: did:web:llm.kis.gov.lv#mcp-server)" fi # Check expiration EXPIRATION=$(jq -r '.expirationDate' "$CREDENTIAL_FILE") log_info "Credential expires: $EXPIRATION" log_info "✅ Credential format valid" echo "" # ============================================================================= # Backup Existing Credential # ============================================================================= log_info "Step 2: Backing up existing credential..." if [[ -f "$TARGET" ]]; then BACKUP="$TARGET.backup-$(date +%Y%m%d-%H%M%S)" cp "$TARGET" "$BACKUP" log_info "Backup created: $BACKUP" else log_warn "No existing credential to backup" fi echo "" # ============================================================================= # Install New Credential # ============================================================================= log_info "Step 3: Installing new credential..." # Copy credential to target location cp "$CREDENTIAL_FILE" "$TARGET" # Set permissions (world-readable) chmod 644 "$TARGET" log_info "✅ Credential installed: $TARGET" echo "" # ============================================================================= # Reload nginx # ============================================================================= log_info "Step 4: Reloading nginx..." if docker ps --format '{{.Names}}' | grep -q "kisc-nginx"; then docker exec kisc-nginx nginx -s reload log_info "✅ nginx reloaded" else log_warn "nginx container not found, skipping reload" fi echo "" # ============================================================================= # Verify Installation # ============================================================================= log_info "Step 5: Verifying installation..." # Test endpoint RESPONSE=$(curl -sS -k https://localhost/.well-known/credentials/mcp-server.json 2>/dev/null || echo "") if [[ -z "$RESPONSE" ]]; then log_error "Endpoint not accessible" exit 1 fi if ! echo "$RESPONSE" | jq empty 2>/dev/null; then log_error "Endpoint returned invalid JSON" exit 1 fi # Check proof value matches INSTALLED_PROOF=$(echo "$RESPONSE" | jq -r '.proof.proofValue') SOURCE_PROOF=$(jq -r '.proof.proofValue' "$CREDENTIAL_FILE") if [[ "$INSTALLED_PROOF" != "$SOURCE_PROOF" ]]; then log_error "Proof value mismatch! Installation may be corrupted." exit 1 fi log_info "✅ Installation verified" echo "" # ============================================================================= # Success Summary # ============================================================================= echo "============================================" echo "Installation Complete" echo "============================================" echo "" echo "Credential Details:" echo " Issuer: $(jq -r '.issuer.name' "$TARGET")" echo " Subject: $(jq -r '.credentialSubject.id' "$TARGET")" echo " Issued: $(jq -r '.issuanceDate' "$TARGET")" echo " Expires: $(jq -r '.expirationDate' "$TARGET")" echo " Status URL: $(jq -r '.credentialStatus.statusListCredential' "$TARGET")" echo "" echo "Endpoint:" echo " https://llm.kis.gov.lv/.well-known/credentials/mcp-server.json" echo "" echo "Next Steps:" echo " 1. Test external access:" echo " curl https://llm.kis.gov.lv/.well-known/credentials/mcp-server.json | jq" echo "" echo " 2. Verify in MCPF Registry:" echo " curl https://mcp.veritrust.vc/mcp/servers/did:web:llm.kis.gov.lv" echo "" echo " 3. Test with AI agent (Claude Desktop, ChatGPT, etc.)" echo ""