Skip to content

feat(sidecar): production keyring backend support (file / os) #162

@bdchatham

Description

@bdchatham

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

  1. 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.
  2. 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.
  3. 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.
  4. 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).
  5. Documentation: extend sidecar/README.md (or create sidecar/docs/keyring.md) describing the env contract and trust model.

Acceptance criteria

  • SEI_KEYRING_BACKEND / SEI_KEYRING_DIR / SEI_KEYRING_PASSPHRASE envs supported in serve.go
  • Shared keyring factory consumed by generate_gentx.go (refactored, not duplicated)
  • Startup-time keyring-open smoke test
  • Passphrase wiped from os.Environ() after initialization
  • Unit tests cover backend selection, missing-passphrase error, malformed-keyring error
  • Genesis path continues to work with BackendTest (regression test)
  • No passphrase appears in any log line at any verbosity (asserted by test)
  • Documentation added

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions