Privacy
Gate is a security tool that reads your most sensitive configuration. It has to be trustworthy in a way an ordinary developer tool does not, so this page is exhaustive rather than reassuring.
The short version
Gate sends counts and identifiers. It does not send content.
It never sends your code, your file contents, your secrets, your repository name, your command lines, your environment values, or anything about you.
One flag turns it off, and everything still works identically:
gate scan --no-telemetry
What Gate may collect
When telemetry is enabled, a completed scan sends one event:
- Name
installationId- Type
- random UUID
- Description
Generated on first run and stored locally. Not derived from your machine, your user, your network, or anything else about you.
- Name
repositoryFingerprint- Type
- 16 hex characters
- Description
A salted, one-way hash. See below.
- Name
fingerprintBasis- Type
- root-commit | remote-url | local-path
- Description
Which method produced the fingerprint, for data-quality analysis.
- Name
gateVersion- Type
- string
- Description
Which version of Gate ran.
- Name
serversDetected, toolsDetected, credentialsDetected- Type
- numbers
- Description
Counts. Not names, not values.
- Name
findings- Type
- counts by severity
- Description
{ critical: 2, high: 3, medium: 1, low: 0, info: 0 }. Not the findings themselves.
- Name
ruleIds- Type
- string[]
- Description
Which rules fired, e.g.
["GATE005", "GATE008"]. Identifiers only, never the finding text, never the location, never the evidence.
- Name
capabilities- Type
- string[]
- Description
Which of the ten capability classes were present. A fixed vocabulary of ten words.
- Name
adapters- Type
- string[]
- Description
Which ecosystems were detected, e.g.
["claude-code"]. A fixed vocabulary of seven words.
- Name
blastRadius, blastRadiusScore- Type
- level and 0-100
- Description
The summary verdict.
- Name
ci, usedBaseline, usedInspect- Type
- booleans
- Description
Whether the scan ran in CI, against a baseline, or with deep inspection.
- Name
platform, nodeMajor- Type
- darwin | linux | win32 | other, number
- Description
Coarse environment, so Gate knows which platforms to keep working on.
- Name
durationMs- Type
- number
- Description
How long the scan took.
That is the complete list. A real event looks like this:
{
"event": "scan_completed",
"installationId": "8f14e45f-ceea-467a-9f14-2e0a1f9c3b7d",
"repositoryFingerprint": "3b1f9c47a2e6d508",
"fingerprintBasis": "root-commit",
"gateVersion": "0.1.0",
"serversDetected": 4,
"toolsDetected": 23,
"credentialsDetected": 3,
"findings": { "critical": 2, "high": 3, "medium": 1, "low": 0, "info": 0 },
"ruleIds": ["GATE005", "GATE008", "GATE014"],
"capabilities": ["read", "write", "delete", "execute"],
"adapters": ["claude-code"],
"blastRadius": "critical",
"blastRadiusScore": 84,
"ci": true,
"usedBaseline": true,
"usedInspect": false,
"platform": "linux",
"nodeMajor": 22,
"durationMs": 412
}
What Gate never collects
- Source code, or any file contents
- Repository name, remote URL, or path
- Secret values, or any prefix, suffix or fragment of one
- Command lines or arguments (they routinely contain secrets)
- Environment variable values
- MCP tool arguments, tool names, or tool descriptions
- Server names or URLs
- Finding messages, evidence, or locations
- Your GitHub username, organisation, or email
- Anything that would let us identify you or your employer
The repository fingerprint
Gate's primary metric is "unique repositories scanned". Measuring that needs something stable per repository and useless to anyone who obtains it.
The obvious identifier is the git remote URL, and it is the worst one: a hash of
github.com/acme/secret-project can be recovered by anyone willing to hash a
list of repository names. Trivially available for public repositories and
guessable for private ones.
So Gate prefers the root commit SHA: the hash of your repository's first commit, run through HMAC-SHA256 with a fixed salt and truncated to 16 hex characters. It is stable across renames, forks, clones and hosts; it contains no name; and it cannot be turned into an identity without already possessing the repository.
Fallbacks, in order: the normalised remote URL, then a hash of hostname plus
absolute path (which is machine-local and therefore not comparable between
developers). Gate reports which one it used in fingerprintBasis.
The underlying value is never transmitted and never stored.
How to turn it off
Any one of these, in order of precedence:
gate scan --no-telemetry
export GATE_TELEMETRY=0
export DO_NOT_TRACK=1
gate.config.ts
export default defineConfig({ telemetry: false })
Gate honours the Console Do Not Track convention.
On the first scan from a new installation, on an interactive terminal only, Gate prints a short notice explaining what it sends and how to turn it off. It does not print in CI, where nobody reads it. There it would be noise in a build log.
CI is not an automatic opt-out. Repositories running Gate in CI are the signal Gate most needs, the event contains nothing identifying, and a team that disagrees has four documented ways to turn it off.
How this is enforced
Not by care. By construction, in three layers:
- The payload is built by an explicit constructor with named scalar fields. There is no code path that spreads an object into it.
- The payload is validated against a strict schema before sending. Unknown keys are a validation failure, so adding a field fails a test rather than shipping.
- The payload is scanned for credential shapes before sending. Nothing in the schema can produce one, so a match means something has gone wrong, and the event is dropped.
The receiving end applies the same allowlist again, since a patched or forged client could otherwise send whatever it liked. The server records one field of its own: a receive timestamp. No IP address, no user agent beyond the Gate version, no headers.
The backend is one Worker writing to one table. Every column in that table corresponds to exactly one field in the list above. There is no column for anything else, so a future bug cannot quietly widen what is kept.
Why we collect anything
Honestly: because we need to know whether Gate is useful, and a local CLI gives no other signal.
Gate has no accounts and no server-side product. Without telemetry there is no way to tell the difference between a tool people run once and a tool people put in CI and keep, and that difference determines what gets built next.
Saying so is more honest than presenting the data as purely for your benefit. In exchange, the collection is minimal, documented to the field, structurally constrained, and one flag away from off.