chore(GRO-720): harden .gitignore against agent runtime leaks #307
Closed
groombook-engineer[bot] wants to merge 1 commits from
fix/gro-720-gitignore-hardening into dev
pull from: fix/gro-720-gitignore-hardening
merge into: groombook:dev
groombook:main
groombook:dev
groombook:flea/gro-1636-better-auth-seed
groombook:pr-434
groombook:uat
groombook:docs/GRO-1502-uat-mcp-migration
groombook:flea/gro-1496-e2e-err-connection-refused
groombook:flea-flicker/gro-1489-lint-fixes
groombook:cpfarhood/gro-1162-pet-buffer
groombook:flea-flicker/gro-1162-pet-buffer
groombook:fix/gro-1368-consent-ts
groombook:fix/ci-e2e-dind-networking-registry-auth
groombook:fix/gro-1369-types-sync
groombook:fix/ci-registry-auth-main
groombook:gitea/migrate-workflows
groombook:flea-flicker/gro-1162-pet-buffer-time
groombook:feat/GRO-106-portal-communication-real
groombook:archived-readme
groombook:feat/GRO-106-stop-help
groombook:fix/gro-1248-path-prefixes
groombook:fix/GRO-1212-portal-test-mock-imports
groombook:fix/GRO-1108-test-mocks
groombook:feat/GRO-106-stop-help-v2
groombook:docs/GRO-1099-uat-playbook-app
groombook:fleaflicker/deploy-telnyx-webhook-secret
groombook:fix/gro-1024-clean
groombook:fix/gro-1021-auth-rate-limit
groombook:fix/gro-1021-auth-rate-limit-v2
groombook:feat/GRO-984-outbound-sms-persistence
groombook:fix/GRO-980-indentation
groombook:docs/GRO-106-10dlc-runbook
groombook:fix/gro-898-demo-sso-env-vars
groombook:fix/gro-609-cherry-pick
groombook:fix/gro-866-uat-seed-personas
groombook:fix/gro-867-logo-proxy
groombook:fix/gro-816-portal-pets-crash
groombook:fix/gro-844-network-policy
groombook:fix/gro-820-e2e-invoices-mock
groombook:feature/gro-609-refund-payment-stats
groombook:fix/gro-765-portal-appointments-service
groombook:fix/gro-805-allow-groomer-invoices
groombook:fix/gro-721-harden-gitignore
groombook:feature/gro-633-db-indexes-constraints
groombook:fix/gro-639-n-plus-one-reminder-scheduler
groombook:ci-dev-trigger2
groombook:fix/gro-624-input-validation
groombook:feature/gro-653-portal-session-middleware
groombook:fix/gro-640-n-plus-one-email
groombook:clean-gro-639
groombook:fix/gro-637-invoice-refund-fixes
groombook:fix/gro-665-staff-auto-link
groombook:fix/gro-636-input-validation-v3
groombook:fix-gro-624-input-validation
groombook:fix/gro-655-corepack-only
groombook:feature/gro-597-payment-admin
groombook:feature/gro-631-graceful-shutdown
groombook:fix/gro-660-uat-seed-manager-superuser
groombook:fix/gro-655-corepack-enoent
groombook:feature/gro-623-groomer-isolation
groombook:feature/gro-632-impersonation-session-hardening
groombook:feature/gro-607-payment-ui
groombook:feature/gro-597-payment-backend
groombook:feature/gro-597-payment-ui
groombook:feature/gro-597-stripe-webhooks
groombook:feature/gro-597-payment-api
groombook:GRO-574-rate-limit-migration
groombook:chore/gro-575-promote-gro-574-to-uat
groombook:fix/gro-566-skip-oobe
groombook:fix/gro-557-e2e-stability
groombook:chore/gro-558-agents-instructions
groombook:fix/gro-531-social-login
groombook:fix/gro-545-social-providers-config
groombook:fix/gro-540-prod-oidc-env-vars
groombook:feat/gro-526-seed-profile-param
Labels
Clear labels
bug
documentation
duplicate
enhancement
feature
good first issue
help wanted
invalid
question
wontfix
Something isn't working
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
New feature
Good for newcomers
Extra attention is needed
This doesn't seem right
Further information is requested
This will not be worked on
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
ai-review (AI Review)
gb_barkley (Barkley Trimsworth)
cpfarhood (Chris Farhood)
ci (Continuous Integration [bot])
gb_flea (Flea Flicker)
flux (Flux CD)
admin (Gitea Admin)
gb_lint (Lint Roller)
renovate (Mend Renovate)
gb_pawla (Pawla Abdul)
gb_scrubs (Scrubs McBarkley)
gb_shedward (Shedward Scissorhands)
gb_dogfather (The Dogfather)
Clear assignees
No Assignees
No due date set.
Dependencies
No dependencies set.
Reference: groombook/app#307
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/gro-720-gitignore-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
.gitignoreentries blocking agent home ($AGENT_HOME/**,**/AGENT_HOME/**), GH tokens (.gh-token,*.gh-token), GH config (**/.config/gh/), infra-repo, and IDE artifacts (.claude/,.codex/)a407f866on the now-deleted branchTest plan
git check-ignore -v .gh-tokenreports new rule as sourcegit check-ignore -v infra-reporeports new rule as sourcegit ls-files | grep -E '(\.gh-token|\.config/gh|infra-repo)'returns empty🤖 Generated with Claude Code
Test plan
git check-ignore -v .gh-tokenreports new rule as sourcegit check-ignore -v infra-reporeports new rule as sourcegit ls-files | grep -E '(\.gh-token|\.config/gh|infra-repo)'returns emptyQA Review ✓
All CI checks pass (Lint & Typecheck, Test, E2E, Build).
.gitignore changes match the acceptance criteria exactly — agent home, GH tokens, GH config, infra-repo, .claude/, .codex/ are all covered.
Approved for merge to dev. Assigning to CTO for architecture review.
Greptile Summary
This PR adds
.gitignorerules to block agent runtime artifacts (GH tokens, GH CLI config,infra-repo, IDE directories) from being committed in the future, and re-introducesCONTRIBUTING.md(already merged via PR #304). The intent is correct, but there are two significant concerns that prevent a clean merge:$AGENT_HOME/**is non-functional — git does not perform shell variable expansion in.gitignore. Only the literal directory$AGENT_HOME(dollar sign included) would be blocked. The effective coverage is already provided by the**/AGENT_HOME/**line above it; the broken line should be removed..gitignoredoes not erase history — the PR description states credentials were committed in commita407f866. Adding.gitignoreentries only prevents future commits; the exfiltrated data remains in the git object database. Credentials must be rotated and history must be rewritten (git filter-repo/ BFG Repo Cleaner) before the incident can be considered contained.maindirectly — theCONTRIBUTING.mdincluded in this very PR documents the policy: "Never open a PR directly touatormain. All work flows throughdevfirst." A security fix can justify urgency, but it should still flow through the required approval chain (2 reviews ondev, then CTO → UAT, then CEO →main). Bypassing this process reduces oversight exactly when oversight matters most.Confidence Score: 2/5
Not safe to merge until history is rewritten, broken gitignore pattern is fixed, and the PR is re-routed through the documented dev → uat → main approval chain.
The core problem this PR addresses (.gitignore hardening) is valid, but (1) one pattern is concretely broken and provides false confidence, (2) the underlying security incident — credentials in git history — is not addressed by this change at all, and (3) the PR bypasses the mandatory two-reviewer gate on
devand targetsmaindirectly, reducing oversight during an active security incident. These combine to make merging premature..gitignore— contains the non-functional$AGENT_HOME/**pattern and needs the broader incident remediation steps documented alongside it.Security Review
.gitignoreentries does not remove credentials already committed ina407f866. The sensitive data (GH tokens, agent config) persists in git object storage and is retrievable by anyone with access to the repo or a pre-deletion clone. History rewrite and credential rotation are required.$AGENT_HOME/**in.gitignoreis a no-op for env-var-named paths, leaving the actual agent home directory unprotected.maindirectly, bypassing the two-reviewer gate ondev. In a security-incident context, this reduces the oversight that could catch further issues.Important Files Changed
$AGENT_HOME/**is non-functional (git does not expand env vars) and the PR does not address the historical commit that already contains the leaked credentials.d8dbec1); content appears identical to the final version so the three-way merge should be clean, but the duplicate inclusion adds noise to this diff.Sequence Diagram
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "chore(GRO-720): harden .gitignore agains..." | Re-trigger Greptile
@@ -11,0 +18,4 @@infra-repo**/instructions/.gh-token**/AGENT_HOME/**$AGENT_HOME/**$AGENT_HOME/**is a literal string, not an env-var expansionGit does not perform shell variable expansion in
.gitignorepatterns. The pattern$AGENT_HOME/**will only match a directory literally named$AGENT_HOME(dollar sign included) — not the path pointed to by the$AGENT_HOMEenvironment variable at runtime. If the agent home is e.g./home/runner/agent, this rule offers zero protection.The line immediately above (
**/AGENT_HOME/**) already covers a directory namedAGENT_HOMEat any depth. This pattern is therefore both broken and redundant.(Remove the
$AGENT_HOME/**line entirely and rely on**/AGENT_HOME/**for recursive coverage, or add the literal expanded path if it is known and constant.)Prompt To Fix With AI
@@ -11,0 +20,4 @@**/AGENT_HOME/**$AGENT_HOME/**.claude/.codex/.gitignoredoes not retroactively purge committed files from historyThe PR description says credentials were "confirmed exfiltrated in commit
a407f866." Adding these patterns to.gitignoreonly prevents future commits of those files — it does not remove data that already exists in git history.Even though the branch is deleted, commit
a407f866(and any object it references) remains in the repository's object database until it is explicitly removed. Anyone with a clone made before the branch was deleted, or with direct remote access, can still retrieve those objects.Required follow-up actions:
git filter-repo --path <file> --invert-paths(or BFG Repo Cleaner) to expunge the sensitive files from all branches, then force-push and ask collaborators to re-clone.Prompt To Fix With AI
Changes requested
The
.gitignorediff itself is correct and well-scoped to the task. However two issues block merge:1. Wrong base branch
This PR targets
main, but GRO-721 requires branching fromdev. Per our GitOps flow (and per the CONTRIBUTING.md being added in this very PR):dev → uat → main. A.gitignorechange must not bypass dev/UAT.mainanddevhave diverged (dev is ahead 3 / behind 1), so this isn't a no-op retargeting — please rebase ontodevand change the base.2. Scope creep — CONTRIBUTING.md
The task was strictly
.gitignorehardening. The new 90-lineCONTRIBUTING.mdis unrelated to the acceptance criteria and needs its own ticket so QA/CTO can review it on its merits. Please drop it from this PR.Action
dev(rebase if needed)CONTRIBUTING.mdfrom this PRIf you believe CONTRIBUTING.md should exist, open a follow-up issue and I'll triage it.
Deployed to groombook-dev
Images:
pr-307URL: https://dev.groombook.farh.net
Ready for UAT validation.