security
Secret detection before an agent ever runs a tool
AI agents generate and commit code faster than post-commit scanning can catch secrets, requiring detection before file creation rather than after.

Hardcoding an AWS access key into a config file takes two seconds. An AI agent reading that file, deciding it's "configuration that should be centralized," and committing it to a shared repository takes even less. By the time a human reviews the pull request, the secret has already touched version control, triggered half a dozen webhooks, and possibly landed in CI logs that get archived for compliance.
The core problem isn't that agents make mistakes—it's that they operate at speeds and scales where a single oversight can cascade before anyone notices. Traditional secret scanning tools run after code is written, often as a pre-commit hook or CI step. For autonomous agents that can generate dozens of files in a single planning cycle, waiting until the git stage is already too late.
Why post-hoc scanning fails in agent workflows
Most secret detection tools were designed for human developers who write a few files, run tests locally, then push. The feedback loop is tight: you get a warning, you fix it, you continue. Agents collapse that loop. A capable coding agent might:
- Clone a repository and scan for patterns to replicate
- Generate ten new microservice configs based on an existing template
- Refactor environment variable usage across 40 files
- Propose infrastructure-as-code changes that reference API tokens
If any step inadvertently introduces a secret—perhaps by copying a .env.example that wasn't actually an example, or by interpolating a credential from a context window that included debugging output—the damage spreads instantly. The agent doesn't pause to manually review diffs before moving to the next task.
Pre-commit hooks help, but they assume a human is in the loop to read the rejection message and course-correct. An agent might retry the same operation with minor variations, hit the hook again, and waste cycles—or worse, interpret the hook failure as a permissions issue and attempt to disable it.
Interception at the constraint layer
Goatfied's architecture separates planning from execution with an explicit constraint phase. Before an agent edits a file or runs a shell command, the plan passes through compile checks, lint rules, and policy gates. Secret detection sits here, not as a post-write guardrail but as a pre-execution constraint.
When an agent proposes a change—say, adding a new environment variable to a Kubernetes manifest—the constraint layer:
1. Parses the planned diff (not yet written to disk)
2. Scans for high-entropy strings, known secret patterns (API keys, private keys, tokens), and suspicious variable names
3. Cross-references against a allowlist of safe test fixtures and placeholder patterns
4. Rejects the plan if a violation is found, returning a structured error to the agent
The agent receives feedback like:
Plan rejected: potential secret detected in kubernetes/api-deployment.yaml
Line 14: ANTHROPIC_API_KEY="sk-ant-..." matches pattern for Anthropic API key
Suggestion: use a secret reference (e.g., secretKeyRef) instead of inline value
Because this happens before any file is touched, there's no git history to scrub, no CI log to redact, no alert fatigue from post-commit scanners. The agent can re-plan immediately, incorporating the constraint into its next attempt.
Entropy analysis and pattern matching
Secret detection for agents needs to be both precise and fast. False positives slow the loop; false negatives create security incidents.
We run two parallel checks:
High-entropy string detection catches secrets that don't match known patterns—random tokens, database passwords, session keys. A simple Shannon entropy calculation flags any base64 or hex string above a threshold (typically 4.5 bits per character). This catches:
- Randomly generated passwords:
X$9mK#pQz2@vL8nR - Custom API tokens:
cust_a89f23bc019d8e7f6c4b3a21 - Cookie secrets:
7f3e9a2c5d8b1e4a6c9f2b5d8e1a4c7f
Known pattern matching uses regex libraries tuned for speed (we use Hyperscan for multi-pattern matching in a single pass) to identify provider-specific formats:
- AWS keys:
AKIA[0-9A-Z]{16} - GitHub tokens:
ghp_[a-zA-Z0-9]{36} - Stripe keys:
sk_live_[a-zA-Z0-9]{24} - Private key headers:
-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----
Combining both methods reduces false negatives. A generic bearer token might have moderate entropy but miss pattern rules; a well-formatted AWS key might have lower entropy but match the AKIA prefix.
Context-aware allowlisting
Not every string that looks like a secret is a secret. Test fixtures, example configs, and documentation often include fake credentials. Blanket scanning produces noise; agents retry endlessly on safe edits.
Goatfied's constraint layer checks context:
- File path signals: anything in
tests/fixtures/,docs/examples/, or*.example.ymlgets relaxed rules - Variable naming:
EXAMPLE_API_KEY,PLACEHOLDER_TOKEN,YOUR_SECRET_HEREare flagged as safe - Placeholder values: patterns like
sk-xxxx,AKIA0000000000000000, orchangemeare allowed - User-defined allowlist: teams can commit a
.goatfied/secrets-allowlist.jsonwith SHA-256 hashes of known-safe strings (never the plaintext secret itself)
If an agent frequently hits the same safe pattern—say, a test suite that uses a hardcoded mock key—an engineer can add the hash to the allowlist once, and future plans sail through.
Self-hosted vs. managed tradeoffs
Secret detection in a cloud-hosted AI editor raises immediate questions: are secrets leaving my network? Who sees the scan results?
Managed Goatfied runs constraint checks server-side, but the implementation is carefully scoped:
- The scanner sees only the diff (changed lines), not the full repository content
- Detection happens in isolated, ephemeral containers; no results are logged beyond pass/fail status
- If a secret is detected, only the location (file, line number) and pattern type ("potential AWS key") are recorded, never the secret value itself
For teams with strict data residency or zero-trust requirements, self-hosted Goatfied runs the entire stack—agents, constraint layer, secret scanner—inside your VPC or on-prem. You control the scanning rules, the allowlist, and the audit logs. The tradeoff is operational overhead: you're responsible for keeping pattern libraries up to date as new secret formats emerge (Anthropic adds a new key prefix, Vercel changes token formats, etc.).
Recovery when secrets slip through
No detection is perfect. If an agent somehow bypasses constraints—perhaps via a tool that directly shells out to git commit instead of using the sanctioned edit interface—you need a fallback.
Goatfied's validate phase runs after edits but before pushing to remote. This includes:
- Re-scanning all modified files (belts and suspenders)
- Running
git secretsortrufflehogas an external validator - Checking CI/CD webhooks haven't fired yet (if they have, the plan is rejected and a rollback is triggered)
If a secret is discovered here, the agent is halted, the commit is amended to scrub the secret, and a new credential is rotated. The original value is added to a blocklist so the agent never attempts to re-introduce it.
This layering—constraint before edit, validation after edit, final scan before push—creates multiple interception points. The agent must fail at all three to leak a secret into shared history.
What changes when agents write most of your code
Human developers know not to commit .env files. Agents don't have that intuition unless it's encoded as a constraint. As AI-generated code becomes the norm, security tooling has to shift left—before the agent acts, not after a human catches the mistake in review.
Secret detection before tool execution is one piece of a larger pattern: treating agents as untrusted actors who operate within well-defined rails. The same constraint framework that checks for secrets also enforces:
- No file writes outside the project directory
- No shell commands that bypass the approved tool set
- No edits that break compilation or lint rules
The result is agents that move fast but can't accidentally (or adversarially) introduce credentials, backdoors, or broken code. You get the speed of automation with the safety of gated execution.