← WebsiteSilver Bullet HelpSecurity and Privacy Version 3.0.0-intl-rc.9

Security and Privacy

For you, and for your security team, DBA, data-protection officer or auditor: what Silver Bullet 3.0 keeps on your computer, what leaves it, and what it can and cannot do to your databases and files. Each statement here was checked against the program; where this release has a limit, it is said plainly.

In short

What Govirang Microspaces Private Limited itself receives, and only when you buy or manage a licence, is in the Privacy Notice (also in the program: About → Privacy Notice). The record that you accepted it, the End User Licence Agreement and the Terms of Service (the versions, the time, the user and the program version) is kept in app.db, on your computer.

What stays on your computer

Everything Silver Bullet keeps is in its data folder:

Data folder
macOS ~/Library/Application Support/SilverBullet3
Windows %LOCALAPPDATA%\SilverBullet3
Linux ~/.local/share/silver-bullet-3
Data Where it is kept
Data sources, the data dictionary, rules and measures, your corrections, verified answers, settings, the audit trail <data>/app.db (SQLite)
Questions you asked, and each answer’s choices, SQL, headline and chart; the Activity & trust record app.db
Saved answers, boards, and each board tile’s last figures (a table tile keeps at most 50 rows); the home brief; executive briefs app.db, with personal data masked
Data-source passwords and cloud API keys sealed, in app.db; the key is <data>/vault.key
Loaded files (the cleaned data) and rows set aside during loading <data>/files/files.duckdb
The rows of recent answers (the temporary result area) <data>/results/; see below
Logs <data>/logs/
Monthly zips of the Activity & trust record <data>/activity-backups/
Backups <data>/backups/
Licence state <data>/licence/

Rows read from your databases are not copied into Silver Bullet, except briefly in the temporary result area and in board tiles as described above. The original file you upload is not kept after loading.

The data folder is created readable by your own account only. On macOS and Linux every file Silver Bullet creates is its owner’s alone (umask 077), and crash dumps are switched off, so memory (and any secret in it) is never written to disk. The data in the folder (loaded files, app.db) is not encrypted beyond the sealed secrets: protect your computer with its own sign-in and, where required, full-disk encryption (FileVault, BitLocker).

The temporary result area

So that re-grouping an answer, switching to the table, or picking “what you meant” does not query the database again, each answer’s rows are kept briefly in <data>/results/:

The file is named from a hash of the session, never from the session token itself.

How you are signed in

There is no user name and no password. Silver Bullet listens on 127.0.0.1 only, and opens your browser with a one-time sign-in link: 32 random bytes, usable once, for two minutes, held in memory only. The link is never on a command line, where other accounts on the computer could read it: the browser opens a small page in the data folder that only your account can read, which forwards to the link and is deleted a minute later. A second start of Silver Bullet asks the running copy for a new link by proving it knows a secret in running.json in the data folder, which only your account can read; it never sends the secret, and opens nothing unless the answer proves the secret too. So another account on the same computer can neither ask for a link nor pose as Silver Bullet.

Browsers send a 127.0.0.1 cookie to every port of the computer, so on the desktop the cookie is not enough on its own: each session is bound to the browser tab that signed in, which sends a value of its own with every request. The cookie ends when the browser closes, and every session ends when Silver Bullet stops or starts. Only Silver Bullet’s own pages can keep it running or tell it they have closed; another website cannot stop it.

The session is a random token in the cookie sb3_session: HttpOnly (scripts cannot read it) and SameSite=Strict. Only its SHA-256 is stored. Every request that changes something must carry the header X-SB: 1, which a page on another site cannot send. The pages carry a strict Content-Security-Policy (they load nothing from anywhere but Silver Bullet itself: fonts are built in, there is no CDN), no framing, no referrer and no content sniffing.

Two-step sign-in (optional). From the user menu, Two-step sign-in → Turn on: scan the QR code with an authenticator app on your phone (Google Authenticator, Microsoft Authenticator or another), type the 6-digit code it shows, and keep the ten recovery codes it gives. From then on, opening Silver Bullet — by its link, from the icon or a second start — asks for the app’s code before anything else; someone else at your computer cannot open it without your phone. The codes are the standard RFC 6238 ones (a new code every 30 seconds; each works once; a phone up to 30 seconds out is accepted). The secret is kept sealed with the vault key, recovery codes only as hashes, and wrong codes count toward the same lockout as other failed sign-ins. Turning it off takes a code from the app or a recovery code. Turning it on, off, failed codes and recovery codes used are in the audit trail.

