The Veilance Shield Database is the public, data-only rule source for Veilance fingerprint protection.
Each JSON file describes:
- the browser behavior that should activate a shield;
- the packaged protection strategy Veilance should apply;
- tightly bounded parameters for that strategy; and
- the user-facing surface and explanation shown by Veilance.
Veilance downloads this repository automatically, validates every rule, and stores the last known good rule set locally. This lets protection rules be added, removed, enabled, or tuned without publishing a new extension version.
Shield rules are declarative data, not remote JavaScript. A rule can only select a protection hook and strategy already implemented in the installed extension. This protects users and keeps the update system compatible with browser-extension store policies that prohibit remotely hosted code.
You can update the database without changing the extension when:
- enabling or disabling a supported protection;
- changing an existing rule's match details;
- changing bounded strategy parameters;
- adding another rule for an API/action hook the extension already exposes; or
- changing names, surfaces, and descriptions.
A new extension release is still required when adding a completely new browser API hook or a new protection strategy.
One rule belongs in each .json file.
{
"schemaVersion": 1,
"id": "navigator-hardware-concurrency",
"name": "CPU thread count bucketing",
"category": "Device characteristics",
"description": "Rounds the reported logical processor count to a common even value and caps unusually high values.",
"surface": "CPU characteristics",
"defaultEnabled": true,
"match": {
"indicatorId": "navigator-characteristics",
"api": "Navigator",
"action": "read-hardware-concurrency"
},
"protection": {
"strategy": "bucket-number",
"parameters": {
"step": 2,
"minimum": 2,
"maximum": 8,
"rounding": "nearest",
"preserveZero": false
}
}
}| Field | Required | Meaning |
|---|---|---|
schemaVersion |
Yes | Must currently be 1. |
id |
Yes | Stable lowercase identifier. Use letters, numbers, dots, underscores, and hyphens. |
name |
Yes | Short human-readable name. |
category |
No | Group such as Canvas, WebGL, or Device characteristics. |
description |
Yes | Factual description of what changes. Do not label ordinary API use as malicious. |
surface |
Yes | Short label used in Shield activity. |
defaultEnabled |
No | Defaults to true; set to false to distribute a dormant rule. |
match |
Yes | Exact packaged hook to match. |
protection |
Yes | Allowlisted strategy and bounded parameters. |
match uses the same vocabulary as Veilance detection signals, but Shield matching is immediate. A shield must protect the first sensitive read, so frequency thresholds such as minCount are intentionally unsupported.
{
"match": {
"indicatorId": "webgl",
"api": "WebGL",
"action": "renderer-query",
"detail": {
"parameter": "UNMASKED_RENDERER_WEBGL"
}
}
}indicatorId,api, and eitheractionoractionsare required.- Use
actionswhen one rule should cover closely related hooks. detailadds exact primitive-value matching. It is useful when one API/action exposes several parameters.- Matches are case-sensitive after validation. Copy identifiers from an existing working rule or the extension hook documentation.
Example with multiple actions:
{
"match": {
"indicatorId": "screen-characteristics",
"api": "Screen",
"actions": ["read-width", "read-avail-width"]
}
}Remote rules can use only the following strategies.
Changes a small deterministic selection of RGB channel values in a protected canvas copy.
{
"strategy": "canvas-pixel-farbling",
"parameters": { "maximumEdits": 8, "delta": 1 }
}maximumEdits: integer from 1 to 64.delta: integer from 1 to 8.
Changes selected integer values in a page-visible typed array, such as WebGL pixel output.
{
"strategy": "typed-array-farbling",
"parameters": { "maximumEdits": 8, "delta": 1 }
}Changes selected floating-point samples by a very small amount.
{
"strategy": "float-array-farbling",
"parameters": { "maximumEdits": 8, "epsilon": 0.0000001 }
}epsilon: from0.000000001through0.001.
Rounds a number into a coarser bucket, then clamps it to a bounded range.
{
"strategy": "bucket-number",
"parameters": {
"step": 100,
"minimum": 320,
"maximum": 3840,
"rounding": "nearest",
"preserveZero": true
}
}rounding may be nearest, floor, or ceil.
Returns one common numeric value.
{
"strategy": "replace-number",
"parameters": { "value": 24 }
}Preserves whether a value is zero while hiding the exact positive value. This is useful for capability counts such as touch points.
{
"strategy": "binary-number",
"parameters": { "zeroValue": 0, "nonZeroValue": 5 }
}Returns a common string profile for a supported string-valued hook.
{
"strategy": "replace-string",
"parameters": { "value": "Google Inc. (Google)" }
}- Copy the closest rule in
veilance-json-shields/. - Give it a unique, stable
idand use that ID as the filename. - Select an
indicatorId,api, andactionalready exposed by the extension. - Choose a compatible strategy from the allowlist above.
- Start with conservative parameters. A shield that breaks normal site behavior is not useful protection.
- Describe exactly what is changed and avoid claiming the underlying website behavior is malicious.
- Run the validator.
- Test both fingerprint resistance and normal behavior on representative sites before merging.
npm testThe validator rejects malformed JSON, unknown fields, duplicate IDs, filename/ID mismatches, unsupported strategies, and unsafe parameter ranges.
Before merging a rule, verify:
- the rule validates with
npm test; - its ID is unique and will remain stable;
- its match corresponds to a packaged Shield hook;
- its strategy is compatible with the original return type;
- repeated reads are consistent within one page session;
- the change does not alter visible canvas output;
- common drawing, media, graphics, localization, and responsive-layout use cases still work;
- the description says what Veilance changes without overstating intent; and
- the rule does not include code, URLs to code, regular expressions intended as code, or unbounded values.
The extension checks the repository every eight hours and on extension installation. It downloads the main branch archive, extracts only veilance-json-shields/*.json, and validates the complete candidate set before replacing the active set.
An update is rejected when it is empty, has too many validation failures, or unexpectedly removes more than half of an established rule set. If validation or download fails, Veilance keeps using the last known good rules and records the error in Settings.
For a bad database release, revert the offending commit on main. Clients will receive the restored archive on their next check. Do not reuse a removed rule ID for unrelated behavior.
Fingerprint protection changes values websites receive, so zero compatibility risk is impossible. Prefer entropy reduction over aggressive spoofing, preserve broad capabilities where practical, and keep changes small. The initial pack is intentionally conservative, but WebGL, audio, screen, and device-profile changes can still affect specialized applications.
Veilance Shield remains opt-in. Detection and Shielding are independent: users can continue observing fingerprint attempts even when protection is disabled.