GATE001: Hardcoded credential in agent configuration
A literal API key, token or password is written directly into an agent or MCP configuration file.
- Name
Severity- Type
- Critical
- Description
Default severity. An individual finding may be reported higher or lower when the surrounding configuration justifies it.
- Name
Capabilities- Type
- secrets
- Description
Capability classes this rule reasons about.
- Name
Explain locally- Type
- gate explain GATE001
- Description
The same text, in your terminal, with no network access.
What Gate detected
Gate found a value in an agent or MCP configuration file that matches the shape of a real credential: a GitHub token, an AWS access key, a database URL with an embedded password, or a high-entropy value in a field named like a secret. Gate never prints the value, and template references such as $\{env:GITHUB_TOKEN\} are not reported: those are the fix, not the problem.
Why this matters
Agent configuration is source-controlled, shared with teammates, copied between machines, and pasted into issues. A credential written into it has already left your control, and it grants the agent, and anyone who reads the file, everything that credential authorises. This is the oldest finding in application security, and agent configuration has quietly recreated it: .mcp.json is a config file that teams commit without thinking of it as a secret store.
Example
This is the shape of configuration that triggers the rule.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_REAL_TOKEN_VALUE_HERE"
}
}
}
}
And a safer version of the same thing:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
Remediation
Revoke and rotate the credential: assume it is compromised, because it is in a file. Replace the literal with an environment reference such as ${env:NAME}, or use your editor's secret input mechanism. Then remove the value from git history, not just from the working tree.
Suppressing this rule
If this finding is acceptable in your repository, record why alongside the suppression:
gate.config.ts
export default defineConfig({
ignore: [
{
rule: 'GATE001',
reason: 'Why this is acceptable here',
},
],
})
Gate refuses to apply an ignore entry with no reason. The reason is the only thing that will tell the next person whether the suppression is still true.