GATE015: Excessive capability combination

The agent holds a combination of capabilities that is far more dangerous together than apart.

  • Name
    Severity
    Type
    Critical
    Description

    Default severity. An individual finding may be reported higher or lower when the surrounding configuration justifies it.

  • Name
    Explain locally
    Type
    gate explain GATE015
    Description

    The same text, in your terminal, with no network access.

What Gate detected

Gate compared the full set of capabilities available to the agent against a table of combinations that compose into a complete attack: secret access plus external communication, execution plus egress, execution plus deletion, financial plus execution, administration plus execution, and identity management plus secret access.

Why this matters

Individual capabilities get reviewed individually, and individually most of them look reasonable. The danger is compositional. Simon Willison named the most important case the "lethal trifecta": access to private data, exposure to untrusted content, and the ability to communicate externally. Any one is fine. All three means attacker-controlled text can cause your data to be sent to the attacker, and no amount of model quality closes that.

This is the rule that justifies Gate existing as a capability graph rather than a linter. You cannot find this by looking at one config line.

Example

This is the shape of configuration that triggers the rule.

// vault.read_secret     -> secrets
// slack.post_message    -> communicate
//
// Together: anything the agent can read, it can send.

Remediation

Break the combination. Split the capabilities across separate agents with separate credentials, remove the egress path, or put a human approval step between the two halves. Breaking one leg of the combination is usually far cheaper than hardening either capability on its own.

Suppressing this rule

If this finding is acceptable in your repository, record why alongside the suppression:

gate.config.ts

export default defineConfig({
  ignore: [
    {
      rule: 'GATE015',
      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?