diff --git a/README.md b/README.md index 553d778..d5525e9 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,13 @@ manifest-driven through `lib/base/dev_manifest.yaml`; use `basectl setup --dev` to install them and `basectl check --dev` or `basectl doctor --dev` to verify them. +If Homebrew is missing, `basectl setup` uses Homebrew's official installer URL +at `https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh`. This is +a deliberate trust decision: Base stays aligned with Homebrew's supported +bootstrap command instead of pinning and maintaining a reviewed installer +commit. Teams that require stricter supply-chain controls should install +Homebrew through their managed device process before running Base. + On macOS, `basectl setup` sends a best-effort notification when setup completes or fails after running for at least 30 seconds. Notifications are skipped during `--dry-run` and never change the setup exit status. Use `basectl setup --notify` diff --git a/TODO.md b/TODO.md index 33be824..c3688f8 100644 --- a/TODO.md +++ b/TODO.md @@ -7,15 +7,6 @@ they are merged. ## P0 — Security And Correctness -- [ ] Document or harden the Homebrew installer trust decision. - - Problem: Base follows Homebrew's official mutable `HEAD` installer pattern, - which executes downloaded code. - - Goal: make the trust model explicit and decide whether Base should pin and - verify the installer. - - Expected behavior: either pin to a reviewed installer commit with SHA - verification, or document in code and docs why Base intentionally follows - Homebrew's official installer command. - ## P1 — Product Core And Composability - [ ] Redesign project manifests around delegation-first orchestration. diff --git a/cli/bash/commands/basectl/subcommands/setup_common.sh b/cli/bash/commands/basectl/subcommands/setup_common.sh index 78fc674..09d51ed 100644 --- a/cli/bash/commands/basectl/subcommands/setup_common.sh +++ b/cli/bash/commands/basectl/subcommands/setup_common.sh @@ -249,6 +249,10 @@ setup_refresh_brew_path() { } setup_install_homebrew() { + # Trust decision: Base follows Homebrew's official install command, which + # intentionally fetches the installer from the mutable HEAD ref. Pinning a + # reviewed commit would reduce mutability risk, but would also make Base own + # installer refreshes and drift from Homebrew's supported bootstrap path. local installer_url="https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh" local exit_code diff --git a/docs/design.md b/docs/design.md index 12048d8..dc749f4 100644 --- a/docs/design.md +++ b/docs/design.md @@ -373,6 +373,14 @@ When `basectl setup` runs on a fresh Mac: 8. For each discovered project, run project-level setup (install declared dependencies, create project venv) +Homebrew installation follows Homebrew's official `install/HEAD/install.sh` +bootstrap command. That means Base intentionally trusts Homebrew's mutable +installer entry point instead of pinning a commit SHA. Pinning would reduce +installer mutability, but would also make Base responsible for tracking +Homebrew installer updates and could diverge from Homebrew's documented support +path. Environments with stricter supply-chain policy should preinstall Homebrew +through managed workstation provisioning before invoking `basectl setup`. + --- ## GitHub and Repository Conventions