Skip to content

ci: don't bake the checkout token into shipped images - #77

Merged
phorcys420 merged 1 commit into
mainfrom
phorcys/ci-drop-baked-git-token
Aug 24, 2026
Merged

ci: don't bake the checkout token into shipped images#77
phorcys420 merged 1 commit into
mainfrom
phorcys/ci-drop-baked-git-token

Conversation

@phorcys420

Copy link
Copy Markdown
Member

What

Stop baking the CI checkout token into shipped images, so git pull on installed boxes works without a credential prompt.

The bug

On an installed box, git pull in /etc/nixos-repo prompts for a GitHub username while a fresh git clone of the same public repo works anonymously:

[root@coder-box:/etc/nixos-repo]# git config --local --get-regexp 'http\..*\.extraheader'
http.https://github.com/.extraheader=AUTHORIZATION: basic <base64 x-access-token:ghs_…>
Username for 'https://github.com':

Root cause

actions/checkout defaults to persist-credentials: true, which writes the job's short-lived token into .git/config as http.https://github.com/.extraheader. box-turnkey.nix bakes the working tree into the image at /etc/nixos-repo via self.outPath (which includes .git on the dirty CI build), so that token ships in every installer/appliance image and lands on installed boxes. The token expired ~1h after the build, so on the box git pull sends a dead credential → GitHub 401 → git prompts for a username. A fresh git clone has no such header and fetches anonymously, which is why clone works but pull doesn't.

Fix

Set persist-credentials: false on the two checkouts whose tree gets baked into an image:

  • test.ymlImages job
  • release.ymlbuild job

The .git directory and origin are still shipped, so git pull keeps working — just anonymously, which is fine for a public repo. The initial CI fetch still authenticates; nothing downstream relies on the persisted credential (no workflow pushes via git, and the release publishes through softprops/action-gh-release using GITHUB_TOKEN). Nix fetches flake inputs with its own fetcher, unaffected.

Validation

  • actionlint clean on both workflows; YAML parses.

Existing boxes

Images built before this merges still carry the dead token. On an affected box, drop it once:

git -C /etc/nixos-repo config --local --unset-all http.https://github.com/.extraheader

New images built after this won't have it.


Generated by Coder Agents on behalf of @phorcys420.

actions/checkout defaults to persist-credentials: true, which writes the
job's short-lived GitHub token into .git/config as
`http.https://github.com/.extraheader`. box-turnkey.nix bakes the working
tree (self.outPath, including .git) into the image at /etc/nixos-repo, so
that dead token ships in every installer/appliance image and lands on
installed boxes. `git pull` there then sends the expired token, GitHub
returns 401, and git prompts for a username (a fresh `git clone` has no
such header and works anonymously).

Set persist-credentials: false on the two checkouts whose tree is baked
(test.yml Images, release.yml build). The repo is public, so the box's
`git pull` works anonymously; the .git and origin are preserved. No
workflow pushes via git, and the release uses GITHUB_TOKEN through
action-gh-release, so nothing else relies on the persisted credential.
@phorcys420
phorcys420 marked this pull request as ready for review August 24, 2026 22:34
@phorcys420
phorcys420 merged commit 0072206 into main Aug 24, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant