cd /news/ai-agents/show-hn-nimblegate-git-push-guardrai… · home topics ai-agents article
[ARTICLE · art-136966] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Show HN: Nimblegate – Git push guardrails for AI agents

Nimblegate launched a self-hosted gateway that sits between an AI agent and a real git host, checking every push against enabled rules and forwarding clean pushes upstream in under a second while holding unsafe ones with a report. The tool, in production since early 2026, ships as a single Docker container with a docker compose plugin, a dashboard on port 7900, and a core rule kit of 18 of 51 frames that applies automatically at repo registration. Repos are registered with an HTTPS upstream URL and a write-scoped Personal Access Token, and the gateway relays over HTTPS only, shipping without an SSH client by design.

read14 min views2 publishedSep 22, 2026
Show HN: Nimblegate – Git push guardrails for AI agents
Image: Michielbdejong (auto-discovered)

Git push guardrails for AI agents: block unsafe pushes consistently, forward safe ones, record every decision.

Status: · used in production since early 2026

nimblegate sits between your AI agent and your real git host. Every push your agent makes is checked against the rules you turned on; clean pushes forward to your upstream in under a second, unsafe ones are held with a clear report. Same input, same answer, every time.

→ Try the live demo: click through a real dashboard over sample data, nothing to install.

→ New here? The Getting Started guide walks you from install to your first guarded push, step by step, no git expertise assumed.

Self-hosted in one container. You need Docker with the docker compose plugin on the machine that runs the gateway.

1. Start the gateway.

curl -O https://raw.githubusercontent.com/nimblegate/nimblegate/main/compose.yaml
docker compose up -d

Deploying to a fresh cloud VPS? One file does the whole box: deploy/cloud-init.yaml - paste it as user data at server creation and it boots hardened (firewall, key-only SSH) with the gateway running.

2. Claim the admin account. Grab the one-time setup token, then set your password:

docker logs nimblegate | grep nbg-setup     # prints the setup token

Open http://localhost:7900/setup, paste the token, choose your admin password.

Remote/headless host? The dashboard binds the host's loopback (it's the admin surface). Tunnel to it:

ssh -L 7900:127.0.0.1:7900 <user>@<gateway-host>   # then open http://localhost:7900

Use 127.0.0.1, not localhost (it's published on IPv4). For a trusted LAN instead, set NIMBLEGATE_DASHBOARD_HOST=0.0.0.0. → dashboard access options

3. Register the repo to guard. In the dashboard: Repos → Add a repo, then fill in:

Name - lowercase letters, numbers, dots, hyphens, underscores (e.g.my-app ). This is the name you'll push to. #

Upstream URL - your real repo asHTTPS :https://github.com/you/my-app.git (not thegit@… SSH form). The container relays overHTTPS only - it ships without an SSH client by design - and a PAT authenticatesboth public and private repos. #

Upstream credential - aPersonal Access Token from your git host, scoped towrite that repo :

  • GitHub fine-grained : repository = that repo,Contents → Read and write
  • GitHub classic : therepo scope
  • GitLab / Gitea: a token with write/push on the repo (Auto-PR's fix-loop needs a little more - see Getting Started.)
  • GitHub

Click Register. If the upstream already has commits, the gateway mirrors its history down automatically at registration, so your existing clones push cleanly. If that seed couldn't run (a missing or wrong credential, say), the repo row shows a one-click Sync from upstream - fix the credential, click it, done. The core rule kit (18 of the 51 frames, the catastrophic-prevention set) applies automatically; widen or narrow it any time on the repo's Policy page. → other git hosts, scoped access

4. Authorize your push key. On your dev machine, print your SSH public key:

cat ~/.ssh/id_ed25519.pub

Copy the whole line, then in the dashboard go to Keys → Add a key, paste it, and save. The gateway only ever sees your public key - never the private one.

5. Point your computer at the gateway and push. Add the gateway as your remote and push to it instead of your real host.

This hop is SSH, not HTTPS. You push to the gateway over SSH on port 2222 - that's not the HTTPS upstream URL from step 3. The two hops use different protocols on purpose: your machine → gateway = SSH, gateway → your real host = HTTPS.

git remote set-url origin ssh://git@<gateway-host>:2222/~/my-app.git   # my-app = the name from step 3
git push

Note the ~/ in the URL - it's required, not a typo. On the gateway the SSH user is locked to git-shell (it can run git push/clone and nothing else - no shell, no commands), which resolves repo paths relative to its home. So the path is ~/<repo>.git, not a bare /<repo>.git. This restriction is a security feature: a key can only move git data through the gate, never run commands or read the gateway's upstream token - so a compromised dev key can't bypass the gate or steal your credential.

6. See it work. A clean push is accepted and forwarded to your upstream; a push that trips a rule is blocked and never reaches the real host. Watch it live on the dashboard Feed.

Bare-metal install, SSH-key upstreams, multi-dev scoped access, or public TLS? → Getting Started - full walkthrough + troubleshooting.

There are three places, and keeping them straight is the whole game:

   YOUR COMPUTER                THE GATEWAY                   THE UPSTREAM
   (you / your agent            (nimblegate)                  (GitHub / Gitea / GitLab:
    write + git push)                                          your real repo)

   git push ──────────────────► checks your rules ─forwards─► stores the code
   git clone ◄───────────────── serves the code
  • Your computer only talks to the gateway: you push to it and clone from it, never the upstream directly (that would skip the checks).
  • Only the gateway talks to the upstream: it holds the credential and forwards clean pushes for you.

Your commits arrive at the upstream byte-for-byte unchanged: same SHA, same author, same signature. The gateway checks and forwards; it never rewrites. You see every push and decision live on the dashboard, and you can change the rules anytime; the next push uses the new set.

What that gets you:

  • Hours back on review. The gate is the filter between an agent's output and your real repo, so you're not eye-scanning every generated diff yourself.
  • Caught at push time, not deploy time. Leaked credentials, force-pushes to main, schema drift: held at the gateway, never in your upstream history.
  • A reviewer the fix-loop converges against. "Push → fail → fix → pass" only works when the reviewer answers the same way every time. Pattern checks do; AI reviewers don't.
  • Proof of what it stopped. A live feed of every decision, plus a stats page estimating the hours saved.
  • Invisible when clean. A clean push forwards in under a second; the gate speaks up only when there's something to see.

Full walkthrough with the mental model spelled out: Getting Started.

Because each of those either lives somewhere the agent can reach, or fires after the code has already landed.

  • A pre-commit hook runs on the machine the agent controls. It can be bypassed (git push --no-verify ), edited, or simply never installed in a fresh worktree. nimblegate runs on a separate box the agent has no shell on, and it holds the only credential to your real host - so there's nothing to skip and nowhere to go around.
  • Branch protection and CODEOWNERS gate the merge, not the push. By the time they fire, a leaked key is already an object in your upstream's history; deleting the branch doesn't unleak it, and rotating the credential is your only real remedy. The gate rejects the push, so the object never reaches your host at all.
  • CI runs after the push landed - and its config lives in the repo the agent is editing. Same exposure, one step later.
  • The fix-loop needs a reviewer that answers the same way every time. "Push → fail → fix → pass" only converges against a deterministic gate. Pattern checks are; an AI reviewer isn't.

None of these replace each other - keep your hooks and your branch protection. The gate is the one layer that sits outside the machine writing the code.

Day to day, the gate fits the normal feature-branch flow:

  1. Your agent works on a feature branch - coding agents often use a git worktree per task, so several branches are in flight at once (one task, one branch) - and pushes itto the gateway .
  2. The gate checks that push. Clean → forwarded to your upstream, where you or the agent open a PR (feature → main ), as usual.Findingrejected , and the bad commit never reaches the upstream.
  3. On a rejection with an open PR, the gate posts the finding as a PR comment (see Auto-PR below) - the agent reads it, fixes, and re-pushes until it passes. (The gate comments on a PR; it doesn't open one - your git host does that.)
  4. You review the PR and merge it to main on your git host, as usual.

Because rejected commits bounce at the gate, the branch on your upstream only ever holds gated-clean code - so by the time you review a PR, it has already passed the automated checks; you spend review time on judgment, not hunting for leaked keys or rm -rf. A new repo's protected refs default to refs/heads/*, so the agent's feature branches are gated, not just main - including nested names like agent/task-1 or feature/login, since a trailing /* matches at any depth. Leave it there unless you deliberately want main-only checks.

When a push is rejected, the gateway posts the findings as a structured comment on the upstream PR and fires a webhook with the same JSON, so an agent (Claude Code, Cursor, Copilot, custom CI) reads the rejection and fixes itself. The sticky comment updates in place, tracking attempt N/M and @-mentioning the agent; when a later push passes, it flips to ✅ All findings resolved and the loop closes. The /auto-pr dashboard surfaces it as Dashboard / Repos / Activity / Setup tabs.

Minimum config (per repo, /auto-pr → Setup or gateway.toml): set [notification] enabled = true and a mention handle and/or webhook URL. The upstream token needs comment permission (separate from the relay's push permission): GitHub - classic repo, or fine-grained Issues: Read and write + Pull requests: Read (PR comments use the Issues API); Gitea - write:issue; GitLab - the api scope (no narrower one allows MR comments). If deliveries fail, the Auto-PR → Repos tab shows the error + a Retry now button. Full setup + receiver examples: notifications.md.

nimblegate ships 51 rules ("frames") for the mistakes agents make most, grouped into one-click kits:

  • core(every repo) : hardcoded credentials, committed private keys, force-push to protected branches,--no-verify bypass,rm -rf of protected paths,curl | sh patterns, DB schema drift, non-idempotent migrations.
  • web-app / cf-pages-project / cf-workers-project : stack-shaped bundles (HTML/SEO, Cloudflare Pages + D1, Workers).
  • security-strict / encoding-strict : the invisible-Unicode attack class, checksum-validated personal data in fixtures (payment cards, IBANs, SSNs), and paste-corruption that silently breaks parsers. Stackable on any kit.
  • Supply-chain :commands/approved-registries-only flags dependency sources (Maven/Gradle repositories, npm registries, pip index URLs) that bypass your approved registry mirror - declare your hosts once, catch the agent-added bypass at push time.

Plus your own regex rules, authored from the dashboard with a live "would have flagged N files" preview: no code, no rebuild. Choosing and authoring policy: policy-authoring.md. Full catalog: frames.md.

Every repo then runs those rules in one of two modes, set per repo:

Enforce (default) Observe ( observe = true )
BLOCK finding push rejected recorded, relayed
Pusher / agent sees findings + push rejected nothing , silent
Operator sees dashboard + audit log dashboard + audit log (⚠ banner)
Acts as a guardrail? yes no, advisory only
Use it for day-to-day protection measuring/benchmarking agents

Observe mode is deliberately silent so an agent can't adapt to the gate; it measures behavior, it is not a safety net (a credential or curl | sh is logged and let through). Switching modes takes effect on the next push.

The gateway exposes a read-only analytics API (MCP + REST) so an agent can query the decision log directly: "which repo had the biggest bounce-back this month?", "how much debugging time has the gate prevented?", "what changed this week?", answered from SQL over the validated log. Mint a bearer token (nimblegate gateway token new <label>) and point your MCP client at http://<host>:7900/mcp. No agent? The same reports are one-click buttons on the dashboard Reports page. Reference: agent-api.md.

Guide What's in it
Getting started Install → first guarded push, step by step, with a troubleshooting quick-check. Start here.
Policy authoring Choosing frame kits, writing custom regex rules, fitting alongside your linters + CI.
Frame catalog Every built-in frame: what each category catches, severity, tiers.
Auto-PR / notifications The fix-loop rail: config, webhook receivers, troubleshooting.
Agent API MCP + REST analytics surface for agents.
Operations Update, backup/recovery, monitoring, password reset.
Dev-machine setup Making the gateway a real boundary (close the bypass paths).
Troubleshooting Operator gotchas beyond the getting-started table.
Security model What's hardened, the trust boundaries, the threat model.

nimblegate is honest about its scope so it stays trustworthy:

  • The rules you enable are exactly what gets caught. A rule that isn't on catches nothing; a pattern outside the rule set flows straight through. The tool issecure as configured : coverage is whatever you turn on.
  • It is not a substitute for human review of human work. The audience is agent pushes, code generated faster than anyone reads every line.
  • It is not a vulnerability scanner or an AI reviewer. It runs the same pattern checks the same way every time. That's the value, and the limit.

The tool itself is hardened: separate machine your agent can't reach, holds the only upstream credential, single-admin auth, append-only audit log. But you're the operator; the coverage is yours to decide. Full version: security-model.md.

Operator security - this part matters:

  • Use a separate, minimal-scope upstream token per repo, and rotate it regularly. A fine-grained PAT scoped toContents: write on that one repo (nothing wider) means a leaked token can push only to that repo, not your whole account - and rotation bounds how long any leak stays useful. Encrypting the token at rest doesnot protect arunning gateway (it must decrypt the token to use it); minimal scope + rotation are what actually limit the blast radius.
  • The guarantee depends on correct deployment. Run the gateway on adedicated box your agent can't otherwise reach, keep the git SSH user ongit-shell (push/clone only - no shell, no commands), don't hand out keys or expose the box loosely, and never authorize a dev key directly on the upstream.Set up improperly, it can be compromised: an attacker who obtains a shell as the git user could read the stored upstream token and pushdirectly to your real repo, bypassing the gate entirely. Treat the gateway as security-sensitive infrastructure.

Non-commercial use is free and unrestricted under PolyForm Noncommercial 1.0.0

  • no time limit, no feature gating, today and for good.

Free, non-commercial - for example:

  • Personal projects and your own learning
  • Research and teaching
  • Use by a non-profit / not-for-profit
  • Trying it out before a commercial decision

Needs a commercial license (contact@nimblegate.com) - for example:

  • Use inside a for-profit business, including gating code that ships a paid product
  • Offering nimblegate, or a derivative, as a hosted service to others

The LICENSE is authoritative; if your case is unclear, just ask.

You get:

  • One combined container (sshd + dashboard, s6-supervised, auto-restart).
  • Single-admin auth built in (bcrypt, server-side sessions, setup-token bootstrap).
  • Same-rules-every-time gate across pre-commit / pre-receive / post-receive.
  • 51 built-in frames + your own regex linters.
  • Auto-PR rail (vendor-neutral): structured PR comment + webhook on every rejected push,@bot mention + multi-bot rotation, loop guardrails, fix-loop closure, exponential-backoff delivery with deadletter. Gitea + GitHub adapters.
  • Dashboard : live feed, time-saved/recurring stats, policy + custom linters + whitelist, repo lifecycle, frames catalog, Auto-PR tabs, health, SSH key management, events log, per-page help.
  • Upstream credential management +whitelist (with required reason).

Using nimblegate in a for-profit setting requires a commercial license - a flat $10/month or $99/year per company (all your devs, the app as-is, best-effort email support, no SLA). Terms and the buy links: commercial license.

Larger organisations needing an SLA, signed terms, or bespoke features: email contact@nimblegate.com.

You define which rules fit your repo, stack, and threat model; you review the coverage you enabled and test the gate in your environment; you keep the rest of your security posture in place (nimblegate is one layer); and you keep the gateway machine itself secure. Found a bypass or coverage gap? Please report it via SECURITY.md.

No telemetry. The binary phones home zero times. The gateway logs what you push to it and sends nothing anywhere except your configured upstream. See PRIVACY.md.

nimblegate is source-available under PolyForm Noncommercial 1.0.0, provided AS-IS without warranty. Non-commercial use is free and unrestricted, today and for good. Commercial use requires a commercial license ($10/month or $99/year per company; email contact@nimblegate.com for larger orgs).

── more in #ai-agents 4 stories · sorted by recency
── more on @nimblegate 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-nimblegate-g…] indexed:0 read:14min 2026-09-22 ·