When the trial or licence has ended, the licence page can still be opened and a key entered; everything else answers SB3-6001 until a key is entered.

What goes to the AI model

The model reads the question and returns either the choices behind an answer (which measure, which grouping, which period, which filters) or, when the question does not fit those, an SQL query. Silver Bullet checks what comes back, writes or checks the SQL itself and runs it. The model never receives rows, query results or answers.

For every question

If the model’s first reply is not usable, it is asked once more, with what was wrong. For a cloud model this names no value of your data other than the question’s own; a local model may be shown a column’s example values again.

When the question does not fit the choices

Silver Bullet asks the model for SQL instead:

Other calls to the model

Local or cloud

Local model (Ollama, LM Studio) Cloud model (OpenAI, Anthropic, Google Gemini, Azure OpenAI, Mistral)
Where the description and the question go to the model server you run over HTTPS to the provider, for every question, under its terms and retention
Example values of non-personal columns yes yes (in questions; not in dictionary suggestions)
Rows, results, answers never never
Values of personal-data columns never never

The default is a local model (Ollama). You choose on Admin → AI model; that page shows what applies under What leaves your network. Cloud providers other than Azure OpenAI are always called at their own fixed address, so a key cannot be sent elsewhere by a mistyped setting. Only the local model qwen3-coder-next was measured for this release.

The AI model page, with what leaves your network

Marking personal data later

A column marked as personal data in the data dictionary after its source was added is protected as soon as the dictionary is published: its values are left out of every prompt (the model’s reading of a question and the fallback in which the model writes SQL: for a database, the examples read at the last test; for a file, the list of a short text column’s values) and masked in everything worked out from then on. A test proves it (TestPersonalColumnsValuesNeverReachTheModel). A column you chose to Keep as is, unprotected in the file wizard is ordinary data: choose one of the protected options for anything personal.

Personal data

How it is found

What it means

The tests that prove it

Test Package What it checks
TestMaskingCannotBeBypassedByAliasing internal/live/answerkit aliases, expressions and unqualified names of personal columns are masked
TestMaskingCannotBeBypassedWithoutNamingTheColumn internal/live/answerkit set operations, whole rows, column lists, U& identifiers, COLUMNS, FOR JSON
TestVisibleSamplesWithholdPersonalColumns internal/live/answerkit example values of personal columns are withheld
TestCloudModelIsSentOnlyTheQuestionsValues internal/answer a cloud model is sent only the values the question names; a local model keeps its examples
TestCloudCorrectionNamesNoValues internal/answer the correction sent back to a cloud model names no value of the data
TestSuggestPromptWithoutValues internal/answer home-page suggestions from a cloud model carry no value of the data
TestKeepValues internal/files/ask the files’ question → SQL prompt keeps only the question’s values for a cloud model
TestQuerySafetyWithoutADatabase internal/plugins/live sampling a column named or marked as personal is refused
TestLoadAndQueryAKitFile internal/plugins/files sampling a file column once marked personal is refused
TestFileWizardAndDictionaryOverHTTP internal/api dictionary suggestions skip personal-data columns
TestMaskingCoversColumnListsAndWholeRowReads internal/live/answerkit FROM t AS c(…) column lists on every dialect, SELECT * / c.*, Oracle XQuery
TestScrubDBErrorKeepsTheSQLAndDropsTheData, TestScrubDBErrorLiveEnginesKeepOnlyTheCode internal/app a database’s error message loses the values it quotes; an error raised while reading data keeps only its code on every engine
TestMaskModesHideComputedValuesWhole internal/live/answerkit a value worked out from a personal column, or shorter than six characters, is hidden whole
TestMeasureTrialMasksErrors internal/api a Power user’s failing measure shows no value of the data; an administrator’s shows the database’s text
TestAskErrorsHideUnquotedValues internal/api a Power user’s failing question on a file shows no value, even where the database writes it without quotes
TestFileColumnListMasked internal/api a column list over a loaded file is masked for a Power user
TestExamplesNeverCarryPersonalValues internal/learn verified answers filtering a personal value are never examples for the model
TestSecLLMPayloads internal/api (integration) every request to the model, over every path, carries no personal value, secret or answer figure
TestSecMaskingMatrix, TestSecMaskingOnSharedPaths, TestSecMaskingBypassAllEngines internal/api (integration) personal columns across the paths (typed, chips, table view, board, brief, verified and expert answers) and the SQL bypasses on all five databases and files
TestSecPromptInjection internal/api (integration) hostile names, comments and values given to the real model

