provisioning-catalog/playbooks/offboard_operator/run.nu

57 lines
3.3 KiB
Text
Raw Normal View History

#!/usr/bin/env nu
# offboard_operator/run.nu — revoke NATS JWT, propose + sign delegation removal, verify blocked, audit
def main [
--workspace: string = ""
--operator-name: string = ""
--operator-did: string = ""
--reason: string = "voluntary"
--dry-run
]: nothing -> nothing {
let ws = if ($workspace | is-not-empty) { $workspace } else { $env.PLAYBOOK_PARAM_WORKSPACE? | default "" }
let op_name = if ($operator_name | is-not-empty) { $operator_name } else { $env.PLAYBOOK_PARAM_OPERATOR_NAME? | default "" }
let op_did = if ($operator_did | is-not-empty) { $operator_did } else { $env.PLAYBOOK_PARAM_OPERATOR_DID? | default "" }
let reason = if ($reason | is-not-empty) { $reason } else { $env.PLAYBOOK_PARAM_REASON? | default "voluntary" }
if ($ws | is-empty) { error make { msg: "workspace is required" } }
if ($op_name | is-empty) { error make { msg: "operator-name is required" } }
if ($op_did | is-empty) { error make { msg: "operator-did is required" } }
let playbook_dir = $env.PLAYBOOK_DIR? | default ($env.FILE_PWD | path expand)
let dry_flag = if $dry_run { "--dry-run" } else { "" }
print $"[offboard_operator] workspace=($ws) operator=($op_name) did=($op_did) reason=($reason) dry-run=($dry_run)"
print ""
print "[step 1/5] revoking NATS JWT credential..."
let r1 = do { ^nu ($playbook_dir | path join "steps/revoke_nats_credential.nu") --workspace $ws --operator-name $op_name $dry_flag } | complete
if $r1.exit_code != 0 { error make { msg: $"NATS credential revocation failed: ($r1.stderr | str trim)" } }
print $r1.stdout
print "[step 2/5] proposing delegation removal on policy repo..."
let r2 = do { ^nu ($playbook_dir | path join "steps/propose_delegation_removal.nu") --workspace $ws --operator-name $op_name --operator-did $op_did --reason $reason $dry_flag } | complete
if $r2.exit_code != 0 { error make { msg: $"Delegation removal proposal failed: ($r2.stderr | str trim)" } }
print $r2.stdout
print "[step 3/5] awaiting quorum signatures on removal patch..."
let r3 = do { ^nu ($playbook_dir | path join "steps/sign_removal_patch.nu") --workspace $ws --operator-name $op_name $dry_flag } | complete
if $r3.exit_code != 0 { error make { msg: $"Removal patch signing failed: ($r3.stderr | str trim)" } }
print $r3.stdout
print "[step 4/5] verifying revoked credential is rejected..."
let r4 = do { ^nu ($playbook_dir | path join "steps/verify_operator_blocked.nu") --workspace $ws --operator-name $op_name $dry_flag } | complete
if $r4.exit_code != 0 {
print $" WARNING: block verification returned errors: ($r4.stderr | str trim)"
} else {
print $r4.stdout
}
print "[step 5/5] emitting operator-offboard audit event..."
let r5 = do { ^nu ($playbook_dir | path join "steps/emit_audit.nu") --workspace $ws --event-type "operator_offboard" --operator-name $op_name --operator-did $op_did --reason $reason $dry_flag } | complete
if $r5.exit_code != 0 { print $" WARNING: audit emit failed: ($r5.stderr | str trim)" }
print ""
print "[offboard_operator] complete"
print $"Verify: NATS rejects connections with ($op_name) credential; ops history shows operator-offboard event"
}