#!/usr/bin/env bash # Validate the DBIS identity completion package. # Usage: # bash scripts/validation/validate-dbis-identity-package.sh \ # --package config/production/dbis-identity-public-did-package.json \ # --secrets config/production/dbis-identity-public-did-secrets.env # # For template validation only: # bash scripts/validation/validate-dbis-identity-package.sh \ # --package config/production/dbis-identity-public-did-package.example.json \ # --secrets config/production/dbis-identity-public-did-secrets.example.env \ # --allow-placeholders set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" PACKAGE_PATH="$PROJECT_ROOT/config/production/dbis-identity-public-did-package.json" SECRETS_PATH="$PROJECT_ROOT/config/production/dbis-identity-public-did-secrets.env" ALLOW_PLACEHOLDERS=false PARTIAL_EXTERNAL_ALLOWED=false log_info() { echo "[INFO] $1"; } log_ok() { echo "[OK] $1"; } log_warn() { echo "[WARN] $1"; } log_err() { echo "[ERROR] $1"; } while [[ $# -gt 0 ]]; do case "$1" in --package) PACKAGE_PATH="$2" shift 2 ;; --secrets) SECRETS_PATH="$2" shift 2 ;; --allow-placeholders) ALLOW_PLACEHOLDERS=true shift ;; *) log_err "Unknown argument: $1" exit 1 ;; esac done ERRORS=0 WARNINGS=0 require_file() { local path="$1" if [[ -f "$path" ]]; then log_ok "Found: $path" else log_err "Missing file: $path" ERRORS=$((ERRORS + 1)) fi } check_placeholder_string() { local label="$1" local value="$2" if [[ -z "$value" ]]; then log_err "$label is empty" ERRORS=$((ERRORS + 1)) return fi if [[ "$value" == *"/dev/null 2>&1; then log_err "jq is required" exit 1 fi if [[ $ERRORS -gt 0 ]]; then exit 1 fi if jq -e ' (.schemaVersion | type == "string") and (.programId | type == "string") and (.packageStatus | type == "string") and (.ariesAgent.adminUrl | type == "string") and (.ariesAgent.didcommUrl | type == "string") and (.ariesAgent.walletType | type == "string") and (.ariesAgent.adminAuthMode | type == "string") and (.ariesAgent.adminApiKeyEnv | type == "string") and (.ledger.type | type == "string") and (.ledger.targetNetwork | type == "string") and (.ledger.trustScope | type == "string") and (.ledger.poolName | type == "string") and (.ledger.genesisSource | type == "string") and (.ledger.didMethod | type == "string") and (.ledger.nymWriteMode | type == "string") and (.governance.governanceVersion | type == "string") and (.governance.changeControlRef | type == "string") and (.governance.changeControlFormat | type == "string") and (.governance.operatorOwner | type == "string") and (.governance.approvalOwner | type == "string") and (.governance.endorserGovernanceModel.type | type == "string") and (.governance.endorserGovernanceModel.quorum | type == "string") and (.governance.endorserGovernanceModel.custodians | type == "array") and (.governance.endorserGovernanceModel.custodians | length >= 3) and (.governance.endorserGovernanceModel.singleKeyDidControl | type == "string") and (.governance.endorserGovernanceModel.currentPhase | type == "string") and (.governance.endorserGovernanceModel.futurePhases | type == "array") and (.governance.endorserGovernanceModel.futurePhases | length >= 1) and (.roles.author.alias | type == "string") and (.roles.author.connectionIdEnv | type == "string") and (.roles.endorser.alias | type == "string") and (.roles.endorser.did | type == "string") and (.roles.endorser.connectionIdEnv | type == "string") and (.anoncreds.schemas | type == "array") and (.anoncreds.schemas | length >= 1) and (.anoncreds.verificationProfiles | type == "array") and (.anoncreds.verificationProfiles | length >= 1) and (.evidence.outputDir | type == "string") and (.evidence.requiredArtifacts | type == "array") and (.evidence.requiredArtifacts | length >= 1) ' "$PACKAGE_PATH" >/dev/null; then log_ok "Package JSON structure is valid" else log_err "Package JSON structure is invalid" ERRORS=$((ERRORS + 1)) fi PACKAGE_STATUS="$(jq -r '.packageStatus' "$PACKAGE_PATH")" if [[ "$PACKAGE_STATUS" == "awaiting-external-endorser" ]]; then PARTIAL_EXTERNAL_ALLOWED=true log_info "Package status allows external-governance gaps to remain warnings" fi check_placeholder_string "schemaVersion" "$(jq -r '.schemaVersion' "$PACKAGE_PATH")" check_placeholder_string "programId" "$(jq -r '.programId' "$PACKAGE_PATH")" check_placeholder_string "ariesAgent.adminUrl" "$(jq -r '.ariesAgent.adminUrl' "$PACKAGE_PATH")" check_placeholder_string "ariesAgent.didcommUrl" "$(jq -r '.ariesAgent.didcommUrl' "$PACKAGE_PATH")" check_placeholder_string "ariesAgent.adminAuthMode" "$(jq -r '.ariesAgent.adminAuthMode' "$PACKAGE_PATH")" check_placeholder_string "ledger.targetNetwork" "$(jq -r '.ledger.targetNetwork' "$PACKAGE_PATH")" check_placeholder_string "ledger.trustScope" "$(jq -r '.ledger.trustScope' "$PACKAGE_PATH")" check_placeholder_string "ledger.poolName" "$(jq -r '.ledger.poolName' "$PACKAGE_PATH")" check_placeholder_string "ledger.genesisSource" "$(jq -r '.ledger.genesisSource' "$PACKAGE_PATH")" check_placeholder_string "ledger.didMethod" "$(jq -r '.ledger.didMethod' "$PACKAGE_PATH")" check_placeholder_string "ledger.nymWriteMode" "$(jq -r '.ledger.nymWriteMode' "$PACKAGE_PATH")" check_placeholder_string "governance.governanceVersion" "$(jq -r '.governance.governanceVersion' "$PACKAGE_PATH")" CHANGE_CONTROL_REF="$(jq -r '.governance.changeControlRef' "$PACKAGE_PATH")" check_placeholder_string "governance.changeControlRef" "$CHANGE_CONTROL_REF" check_change_control_ref "$CHANGE_CONTROL_REF" check_placeholder_string "governance.changeControlFormat" "$(jq -r '.governance.changeControlFormat' "$PACKAGE_PATH")" check_placeholder_string "governance.operatorOwner" "$(jq -r '.governance.operatorOwner' "$PACKAGE_PATH")" check_placeholder_string "governance.approvalOwner" "$(jq -r '.governance.approvalOwner' "$PACKAGE_PATH")" check_placeholder_string "governance.endorserGovernanceModel.type" "$(jq -r '.governance.endorserGovernanceModel.type' "$PACKAGE_PATH")" GOV_QUORUM="$(jq -r '.governance.endorserGovernanceModel.quorum' "$PACKAGE_PATH")" check_placeholder_string "governance.endorserGovernanceModel.quorum" "$GOV_QUORUM" check_quorum_format "$GOV_QUORUM" check_placeholder_string "governance.endorserGovernanceModel.singleKeyDidControl" "$(jq -r '.governance.endorserGovernanceModel.singleKeyDidControl' "$PACKAGE_PATH")" check_placeholder_string "governance.endorserGovernanceModel.currentPhase" "$(jq -r '.governance.endorserGovernanceModel.currentPhase' "$PACKAGE_PATH")" if jq -e '(.governance.endorserGovernanceModel.custodians | type == "array") and (.governance.endorserGovernanceModel.custodians | length >= 3)' "$PACKAGE_PATH" >/dev/null; then log_ok "governance.endorserGovernanceModel.custodians has at least 3 entries" else log_err "governance.endorserGovernanceModel.custodians must have at least 3 entries" ERRORS=$((ERRORS + 1)) fi if jq -e '(.governance.endorserGovernanceModel.futurePhases | type == "array") and (.governance.endorserGovernanceModel.futurePhases | length >= 1)' "$PACKAGE_PATH" >/dev/null; then log_ok "governance.endorserGovernanceModel.futurePhases is populated" else log_err "governance.endorserGovernanceModel.futurePhases must contain at least one entry" ERRORS=$((ERRORS + 1)) fi check_placeholder_string "roles.author.alias" "$(jq -r '.roles.author.alias' "$PACKAGE_PATH")" AUTHOR_PUBLIC_DID="$(jq -r '.roles.author.publicDid' "$PACKAGE_PATH")" ENDORSER_DID="$(jq -r '.roles.endorser.did' "$PACKAGE_PATH")" check_placeholder_string_maybe_partial "roles.author.publicDid" "$AUTHOR_PUBLIC_DID" check_placeholder_string_maybe_partial "roles.author.verkey" "$(jq -r '.roles.author.verkey' "$PACKAGE_PATH")" check_placeholder_string "roles.endorser.alias" "$(jq -r '.roles.endorser.alias' "$PACKAGE_PATH")" check_placeholder_string_maybe_partial "roles.endorser.did" "$ENDORSER_DID" check_placeholder_string "anoncreds.schemas[0].name" "$(jq -r '.anoncreds.schemas[0].name' "$PACKAGE_PATH")" check_placeholder_string "anoncreds.schemas[0].version" "$(jq -r '.anoncreds.schemas[0].version' "$PACKAGE_PATH")" if [[ -n "$AUTHOR_PUBLIC_DID" ]]; then check_indy_did_format "roles.author.publicDid" "$AUTHOR_PUBLIC_DID" fi if [[ -n "$ENDORSER_DID" && "$ENDORSER_DID" != *"