Identifiers
Read when:
- changing how Crabbox names leases, slugs, runs, or claims;
- debugging "why does
crabbox run --idnot find this lease?"; - adding a new lookup form (alias, provider id, anything that resolves to a
lease).
Crabbox names every long-lived thing twice: once with a stable canonical ID that machines compare, and once with a friendly slug that humans type. This page lists the identifiers, where they come from, and how lookup resolves across them.
#Lease ID
Canonical lease IDs look like:
cbx_abcdef123456
The pattern is fixed: the literal cbx_ prefix followed by 12 hex characters. isCanonicalLeaseID enforces it as a regex; anything else is treated as a slug or alias.
The CLI mints a provisional lease ID before calling the broker. The broker may return a different final ID (when the Worker dedupes a retried request, for example); the CLI then moves the local SSH key directory and claim file from the provisional ID to the final ID with MoveStoredTestboxKey and re-keys references accordingly.
Provider resources reference the lease ID through Crabbox labels:
crabbox-lease=cbx_abcdef123456
That label is what crabbox cleanup and crabbox list use to map a provider machine back to a Crabbox lease.
#Slug
Slugs are friendly, human-typeable lease names. They look like:
blue-lobster
amber-crab
silver-shrimp
Slugs are generated from a stable hash of the lease ID, so the same lease always gets the same slug. The vocabulary is small (14 adjectives, 8 nouns) because Crabbox is intentionally a small fleet. When a slug collides with an existing active lease, slugWithCollisionSuffix appends a 4-hex suffix keyed by the seed:
blue-lobster-1234
The collision path is rare in normal use - a single user's active leases rarely exceed the 14 × 8 = 112 unique base slugs.
Slugs are normalized everywhere they are accepted. normalizeLeaseSlug keeps only [a-z0-9-], collapses runs of separators, and trims leading/trailing dashes. Blue_Lobster and BLUE-LOBSTER resolve to blue-lobster.
#Provider Name
Each managed lease also gets a per-provider resource name that includes the slug and a hash of the lease ID, so the provider console shows useful names:
crabbox-blue-lobster-7f8a2c1d
That name is what shows up as the EC2 Name tag, the Hetzner server name, and the Daytona sandbox name. It is derived from leaseProviderName(leaseID, slug); the function falls back to crabbox-cbx-... if the slug is empty.
#Run ID
Each crabbox run against a coordinator also gets a durable run handle:
run_abcdef123456
A run is created before the lease is acquired so events can be appended for leasing failures, sync failures, and command output even when the run never reaches command-start. Run IDs are stable across a single invocation; retrying the same command produces a new run.
crabbox history, crabbox events, crabbox attach, crabbox logs, and crabbox results all accept run IDs. Slugs do not resolve to runs - only to leases.
#Local Claims
Reusable leases get a JSON claim file stored under the user state directory:
$XDG_STATE_HOME/crabbox/claims/cbx_abcdef123456.json
When XDG_STATE_HOME is not set, claims live next to user config in ~/Library/Application Support/crabbox/state/claims on macOS or ~/.config/crabbox/state/claims on Linux.
The claim payload looks like:
{
"leaseID": "cbx_abcdef123456",
"slug": "blue-lobster",
"provider": "aws",
"repoRoot": "/Users/steipete/Projects/openclaw",
"claimedAt": "2026-05-07T07:42:18Z",
"lastUsedAt": "2026-05-07T07:55:12Z",
"idleTimeoutSeconds": 1800
}
Claims do three things:
- bind a lease to one repo so wrappers and agents do not silently reuse a
- give
crabbox run --id blue-lobstera slug-to-canonical-ID translation - power "is this lease still mine?" checks before destructive operations
lease against a different checkout;
without round-tripping the broker;
(stop, cleanup, actions register).
A conflicting claim (same lease, different repo) refuses commands by default; --reclaim overrides the check and rewrites the claim atomically.
Static SSH leases tag their claims with provider: ssh so the resolver knows the lease bypasses the coordinator. Coordinator-backed claims leave provider blank because the coordinator owns provider tracking.
#SSH Key Storage
Per-lease SSH key directories are keyed by lease ID:
~/.config/crabbox/testboxes/cbx_abcdef123456/id_ed25519
~/.config/crabbox/testboxes/cbx_abcdef123456/id_ed25519.pub
~/.config/crabbox/testboxes/cbx_abcdef123456/known_hosts
The provisional → final lease ID move uses os.Rename on the directory so the key, public key, and known_hosts file all migrate atomically. The provider key name (crabbox-cbx-abcdef123456) is what the cloud account sees.
#Resolving An Identifier
crabbox <command> --id <value> accepts:
- a canonical
cbx_...lease ID; - a normalized slug (
blue-lobster,Blue Lobster,BLUE_LOBSTERall resolve - in coordinator mode, also the slug as known to the broker, regardless of
to the same lease);
case.
Resolution order:
- Read the local claim store for the literal identifier or any slug match
- If a matching claim exists, use its
leaseIDas the canonical handle. - If no claim is found and a coordinator is configured, ask the coordinator
- For static SSH and direct-provider modes, fall back to the provider's
in claims/.
to resolve the identifier (slug or canonical ID).
Resolve implementation (SSHLeaseBackend.Resolve).
The first source that returns a hit wins. This is why --id blue-lobster works from any directory once the warmup ran in some other repo - the local claim translates slug to lease ID before the broker is involved.
#Identifier Lifetime
provisional lease ID newLeaseID() call → broker returns final ID
final lease ID broker accepts → stored in claim, key dir, labels
slug computed on first lease creation, stable forever
provider name derived from lease ID + slug
run ID minted per crabbox run when a coordinator is configured
Slugs are not recycled. When a lease ends, the slug stays free for any future lease that happens to hash to it; the small vocabulary makes that collision-by-hash possible but rare in practice.
Related docs: