Description
filecoin-pin only accepts wallet auth as PRIVATE_KEY=0x... env var. Users hand the CLI, server, and GitHub Action raw private keys. No encrypted-at-rest option, no policy gating, no OS keychain integration.
Impact
- CI users put raw keys in GitHub Actions secrets when an encrypted artifact would be safer.
- Local users with multiple wallets juggle env vars instead of named identities.
- Server daemon operators leave keys readable in process env / shell history.
- Blocks adoption from teams with key-handling policies.
Proposed avenues
Three tiers, additive. Resolver order: explicit flag → keystore → PRIVATE_KEY → devnet auto-resolve.
-
Encrypted Keystore v3 (port from synapse-sdk)
- synapse-sdk PR #554 ships keystore in its example CLI (
examples/cli/src/{client,commands/init,config}.ts). Port the pattern into src/core/keystore/.
- CLI:
keystore create|import|list|remove, --keystore <name> flag, KEYSTORE_PASSWORD env for non-interactive.
- Storage: platform data dir under
keystores/<name>.json.
- Lowest integration risk, unblocks CI via
KEYSTORE_PASSWORD secret + committed encrypted JSON.
- Universal baseline (works in Node, browser-safe, all platforms).
-
OpenWallet Standard (openwallet.sh)
@open-wallet-standard/core + @open-wallet-standard/adapters (viem). In-process, policy-gated signing. Filecoin is a first-class chain.
- CLI consumes a wallet ID; users manage wallets via
ows CLI.
- synapse-sdk is already viem-native and
initializeSynapse() in src/core/synapse/index.ts already accepts a pre-built viem Account, so the OWS viem adapter slots in with no SDK plumbing changes.
- Platform coverage: napi-rs prebuilt binaries published on npm for
linux-x64-gnu, linux-arm64-gnu, darwin-x64, darwin-arm64. No win32-x64-msvc or musl/Alpine artifact on npm today. The Rust crate itself is cross-platform (winapi is in Cargo.lock), so a Windows prebuilt is feasible upstream — just not shipped yet. GitHub Action default runners install cleanly with no Rust toolchain.
- Node-only (CJS loader uses
fs / child_process). Tier 2 must stay out of browser exports; ship in CLI, server, and Action only.
- Windows and Alpine users fall back to tier 1 until upstream publishes those prebuilts (or we vendor a build).
-
OS-native keychain wrapper
- macOS Keychain / Windows Credential Manager / libsecret via
keytar or @napi-rs/keyring.
- Stores the keystore password (tier 1), not the raw key. Local-dev DX.
Out of scope
- Hardware wallets (Ledger/Trezor) — separate issue if requested.
- Devnet path keeps auto-resolving from
devnet-info.json.
Next step
Land tier 1 first. Layer tier 2 on top as opt-in for supported platforms.
Description
filecoin-pinonly accepts wallet auth asPRIVATE_KEY=0x...env var. Users hand the CLI, server, and GitHub Action raw private keys. No encrypted-at-rest option, no policy gating, no OS keychain integration.Impact
Proposed avenues
Three tiers, additive. Resolver order: explicit flag → keystore →
PRIVATE_KEY→ devnet auto-resolve.Encrypted Keystore v3 (port from synapse-sdk)
examples/cli/src/{client,commands/init,config}.ts). Port the pattern intosrc/core/keystore/.keystore create|import|list|remove,--keystore <name>flag,KEYSTORE_PASSWORDenv for non-interactive.keystores/<name>.json.KEYSTORE_PASSWORDsecret + committed encrypted JSON.OpenWallet Standard (openwallet.sh)
@open-wallet-standard/core+@open-wallet-standard/adapters(viem). In-process, policy-gated signing. Filecoin is a first-class chain.owsCLI.initializeSynapse()insrc/core/synapse/index.tsalready accepts a pre-built viemAccount, so the OWS viem adapter slots in with no SDK plumbing changes.linux-x64-gnu,linux-arm64-gnu,darwin-x64,darwin-arm64. Nowin32-x64-msvcor musl/Alpine artifact on npm today. The Rust crate itself is cross-platform (winapiis inCargo.lock), so a Windows prebuilt is feasible upstream — just not shipped yet. GitHub Action default runners install cleanly with no Rust toolchain.fs/child_process). Tier 2 must stay out of browser exports; ship in CLI, server, and Action only.OS-native keychain wrapper
keytaror@napi-rs/keyring.Out of scope
devnet-info.json.Next step
Land tier 1 first. Layer tier 2 on top as opt-in for supported platforms.