Provisioning Keys
A provisioning key is a reusable credential you put in an image or a provisioning script. Devices carrying it enroll, get accepted according to the key’s mode, and arrive with tags already applied.
This is what turns enrollment from an afternoon of clicking into something that happens on its own.
Creating one
In Add Device, open Fleet and click New key. A key has:
| Field | Meaning |
|---|---|
| Name | Unique within the namespace. How you identify it later |
| Mode | How an enrollment is decided |
| Expiration | A date after which the key stops enrolling, or never |
| Usage limit | Single-use, a number of devices, or unlimited |
| Ephemeral | Whether devices enrolled with it are removed after a spell offline |
| Tags | Applied to every device enrolling with the key |
The key is not copy-once. It is stored encrypted and can be read again: open a key in the Fleet
list and its install command carries it, or open the key’s page and click Show under
Details. Reading it needs the provisioningKey:reveal permission, so a role
that can use the console is not automatically a role that can retrieve a credential.
Using one
$ curl -sSf https://cloud.shellhub.io/install.sh | PROVISIONING_KEY=<your-provisioning-key> sh
Or as an agent variable, SHELLHUB_PROVISIONING_KEY, which is how it goes into a
Yocto or Buildroot image.
The key only matters while the server does not know the device. On first start the agent generates its own private key, and the server recognizes the device by that key together with its hostname and MAC address. The agent keeps presenting the provisioning key, so a removed or ephemeral device can enroll again, but for a device the server already knows the key decides nothing. A device whose hostname or MAC address changes is a new device to the server, and enrolling it counts against the key’s usage limit.
Modes
The mode decides what happens when a device presents the key.
| Mode | Device lands | Use it for |
|---|---|---|
automatic |
Accepted | Fleets you trust by construction — your own images, your own provisioning |
manual |
Pending | Keeping the human check while still getting tags |
webhook |
Whatever your endpoint says | Deciding from your own inventory |
allowlist |
Accepted if the identity it reports is listed, rejected otherwise | A known, fixed set of hardware |
Automatic
The mode for images that should join with nobody watching. A device presents the key and joins the namespace, with the key’s tags applied.
The trade is real: anything holding the key can enroll and be accepted. Scope keys narrowly — one per product line, per site, per batch — so revoking one does not strand everything.
Manual
Tags without automatic acceptance. Useful when you want the fleet sorted but still want to look at each arrival.
Webhook
The decision goes to an endpoint of yours, called at enrollment. Your service answers, and its answer decides.
This is how you enroll against your own source of truth: an ERP, a manufacturing database, whatever knows which serial numbers are genuinely yours.
Bounds worth knowing: the call times out after 5 seconds by default, 15 at most. A deferred decision has a callback window, 1 hour by default and 24 hours at most. The request is signed with HMAC-SHA256. See Provisioning Key Webhook for the contract.
What matters without the contract is how it fails. A webhook that does not answer in time fails closed to pending, not to accepted — the device waits for a human rather than walking in. And a device left pending by a webhook or an allowlist key has its enrollment re-evaluated the next time the agent authenticates, so a decision that was deferred or blocked resolves on its own once the condition clears.
The webhook may only reach a public address. The destination is checked after DNS resolution, so a hostname that resolves into a private network is refused too.
Allowlist
Accepted if the identity the device reports is in the key’s list, rejected otherwise. For a fixed set of hardware you can enumerate in advance.
The identity is the primary interface’s MAC address, unless the agent was started with
SHELLHUB_PREFERRED_IDENTITY, which replaces it with any string you choose and is commonly set to
the equipment’s serial number. List what your fleet actually reports, not what the hardware’s MAC
happens to be. Matching ignores case and surrounding whitespace.
Tags
A key applies its tags to every device that enrolls with it. This is the highest-leverage part of the whole feature, because tags are what policies select on.
Put the tag on the key and the fleet is governable the moment it arrives — a policy granting
tag:production covers every device that ever enrolls with the production key, including ones
that do not exist yet. See Tags and
Access Policies.
Bounding a key
A provisioning key outlives the session you created it in. Three settings bound it without you having to remember to.
Expiration is a date. Four presets are offered — 30, 60 and 90 days, and a year — and any other date can be picked from the calendar beside them. A key with no expiry keeps enrolling devices for as long as the namespace exists.
Usage limit is how many devices may ever enroll with it: single-use, a count, or unlimited. A key cut for one production batch should be capped at that batch.
Ephemeral marks the devices it enrolls for automatic removal once they have been offline past a timeout, between 1 and 10 minutes. Use it for machines that come and go by design — a CI runner, a short-lived container — so the device list reflects what exists rather than everything that ever ran.
Reviewing a pending enrollment
A key in manual mode, and a key whose webhook deferred, leaves devices waiting. They are reviewed on the key’s page rather than in the device list, and the Fleet list marks every key that has devices waiting. Devices that registered with the tenant ID have their own page, Pending devices, linked from the Devices list and the dashboard, which anyone who may accept devices can work.
The page lists each enrollment attempt by day, newest first. A device still waiting stands out with Accept and Reject beside it; every other attempt is one line with how it was resolved, and opens to what the agent reported: the identity, the source address, the architecture, the agent version and the device key. A device that was rejected can still be accepted later.
What you have to decide on is what the agent said about itself. A hostname you did not choose, or an architecture that does not match anything you deploy, is worth understanding before accepting. Rejecting costs little — a device that should be there can enroll again.
Accepting from a device’s own page does the same thing, and is how you decide on one you arrived at from somewhere else.
This is the audit trail for enrollment. When a device turns up that you did not expect, this is where you find out which key let it in.
On Pending devices, an agent the namespace refused because it could not prove it holds its device key is a line marked refused, with the agent version and how many times it tried, and nothing to accept. It stays one line while the agent retries. Update the agent, or turn off Device signature enforcement, and its next attempt lands pending.
Pausing and revoking
The actions menu on a key offers Edit, Disable and Revoke, and the difference between the last two matters.
Disable is a pause. The key stops enrolling devices and can be enabled again — the right move while you work out whether a key is being misused.
Revoke is permanent and cannot be undone. A revoked key never enrolls another device. There is no delete: the key stays in the list, which is what keeps the devices it admitted attributable to it on their device pages.
Neither affects devices already enrolled. They stay accepted and connected.
The two keys you did not create
Every namespace has two keys it manages itself.
Pairing code covers devices that pair by the code the agent prints during install, or by the link printed with it. There is nothing to reveal and no mode worth setting — the code itself is the acceptance.
Tenant-only registration is the deprecated path a device enrolls through with the namespace identifier and no key at all, and the only one a legacy namespace has. It is fixed on manual mode and cannot be edited or disabled, so every tenant-only enrollment lands in Pending, on the Pending devices page the Devices list links to. A new namespace lists the row only while devices are pending under it.
Treating a key as a secret
A key in an image is a credential you shipped. Anyone with the image has it, and on automatic
a leaked key puts the leaker’s machine in your namespace already accepted.
- Scope narrowly — per product line or batch, not one key for everything.
- Cap each batch’s key with a usage limit and an expiration.
- Rotate when a batch is done.
- Prefer
webhookorallowlistoverautomaticwhen the images go somewhere you do not control. - Check the key’s page when the device list grows in a way you did not expect.
Where to go next
- Provisioning Key Webhook — The contract, if your endpoint decides.
- Tags — What the key applies, and why it matters.