~/.blobhub/credentials.yaml, the same file
blobhub-cli reads and writes. One login on a machine serves both tools.
Four commands cover it: login stores a profile, whoami reports which credential a start would pick up
and where its state lives, and profile ls lists what is stored. start takes the same selection flags as
the rest.
Removing a credential and moving the default belong to
blobhub — blobhub logout and blobhub profile use.
The worker deliberately ships no second writer for verbs the CLI already owns. Until blobhub-cli is published,
editing ~/.blobhub/credentials.yaml by hand is the supported way to remove a profile on a worker-only
install; the file is a default: key and a profiles: map, nothing more.Why a profile is more than a credential here
For the CLI a profile is only a credential: every invocation is short-lived and keeps nothing. The worker is different. Everything it persists — which sessions it watches, how far it has read them, the identity it is pinned to, its single-instance lock — is meaningful only under one identity on one deployment. So a profile here also names a state tree, and each profile gets its own. That is what lets one machine run several workers at once:config.yaml, its own cursors, its own logs, and its own lock. A second worker on the same
profile is still refused with WORKER_ALREADY_RUNNING, and the message names the profile.
Which tree a run uses
A state tree is named after wherever its key came from, not after the profile name that happened to resolve:
The digest is a one-way hash of the key, so the key itself is never a path, never logged and never printed.
This rule exists to make one situation unrepresentable. With
default: prod stored and a different
BLOBHUB_API_KEY exported, the ladder below resolves the name prod and a key from the environment — and
a tree named after prod would put two identities into one set of cursors and one lock. Naming by origin
instead means two credentials can never share a tree.
Two consequences follow. The same key supplied by two different routes gets two trees, which surfaces loudly
as INVALID_CONFIG naming a config.yaml that is not there rather than as silent misbehaviour. And
--profile alongside a supplied key runs in a key tree — the named profile then contributes only its URL,
and the worker says so in its log.
Run whoami to see the resolved path. You need it: a key-derived tree’s name cannot
be guessed, and its config.yaml has to be authored inside it before the first start.
How a credential is resolved
Three values, each highest-precedence first. This is blobhub-cli’s ladder rung for rung.- Profile name —
--profile, elseBLOBHUB_PROFILE, else thedefault:recorded in the file. A name that is not stored isPROFILE_NOT_FOUND. - Key —
--api-key, elseBLOBHUB_API_KEY, else the resolved profile’s. None of the three isCREDENTIALS_NOT_FOUND. - URL —
--api-url, elseBLOBHUB_API_URL, else the profile’s, elsehttps://api.blobhub.io/v1.
BLOBHUB_API_KEY on its own is enough.
start announces the profile and tree it resolved on its first log line. That is deliberate: blobhub profile use, typed for a CLI reason, moves which profile a bare blobhub-worker start picks up.
blobhub-worker login
Store an API key under a name, and record the identity it belongs to.
There is no
--api-key flag: the key is prompted for without echo, and a flag would put it in your shell
history. The first profile stored becomes the file’s default:; later logins add or replace a profile and
leave the default where it is. Full detail: blobhub-worker login.
blobhub-worker whoami
Show which credential a start would use, and where that run’s state lives.
start does, calls GET /v1/users/me, and prints five lines:
Profile: key <digest> — there is no worker
equivalent of the CLI’s Profile: (none), because the name is what selects the tree. Every failure a start
would hit surfaces here identically, which is the point of running it first.
blobhub-worker profile ls
List stored profiles, annotated with what this machine knows about each.
* marks the file’s default. The bracket says whether this machine has a state tree for that profile and
whether a worker is live in it — which is what blobhub profile ls structurally cannot show. Key-derived
trees are listed too, by digest, since they are state trees with no name. No network call is made.
Upgrading from a pre-profiles worker
Installs older than v0.5.0 kept everything flat under~/.blobhub-worker/. The first login or start after
upgrading migrates automatically and prints what it moved: state into profiles/default/, and the credential
into ~/.blobhub/credentials.yaml as the profile default. The old copy of the key is removed, not left
behind.
It refuses rather than overwrites in two cases — a pre-upgrade worker still running (stop it first), and a
default profile already in the shared store under a different key (MIGRATION_CONFLICT; rename yours or
move it aside).
One case migrates but needs a follow-up, and the migration says so: if the shared file’s default: already
names some other profile, it is left alone — it is not the worker’s to move — so a bare blobhub-worker start will not pick up the tree just migrated. Use --profile default, or move the pointer with blobhub profile use.
Sharing the file with blobhub-cli
Because there is one store, actions in one tool are visible in the other:blobhub login --profile prodcreates a profile this worker can use immediately. Its firststartrecords the identity then, rather than requiring ablobhub-worker loginyou have effectively already done.blobhub logout --allremoves the worker’s credential too.blobhub profile usemoves which profile a bareblobhub-worker startresolves.- blobhub-cli has no identity-change guard on
login— a CLI switches identities by design. So re-logging into a name this worker is pinned to surfaces at its nextstartasUSER_IDENTITY_MISMATCH, which is the right place for it to land: the tree’s cursors belong to the old identity.
blobhub logins.
Errors
Full catalog: Reference.
See also
blobhub-worker login— the command in full, including running as a service account.blobhub-worker start— the selection flags and the preflight order.- Filesystem layout — what a state tree contains.
- blobhub-cli authentication — the other half of the shared store.

