Ferrule

Private, on-device Terraform security review for Chrome

View the Project on GitHub Erya-Labs/Ferrule

Ferrule privacy policy

Ferrule collects nothing, transmits nothing, and has no servers.

That is the whole policy. The rest of this document explains what the extension does with your data so the claim can be checked rather than trusted, and points at where in the source each statement is enforced.

Last updated: 2026-08-24.

What Ferrule handles

Your Terraform code. Read from either a GitHub repository you name or a folder you pick on this machine. It is held in memory for the duration of a scan, passed to the rule engine, and — if you opt into explanations — into a prompt for a language model running on your own GPU. It is never uploaded and never sent anywhere. Ferrule does not store your source on disk; the one thing it keeps is the recent reports described below, which carry findings, any ferrule:ignore reason text, and model narrations — and those stay in this browser profile.

Your GitHub personal access token, if you choose to save one. Stored in chrome.storage.local, which is local to this browser profile on this machine. It is sent only to api.github.com, only in an Authorization header, and never appears in a URL, a log, or an error message.

Scan reports, if you have run scans. The most recent few are kept in chrome.storage.local so the panel can show what changed since last time.

Two more local stores, for completeness. A model you download from the settings page is kept in this extension’s own CacheStorage (a few gigabytes; the settings page can delete it), and if you scan a local folder the browser keeps a read-only handle to that folder in the extension’s IndexedDB so you can rescan it. Both live only in this browser profile, neither syncs, and both go away with the profile.

chrome.storage.local is deliberate: Chrome also offers chrome.storage.sync, which replicates data through your Google account. Ferrule never uses it, because that would send your code and token off this machine.

Where Ferrule connects

Three hosts, each only when the relevant feature is used:

Host When Why
api.github.com scanning a GitHub repository read the repository’s .tf files
huggingface.co you press Download on the settings page fetch the model file
*.cdn.hf.co the same download, one hop later Hugging Face serves the bytes from its own CDN

Scanning a local folder makes no network requests at all.

The model download is the only thing those last two hosts are for, and Ferrule will not start one until you allow it: they are optional permissions, so the install prompt names GitHub alone, and the first download asks your browser for access to those two hosts. You can take that access back at any time on the settings page. To be exact about what the grant enforces: Ferrule’s code does not begin a download without it, and without it the browser will not let a request bypass CORS; the connect-src policy below is what guarantees those hosts are the only ones reachable. If you would rather not grant it, fetch the model file yourself and hand it to the extension with the side panel’s file picker — that path still works and touches no network.

The download only ever goes one way. Your Terraform is never uploaded anywhere; the model comes to your machine.

This is enforced, not merely promised, by the connect-src directive of the extension’s Content Security Policy in manifest.json. In Manifest V3 the host_permissions list does not restrict outbound requests — it grants the ability to make cross-origin ones — so the policy is what actually confines them.

What Ferrule does not do

Permissions, and why each exists

Optional, requested only when you first download a model, and revocable from the settings page:

Verifying any of this

The source is public and the network surface is small by design: the browser’s fetch is reached from exactly two places in the codebase — one for GitHub, one for the model download — and both are injected into code that checks the request origin against a closed list and refuses a response whose origin, after any redirect, is not on it. Independent privacy audits of the whole tree are recorded verbatim, including the findings that were failures, in docs/privacy-audit.md.

You can also just watch: open DevTools → Network on the side panel and run a scan.

Contact

Report a privacy concern by opening an issue on the project’s GitHub repository.