Legal
Privacy Policy
Effective 13 October 2026. Applies to all SFDT software and to this website.
Summary
SFDT is a set of developer tools for Salesforce admins and developers, published by Hallows Group LLC (Texas, United States). This policy covers four surfaces:
- the browser extension “SFDT for Salesforce” (Chrome Web Store; the same source also builds for Firefox),
- the VS Code extension “SFDT for Salesforce” (sfdt.sfdt-devtools),
- the command-line tool @sfdt/cli, and
- this website, sfdt.dev.
There is no SFDT server. We operate no accounts, no sign-up, no billing and no analytics backend. No SFDT surface sends your Salesforce data, your source code or your usage to Hallows Group LLC or to any service we control — there is nothing of ours for it to be sent to. Everything these tools record, they record on your own device.
The one piece of personal data we will not claim away: this website is hosted, and serving you a page means our host logs the request — your IP address, user agent and the URL. For that minimal set, and only that, Hallows Group LLC is a data controller. §4 and §5 say exactly what it is, why we have it and on what legal basis.
All of the source is public at github.com/scoobydrew83/sfdt. Every claim below can be checked against it, and the sections that name a test are enforced by that test in CI.
1. Browser extension
What it reads
- Salesforce pages. The content script is injected only on *.salesforce.com, *.salesforce-setup.com, *.my.salesforce.com, *.lightning.force.com. It reads the page’s DOM and URL to place its UI and to work out context — the record Id, object or Flow you are looking at. It does not read any other site.
- Your existing Salesforce session cookie (sid), so API calls run as you without a second login. The cookie is read in the extension’s background service worker only, and is used only as the authorization on requests to your own org. It is never shown in the UI, never written to storage and never sent anywhere else — enforced with no allowlisted exceptions by test/sid-never-leaves-worker.test.ts.
- Your org’s data, when you run a tool. SOQL/SOSL results, record fields, Flow and other metadata, debug logs, org limits, test and coverage results, and streaming events are fetched from your org’s REST, Tooling, SOAP and streaming APIs and rendered in your browser.
- Additional host permissions (*.my.salesforce.mil, *.lightning.force.mil, *.sfcrmapps.cn, *.mcas.ms) exist so GovCloud, Salesforce China and Microsoft Defender-proxied orgs can have their API session resolved and called. No UI is injected on them.
What it stores, and where
All extension state lives in chrome.storage.local inside your own browser profile. None of it is synced to other browsers and none of it is transmitted to us.
| Key | Contents | Written when |
|---|---|---|
| sfdt.settings | Per-feature toggles, AI provider preference, local bridge token | You save the options page |
| sfdt.killswitch.cache | The disabled-feature list most recently returned by the local CLI bridge | After a successful bridge ping |
| sfdt.telemetry | Opt-in local feature-use counters (see below) | Only while you have telemetry switched on |
| sfdt.activity | The last 100 operations you ran: timestamp, tool id, action label, outcome, and a truncated description of the target | After a SOQL/SOSL run, anonymous Apex execution, metadata deploy/retrieve, or bridge tool run |
A separate memory-only cache (chrome.storage.session, which the browser clears when it closes) holds the resolved API hostname and org id per Salesforce host so each call does not have to re-resolve it. It never holds the session cookie. Incognito windows get a wholly separate session (incognito: "split"), so incognito and normal browsing never share resolved sessions.
The activity log
This is the only local key that can contain data from your org, so it is worth being precise. The resource field stores the first 120 characters of the SOQL statement or Apex snippet you ran, or a class name or deploy job id. Whitespace is collapsed before the cap is applied, so it cannot be padded past the limit. Query results are never stored — no records, no field values returned by Salesforce, ever. The log is capped at 100 entries and the oldest falls off. A WHERE clause can contain personal data, which is why the cap exists and why the log has its own switch: Options → Activity log → uncheck “Record recent activity” and nothing is written at all.
Telemetry — opt-in, local-only
The extension collects no telemetry unless you open the options page and check “Enable local telemetry”. Even then, it stays on your device:
- The schema is a per-feature { activated, errored, disabled_remote } integer triple keyed by feature id, plus coarse local-bridge failure counts by category (offline, timeout, unauthorized, protocol, other) and a month key such as 2026-10.
- Counters reset at the start of each calendar month and are capped at 500 feature ids.
- No org names, usernames, Flow names, record ids, IP addresses, or timestamps finer than the month.
- No network egress. The counters are read back into the options page so you can see your own usage. This is enforced by test/telemetry.test.ts.
- If you are also running the local CLI, the extension may push a copy of these counters through the local bridge to <project>/.sfdt/telemetry-snapshot.json on your own disk, so sfdt extension stats can render them.
The local CLI bridge and native host
Some features (Flow Deploy, Rollback, Org Compare, Drift Check, Metadata Scan, Quality Results, the deeper Org Health checks, and the AI runs) work by asking the sfdt CLI on your own machine to do the work. They are inactive until you start it yourself with sfdt ui. Requests then go to http://127.0.0.1:7654 — a loopback address, meaning the traffic never leaves your machine — authenticated with a bearer token stored in your home directory. The optional native messaging host (com.sfdt.host, installed only if you run sfdt extension install-host) is a read-only fallback over stdio to a process on the same machine, and its manifest permits only this extension’s id to talk to it.
The disabled-feature list the extension caches (its “kill switch”) is read by that local bridge from a file in your own project, .sfdt/feature-flags.json. No server of ours is contacted for it.
AI features
Two features can use a language model: the Flow AI Assistant (its non-AI half — clean up, summarise, copy — runs in the browser) and Generate query in the SOQL Runner, which ships off. Neither contains a model endpoint: the prompt goes over the local bridge to the CLI, which calls the provider you configured, under your API key or subscription, billed to you and governed by that provider’s privacy policy. We are not in that path — we do not see, log or store prompts or completions.
For Generate query, what is sent is the description you typed plus a schema table for the objects involved: object and field API names, labels, data types, whether a field is required, and inline help text. Record data is not sent, and a check refuses the send outright if any value from the results table on screen appears in the assembled prompt. With no bridge running, or with "features.ai": false in the project config, nothing is sent and the panel tells you what to enable.
Permissions, and what each is for
| Permission | Why it is requested |
|---|---|
| storage | Save your feature toggles and the opt-in local counters described above |
| clipboardWrite | Copy generated output to your clipboard when you ask — reports, SOQL results, object schema, the Copy-JSON actions |
| cookies | Read your existing Salesforce session cookies to list the orgs you are already logged into and authenticate calls to the one you pick. Read locally; never transmitted off your device |
| contextMenus | Offer an optional right-click “Inspect this record” item on your Salesforce pages. It reads only the URL to find a record Id |
| sidePanel | Dock the extension’s own tool panel beside Lightning. No new data access and no new host access. Chrome only; Firefox’s native sidebar needs no permission |
| host_permissions | The Salesforce origins listed above, so feature scripts can run and API calls can be made against your logged-in org — plus localhost / 127.0.0.1 for the local CLI bridge, inactive until you start it |
The extension bundles no remote code: there is no externally_connectable, no remotely-loaded script, and no eval. It contains no third-party SDK, analytics service, error reporter, ad network or tracking pixel.
2. VS Code extension
The VS Code extension is a thin user interface over the CLI; it reimplements no logic. It runs sfdt, sf, git and npm in your workspace and renders what they print.
- Reads files in your workspace: sfdx-project.json, .sfdt/config.json, the logs/*-latest.json snapshots the CLI wrote, and the Apex test files you act on.
- Stores nothing of its own. It uses no VS Code global or workspace state, no secret storage, and keeps no database. The one file it can write is the opt-in sfdt.orgColor window tint, which adds workbench.colorCustomizations to your workspace’s .vscode/settings.json and removes those keys again when you turn it off.
- Has no telemetry. It reports nothing — not to us, and not into VS Code’s own telemetry channel. Whatever VS Code itself collects is Microsoft’s and is governed by your VS Code telemetry setting and Microsoft’s privacy statement.
- The embedded dashboard (SFDT: Open Dashboard) is a webview framing http://localhost:<port> — the sfdt ui server running on your own machine. Its content-security policy allows that origin and nothing else.
- One outbound request. On activation and on refresh it runs npm view @sfdt/cli version to show an “update available” hint. That goes from your machine to whichever npm registry your npm is configured for (by default registry.npmjs.org) and carries nothing about you beyond what any npm request carries. Nothing else leaves your machine.
3. Command-line tool
The CLI runs on your machine, under your shell, against orgs you have already authenticated with Salesforce’s own sf CLI. It never asks for, stores or transmits your Salesforce credentials; its config references secrets by environment-variable name, never by value.
What it writes to your disk
- .sfdt/config.json — your project configuration.
- logs/ — timestamped JSON snapshots of audit, monitor, quality, deploy and test runs, plus history.db, a local SQLite index of your runs (type, timestamp, org alias, exit code, duration, status and a small summary). It keeps the most recent 200 rows per run type and prunes the rest.
- ~/.sfdt/bridge-token — the local bridge’s bearer token, written with 0600 permissions so other users on the machine cannot read it.
- Backups, reports and generated documentation, where you asked them to go.
Audit logs and AI prompts pass through a redaction step that strips credential-shaped material: access and refresh tokens, bearer and basic auth headers, private key blocks, SFDX auth URLs, and secret-shaped assignments. To be clear about its limit — that step removes credentials, not business data. A query, log or diff that you choose to send somewhere may still contain personal data from your org, and deciding that is your call, not ours.
What it sends, and only when you ask
- Your Salesforce org, through the sf CLI you authenticated.
- The npm registry — registry.npmjs.org — when you run sfdt update, and when the local dashboard loads, to fill in its “update available” banner.
- An AI provider you configure, and only with "features.ai": true. That is either a provider CLI already installed and signed in on your machine (Claude Code, Gemini, OpenAI/Codex) or an OpenAI-compatible endpoint you point ai.baseURL at — which can be entirely local, for example Ollama on http://localhost:11434/v1. The API key is read from the environment variable you name. Your prompts go to your provider under your own account; they never reach us.
- Notification channels you set up, if you enable notifications: Slack, Microsoft Teams, Google Chat, a generic webhook, Grafana Loki, or email over an SMTP server you supply. Only to destinations you configured, with the content you asked to be sent.
- GitHub, through your own authenticated gh CLI, for the pull-request comment and description helpers.
The local dashboard (sfdt ui) binds to 127.0.0.1 only and is token-authenticated; it is not reachable from your network. A development-loop telemetry facility exists in the source (src/lib/harness-telemetry.js) for this repository’s own work: it writes a local JSONL file only when an explicit path is passed, and no path is passed in installed CLI use.
4. This website
- No accounts, no cookies, no analytics. The site sets no cookies of its own, runs no analytics or tag manager, embeds no tracking pixel and carries no advertising. There is no form to submit and no user input collected anywhere on it.
- Hosting, and the one thing we are a controller of. The site is a static export served by Cloudflare Workers Static Assets. To deliver a page, Cloudflare necessarily receives and logs the request — your IP address, your user agent and the URL you asked for — as any web host must. For that minimal set of web-request data Hallows Group LLC is the controller and Cloudflare is our hosting processor; under the UK/EU GDPR our legal basis is legitimate interest (Article 6(1)(f)) in keeping the site available and secure and in investigating abuse or attack. That is the whole purpose. We do not add analytics on top of it, we do not build profiles from it, we do not combine it with anything else and we do not sell or share it. Cloudflare processes request data under its own privacy policy; we do not export or keep request logs. If you want this data not to exist, do not visit the site; nothing on it requires a visit, since the tools are distributed through the stores and npm.
- No third-party requests. Every script, stylesheet, image and font is served from this site itself, so loading a page here contacts no one but the host above. Nothing is fetched from a font, CDN, analytics or advertising service, and no request of yours reaches Google. Links to other sites (GitHub, npm, the Chrome Web Store and others) are only followed if you click them.
- Stored in your browser, never sent. The site remembers your light/dark theme choice in your browser’s localStorage so the page renders in the theme you picked. It is not a cookie, it never leaves your browser, and clearing site data removes it. Site search runs entirely in your browser against an index downloaded from this site; what you type into it is not sent anywhere.
- Following a documentation link from the CLI or from either extension is an ordinary request to this site and is handled exactly as above.
5. Where data goes — the complete list
Across all four surfaces, data leaves your device to exactly these destinations, each of which you choose:
- Your own Salesforce org — the origin you are already authenticated to.
- The npm registry — version checks from the CLI, the local dashboard and the VS Code extension.
- An AI provider you configured — under your own API key or subscription, only when AI features are enabled and you invoke one.
- Notification channels you configured — Slack, Teams, Google Chat, a webhook, Loki or your SMTP server, only when you set them up.
- GitHub — through your own gh CLI, for the PR helpers.
- This website’s host, Cloudflare — when you load a page here, and only the web-request data described in §4.
Hallows Group LLC is not a destination on that list. From the software — the browser extension, the VS Code extension and the CLI — we receive no personal data at all, so for everything those three surfaces read, store or send we are neither a controller nor a processor: there is no copy in our hands to disclose, sell, share or hand over. Loopback traffic to 127.0.0.1 and the native messaging host are not on the list because they do not leave your machine.
This website is the one exception, and we would rather state it than claim a clean sweep. Serving a page means our host logs the request, and for that minimal web-request data — IP address, user agent, URL — Hallows Group LLC is the controller, on the legitimate-interest basis set out in §4. It is the only personal data anywhere in this policy for which we hold that role. None of it, on any surface, is used for advertising, profiling, creditworthiness or lending decisions.
6. Chrome Web Store Limited Use
The browser extension’s collection and use of information complies with the Chrome Web Store User Data Policy, including its Limited Use requirements. Specifically:
- Any data the extension handles is used only to provide the user-facing features described in the listing and in this policy — its single purpose of enhancing Salesforce for admins and developers.
- We transfer no user data to anyone. The extension sends data only to your own Salesforce org, to a process on your own machine, or — if you explicitly enable an AI feature — to the model provider you configured under your own key. There is no transfer to Hallows Group LLC.
- We do not sell user data, and we do not transfer it for advertising purposes.
- We do not use or transfer user data to determine creditworthiness or for lending purposes.
- No human at Hallows Group LLC reads user data. We have no mechanism to: nothing is transmitted to us.
7. Your controls
- Browser extension: every feature has a toggle on the options page, and three ship off by default (Delete records, Bulk delete from SOQL results, Generate SOQL from a description). Local telemetry is a single checkbox, off by default. The activity log has its own switch and a “Clear activity log now” action. To erase everything at once: chrome://extensions → SFDT for Salesforce → Site data → Remove all.
- CLI: delete .sfdt/ and logs/ to remove its local state. Set "features.ai": false to disable AI entirely; configure no notification channels and nothing is ever sent.
- VS Code extension: uninstalling removes it completely — it keeps no state outside your workspace.
- This website: there is no cookie banner because there are no cookies, and no analytics opt-out because there is no analytics. The only record of your visit is the host’s request log described in §4; the one way to prevent that is not to visit, and nothing here requires you to.
Exercising a right of access, erasure, portability, objection or restriction. For the extension, the VS Code extension and the CLI there is no request to make, because we hold no data about you — the copy that exists is on your own device, under your own control, and the paths above remove it. For the website request logs in §4, write to us using the contact details below and we will do what we can; be aware that those logs are keyed to an IP address and nothing else, so in the ordinary case we cannot tie one to a person, which also means we cannot verify that a given log line is yours. You can object to our legitimate-interest processing of them at any time. Wherever we can act, we respond within one month (GDPR) or 45 days (US state privacy laws), and there is no charge and no requirement to create an account.
Children’s privacy
SFDT is a developer and administrator productivity tool. It is not directed at children under 13 and we do not knowingly collect any data from them.
8. Changes and contact
If this policy changes materially, the effective date above changes with it, and because this page is in a public repository, the full history of every edit is visible in git.
Privately, and for anything about your own data. Email sales@hallowsgroup.com, or write to us:
Hallows Group LLC5900 Balcones Drive #31966Austin, TX 78731United StatesThat is the route for a privacy question, a data-subject or state-privacy request, a complaint, or a legal notice — use it rather than the issue tracker for anything you do not want in public. Hallows Group LLC is the data controller named in this policy and is reachable at both addresses above.
Publicly, if you would rather. A question about this page, or a correction to it, is also welcome as an issue in the public repository — that is often the faster route for anything that is fine in the open. Please report security vulnerabilities privately instead, through GitHub’s private security advisories, as described in SECURITY.md.
If you are in the EU or UK, the email and postal address above are the contact points for a GDPR request, and you also have the right to complain to your local supervisory authority.
SFDT is an independent open-source project and is not affiliated with, endorsed by, or sponsored by Salesforce, Inc. See the Terms of Use.