What Silver Bullet can do to your databases

Read, within limits; nothing else. Five independent layers, each of which would stop a write on its own:

  1. The account. Every connection test reads the account’s privileges from the database’s own catalog and refuses an account that can write (insert, update, delete, change structure, run procedures, administer). Questions are refused until a test has passed, and there is no way to switch this off. Create a read-only login on the data source’s page writes the script for your database; the scripts are also in the Installation Guide.
  2. The SQL check. Every query is read the way that database reads it and refused unless it is one SELECT (or WITH … SELECT) reading only the tables the last test found for this source. Refused, among others: a second statement; write words (INSERT, DROP, EXEC, INTO …); locking reads and hints (FOR UPDATE, UPDLOCK, NOLOCK …); functions that sleep, lock, read files or reach the network (pg_sleep, SLEEP, xp_cmdshell, DBMS_* …, quoted or not); table functions; TABLE name used as a query; Oracle XQuery; database links, linked servers and other databases; parameters; system catalogs. A refusal is never sent back to the model to be “repaired”.
  3. The session. PostgreSQL: a read-only transaction (default_transaction_read_only). MySQL and MariaDB: a read-only session and transaction. Oracle: SET TRANSACTION READ ONLY. SQL Server, which has no read-only transaction: the query is first compiled by SQL Server (SHOWPLAN, nothing runs) and refused unless SQL Server says it is exactly one SELECT, then run in a transaction that is rolled back. Lock waits are short.
  4. Cost before running. The database’s own plan estimate is checked: by default a full scan of a table over 1,000,000 rows is refused.
  5. Limits while running. 30 seconds per query, at most 5,000 rows read back, at most 2 queries at once per source (each changeable per source).

What Silver Bullet can do to your files

Loading a file never changes the file you have. Questions about files are answered from Silver Bullet’s own copy, through two independent checks:

  1. One read-only statement: a single SELECT or WITH; none of INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, ATTACH, DETACH, COPY, EXPORT, IMPORT, PRAGMA, SET, INSTALL, LOAD, CALL, GRANT, REVOKE, VACUUM, CHECKPOINT.
  2. Only this source’s tables, checked on the database engine’s own reading of the query: every table must be one of the source’s own loaded tables (or a named sub-query). It cannot read another source’s tables, Silver Bullet’s own tables, other files, or anything outside: functions that read files or the network, list tables, read settings or load extensions are refused.

The query then runs in a read-only transaction that is always rolled back, with the same time and row limits. The time limit holds even for a query the database engine cannot interrupt (one long calculation): the answer comes at the limit. At most six queries about files run at once, three of them one person’s; while three of one person’s are still finishing past their limit, that person’s further questions about files are refused as busy, and other people’s still run. A query past its limit gives its place up, so two people’s slow queries cannot hold up a third. Once eight queries are busy, the places left go to people who have none running, one each. The files database and the kept results of every signed-in session share one limit: half the processors and half the memory in all, however many people or sessions ask. So queries past their limit leave the rest of the computer free.

A workbook is a zip, and a few kilobytes can declare a sheet a million rows by 16,384 columns, unpack a thousandfold, or point a million cells at one long text; a Parquet file can do the same with one stored value. A file is refused with a message when it would make more cells than it has bytes (at least 4 million), when its contents or its values come to more than 16 times its size (at least 64 MB), when a workbook’s parts nest more than 64 levels deep, hold over a million elements or a tag longer than 1 MB, or when one cell is longer than Excel allows (32,767 characters). The small parts that list a workbook’s other parts are read within a few megabytes of memory. A whole number may have at most 4,300 digits, and long numbers are refused before they are converted. A Parquet file’s text is counted before it is read, with each special character counted as it will be written out, and the database engine reading it has a memory limit of its own. One Parquet value may be at most 1,048,576 characters when written out; a file with a longer one is refused with a message.

An upload may carry at most 32 fields besides its files, 256 KB in all. A field’s name may be at most 64 characters, and a file’s name at most 255. Fields the product does not use are not kept.

An upload is written to disk as it arrives, never held whole in memory. Each person has one upload and one file check (reading a file to list its sheets or check it) at a time, a second waiting for the first; at most five file imports waiting; and an upload needs twice its size free on the disk. While the file wizard is open the uploaded file waits in <data>/imports/; it is deleted when the file is added, the wizard is cancelled, or it is left unused for 24 hours.

