better/compute
Bare metal

Dedicated-root metal

Lease whole machines to tenants with root, under tenant-controlled trust and node-tenant certificates, and take them back with a BMC-driven teardown.

Some tenants need the whole machine: their own kernel, their own OS image, root on the host. The moment a tenant has root, nothing running on that machine can be trusted by the platform again: not its agent, not its inventory, not its reports. A dedicated-root lease is designed around that. For the lease, the machine's trust changes to tenant-controlled and the platform gives up its identity on it. Afterwards, the machine comes back only through a teardown driven entirely from the BMC side.

Dedicated-root leases are a v0.5 feature of PLAN.md. They are implemented in metal (metal/0003_tenant_root) and capacity (whole-node placement), and tested end to end against the simulated site. The contract between the two modules is rows only; neither imports the other.

Set up a tenant-root pool

Whole-node leases are served only by pools that opt in with policy.tenantRoot. Give the pool a firmware baseline too: the teardown verifies it, and fails without one.

await compute.api.pools.create(credential, {
  tenantId: 'root',
  siteId,
  class: 'metal-dedicated',
  policy: {
    hardwareProfile: 'gpu-redfish',
    tenantRoot: true,
    firmwareBaseline: { bmc: '1.12.0', bios: '2.4.1', 'gpu-vbios': '96.00.5f' },
    firmwareRemediation: 'reflash', // or 'quarantine', the default
    firmwareImages: {
      bios: { url: 'https://firmware.site-a/bios-2.4.1.bin', sha256: '<64 hex digits>' },
    },
  },
});

Prop

Type

Offer the pool to the tenants who may lease from it, as with any pool (see pools). Nodes under tenant control add no capacity to the pool's rollups while they are leased.

Reserve a whole machine

The tenant creates a with binding: 'node' and names the metal profile to deploy:

const reservation = await client.reservations.create({
  tenantId: 'acme',
  poolId,
  devices: [{ class: 'gpu', count: 8 }],
  duration: '7d',
  binding: 'node',
  node: { profileId: 'acme-root-os', profileVersion: 1 },
  idempotencyKey: 'acme-root-2026-09',
});
  • binding: 'node' needs node.profileId, and node needs binding: 'node' (INVALID_INPUT otherwise). Always pass profileVersion: metal refuses to start a lease whose reservation names no version, publishes node.tenant-root.refused, and leaves the node ready.
  • A node binding cannot be spot, and a pool without policy.tenantRoot refuses it.
  • Placement takes nodes that are ready, not in maintenance, not cordoned, with platform trust and no live allocation in the window, whose healthy atoms cover devices. Other NoSchedule reasons do not stop a lease, with one exception: a node tainted dedicated=<tenant> is leased only by that tenant (see taints). The same check guards the lease's commit and BookingRepair. The allocation books every bookable atom of the node, so nothing else can land on it. gang leases several such nodes on one topology value.
  • The profile resolves in the lessee's tenant: the lessee's own profile, or a public one. The image it deploys resolves in the machine owner's tenant, so the lessee's profile has to name a public (promoted) image.
  • If metal has not finished deploying the node within 2 hours, the lease fails and is not placed again elsewhere.
  • A bound lease bills node.metal.hours per lease-hour, plus the GPU meter for the GPUs that were healthy at the start of each hourly window. See billing and usage.

How a lease starts

  1. When the reservation reaches its start (binding), capacity queues the node's metal work.
  2. On a ready node of a tenant-root pool, not in maintenance, metal records the lease, marks the machine tenant_root, sets its release wipe to secure-erase and its trust to tenant-controlled, and starts a new identity generation, which revokes every platform certificate of the node before any tenant code runs. It then applies deploy with the lessee's profile and publishes node.tenant-root.leased (allocation, reservation, lessee tenant, profile and version).
  3. The deploy workflow runs in the lessee's tenant. When the installed OS joins, JoinService sees the node's tenant-controlled trust and issues a node-tenant instead of a node one.
  4. When the deploy completes, the node is deployed with the profile's role (usually dedicated). Metal marks the allocation bound and queues capacity's reservation work, which moves the reservation to active, and publishes node.tenant-root.bound.

