Credential management

This page is short on purpose. You meet a client secret on your first afternoon with auth, and the full answer lives three sections away — so here is the short one.

What auth declares

Secrets is the capability holding them, the config directory is where the dev copies live, and rotating one is the operation you will run on them.

SecretWhen you need itWhere it comes from
auth-session-secretAlwaysMinted for you
auth-google-credentialsOnly if Google is enabledGoogle Cloud Console
auth-apple-credentialsOnly if Apple is enabledThe Apple Developer portal
auth-github-credentialsOnly if GitHub is enabledGitHub developer settings
auth-facebook-credentialsOnly if Facebook is enabledThe Meta app dashboard

Composing email adds one more — a link-signing key, also minted for you.

The one that is minted

pithy add auth mints your dev session secret into <config>/<project>/secrets.jsonc, outside every checkout, and says so:

Minted a dev auth-session-secret into ~/.config/pithy/acme/secrets.jsonc. Local only.
Deployed environments need pithy secrets create auth-session-secret.

It is written only when absent. A new value signs out every live session, so re-running pithy add auth never replaces one.

Why it can be minted at all: it is arbitrary. Any random string works, because nothing outside your project has to agree with it. That is what the registry means by an origin the kit can produce.

For deployed environments, pithy secrets provision creates it for you — it creates every secret the registry says nobody chooses.

The ones that are obtained

A provider’s client secret authenticates you to them. A random string authenticates against nothing, so nothing can mint one.

Each is a typed JSON secret holding both halves together, because the client id never usefully splits off into config:

pithy secrets create auth-google-credentials

The value comes from stdin or a masked prompt. Never from a flag — that would leave a live credential in shell history and in every process list on the machine.

Then enable the provider in config, with no credential values in it:

auth({
  google: { enabled: true },
}),

Each provider’s own page has the console steps: Google · Apple · GitHub · Facebook.

Per environment, always

Each environment holds its own value. Staging’s Google client and production’s are different registrations, and pointing both at one is how a staging test lands in a production account.

That is not a Pithy rule — every provider’s console is per environment on its own terms.

Rotation

The session secret is local: the kit produces the value, so it produces another. pithy secrets rotate auth-session-secret --env prod mints and stores in one step.

Rotating it signs everybody out. That is the correct behavior — a session secret you are rotating is one you no longer trust — but do it deliberately.

The four provider credentials are manual, because none of those companies returns a replacement over an API. The rotate command prints the console, the page and the command that records the result, and calls nothing. It exits 0 and never prints Done. — nothing was done.

Apple’s expires within six months by construction, so it is the one to put in a calendar.

Say what would happen before doing it:

pithy secrets rotate auth-apple-credentials --env prod --dry-run

That reaches no account, needs no credentials, and rolls nothing — which is what makes it the thing to type first at 2am.

Where each value actually sits

Your dev values: <config>/<project>/secrets.jsonc. The source, not a copy — edit it and the next pithy dev hands the Worker the new value. Nothing to gitignore, nothing git add -A can reach, nothing npm pack can carry.

Deployed values: encrypted in that environment’s own store, under a master key that lives inside the environment’s secrets manager Worker and never leaves it. Nothing reads it back out.

That last fact has a consequence: a stored value cannot be copied between environments. If you need the same value in two, set it in both.

What to check

pithy secrets ls

Offline, no credentials, no values — just the declared names and their routing facts.

pithy doctor goes further: its settings check is one of the few that looks at a value rather than at presence, so an enabled provider with no credential behind it is a finding rather than a 503 on somebody’s first sign-in.

ESC