SEC-B09: governance emergency multisig rehearsal runbook and LocalTerra dry-run (#397) #927

Merged
PlasticDigits merged 3 commits from issue-397-governance-emergency-rehearsal into main 2026-06-19 13:46:27 +00:00
PlasticDigits commented 2026-06-19 11:09:57 +00:00 (Migrated from gitlab.com)

Summary

Implements SEC-B09 (#397): governance emergency controls must be rehearsed from the actual planned multisig signing flow, not only local test1 deploy keys.

This MR adds:

LocalTerra rehearsal proves message shapes and threshold signing; production launch still requires operators to repeat from the planned production multisig on testnet/staging and attach tx hashes to the launch tracking issue (#391).

Acceptance checklist

Criterion Command / step Result
Rehearsal uses multisig threshold signing flow ./scripts/rehearse-governance-emergency-controls.sh (2-of-3 terrad tx sign + multisign) PASS
Covers pause, blacklist, unpause, unblacklist Script executes all four factory messages; LCD verifies is_paused + blacklist_check PASS
Signed tx hashes / transcript producible --output /tmp/sec-b09.md transcript table with tx hashes PASS
Rehearsal on LocalTerra (not mainnet) network=localterra in transcript PASS
Phase 5 PAUSE gate references evidence docs/runbooks/launch-checklist.md links runbook + make verify-issue-397 PASS
Production multisig evidence on launch issue Operator step — post filled template on #391 after testnet/staging run SKIP (human gate before mainnet)

Verification checklist (third parties)

# Doc invariants only (no chain):
make check-governance-emergency-rehearsal-docs

# Full verify (needs LocalTerra + deploy):
make setup-cloud-localterra   # first time ~10–15 min
make verify-issue-397

# Manual rehearsal + save transcript:
make rehearse-governance-emergency
./scripts/rehearse-governance-emergency-controls.sh --output /tmp/sec-b09-rehearsal.md

Expected: all doc checks PASS; with chain up, LocalTerra multisig rehearsal PASS and transcript lists four emergency operations with tx hashes.

Follow-ups

  • Operators must run the same four operations from the production governance multisig on testnet/staging and pin evidence on #391 before mainnet GO.

Related to #397

## Summary Implements **SEC-B09** ([#397](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/397)): governance emergency controls must be rehearsed from the **actual planned multisig signing flow**, not only local `test1` deploy keys. This MR adds: - **Runbook** [`docs/runbooks/governance-emergency-rehearsal.md`](docs/runbooks/governance-emergency-rehearsal.md) — scope (pause → blacklist → unpause → unblacklist), Cosmos multisign flow, evidence workflow - **Evidence template** [`docs/templates/governance-emergency-rehearsal-evidence.md`](docs/templates/governance-emergency-rehearsal-evidence.md) for launch-issue sign-off - **LocalTerra dry-run** [`scripts/rehearse-governance-emergency-controls.sh`](scripts/rehearse-governance-emergency-controls.sh) — 2-of-3 `terrad tx multisign` rehearsal with on-chain verification and transcript output - **Agent skill** [`skills/AGENTS_GOVERNANCE_EMERGENCY_REHEARSAL.md`](skills/AGENTS_GOVERNANCE_EMERGENCY_REHEARSAL.md) - **Doc regression** `make check-governance-emergency-rehearsal-docs` + `make verify-issue-397` - **Launch checklist** Phase 5 PAUSE criterion updated to link SEC-B09 evidence and verification commands LocalTerra rehearsal proves message shapes and threshold signing; **production launch** still requires operators to repeat from the **planned production multisig** on testnet/staging and attach tx hashes to the launch tracking issue ([#391](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/391)). ## Acceptance checklist | Criterion | Command / step | Result | |-----------|----------------|--------| | Rehearsal uses multisig threshold signing flow | `./scripts/rehearse-governance-emergency-controls.sh` (2-of-3 `terrad tx sign` + `multisign`) | **PASS** | | Covers pause, blacklist, unpause, unblacklist | Script executes all four factory messages; LCD verifies `is_paused` + `blacklist_check` | **PASS** | | Signed tx hashes / transcript producible | `--output /tmp/sec-b09.md` transcript table with tx hashes | **PASS** | | Rehearsal on LocalTerra (not mainnet) | `network=localterra` in transcript | **PASS** | | Phase 5 PAUSE gate references evidence | `docs/runbooks/launch-checklist.md` links runbook + `make verify-issue-397` | **PASS** | | Production multisig evidence on launch issue | Operator step — post filled template on #391 after testnet/staging run | **SKIP** (human gate before mainnet) | ## Verification checklist (third parties) ```bash # Doc invariants only (no chain): make check-governance-emergency-rehearsal-docs # Full verify (needs LocalTerra + deploy): make setup-cloud-localterra # first time ~10–15 min make verify-issue-397 # Manual rehearsal + save transcript: make rehearse-governance-emergency ./scripts/rehearse-governance-emergency-controls.sh --output /tmp/sec-b09-rehearsal.md ``` Expected: all doc checks PASS; with chain up, LocalTerra multisig rehearsal PASS and transcript lists four emergency operations with tx hashes. ## Follow-ups - Operators must run the same four operations from the **production governance multisig** on testnet/staging and pin evidence on [#391](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/391) before mainnet GO. Related to #397
PlasticDigits commented 2026-06-19 11:13:03 +00:00 (Migrated from gitlab.com)

Security review — MR !927

Commit reviewed: 3493333f254e4899a541233494478a36ffa54261

Scope: SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, scripts/rehearse-governance-emergency-controls.sh, scripts/lib/terrad-multisig-tx.sh, scripts/qa/verify-issue-397.sh, scripts/check_governance_emergency_rehearsal_docs.py, Makefile targets, agent skill cross-links.

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ findings).

Review notes

Reviewed all added/modified code for injection, authn/authz bypass, secret leakage, SSRF, path traversal, and supply-chain risk. This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes.

  • terrad-multisig-tx.sh: Arguments are interpolated into docker exec sh -c with single-quote wrapping. A crafted env value (e.g. BLACKLIST_TARGET containing ') could break quoting, but the script is operator-local, requires the localterra compose container, and execution stays inside that dev container — not a plausible remote or CI attacker path at medium+ severity.
  • Governance rotation via test1: Intentional for LocalTerra rehearsal; script hard-requires the localterra docker service and documents that production sign-off needs a separate testnet/staging run.
  • Secrets / logging: Rehearsal keys use --no-backup in the test keyring; transcript output is addresses and tx hashes only.
  • Dependencies / attack surface: No new runtime packages; no network-exposed endpoints introduced.

Security review: no medium+ findings on this diff.

## Security review — MR !927 **Commit reviewed:** `3493333f254e4899a541233494478a36ffa54261` **Scope:** SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, `scripts/rehearse-governance-emergency-controls.sh`, `scripts/lib/terrad-multisig-tx.sh`, `scripts/qa/verify-issue-397.sh`, `scripts/check_governance_emergency_rehearsal_docs.py`, Makefile targets, agent skill cross-links. **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** None (no medium+ findings). ### Review notes Reviewed all added/modified code for injection, authn/authz bypass, secret leakage, SSRF, path traversal, and supply-chain risk. This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes. - **`terrad-multisig-tx.sh`:** Arguments are interpolated into `docker exec sh -c` with single-quote wrapping. A crafted env value (e.g. `BLACKLIST_TARGET` containing `'`) could break quoting, but the script is operator-local, requires the `localterra` compose container, and execution stays inside that dev container — not a plausible remote or CI attacker path at medium+ severity. - **Governance rotation via `test1`:** Intentional for LocalTerra rehearsal; script hard-requires the `localterra` docker service and documents that production sign-off needs a separate testnet/staging run. - **Secrets / logging:** Rehearsal keys use `--no-backup` in the test keyring; transcript output is addresses and tx hashes only. - **Dependencies / attack surface:** No new runtime packages; no network-exposed endpoints introduced. **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-19 12:49:59 +00:00 (Migrated from gitlab.com)

added 7 commits

  • 3493333f...d487a0cd - 6 commits from branch main
  • af1e6156 - Merge origin/main into issue-397-governance-emergency-rehearsal.

Compare with previous version

added 7 commits <ul><li>3493333f...d487a0cd - 6 commits from branch <code>main</code></li><li>af1e6156 - Merge origin/main into issue-397-governance-emergency-rehearsal.</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/209/diffs?diff_id=1861161518&start_sha=3493333f254e4899a541233494478a36ffa54261)
PlasticDigits commented 2026-06-19 12:50:04 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main by merging origin/main into issue-397-governance-emergency-rehearsal.

Conflicts resolved:

  • Makefile — kept SEC-B09 targets (check-governance-emergency-rehearsal-docs, rehearse-governance-emergency, verify-issue-397) alongside main's SEC-B12 blacklist decision targets (check-blacklist-decision-docs, verify-issue-400); updated .PHONY, lint, and help.
  • docs/testing.md — added both CI reference rows (docs-governance-emergency-rehearsal and docs-blacklist-decision).

Sanity checks: make check-governance-emergency-rehearsal-docs and make check-blacklist-decision-docs both PASS.

Resolved merge conflicts with `main` by merging `origin/main` into `issue-397-governance-emergency-rehearsal`. **Conflicts resolved:** - `Makefile` — kept SEC-B09 targets (`check-governance-emergency-rehearsal-docs`, `rehearse-governance-emergency`, `verify-issue-397`) alongside main's SEC-B12 blacklist decision targets (`check-blacklist-decision-docs`, `verify-issue-400`); updated `.PHONY`, `lint`, and `help`. - `docs/testing.md` — added both CI reference rows (`docs-governance-emergency-rehearsal` and `docs-blacklist-decision`). **Sanity checks:** `make check-governance-emergency-rehearsal-docs` and `make check-blacklist-decision-docs` both PASS.
PlasticDigits commented 2026-06-19 12:53:12 +00:00 (Migrated from gitlab.com)

Security review — MR !927

Commit reviewed: af1e61564a33c2bde42c06861854f455ef15ea51

Scope: SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, scripts/rehearse-governance-emergency-controls.sh, scripts/lib/terrad-multisig-tx.sh, scripts/qa/verify-issue-397.sh, scripts/check_governance_emergency_rehearsal_docs.py, Makefile targets, agent skill cross-links. Re-reviewed after merge of origin/main (conflict resolution in Makefile / docs/testing.md only; no new SEC-B09 logic).

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ findings).

Review notes

Traced attacker-controlled inputs through the added shell paths (docker exec sh -c, LCD smart queries, --output, env overrides). This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes.

  • terrad-multisig-tx.sh: Arguments are interpolated into docker exec sh -c with single-quote wrapping. A crafted env value containing ' could break quoting, but inputs are operator-local defaults or bech32 addresses from deploy/LCD; execution stays inside the localterra compose container — not a plausible remote or CI attacker path at medium+ severity.
  • Governance rotation via test1: Intentional for LocalTerra rehearsal; script hard-requires the localterra docker service and documents that production sign-off needs a separate testnet/staging run from the planned multisig.
  • Secrets / logging: Rehearsal keys use --no-backup in the test keyring; transcript output is addresses and tx hashes only.
  • CI surface: make lint runs doc invariants only (check-governance-emergency-rehearsal-docs); live chain rehearsal runs only via explicit make verify-issue-397 / make rehearse-governance-emergency when LocalTerra is up.
  • Dependencies / attack surface: No new runtime packages; no network-exposed endpoints introduced.

Security review: no medium+ findings on this diff.

## Security review — MR !927 **Commit reviewed:** `af1e61564a33c2bde42c06861854f455ef15ea51` **Scope:** SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, `scripts/rehearse-governance-emergency-controls.sh`, `scripts/lib/terrad-multisig-tx.sh`, `scripts/qa/verify-issue-397.sh`, `scripts/check_governance_emergency_rehearsal_docs.py`, Makefile targets, agent skill cross-links. Re-reviewed after merge of `origin/main` (conflict resolution in `Makefile` / `docs/testing.md` only; no new SEC-B09 logic). **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** None (no medium+ findings). ### Review notes Traced attacker-controlled inputs through the added shell paths (`docker exec sh -c`, LCD smart queries, `--output`, env overrides). This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes. - **`terrad-multisig-tx.sh`:** Arguments are interpolated into `docker exec sh -c` with single-quote wrapping. A crafted env value containing `'` could break quoting, but inputs are operator-local defaults or bech32 addresses from deploy/LCD; execution stays inside the `localterra` compose container — not a plausible remote or CI attacker path at medium+ severity. - **Governance rotation via `test1`:** Intentional for LocalTerra rehearsal; script hard-requires the `localterra` docker service and documents that production sign-off needs a separate testnet/staging run from the planned multisig. - **Secrets / logging:** Rehearsal keys use `--no-backup` in the test keyring; transcript output is addresses and tx hashes only. - **CI surface:** `make lint` runs doc invariants only (`check-governance-emergency-rehearsal-docs`); live chain rehearsal runs only via explicit `make verify-issue-397` / `make rehearse-governance-emergency` when LocalTerra is up. - **Dependencies / attack surface:** No new runtime packages; no network-exposed endpoints introduced. **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-19 13:13:32 +00:00 (Migrated from gitlab.com)

added 9 commits

  • af1e6156...049471ed - 8 commits from branch main
  • 9d1abf86 - Merge origin/main into issue-397-governance-emergency-rehearsal.

Compare with previous version

added 9 commits <ul><li>af1e6156...049471ed - 8 commits from branch <code>main</code></li><li>9d1abf86 - Merge origin/main into issue-397-governance-emergency-rehearsal.</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/209/diffs?diff_id=1861211688&start_sha=af1e61564a33c2bde42c06861854f455ef15ea51)
PlasticDigits commented 2026-06-19 13:13:41 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with latest main.

