ops(reboot): add post-reboot next gate dispatch [skip ci]

This commit is contained in:
ogt
2026-06-26 08:22:12 +08:00
parent 6458a54ef5
commit a4ac7be310
5 changed files with 233 additions and 5 deletions

View File

@@ -0,0 +1,171 @@
#!/usr/bin/env bash
# AWOOOI post-reboot next-gate dispatch checklist.
# Read-only by design. It does not send requests, restart services, modify
# hosts, query secrets, or enable runtime actions.
set -uo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SUMMARY_FILE=""
RUN_SUMMARY=1
NO_COLOR_FLAG=0
usage() {
cat <<'USAGE'
Usage: post-reboot-next-gate-dispatch.sh [options]
Turns post-reboot readiness summary blockers into a deterministic owner/action
checklist. This is a dispatch checklist only; it does not dispatch requests.
Options:
--summary-file PATH Use an existing post-reboot readiness summary file.
--no-run-summary Do not run post-reboot-readiness-summary.sh.
--no-color Disable color in delegated summary.
-h, --help Show this help.
Exit codes:
0 = checklist emitted. Runtime action remains unauthorized.
2 = summary unavailable or service blocker observed.
USAGE
}
while [[ $# -gt 0 ]]; do
case "$1" in
--summary-file)
shift
SUMMARY_FILE="${1:-}"
;;
--no-run-summary)
RUN_SUMMARY=0
;;
--no-color)
NO_COLOR_FLAG=1
;;
-h|--help)
usage
exit 0
;;
*)
printf 'Unknown argument: %s\n' "$1" >&2
usage >&2
exit 2
;;
esac
shift
done
if [[ -z "$SUMMARY_FILE" && "$RUN_SUMMARY" -eq 1 ]]; then
SUMMARY_FILE="$(mktemp -t awoooi-post-reboot-summary.XXXXXX)"
summary_args=()
[[ "$NO_COLOR_FLAG" -eq 1 ]] && summary_args+=(--no-color)
bash "$ROOT_DIR/scripts/reboot-recovery/post-reboot-readiness-summary.sh" "${summary_args[@]}" >"$SUMMARY_FILE" 2>&1
summary_rc=$?
else
summary_rc=0
fi
if [[ -z "$SUMMARY_FILE" || ! -s "$SUMMARY_FILE" ]]; then
echo "BLOCKED_SUMMARY_UNAVAILABLE=1"
echo "RUNTIME_ACTION_AUTHORIZED=0"
exit 2
fi
value_for() {
local key="$1"
awk -F= -v key="$key" '$1 == key {value=$2; found=1} END {if (found) print value; else print ""}' "$SUMMARY_FILE"
}
service_green="$(value_for SERVICE_GREEN)"
overall_declaration="$(value_for OVERALL_DECLARATION)"
next_required_gates="$(value_for NEXT_REQUIRED_GATES)"
escrow_missing_count="$(value_for ESCROW_MISSING_COUNT)"
host_188_hygiene_blocked="$(value_for HOST_188_HYGIENE_BLOCKED)"
wazuh_registry_accepted="$(value_for WAZUH_MANAGER_REGISTRY_ACCEPTED)"
runtime_action_authorized="$(value_for RUNTIME_ACTION_AUTHORIZED)"
summary_artifact_dir="$(value_for ARTIFACT_DIR)"
contains_gate() {
local gate="$1"
[[ ",${next_required_gates}," == *",${gate},"* ]]
}
print_gate_header() {
local id="$1"
local title="$2"
echo
echo "GATE_ID=$id"
echo "GATE_TITLE=$title"
}
echo "AWOOOI_POST_REBOOT_NEXT_GATE_DISPATCH=1"
echo "SUMMARY_FILE=$SUMMARY_FILE"
echo "SUMMARY_ARTIFACT_DIR=${summary_artifact_dir:-unknown}"
echo "SUMMARY_RC=$summary_rc"
echo "SERVICE_GREEN=${service_green:-unknown}"
echo "OVERALL_DECLARATION=${overall_declaration:-unknown}"
echo "NEXT_REQUIRED_GATES=${next_required_gates:-unknown}"
echo "RUNTIME_ACTION_AUTHORIZED=0"
echo "DISPATCH_AUTHORIZED=0"
echo "REQUEST_SENT_COUNT=0"
echo "HOST_WRITE_AUTHORIZED=0"
echo "SECRET_VALUE_COLLECTION_ALLOWED=0"
if [[ "$service_green" != "1" ]]; then
echo
echo "BLOCKED_SERVICE_GREEN=0"
echo "NEXT_STEP=restore_service_before_boundary_dispatch"
exit 2
fi
gate_count=0
if contains_gate "credential_escrow_evidence"; then
gate_count=$((gate_count + 1))
print_gate_header "credential_escrow_evidence" "DR credential escrow non-secret evidence"
echo "GATE_PRIORITY=P0"
echo "GATE_STATUS=owner_evidence_required"
echo "CURRENT_EVIDENCE=escrow_missing_count:${escrow_missing_count:-unknown}"
echo "OWNER_GROUP=backup_dr_owner,security_owner,business_owner"
echo "REQUIRED_ITEMS=restic_repository_password,offsite_provider_credentials,break_glass_admin_credentials,dns_registrar_recovery,oauth_ai_provider_recovery"
echo "REQUIRED_EVIDENCE=non_secret_evidence_id,owner_role,owner_team,evidence_location,review_date,reviewer"
echo "FORBIDDEN_PAYLOADS=password,token,secret_value,hash,prefix,suffix,raw_credential,screenshot_with_secret"
echo "ALLOWED_ACTION=collect_non_secret_marker_evidence_only"
echo "FORBIDDEN_ACTION=mark_placeholder,write_fake_marker,store_secret,disable_alert"
echo "DONE_CRITERIA=escrow_missing_count:0,offsite_report_full_marker:1,backup_status_core_blockers:0"
fi
if contains_gate "host_188_hygiene_maintenance_window"; then
gate_count=$((gate_count + 1))
print_gate_header "host_188_hygiene_maintenance_window" "188 host PostgreSQL / certbot hygiene maintenance window"
echo "GATE_PRIORITY=P0"
echo "GATE_STATUS=maintenance_window_required"
echo "CURRENT_EVIDENCE=host_188_hygiene_blocked:${host_188_hygiene_blocked:-unknown}"
echo "OWNER_GROUP=188_host_owner,db_owner,dns_tls_owner,rollback_owner"
echo "REQUIRED_DECISIONS=postgresql_14_main_retire_or_restore_or_break_glass,certbot_dns_acme_owner_path,startup_unit_source_of_truth,rollback_owner,postcheck_owner"
echo "REQUIRED_EVIDENCE=maintenance_window,rollback_plan,precheck_artifact,postcheck_artifact,service_impact,stop_condition"
echo "FORBIDDEN_ACTIONS=pg_resetwal,certbot_renew,nginx_reload,systemctl_reset_failed,db_restore,docker_restart,host_file_write"
echo "ALLOWED_ACTION=prepare_maintenance_packet_and_read_only_preflight"
echo "DONE_CRITERIA=service_green:1,host_188_hygiene_blocked:0,systemd_failed_units:0,certbot_owner_evidence_accepted:1"
fi
if contains_gate "wazuh_manager_registry_export"; then
gate_count=$((gate_count + 1))
print_gate_header "wazuh_manager_registry_export" "Wazuh manager registry redacted export"
echo "GATE_PRIORITY=P0"
echo "GATE_STATUS=readonly_registry_export_required"
echo "CURRENT_EVIDENCE=wazuh_manager_registry_accepted:${wazuh_registry_accepted:-unknown}"
echo "OWNER_GROUP=iwooos_soc_owner,wazuh_owner,host_owner"
echo "REQUIRED_EXPORT=redacted_manager_registry_counts,per_host_alias_status,dashboard_api_connection_status,dashboard_api_version_status,collection_time_window,reviewer"
echo "FORBIDDEN_PAYLOADS=agent_real_name,internal_ip,client_keys,raw_wazuh_payload,token,password,authorization_header"
echo "FORBIDDEN_ACTIONS=active_response,agent_reenroll,wazuh_restart,secret_patch,host_write,kali_active_scan"
echo "ALLOWED_ACTION=collect_redacted_registry_export_or_no_data_attestation"
echo "DONE_CRITERIA=manager_registry_accepted:1,owner_evidence_accepted:1,runtime_gate:0"
fi
echo
echo "NEXT_GATE_COUNT=$gate_count"
echo "NEXT_STEP=dispatch_owner_packets_manually_after_review"
echo "POSTCHECK_COMMAND=scripts/reboot-recovery/post-reboot-readiness-summary.sh --no-color"
echo "NO_FALSE_GREEN_RULE=service_green_does_not_equal_dr_complete_or_wazuh_registry_recovered"
exit 0