---
title: "Block pushes that contain secrets · Agent Wranglers"
url: https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/secret-push-protection
id: ENG-58
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1145
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Block pushes that contain secrets

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: ENG-58
- Level: Recommended
- Chapter: [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md)
- Rule: Turn on the code host's secret push protection for every repository, so a push with a key is refused before it lands. Every bypass needs a reason and alerts an owner.
- Check: A script lists the repositories with push protection switched off, and the list is empty. Push a commit holding a test key in a known format, such as a sample from the provider's docs. The code host refuses the push.
- How: A scanner in the build finds a key after it is already in the history, as [Keep secrets out of code](https://agentwranglers.se/playbook/application-security/secrets-and-configuration/secrets-out-of-code.md) explains. Push protection stops it on the server, for every client and every agent. GitHub calls it push protection, and GitLab calls it secret push protection. Turn it on at the organisation level, so new repositories get it too. Let only named people approve a bypass, and send each bypass to the security owner. Add patterns for your own token formats, such as a `shop_live_` prefix. Keep a pre-commit scanner as well, because it catches the key before it is even committed. Treat any key that reached a branch as leaked and replace it, as [Keep secrets in a secrets store](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Shell example

```sh
# GitHub: list repositories without push protection
gh api --paginate orgs/example/repos --jq '.[] | select(.security_and_analysis.secret_scanning_push_protection.status != "enabled") | .full_name' \
  | grep . && { echo "FAIL: push protection off"; exit 1; } || echo "PASS"
```

### Python example

```python
# The same check with the GitHub REST API
import os, sys, requests

headers = {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"}
repos = requests.get("https://api.github.com/orgs/example/repos?per_page=100", headers=headers, timeout=10).json()
unprotected = [r["full_name"] for r in repos
               if r.get("security_and_analysis", {}).get("secret_scanning_push_protection", {}).get("status") != "enabled"]
if unprotected:
    sys.exit(f"FAIL: push protection off in {', '.join(unprotected)}")
```

### JavaScript example

```js
// The same check in Node.js 22
const response = await fetch('https://api.github.com/orgs/example/repos?per_page=100', {
  headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` },
});
const unprotected = (await response.json())
  .filter(repo => repo.security_and_analysis?.secret_scanning_push_protection?.status !== 'enabled')
  .map(repo => repo.full_name);
if (unprotected.length) throw new Error(`Push protection off in ${unprotected.join(', ')}`);
```

## Sources

- [GitHub: About push protection](https://docs.github.com/en/code-security/secret-scanning/introduction/about-push-protection)

## Related rules

- APS-60 [Keep secrets out of code](https://agentwranglers.se/playbook/application-security/secrets-and-configuration/secrets-out-of-code.md) in Application security
- ENG-26 [Keep secrets in a secrets store](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store.md) in Engineering

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/secret-push-protection">Agent Wranglers engineering playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Scan every image before it ships](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/image-scanning.md)
- Next: [Sign release tags and require verified commits on main](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/signed-commits-and-tags.md)
- [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md)
