filecoin-project / filecoin-project/filecoin-pin

feat(auth): session keys as the recommended CI path

Open
#682 0 comments 0 reactions 0 assignees View on GitHub
enhancement team/filecoin-pin team/fs-wg
Dominant language
TypeScript
Stars
26
Forks
21
Avg merge
5d 18h
Merged PRs (30d)
27

Description

Part of #457.

### Description

Make scoped session keys the documented and supported auth mode for CI, replacing the current guidance of storing the wallet's raw private key as a repo secret. `filecoin-pin session create` already exists: the owner authorizes a session address once, and CI holds only the session key: scoped to specific permissions, revocable with `session revoke`, and never able to drain the wallet.

This is the ecosystem-native answer to CI hardening. We deliberately do not ship or recommend cloud KMS backends (see #457); users who want an HSM-backed signer can inject any viem `Account` through the seam `initializeSynapse()` already exposes.

### Scope

- Upload-only permission profile, the core requirement: `session create --profile ci-upload` (name negotiable) minting exactly `CreateDataSet` + `AddPieces`. `FilecoinPinFwssPermissions` (`src/core/session/authorize-session.ts:22`) grants `DefaultFwssPermissions`, which includes `SchedulePieceRemovals` and `TerminateService`: a "CI upload key" minted with the defaults can destroy the stored data. `initializeSynapse` must accept a matching `requiredPermissions` set instead of validating against all four (`src/core/synapse/index.ts:157`), with tests asserting a ci-upload session cannot authorize the destructive pair.
- upload-action: add a `sessionKey` + `walletAddress` input pair as an alternative to `walletPrivateKey` (which is required by `upload-action/src/inputs.js` and passed straight to `initializeSynapse`). `walletPrivateKey` becomes optional; document the input change as a minor-version note.
- Define funding behavior in session-key mode. Session keys are permission-scoped (`CREATE_DATA_SET`, `ADD_PIECES`) and cannot move funds (see `documentation/glossary.md#session-key`; `src/core/payments/index.ts` already skips allowance updates in session-key mode). The Action's `minRunwayDays`/`maxBalance` deposits are owner operations, so session-key mode must either skip funding with a clear log line or fail fast when funding inputs are combined with `sessionKey`; pick one and document it. Owner funds and sets allowances out-of-band. #141 (skip payments adjustments in the action) is the same mechanism requested independently; build on it rather than adding a second opt-out.
- Sequencing: coordinate with #527 (extracting upload-action to a standalone repo) so the `sessionKey` input lands in whichever repo the Action lives in when this ships.
- Docs: a CI hardening guide: owner creates and funds a hot wallet with capped allowances, authorizes a session key, stores only the session key as the repo secret, revokes on suspicion. State plainly what this is and is not: the session key is still a secret in CI, but a bounded, revocable one.
- Docs: a short "bring your own signer" section showing library users how to pass a custom viem `Account` (the KMS/HSM escape hatch, vendor-unnamed).
- Fork-PR policy is unchanged: the action does not run for fork workflows regardless of auth backend; say so in the guide to prevent false expectations.
- Cross-link the unify-auth-surfaces child for pinning-server session-key mode: the same skip-owner-funding semantics apply there once the server consumes shared auth resolution.
- Agent guide section on credential visibility: for agents invoking filecoin-pin locally, recommend the keychain-stored session key (#680) over `SESSION_KEY` in the agent's environment, and state the risk exposure in both setups: env-var keys appear in agent transcripts, env dumps, and error reports; keychain keys do not, but remain readable by any same-user process. Neither protects against a compromised agent; the permission profile, expiry, and revocation are what bound that case.

- Expiry and starvation warnings, so session-key mode is not a silent timebomb. Session-key expiry is the action's to warn about (nothing else sees it in context): emit a `::warning::` annotation when the key is within N days of expiry (default validity is 10 days per `src/core/session/authorize-session.ts:52`; document the `--validity-days` tradeoff up to 365). Funding alerts already have a home: [pay.filecoin.cloud/console/notifications](https://pay.filecoin.cloud/console/notifications) low-balance alerts watch the account continuously, which a CI job cannot. The action still emits a runway `::warning::` when it happens to run below `minRunwayDays`, and the CI guide makes console alert signup a required step of session-key setup, since the action no longer auto-funds.
- Rotation story: a documented re-authorize flow (scheduled owner-side workflow or a dated calendar step in the guide); rotation requires the owner signer by design.
- Secret redaction: `SESSION_KEY` currently prints to stdout on create and the action logs its full context object (`upload-action/src/upload.js:42`, context type includes the key). Central redaction rule before any new credential input lands.
- Fix the dead end where `payments setup --auto` with a session key skips the key prompt and then runs funding flows that cannot succeed (`src/payments/interactive.ts`); fail early with a message naming the owner-key requirement.

### Notes

Session creation still requires the owner key once, locally. That is by design; the owner key never reaches CI. Blast radius stated honestly: a leaked ci-upload session key can spend deposited Filecoin Pay capacity on junk uploads until revocation confirms (remaining balance, not "nothing"); it cannot move funds out, and with the upload-only profile it cannot remove or terminate existing data. `deposit` is not owner-only at the contract level (it takes a `to` recipient), so third parties can top up an owner's account; only spending and allowances need the owner.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.