What the tenant gets, what the platform keeps

A node-tenant certificate runs a session as a node, but carries none of a platform node's authority:

LesseePlatform
Root on the OS, its disks and kernelyesno
Session through the gateway, telemetry and leaveyes
Secrets from the brokernever: the broker refuses node-tenant certificates
Destructive commandsnever: the gateway rejects them as tenant-controlled
Results that count (wipe, diagnostics)never: only platform identities attestthe platform ramdisk
BMC, power and boot devicenoyes, from the site agent
The teardownnoalways

The attestation check accepts only ramdisk and node certificates by default, so even a wipe result the lessee's OS signs with its own key for this very node is refused.

The lessee's inventory and health reports are advisory. While the node is tenant-controlled, an inventory it sends is appended as a snapshot (node.inventory.changed with advisory: true) but changes none of the node's devices, device health, labels, conditions, image cache or hardware key, and its XIDs and host pressure are ignored. A GPU the lessee reports missing or unhealthy therefore stays healthy and on the lease's bill. metal.exitTenantRoot ends the advisory period, so the first report under platform trust applies for real. See trust.

PLAN.md also disables in-band BMC access where the vendor supports it. That is not implemented yet, which is one reason the teardown rotates the BMC password.

The teardown

When capacity releases the allocation (a release, the end of its time or a lapsed lease), metal moves the deployed node to releasing (node.tenant-root.ending) and runs metal-tenant-root-release@1 instead of the ordinary release. Every step is driven from the site agent or the control plane:

#StepWhy
1power.setPower offstop the tenant's OS
2metal.fenceTenantrevoke the lessee's certificates first, so nothing left behind can sign for this node
3metal.rotateBmcCredentialthe lessee may have learned the BMC password; see BMC rotation
4metal.ensureRamdiskboot the platform ramdisk over PXE
5disk.wipe secure-erasean attested wipe of every disk
6diag.dcgm level 1GPU reset and ECC check
7metal.firmwareCheckevery component must match policy.firmwareBaseline
8metal.exitTenantRoota new identity generation, trust back to platform, the lease cleared
9power.setPower offpark the machine

The cleanup step boot.cleanUp removes the boot entries. As with every release, the node reaches ready only if the wipe's result is node-signed and every disk passed read-back. The v0.5 exit criterion holds in the tests: a lease and its release yield a new identity generation.

Agentless pools (agent: 'none') run metal-tenant-root-release-oob@1 instead: power off, fence, rotate, eject media, firmware check, exit. It has no wipe, so it reaches ready only with policy.allowUnverifiedRelease.

When the teardown fails

Every failure quarantines the machine: the node is failed with failedFrom: 'releasing' and maintenance on, and it stays tenant_root with tenant-controlled trust, because only a completed teardown clears them.

  • Firmware drift fails the check with code: 'FIRMWARE_DRIFT', listing each drifted component. With firmwareRemediation: 'reflash' and an image for every drifted component, the site agent writes the images (bmc.firmware) and the check runs again; drift that survives the reflash still quarantines.
  • A rotation the BMC refuses fails the teardown, and the old credential stays current.
  • A wipe not signed by a platform identity never reaches ready.
  • A pool without firmwareBaseline fails the check with INVALID_CONFIG.

metal.recover sends the node back to releasing, and since it is still tenant_root, the teardown runs again from the start. The same holds for a lessee deploy that failed: recovering it runs the tenant-root teardown, not the ordinary release. Maintenance stays on after recovery; see failure and recovery.

When the lessee's tenant is deleted

When Better IAM deletes the lessee's tenant, compute's tenancy teardown ends its reservations through capacity (capacityTenantDeleted), so each lease is released now and runs the tenant-root teardown above. Metal's own tenantDeleted hook retires the machines the deleted tenant owns, not the platform machines it leased. See tenancy.

Limits

  • PLAN.md offers dedicated-root only on vetted hardware until TPM measured boot exists, since a tenant with root could otherwise persist below the OS in ways a firmware version check does not see.
  • Reservation lifecycle, quotas and offerings work as for any reservation; see reservations.

Was this page helpful?

Better Compute is created by Sean Filimon

Last updated

On this page