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.

References

Was this page helpful?