Creating a machine identity
The three-step wizard — naming, permissions, first key — and what to do with the token before you close the dialog.
Secrets → Machine identities → New machine identity opens a three-step wizard. It exists so the first key of every machine is born with the same constraints you would eventually have given it — the guided flow used to collect only a name, which made the very first credential the least constrained one that machine would ever have.
You need secrets:service_account:manage to start it.
Step 1 — Identity#
| Field | Rules |
|---|---|
| Name | free text, how the machine appears in lists |
| Slug | ^[a-z][a-z0-9_-]{0,63}$ — lowercase letter first, then letters, digits, _ or - |
| Description | optional; say what pipeline this is, not what it does technically |
The slug is the identity in your audit trail — every event this machine causes is attributed to
<slug>@service-account. Name it after the job, not the person or the tool: deploy-web,
nightly-backup, staging-migrator.
The pin is shown here and decided here. Inside a project workspace the new identity is pinned to that project by default; leaving it unpinned makes it space-wide.
Pinning cannot be changed afterwards — see Machine identities. Everything else on this page can be changed on a live identity without re-issuing anything.
Account type is CI at this phase; there is no other type to choose.
Step 2 — Permissions#
Attach the policies this machine needs. You can skip the step and attach them later — the identity simply reaches nothing until you do.
Two things about this step surprise people:
- You attach here; you author elsewhere. The pattern rules live on the Permission library screen and only there. A second copy of them inside this wizard is how the two drifted apart.
- A template grants nothing until it is bound. A library entry with no patterns of its own is a template — an intent ("read this environment") whose path you supply when you attach it. The wizard will not let you continue with an unbound template selected.
Full detail: Permissions.
Step 3 — First key#
Issue the machine's first API key. Everything on this step is covered in API keys; the fields are:
| Field | Default | Notes |
|---|---|---|
| Description | — | a label for the key list; cannot be changed later |
| Expires after | 90 days | required, 1–365; presets for 30/60/90/180/365 |
| IP allowlist | empty | CIDR blocks; empty means "from any address" |
| Rate limit | 100/min | up to your plan's ceiling (200 Solo Professional → 3,000 Enterprise) |
Set the IP allowlist here even though it can be changed later. The plaintext token is shown exactly once, at exactly this moment, which is when it gets pasted into CI — a key issued wide and narrowed afterwards spends that window unrestricted with its token already out.
The token, and the next sixty seconds#
When the key is issued the plaintext appears once:
Only sha256(token) is stored. Nobody — not you, not an administrator, not support — can retrieve
the value again. If it is lost, revoke the key and issue another.
Because that loss is unrecoverable, the reveal dialog has no ✕, ignores Escape and the backdrop, and keeps I've stored it — done disabled until you have copied the token. If your browser blocks clipboard access, the token is selected for you and a confirmation checkbox appears instead.
The reveal dialog also shows ready-made snippets for reading and writing a secret over the machine API and for running a command with secrets injected by the CLI. They use your project's slug and the API host for this environment, so they are copy-paste correct.
Paste the token into your CI provider's encrypted secret store — never into a repository file, a
pipeline definition, or a chat message. The pv_live_ prefix is registered with GitHub and GitLab
secret scanning, so a token committed to a repository on either platform is likely to be reported —
but treat that as a safety net that fires after the fact, not as a control.
After the wizard#
- Open the Setup tab on the identity's page for the same CI snippets at any time.
- Run one read from CI and confirm it works.
- Check Last used on the Credentials tab — it updates within about a minute and is the cheapest proof the credential reached the platform at all.
- Look at the blast radius panel above the tabs. If it says the machine reaches more than the job needs, fix it now, while nothing depends on the extra reach.