feat(bin): ship the agent credential shims + lint ~/.local/bin - #14
Merged
Conversation
PR #12 added a gitconfig pointing at a credential helper the repo did not contain, so a rebuilt agent host got config with nothing behind it. Ship the three shims it depends on: gh injects the per-org PAT, resolving owner from -R/--repo, GH_REPO, an `gh api` path, a POSITIONAL owner/repo, or the cwd's origin. No default-org fallback: a repo-less call runs unauthenticated rather than quietly carrying an org credential. git refuses force-push and branch-delete, audits, and notifies. An ACCIDENT CATCHER, not a control — anything running as the agent can call /usr/bin/git or set NORM_ALLOW_FORCE=1. It fails OPEN to real git by design; breaking every git call would be worse than missing one force-push. git-credential-github-org one PAT per org, keyed on the remote URL's owner. All three append to ~/.local/state/norm-gh-audit.jsonl (0600, created before first write — the ambient umask would otherwise leave it world-readable). The token value is never logged. Gated in .chezmoiignore on .agent: `gh` and `git` SHADOW the real binaries, so on a host without ~/.config/github-pats they would break github.com auth outright. Verified both renderings with --override-data. Also wire home/dot_local/bin/* into the shellcheck job. Those files shadow real binaries and were outside the linter's reach; all four pass clean (0.11.0).
Widening the shellcheck job to home/dot_local/bin/* newly lints this file and SC2015 fires on `cd "$WORK" && git pull ... || true`. The warning is right: `|| true` swallowed a failed cd as well as a failed pull, while everything below (including the later `cd "$WORK"`) assumes we are in $WORK. Split so cd failure is fatal under set -eu and only the pull is best-effort. Verified with shellcheck 0.9.0 (matches CI's Ubuntu build) and 0.11.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #12, which shipped a gitconfig pointing at a credential helper this repo did not contain — so a rebuilt agent host got config with nothing behind it. This adds the three shims.
gh-R/--repo,GH_REPO, angh apipath, a positionalowner/repo, or the cwd origin. No default-org fallback — a repo-less call runs unauthenticated rather than quietly carrying an org credential.gitgit-credential-github-orgThe
gitguard is an accident catcher, not a control. Anything running as the agent can call/usr/bin/git, use the API, or setNORM_ALLOW_FORCE=1(itself audited and notified). It exists because the broker hard-deny on force-push does not reach the ambient PAT path. It fails open to real git by design — breaking every git call is worse than missing one force-push. Non-pushsubcommands are untouched, soclean -fd/checkout -f/tag -f/branch -dstill work..chezmoiignoreon.agent:ghandgitshadow real binaries, so on a host with no~/.config/github-patsthey would break github.com auth outright. Both renderings verified with--override-data.0600before first write — the ambient umask would otherwise leave a world-readable record of every credentialed operation. The token value is never logged.home/dot_local/bin/*now covered by the shellcheck job; those files shadow real binaries and were outside the linter entirely. All four pass clean (0.11.0).Verified on the agent host: 51 behavioural tests incl. sabotage passes, a real blocked force-push (nothing reached the remote), and a real push+delete cycle on a throwaway branch.
Supersedes #13, which had a stale merge base (that PR re-added the already-squashed gitconfig block).