Module

Secrets

Encrypted secret storage for Pithy. One dedicated store per environment, a worker-only master key, automatic at-rest key rotation, and the `pithy secrets` CLI to manage it.

@pithy-sh/secrets

terminal
pithy add secrets
Read the docs Source on GitHub

What it is for

Somewhere to put the values you cannot commit: DKIM keys, webhook secrets, rail credentials, the auth signing key. Encrypted at rest, rotated automatically, managed from pithy secrets.

What it sits on

Its own D1, separate from your application database.

Secrets do not ride the per-feature lifecycle. A deployed Worker still needs its signing key and webhook secrets after a feature branch is torn down, so the store is its own D1 per environment, not a table in the app database.

The master key is worker-only. Nothing outside your Worker can reach it, and there is no API of ours that returns it.

  • D1
  • Workers

The honest bit

Rotation is the part most stores skip.

At-rest key rotation happens on its own, and it is append, prove, then expire — never replace. A rotation that fails leaves the old key working rather than locking you out of your own secrets.

Plenty of secret stores encrypt. Far fewer rotate without a maintenance window, and that is the difference worth caring about.

If you build it yourself

Encrypting is the easy part. Rotating is not.

Anyone can seal a value. Very few systems can change the key afterwards.

Envelope encryption

A master key that never leaves the Worker, per-value envelopes, and additional authenticated data binding a value to its own name.

Rotation with an overlap

New key, prove it, expire the old one — never replace, or a failed rotation locks you out of everything at once.

A store with a different lifecycle

Application data comes and goes per branch; a signing key must survive that, which is why it lives in its own database.

Never logging a secret

Redaction at the boundary, and a toJSON that cannot betray you in a stack trace.

Per environment, not per project

One value per environment, present in all of them at once, without copying it by hand.

terminal
pithy add secrets

In the dashboard

Administer it from a browser, without building the screen.

Which secrets exist, in which environment, and when each was last rotated — never their values.

The dashboard is the admin interface for your own application: whatever this capability writes, your team can look up, check and act on from a browser. Reading is free, forever, with no time limit. Connect the project when you deploy.

Designed, not shipped

What is coming to this capability.

Written down, argued out, and not built yet. Each one links to the issue it is being designed in, so you can read the reasoning or disagree with it.

Add it, and get on with the feature.

One command installs the package, wires its bindings into every environment your project declares, and runs its migrations.