59 lines
2.3 KiB
Bash
59 lines
2.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Restores the ASP.NET Data Protection keyring into the production Docker volume.
|
|
# REQUIRED after volume loss or host migration — without the matching keyring,
|
|
# every encrypted patient PHI column is permanently unreadable.
|
|
#
|
|
# See docs/ops/phi-encryption-runbook.md (Keyring restore).
|
|
#
|
|
# Usage:
|
|
# ./scripts/restore-dp-keys.sh /var/backups/vigilcare/dp-keys/dp-keys-20260804T021500Z.tar.gz
|
|
#
|
|
# Stops the API container, replaces volume contents, then leaves the operator
|
|
# to bring the stack back up (so schema/image tags stay under compose control).
|
|
set -euo pipefail
|
|
|
|
ARCHIVE="${1:-}"
|
|
VOLUME_NAME="${VOLUME_NAME:-vigilcare_dp_keys}"
|
|
COMPOSE_FILE="${COMPOSE_FILE:-/opt/vigilcare/docker-compose.prod.yml}"
|
|
COMPOSE_DIR="$(dirname "${COMPOSE_FILE}")"
|
|
API_SERVICE="${API_SERVICE:-api}"
|
|
|
|
if [[ -z "${ARCHIVE}" || ! -f "${ARCHIVE}" ]]; then
|
|
echo "Usage: $0 <path-to-dp-keys-YYYYMMDDThhmmssZ.tar.gz>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! tar tzf "${ARCHIVE}" | grep -q '\.xml$'; then
|
|
echo "ERROR: ${ARCHIVE} does not contain Data Protection *.xml key files." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Stopping API service (${API_SERVICE}) so the volume is unused..."
|
|
if [[ -f "${COMPOSE_FILE}" ]]; then
|
|
docker compose -f "${COMPOSE_FILE}" --env-file "${COMPOSE_DIR}/.env" stop "${API_SERVICE}" || true
|
|
else
|
|
echo "WARN: ${COMPOSE_FILE} not found — ensure no container has ${VOLUME_NAME} mounted." >&2
|
|
fi
|
|
|
|
if ! docker volume inspect "${VOLUME_NAME}" >/dev/null 2>&1; then
|
|
echo "Creating volume ${VOLUME_NAME}..."
|
|
docker volume create "${VOLUME_NAME}" >/dev/null
|
|
fi
|
|
|
|
echo "Restoring ${ARCHIVE} → volume ${VOLUME_NAME}"
|
|
# Clear existing keys then extract. Use a throwaway alpine container.
|
|
docker run --rm \
|
|
-v "${VOLUME_NAME}:/keys" \
|
|
-v "$(cd "$(dirname "${ARCHIVE}")" && pwd):/backup:ro" \
|
|
alpine sh -c "rm -rf /keys/* /keys/.[!.]* 2>/dev/null; tar xzf /backup/$(basename "${ARCHIVE}") -C /keys"
|
|
|
|
echo "Restored key files:"
|
|
docker run --rm -v "${VOLUME_NAME}:/keys:ro" alpine ls -la /keys
|
|
|
|
echo
|
|
echo "Next steps:"
|
|
echo " 1. docker compose -f ${COMPOSE_FILE} --env-file ${COMPOSE_DIR}/.env up -d ${API_SERVICE}"
|
|
echo " 2. curl -fsS http://localhost:5270/health/ready"
|
|
echo " 3. Fetch a known patient and confirm firstName/lastName decrypt"
|
|
echo " 4. Record this restore in the ops log (date, archive name, operator)"
|