Skip to content

fix(infra): stop a flagless plan from deleting the executor KMS key - #68

Merged
robertleifke merged 1 commit into
mainfrom
infra/rebalance-kms-key
Sep 18, 2026
Merged

robertleifke merged 1 commit into
mainfrom
infra/rebalance-kms-key

Conversation

@robertleifke

Copy link
Copy Markdown
Contributor

What

executor_kms_enabled and executor_kms_signing default to false, but the live stack has both true — they were passed as -var flags during the executor rollout (#62#64) and written down nowhere. Every terraform plan in infra/aws that omitted them proposed destroying the key the venue settles with.

Found while planning an unrelated change. Nothing was applied; plans are read-only and this was caught by reading the destroy list, not by any failure.

aws_kms_key.executor[0]                  will be destroyed
aws_kms_alias.executor[0]                will be destroyed
aws_iam_role_policy.executor_kms_sign[0] will be destroyed
aws_ecs_task_definition.execution        must be replaced

Plan: 3 to add, 1 to change, 4 to destroy.

Since #64 deleted the stored PRIVATE_KEY, signing = false is not a fallback — the task gets neither EXECUTOR_KMS_KEY_ID nor PRIVATE_KEY and refuses to boot. So the setting is dead, not merely wrong.

Fix

Both halves, because either alone leaves a gap:

effect
defaults → true a plan with no flags is a no-op
lifecycle.prevent_destroy on both KMS keys an explicit -var executor_kms_enabled=false errors instead of destroying

The local counts.auto.tfvars workaround is removed — it is gitignored, so it never survived a fresh clone or a second machine, which is what made this worth fixing in the repo.

Verification

Against live state, with images pinned to what is running:

  • plan with no KMS flags → No changes. Your infrastructure matches the configuration.
  • plan with executor_kms_enabled=falseError: Instance cannot be destroyed

Also

Adds aws_kms_key.rebalance (alias numo-exchange-rebalance), applied 2026-09-17, deriving to 0x1661AA54fA390cd916722F971e4A9Fe4c01889fB. It signs USDC→cNGN swaps on the HyperFX IntentGateway for the cNGN rebalance loop, and is deliberately not the executor key — a compromise there costs the float, not the venue's settlement authority. It holds nothing yet.

🤖 Generated with Claude Code

executor_kms_enabled and executor_kms_signing defaulted to false while the
live stack has both true -- they were passed as -var during the rollout in
#62-#64 and persisted nowhere. Any plan in infra/aws that omitted them
proposed:

  aws_kms_key.executor[0]                  will be destroyed
  aws_kms_alias.executor[0]                will be destroyed
  aws_iam_role_policy.executor_kms_sign[0] will be destroyed
  aws_ecs_task_definition.execution        must be replaced

  Plan: 3 to add, 1 to change, 4 to destroy.

That schedules the settlement key for deletion and drops
EXECUTOR_KMS_KEY_ID from execution-service. Since #64 deleted the stored
PRIVATE_KEY there is no second signing path, so the replacement task would
carry no key at all and fail its config schema at boot.

Two changes, because either alone leaves a gap:

  - the defaults are true, so a plan with no flags is a no-op
  - both KMS keys carry lifecycle.prevent_destroy, so an explicit
    -var executor_kms_enabled=false errors instead of destroying

Verified against the live state: a plan with no KMS flags reports "No
changes"; the same plan with executor_kms_enabled=false now fails with
"Instance cannot be destroyed" rather than producing an appliable plan.

Also adds aws_kms_key.rebalance (alias numo-exchange-rebalance), applied
2026-09-17 and deriving to 0x1661AA54fA390cd916722F971e4A9Fe4c01889fB,
which signs USDC->cNGN swaps on the HyperFX IntentGateway for the cNGN
rebalance. Deliberately not the executor key: a compromise there costs the
float, not the venue's settlement authority.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@robertleifke
robertleifke merged commit 80a8dd0 into main Sep 18, 2026
1 check passed
@robertleifke
robertleifke deleted the infra/rebalance-kms-key branch September 18, 2026 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant