Problem
The sidecar today opens keyring.New(..., keyring.BackendTest, ...) (hardcoded in sidecar/tasks/generate_gentx.go). BackendTest is an in-process backend used only for genesis ceremonies — keys are ephemeral, no passphrase, no on-disk persistence.
To sign governance, staking, and upgrade-proposal transactions from the sidecar against an externally-mounted operator-account keyring (per the sister issue in sei-protocol/sei-node-controller), the sidecar must support the Cosmos SDK file-keyring backend pointed at the mounted Secret.
Impact
- Direct blocker on the sidecar
sign-tx task family.
- Once shipped, becomes the single keyring entry point used by every governance-signing task.
Relevant experts
- platform-engineer — env contract, container-startup ordering, distroless implications
- blockchain-developer — Cosmos SDK keyring backend semantics
Proposed approach
- Two new envs read in
serve.go:
SEI_KEYRING_BACKEND — one of test (default; preserves genesis behavior), file, os. Validates at startup; refuses to start on unrecognized value.
SEI_KEYRING_DIR — path where the keyring lives. Required when backend is file; defaults to \$SEI_HOME/keyring-file if unset.
- Passphrase handling for
file backend: a third env SEI_KEYRING_PASSPHRASE is read once at startup, used to construct a bytes.Buffer that feeds keyring.New's userInput io.Reader. The passphrase is wiped from process env immediately after consumption (os.Unsetenv). Never logged.
- Refactor
sidecar/tasks/generate_gentx.go to take its keyring backend from a shared sidecar-level factory rather than hardcoding BackendTest. The factory reads from envs above. Genesis path continues to use BackendTest when configured.
- Add a startup-time keyring-open smoke test: if
SEI_KEYRING_BACKEND=file is set, the sidecar attempts to open the keyring at startup and fails fast with a clear error if it can't (rather than failing at first sign-tx).
- Documentation: extend
sidecar/README.md (or create sidecar/docs/keyring.md) describing the env contract and trust model.
Acceptance criteria
Out of scope
- Sign-tx task implementation (separate issue: "sign-tx task family")
- HSM / KMS / Vault / remote-signer backends (deferred; comment-reserved)
- Per-tx passphrase delivery (single startup-time passphrase only)
- Multi-key keyring rotation
References
- Coral session 2026-05-11
- Existing pattern:
sidecar/tasks/generate_gentx.go (already imports sei-cosmos/crypto/keyring)
- Env-loading pattern:
serve.go:38-47
- Cosmos SDK keyring docs: https://docs.cosmos.network/main/user/run-node/keyring
- Sister issue in
sei-protocol/sei-node-controller: CRD validator.operatorKeyring surface (the Secret this consumes)
Sequencing
Phase 1, step 2 of 5 in the governance-flow migration. Pairs with sei-node-controller "validator.operatorKeyring CRD surface" (step 1). Blocks step 3 (sign-tx task family).
Problem
The sidecar today opens
keyring.New(..., keyring.BackendTest, ...)(hardcoded insidecar/tasks/generate_gentx.go).BackendTestis an in-process backend used only for genesis ceremonies — keys are ephemeral, no passphrase, no on-disk persistence.To sign governance, staking, and upgrade-proposal transactions from the sidecar against an externally-mounted operator-account keyring (per the sister issue in
sei-protocol/sei-node-controller), the sidecar must support the Cosmos SDK file-keyring backend pointed at the mounted Secret.Impact
sign-txtask family.Relevant experts
Proposed approach
serve.go:SEI_KEYRING_BACKEND— one oftest(default; preserves genesis behavior),file,os. Validates at startup; refuses to start on unrecognized value.SEI_KEYRING_DIR— path where the keyring lives. Required when backend isfile; defaults to\$SEI_HOME/keyring-fileif unset.filebackend: a third envSEI_KEYRING_PASSPHRASEis read once at startup, used to construct abytes.Bufferthat feedskeyring.New'suserInput io.Reader. The passphrase is wiped from process env immediately after consumption (os.Unsetenv). Never logged.sidecar/tasks/generate_gentx.goto take its keyring backend from a shared sidecar-level factory rather than hardcodingBackendTest. The factory reads from envs above. Genesis path continues to useBackendTestwhen configured.SEI_KEYRING_BACKEND=fileis set, the sidecar attempts to open the keyring at startup and fails fast with a clear error if it can't (rather than failing at first sign-tx).sidecar/README.md(or createsidecar/docs/keyring.md) describing the env contract and trust model.Acceptance criteria
SEI_KEYRING_BACKEND/SEI_KEYRING_DIR/SEI_KEYRING_PASSPHRASEenvs supported inserve.gogenerate_gentx.go(refactored, not duplicated)os.Environ()after initializationBackendTest(regression test)Out of scope
References
sidecar/tasks/generate_gentx.go(already importssei-cosmos/crypto/keyring)serve.go:38-47sei-protocol/sei-node-controller: CRDvalidator.operatorKeyringsurface (the Secret this consumes)Sequencing
Phase 1, step 2 of 5 in the governance-flow migration. Pairs with sei-node-controller "validator.operatorKeyring CRD surface" (step 1). Blocks step 3 (sign-tx task family).