Downloads and copies: a text cell that a spreadsheet would read as a formula (one starting with =, +, -, @, a tab or a carriage return) is written with a leading apostrophe in a downloaded CSV, a copied table and the set-aside rows’ CSV, so it opens as text; the Excel download’s text cells are never formulas.

Secrets

Secret Protection Key
Data-source passwords and cloud API keys AES-256-GCM, each value sealed separately and bound to where it is sent (the source’s server, database and sign-in; the model’s address): it does not open for anywhere else <data>/vault.key, 32 random bytes, created on first start, readable by your account only (on macOS and Linux a key readable by others is refused)
Session tokens SHA-256 hash (not reversible) none

Activity & trust: proof of what was sent

Activity & trust (in your account menu, or Admin → Activity & trust) records every question you ask and every request sent to an AI model, so the claims above can be checked, question by question, rather than taken on trust.

One question’s trail: what was sent and what was kept

The audit trail

Besides the questions, Silver Bullet records what was changed and done: data sources created, changed, tested and deleted, schedules, the dictionary (drafts, publish, suggestions), rules and verified answers, your corrections saved or dismissed, the AI model and API keys, settings, boards (and their tiles, refreshes and PDF downloads), an answer copied or downloaded (answer.export: the format, the source and the row count), the set-aside rows downloaded, a column’s sample values read (source.sample: which column, not the values), expert queries run, a flagged value revealed, network checks, support bundles, and licence activations (including failed ones). It never contains passwords, keys or data rows; a database error recorded with an expert query loses any value it quotes.

The audit trail is kept in app.db, and this release does not purge it automatically. It has no page of its own in the app: the last 30 days of it are in the support bundle.

Network

Buying a licence: what is sent

Buying is done in your browser, on Dodo Payments’ checkout (checkout.dodopayments.com): Dodo is the merchant of record and takes the payment, the tax and the invoice; Silver Bullet never sees your card. There are no customer accounts. Silver Bullet itself talks to the licensing service (HTTPS, port 443; its address is on Network and firewall) only:

When What is sent
After Buy, until the key arrives (every 10 seconds for half an hour, then hourly, at most 30 days) — on by default, can be switched off the claim made at Buy (128 random bits) and this computer’s code
Once a day while a key bought online is installed, the first time soon after each start (whatever the saved time of the last check says), when such a key is entered (also with licence activate), when the key file holds another key than the one last checked, and every hour in the week after the licence moves to another computer — always (the switch only stops a newer key being installed); it is how a licence moved to another computer stops on the old one the key in use, which the service checks by its signatures
Get my key, Move to this computer — when you use them the order number and e-mail address you type, and this computer’s code

The computer’s code is a hash of the computer’s own id with the product’s salt: the id itself never leaves the computer. Nothing about your data, questions, databases or files is ever sent. Requests carry these in the body, never in the address. The calls use the web proxy in HTTPS_PROXY and the system’s certificates. With both switches off, or with no connection at all, a key pasted from the e-mail works as always; the checkout can be paid from a phone with the QR code.

What the licensing service keeps (Govirang Microspaces Private Limited is the controller; Cloudflare hosts it, Resend sends the e-mail): the order number, the computer’s code, the e-mail address Dodo collected (erased two years after the licence ends), the plan, and when each key was issued — never the key’s text, your name, address or card. A key bought online names your business (or your name) as given at checkout, never your e-mail. To have your e-mail erased, write to the licence address.

Voice

Backups contain data and keys

Silver Bullet backs itself up into backups/ in the data folder (every 24 hours by default, the newest 7 kept; see the Administration Guide). The backups have the data folder’s own permissions. A backup holds app.db and vault.key (anyone with both can open the stored database passwords and API keys) and files.duckdb, which holds all loaded data; so does any copy of the data folder. Treat backups like the data and the passwords they protect: restricted storage, never e-mail, delete copies you no longer need.

How the packages are signed

Every package is signed by Govirang with its own release key, and by no one else: not by Apple (the Mac app has an ad hoc signature only and is not notarised), not by Microsoft, not by a certificate authority. So macOS Gatekeeper and Windows SmartScreen warn on the first start. This is by design and will not change (EULA clause 10A). Check every package against the SHA-256 checksums and the release-key fingerprint published with the release before installing (Installation Guide, Checking the packages); SilverBullet version prints the fingerprint the program trusts.

What Silver Bullet does not do

Reporting a security issue

Report a suspected security issue to Govirang Microspaces Private Limited directly, not in a public tracker, with the version (About Silver Bullet in your account menu).

Support: ______________________