Skip to content

Create an agent identity

An agent identity gives writes a recognizable persona. A Personal Access Token (PAT) remains owned by the user who created it: its scopes control access, and its committer identity controls attribution. Binding a token to an identity does not grant that identity permissions.

This guide uses an org named acme, a private identity repo, and a product repo. Substitute an org you manage. Run setup and token management with your signed-in owner profile; run agent writes with the agent’s token. See Getting access if you need to sign in first.

Terminal window
wh auth status

The output includes your identity wref. A wref is WarmHub’s name-based address for a thing or shape; its canonical form, wh:<org>/<repo>/<name>, also names the repo.

Your identity wref identifies your public identity in warmhub/users. That repo is maintained by WarmHub. Create custom identities in your own repo. An identities repo is a naming choice; WarmHub does not create one automatically.

Create the repos if you do not already have suitable ones, then install the canonical Identity shape. A shape defines the fields a thing can carry; Identity is the persona shape that the first-party warmhub/identity component provides:

Terminal window
wh repo create acme/identities --visibility private
wh repo create acme/product-catalog --visibility private
wh component install warmhub/identity --repo acme/identities

Create the agent as an ordinary thing. Its name is catalog-bot; Identity is its shape, not part of its name or wref.

Terminal window
wh thing create catalog-bot --shape Identity \
--data '{"external_id":"catalog-bot","display_name":"Catalog Bot"}' \
-m "Create catalog agent" --repo acme/identities
wh thing list --shape Identity --repo acme/identities
wh thing view catalog-bot --repo acme/identities

For a custom identity, external_id is your own identifier, not an internal WarmHub user ID. Its canonical wref is wh:acme/identities/catalog-bot.

Grant the token access to the data repo and read access to the private repo holding its identity:

Terminal window
wh token create --name catalog-bot \
--committer-identity wh:acme/identities/catalog-bot \
--scope acme/product-catalog=repo:read,repo:write \
--scope acme/identities=repo:read \
--expires 30d
wh token list
wh token get --name catalog-bot

Save the token value when it is displayed; list/get show metadata, not the secret. Put it in your agent’s secret store and supply it as WH_TOKEN. The commands below assume your launcher provides the token in CATALOG_BOT_TOKEN. See PATs for authentication, expiry, and scope details. For a non-default backend, select the matching profile or pass --api-url too.

The token’s permissions cannot exceed yours. If the identity lives in a different private repo and its read scope is omitted, a bound-identity write fails with IDENTITY_USE_DENIED. Access is rechecked at write time.

As the owner, define the data shape before the agent starts writing:

Terminal window
wh shape create Product --fields '{"sku":"string","name":"string"}' \
--repo acme/product-catalog

Then write using the agent’s token:

Terminal window
WH_TOKEN="${CATALOG_BOT_TOKEN:?Set the agent token first}" wh thing create widget-001 --shape Product \
--data '{"sku":"WID-001","name":"Standard Widget"}' \
-m "Add product as Catalog Bot" --repo acme/product-catalog
wh thing history widget-001 --repo acme/product-catalog --json

The CLI JSON history’s items show committerWref for the agent and revisedBy for the authenticated user behind that write. References may be opaque durable IDs; the response’s decorations map supplies names where you can read them. The web history card displays the persona with a distinct “via” user.

To choose a persona for just one write, pass --committer with your owner profile instead of binding a token:

Terminal window
wh thing create widget-002 --shape Product \
--data '{"sku":"WID-002","name":"Second Widget"}' \
--committer wh:acme/identities/catalog-bot --repo acme/product-catalog

An explicit committer takes precedence over a token’s bound identity; without either, user writes normally use the user’s public identity, the entry WarmHub maintains for that account in warmhub/users. You cannot claim another user’s public identity. Just after a first sign-in your own public identity may not exist yet; the write still lands, with no committer recorded.

Use the owner profile to revise the complete body, preserving its shapes:

Terminal window
wh thing revise catalog-bot --keep-shapes \
--data '{"external_id":"catalog-bot","display_name":"Catalog Assistant"}' \
--repo acme/identities
wh thing retract catalog-bot -m "Retire catalog agent" --repo acme/identities
wh thing history catalog-bot --include-retracted --repo acme/identities

Retraction retains history. Further writes using that token’s bound default fail because the identity is no longer active; the token does not silently switch to your user identity. A new thing with the same name is a different identity and does not replace the old token binding. Revoke the retired agent’s token with wh token revoke --name catalog-bot.

For more detail, see Things, components, and PATs.