Conflict: Makefile .PHONY line — merged SEC-B09 targets (check-governance-emergency-rehearsal-docs, rehearse-governance-emergency, verify-issue-397) with main additions (smoke-wrap-mapper-pause, verify-issue-396).

Sanity checks: make check-governance-emergency-rehearsal-docs and make check-blacklist-decision-docs both PASS.

Resolved merge conflicts with latest `main`. **Conflict:** `Makefile` `.PHONY` line — merged SEC-B09 targets (`check-governance-emergency-rehearsal-docs`, `rehearse-governance-emergency`, `verify-issue-397`) with `main` additions (`smoke-wrap-mapper-pause`, `verify-issue-396`). **Sanity checks:** `make check-governance-emergency-rehearsal-docs` and `make check-blacklist-decision-docs` both PASS.
PlasticDigits commented 2026-06-19 13:17:39 +00:00 (Migrated from gitlab.com)

Security review — MR !927

Commit reviewed: 9d1abf868e67e07f5d688bfdc964b4e50356a8fc

Scope: SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, scripts/rehearse-governance-emergency-controls.sh, scripts/lib/terrad-multisig-tx.sh, scripts/qa/verify-issue-397.sh, scripts/check_governance_emergency_rehearsal_docs.py, Makefile targets, agent skill cross-links. Re-reviewed after merge of origin/main (Makefile .PHONY / verify-issue-396 conflict resolution; no SEC-B09 logic changes).

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ findings).

