# edge-host-enrollment Specification ## Purpose Define how an edge Host Agent bootstraps its identity, enrolls local devices with cloud-assigned identifiers, and maintains durable credentials and device mappings across restarts without requiring static configuration. ## Requirements ### Requirement: Host bootstrap uses a one-time enrollment credential The Cloud Control Plane SHALL provide a Host enrollment operation that authenticates a configured bootstrap credential, generates the authoritative `host_id`, and binds it to an edge-generated long-lived Host credential without storing the plaintext Host credential. #### Scenario: New edge instance enrolls - **WHEN** an edge instance presents a valid unused enrollment token, a new instance identifier, and a high-entropy candidate Host credential - **THEN** the control plane returns a generated `host_id` and durably stores only the credential digest and enrollment binding #### Scenario: Enrollment token is invalid - **WHEN** an edge instance presents an unknown enrollment token - **THEN** the control plane rejects enrollment without creating a Host identity or consuming any configured token #### Scenario: Enrollment token is reused by another instance - **WHEN** a consumed enrollment token is presented with a different instance identifier - **THEN** the control plane returns a conflict and preserves the original Host binding ### Requirement: Host enrollment is idempotent across response loss The Host enrollment operation SHALL return the existing cloud Host identity when the same instance repeats enrollment with the same bootstrap-token binding and Host credential digest. #### Scenario: Identical enrollment is retried - **WHEN** an edge instance repeats a successful enrollment request after losing the response - **THEN** the control plane returns the original `host_id` without creating another Host or rotating the submitted Host credential #### Scenario: Instance retries with a different Host credential - **WHEN** an enrolled instance repeats enrollment with a different candidate Host credential - **THEN** the control plane rejects the request and leaves the original Host credential binding unchanged ### Requirement: Cloud assigns Host-scoped device identities An authenticated Host SHALL enroll each local device through an opaque Host-scoped local reference, and the control plane SHALL generate and durably return the `device_id` used by scheduling, heartbeat, leases, and assignment execution. #### Scenario: Host enrolls a local device - **WHEN** an authenticated Host submits a previously unknown local device reference and valid driver metadata - **THEN** the control plane creates a device enrollment owned by that Host and returns a generated `device_id` #### Scenario: Device enrollment is repeated - **WHEN** the same Host repeats enrollment for the same local device reference - **THEN** the control plane returns the existing `device_id` and does not create a duplicate enrollment #### Scenario: Same local reference appears on another Host - **WHEN** a different Host enrolls an identical local device reference - **THEN** the control plane creates a distinct Host-scoped device enrollment rather than silently transferring ownership ### Requirement: Edge identity and device mappings survive restart The Host Agent SHALL persist its generated instance identifier, long-lived Host credential, assigned Host ID, and local-to-cloud device mappings outside process memory and SHALL reuse them on later starts. #### Scenario: Host Agent restarts after enrollment - **WHEN** a managed Host Agent restarts with intact identity state - **THEN** it authenticates with the previously assigned `host_id` and credential without consuming another enrollment token #### Scenario: Device mapping is missing but Host identity remains - **WHEN** a managed Host Agent has its Host identity but lacks a cached mapping for a configured local device - **THEN** it repeats idempotent device enrollment and restores the original cloud `device_id` #### Scenario: Enrollment response is lost before Host ID persistence - **WHEN** the Host Agent persisted its candidate credential but did not persist the successful response - **THEN** its next start retries the identical enrollment request and recovers the original `host_id` ### Requirement: Enrolled Host credentials are revocable The cloud repository SHALL support revoking a dynamically enrolled Host credential, and authentication SHALL reject revoked credentials without deleting task or attempt history. #### Scenario: Revoked Host sends heartbeat - **WHEN** a Host presents a credential whose enrollment has been revoked - **THEN** the internal API rejects the request and preserves existing cloud history for that Host and its devices