4.9 KiB
Why
The Host Agent today cannot start unattended on a fresh install: it requires an operator to hand-carry an out-of-band HOST_AGENT_ENROLLMENT_TOKEN (issued via CLOUD_ENROLLMENT_TOKENS_JSON on the cloud side) before it will enroll, and it accepts any HOST_AGENT_CONTROL_PLANE_URL an installer happens to set, which for the single home deployment at https://amcp.home.jerryyan.top is unnecessary ceremony. There is also no local gate preventing the daemon from starting with no operator ever having touched the machine, and no local record of who set it up. This change removes the pre-issued-token requirement for this deployment, fixes the control-plane address, and adds a one-time local setup gate, while leaving the existing token-based and static-credential paths intact for other deployments.
What Changes
- Add a Host Agent CLI first-run bootstrap: if no local account file exists,
device-host-agentinteractively prompts (viagetpass) for a username and password, hashes the password, and persists the credential atomically with restricted file permissions before continuing. On later starts, if the account file exists, the daemon starts straight into background polling with no prompt. - Change
host_agent/config.py::load_host_agent_configdefault forHOST_AGENT_CONTROL_PLANE_URLfromhttp://127.0.0.1:8001tohttps://amcp.home.jerryyan.top; the environment variable still overrides it for development/testing. - BREAKING (new deployments only, additive for existing ones): Remove the hard requirement for
HOST_AGENT_ENROLLMENT_TOKENwhen no local identity and no staticHOST_AGENT_HOST_ID/HOST_AGENT_TOKENare configured.host_agent/enrollment.py::resolve_host_identitynow falls back to an unauthenticated self-service enrollment call when no enrollment token is configured, instead of raisingHostAgentConfigurationError. - Add a cloud-side self-service enrollment mode, gated by a new
CLOUD_SELF_SERVICE_ENROLLMENT_ENABLEDflag (defaultfalse): when enabled,POST /internal/v1/enrollmentsaccepts requests with no enrollment-token bearer credential and storesenrollment_token_digest = NULLfor that Host row (the column is already nullable). When the flag is disabled, current behavior (token required,401otherwise) is unchanged. - Existing static-credential (
HOST_AGENT_HOST_ID/HOST_AGENT_TOKEN), token-based enrollment (HOST_AGENT_ENROLLMENT_TOKEN+CLOUD_ENROLLMENT_TOKENS_JSON), and revocation paths fromedge-host-enrollmentare unchanged and remain fully supported side by side with self-service enrollment. - No changes to
host_agent/heartbeat.py— periodic device-status reporting already exists and continues to run against the (now-fixed) control-plane URL; this change only confirms the wiring stays intact once the URL and enrollment path change.
Capabilities
New Capabilities
host-agent-local-bootstrap: First-run interactive local account creation gate for the Host Agent CLI — credential storage format, hashing, one-time prompt behavior, and non-interactive skip on subsequent starts.
Modified Capabilities
edge-host-enrollment: Add a cloud-side self-service enrollment mode that does not require a pre-issued enrollment token, and change the Host Agent's default control-plane URL and fallback behavior when no enrollment token is configured. (Note: this capability's spec currently lives only in the not-yet-archivedopenspec/changes/edge-host-enrollment/change, not in canonicalopenspec/specs/; this change's delta is authored against that pending spec and should be reconciled whenedge-host-enrollmentis archived.)
Impact
- Host Agent (
apps/device-host-agent): newhost_agent/local_account.py(or similarly named) module and CLI wiring inhost_agent/cli.py;host_agent/config.pydefault URL change;host_agent/enrollment.py::resolve_host_identityfallback behavior change; new local credential file (default path under the existingtasks/state directory, permissions0600). - Cloud Platform (
packages/cloud-platform/cloud,apps/cloud-api):control_config.pygainsCLOUD_SELF_SERVICE_ENROLLMENT_ENABLED;internal_api/api.py::enroll_hostgains a self-service path; no schema migration required (enrollment_token_digestis already nullable). - Dependencies: no new third-party dependency for password hashing is planned (stdlib-based); to be confirmed in design.md.
- Deployment/docs:
.env.example,compose.yaml/compose.deploy.yaml, anddocs/CLOUD_DEPLOYMENT.mdneed the new flag documented;docs/MACOS_IPHONE_SETUP.mdneeds the first-run local-account step documented. - Security posture: enabling
CLOUD_SELF_SERVICE_ENROLLMENT_ENABLEDmeans any network caller reaching the control-plane URL can self-register as a Host with no approval step; this is an explicit, accepted tradeoff for the single-operator home deployment and is opt-in (default off) for other deployments.