Review notes

Traced attacker-controlled inputs through the added shell paths (docker exec sh -c, LCD smart queries, --output, env overrides). This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes.

  • terrad-multisig-tx.sh: Arguments are interpolated into docker exec sh -c with single-quote wrapping. A crafted env value containing ' could break quoting, but inputs are operator-local defaults or bech32 addresses from deploy/LCD; execution stays inside the localterra compose container — not a plausible remote or CI attacker path at medium+ severity.
  • Governance rotation via test1: Intentional for LocalTerra rehearsal; script hard-requires the localterra docker service and documents that production sign-off needs a separate testnet/staging run from the planned multisig.
  • Secrets / logging: Rehearsal keys use --no-backup in the test keyring; transcript output is addresses and tx hashes only.
  • CI surface: make lint runs doc invariants only (check-governance-emergency-rehearsal-docs); live chain rehearsal runs only via explicit make verify-issue-397 / make rehearse-governance-emergency when LocalTerra is up.
  • Dependencies / attack surface: No new runtime packages; no network-exposed endpoints introduced.

Security review: no medium+ findings on this diff.

## Security review — MR !927 **Commit reviewed:** `9d1abf868e67e07f5d688bfdc964b4e50356a8fc` **Scope:** SEC-B09 governance emergency multisig rehearsal — runbook/docs/templates, `scripts/rehearse-governance-emergency-controls.sh`, `scripts/lib/terrad-multisig-tx.sh`, `scripts/qa/verify-issue-397.sh`, `scripts/check_governance_emergency_rehearsal_docs.py`, Makefile targets, agent skill cross-links. Re-reviewed after merge of `origin/main` (Makefile `.PHONY` / `verify-issue-396` conflict resolution; no SEC-B09 logic changes). **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** None (no medium+ findings). ### Review notes Traced attacker-controlled inputs through the added shell paths (`docker exec sh -c`, LCD smart queries, `--output`, env overrides). This MR adds operator runbooks, a LocalTerra-only multisig dry-run script, and doc/CI regression checks. No production dApp, indexer API, or CosmWasm contract logic changes. - **`terrad-multisig-tx.sh`:** Arguments are interpolated into `docker exec sh -c` with single-quote wrapping. A crafted env value containing `'` could break quoting, but inputs are operator-local defaults or bech32 addresses from deploy/LCD; execution stays inside the `localterra` compose container — not a plausible remote or CI attacker path at medium+ severity. - **Governance rotation via `test1`:** Intentional for LocalTerra rehearsal; script hard-requires the `localterra` docker service and documents that production sign-off needs a separate testnet/staging run from the planned multisig. - **Secrets / logging:** Rehearsal keys use `--no-backup` in the test keyring; transcript output is addresses and tx hashes only. - **CI surface:** `make lint` runs doc invariants only (`check-governance-emergency-rehearsal-docs`); live chain rehearsal runs only via explicit `make verify-issue-397` / `make rehearse-governance-emergency` when LocalTerra is up. - **Dependencies / attack surface:** No new runtime packages; no network-exposed endpoints introduced. **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-19 13:46:27 +00:00 (Migrated from gitlab.com)

mentioned in commit 0c87b934f4

mentioned in commit 0c87b934f48eb5bb6cd0b7e4a7675c11c38e446e
PlasticDigits (Migrated from gitlab.com) merged commit 0c87b934f4 into main 2026-06-19 13:46:27 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!927
No description provided.