github-guard-0.1.1 is not a library.
gg - Git & GitHub CLI Guard
A safety proxy for git and gh that enforces command policies. Designed to prevent AI coding agents from executing dangerous operations.
$ gg push --force origin main
[gg] BLOCKED: `git push --force origin main` is denied by policy
$ gg status
On branch main
nothing to commit, working tree clean
$ gg pr list
Showing 3 of 3 pull requests in owner/repo
Why
AI coding agents (Claude Code, Cursor, Copilot, etc.) run git and gh commands on your behalf. Most of the time this is fine, but some commands are destructive and hard to reverse:
git push --forceoverwrites remote historygit reset --harddiscards uncommitted changesgh repo deletedeletes an entire repositorygh pr mergemerges without human review
gg sits between the agent and git/gh, enforcing allow/confirm/deny rules before any command executes.
Install
From source
From crates.io
Binary releases
Download from GitHub Releases.
Quick Start
- Create a config file at
~/.config/gg/config.toml:
[]
= true
[]
= ["status*", "log*", "diff*", "branch*"]
= ["add*", "commit*", "push", "pull*"]
= ["push --force*", "push -f*", "reset --hard*"]
[]
= ["pr list*", "pr view*", "issue list*"]
= ["pr create*", "issue create*"]
= ["pr merge*", "repo delete*"]
- Configure your AI agent to use
gginstead ofgit/gh:
Claude Code (~/.claude/settings.json):
Shell aliases (for manual use):
How It Works
Agent runs: gg push origin main
│
▼
┌──────────────┐
│ Auto-detect │ Is this git or gh?
│ git vs gh │ (rules → subcommand list)
└──────┬───────┘
│
▼
┌──────────────┐
│ Evaluate │ Check deny → confirm → allow
│ rules │ (first match wins)
└──────┬───────┘
│
┌───────┼────────┐
▼ ▼ ▼
[ALLOW] [CONFIRM] [DENY]
│ │ │
│ prompt block
│ user (exit 77)
▼ │
Execute ┌─┴─┐
git/gh y n
│ │
Execute block
Rule Evaluation Order
- deny rules are checked first - if matched, command is blocked
- confirm rules are checked next - if matched, user is prompted
- allow rules are checked last - if matched, command runs
- If no rule matches:
deny_by_default = trueblocks,falseallows
Pattern Matching
- Exact:
"status"matchesgg status - Prefix:
"push"matchesgg push origin main - Glob:
"push --force*"matchesgg push --force origin main
Configuration
Config Search Order
./gg.toml(project-local)$GG_CONFIG(environment variable)~/.config/gg/config.toml(XDG)- Platform config dir (
~/Library/Application Support/gg/config.tomlon macOS) ~/.gg.toml(home)
Options
| Key | Default | Description |
|---|---|---|
deny_by_default |
true |
Block commands with no matching rule |
log |
true |
Write audit log |
log_file |
~/.local/share/gg/audit.log |
Custom log file path |
priority |
"git" |
Preferred tool when a command matches both git and gh rules |
Environment Variables
| Variable | Description |
|---|---|
GG_CONFIG |
Path to config file |
GG_GIT_PATH |
Path to git binary (default: git) |
GG_GH_PATH |
Path to gh binary (default: gh) |
GG_VERBOSE |
Show config loading messages when set |
GG_NO_LOCAL |
Ignore local ./gg.toml and $GG_CONFIG (use only global config) |
CLI Reference
gg [--git|--gh] <command...>
Options:
--git Force command as git
--gh Force command as gh
--dump-config Show loaded configuration
-h, --help Show help
-V, --version Show version
Exit codes:
0 Success
77 Command blocked by policy
78 Could not determine git/gh (use --git or --gh)
other Passthrough from git/gh
Security
See SECURITY.md for the threat model and limitations.
Key point: gg is a policy layer, not a sandbox. It only protects when commands go through it. See the security doc for recommended setup to maximize protection.