Criteria Colors
Optional, without provider ratings
Criteria colors are off by default. You can enable them in the matrix. Each color refers exclusively to the corresponding goal explained below. Meeting a criterion does not mean that a provider is safe, trustworthy or suitable for you overall.
There is no overall grade, no scores, weights or rankings, and no sorting by quality. Results are not added up into a provider rating. Which functions you need depends on your use case; additional functions are not automatically an advantage.
What the colors mean
- Met
- Green: The stored value meets the explicitly stated goal of this criterion.
- Partially met
- Yellow: The stored value describes a specifically defined partial scope or an additional setting that is needed.
- Not met
- Red: The stored value does not meet this individual goal. This is not a negative overall rating of the provider.
- Neutral
- Neutral: There is no mapping, no usable value or no unambiguous evidence. It means neither met nor not met.
Binary criteria only map to met or not met. A yellow intermediate level is not invented. Missing or disputed information remains neutral for these criteria too.
Source quality stays separate
A provider statement (claimed) can meet an individual goal according to its raw value. It still remains a provider statement and does not become independent evidence (confirmed) through a green color. The same raw value gets the same criterion color for claimed and confirmed; confidence, sources and retrieval dates stay separate.
For unknown or disputed, the criterion color stays neutral even when a value is stored. Colors replace neither reading the sources nor your own checks. The scope, platform, configuration and date of evidence can limit what it establishes.
Missing does not mean false
A missing data point, null, undefined, an empty string or a whitespace-only string does not mean false. Unknown enum values, mismatched data types and criteria without a classification stay neutral. An explicit boolean false can, however, mean not met for a mapped functional goal. Free text is not interpreted, and values are not converted into other types.
Prices, countries, company names, ownership structures, server counts and other information without a generally defined direction deliberately stay neutral. Functions not listed here and free-text fields also receive no color. Neutral says nothing about a provider's quality.
Current Mappings
This list is generated directly from the same rules as the criteria colors. Each goal states its limitations. Mappings apply only to claimed or confirmed; all other values and unknown or disputed receive neutral. The order follows the criteria catalog, not a weighting.
Quotation marks indicate exact enum strings. true and false without quotation marks are booleans. Similar words, different spellings or the strings "true" and "false" are not treated as equivalent.
Jump to a criterion
No activity or traffic logs
logging.activity_logsThe goal is not to log visited domains, DNS queries, destination servers or content. Keeping activity logs does not meet this goal. Connection metadata is considered separately.
"no"- Met
"yes"- Not met
"unclear"- Neutral
No connection logs
logging.connection_logsThe goal is not to retain connection metadata. Aggregated totals without an account link are a defined partial form of data minimization, but not a complete absence of collection. Per-session records do not meet the goal.
"no"- Met
"aggregated"- Partially met
"per_session"- Not met
"unclear"- Neutral
No lasting storage of the real IP address
logging.source_ip_storedThe goal is not to store the source IP beyond the current connection. No storage and exclusively transient processing during the connection both meet this goal. A VPN server temporarily needs to know the source IP to handle the connection; this is not classified as a shortcoming.
"no"- Met
"transient"- Met
"yes"- Not met
"unclear"- Neutral
No storage of the assigned VPN IP
logging.assigned_ip_storedThe goal is not to store the VPN IP assigned to a session. A stored assignment can help link sessions when combined with other data. This field alone does not establish identifiability.
"no"- Met
"yes"- Not met
"unclear"- Neutral
No stored timestamps
logging.timestamps_storedThe goal is not to store timestamps. Coarse dates limit time precision and meet the goal partially, while timestamps accurate to the second do not. This says nothing about other possible connection data.
"no"- Met
"coarse"- Partially met
"precise"- Not met
"unclear"- Neutral
No recording of transferred data volume
logging.bandwidth_loggedThe goal is not to record transferred data volume. Pure totals without an account link are a partial form of data minimization; per-account recording does not meet the goal. Data caps may require such counting, but this is not an overall assessment of those plans.
"no"- Met
"aggregate"- Partially met
"per_account"- Not met
"unclear"- Neutral
Telemetry off by default and avoidable
logging.app_telemetryThe goal is for app telemetry not to run without active consent and for the app to be usable without it. No telemetry and opt-in meet both requirements. Opt-out meets only the ability to disable it, since transmission is on by default. Forced telemetry does not meet the goal. This says nothing about VPN logs.
"none"- Met
"opt_in"- Met
"opt_out"- Partially met
"forced"- Not met
No-logs claim examined externally
trust.nolog_auditThe goal is the existence of an independent no-logs audit. Met only means that such an examination took place according to the data point, not that it covers every system, is current or proves a lasting absence of logging. The data point's evidence quality stays separate.
true- Met
false- Not met
Full audit report public
trust.audit_report_publicThe goal is to be able to read the complete audit report with its scope, limitations and findings. A summary offers only part of this insight. Publication says nothing about whether the audit found any issues.
"full"- Met
"summary"- Partially met
"no"- Not met
Regular transparency reports
trust.transparency_reportThe goal is regular reporting on requests from authorities, with case numbers and a reporting period. Irregular reports meet the publication part, but not the regularity requirement. A report's existence does not establish its completeness.
"regular"- Met
"irregular"- Partially met
"none"- Not met
All clients open source
trust.opensource_clientsThe goal is inspectable source code for all clients. Some open clients meet only part of the goal. Open code proves neither the absence of flaws nor that the distributed app was built from exactly that code.
"all"- Met
"some"- Partially met
"none"- Not met
Server-side software open source
trust.opensource_serverThe goal is inspectable source code for the server-side software. Partially published code meets the goal partially. Even fully open code does not establish that this exact version runs on the servers in service.
"yes"- Met
"partial"- Partially met
"no"- Not met
Reproducible builds available
trust.reproducible_buildsThe goal is to produce bit-for-bit identical binaries from the same source code and thereby check published builds against it. This property alone establishes neither code security nor that every distributed version has been checked.
true- Met
false- Not met
Android app available through F-Droid
trust.fdroid_availableThe functional goal is installation through F-Droid without a Google account. This concerns a specific distribution channel, not the quality of the Android app or availability on iOS.
true- Met
false- Not met
Connections through WireGuard available
crypto.wireguardThe functional goal is the availability of WireGuard. Other protocols do not meet this specific compatibility goal, but that does not make them generally insecure. Implementation and handling of internal IP assignments are separate questions.
true- Met
false- Not met
Connections through OpenVPN over UDP available
crypto.openvpn_udpThe functional goal is OpenVPN over UDP support for compatible clients and networks. This assesses neither other protocols nor actual throughput or the encryption used.
true- Met
false- Not met
Connections through OpenVPN over TCP available
crypto.openvpn_tcpThe functional goal is OpenVPN over TCP support for compatible clients and networks. It does not guarantee bypassing network blocks or achieving a particular speed.
true- Met
false- Not met
Connections through IKEv2/IPsec available
crypto.ikev2The functional goal is IKEv2/IPsec support. This is a compatibility statement, not superiority over other protocols or a promise of support on every operating system.
true- Met
false- Not met
Perfect forward secrecy available
crypto.pfsThe goal is to protect past sessions against later decryption even if the long-term server key is subsequently exposed. This field records the property, not a flaw-free implementation or protection against every attack path.
true- Met
false- Not met
Post-quantum key exchange on by default
crypto.post_quantumThe goal is post-quantum key exchange that is already available and enabled by default. An opt-in option meets availability, but not the default setting. An announcement is not an available function. No general security guarantee is inferred.
"default"- Met
"optional"- Partially met
"announced"- Not met
"no"- Not met
DNS leak protection available
crypto.dns_leak_protectionThe goal is technical measures against DNS queries outside the tunnel. The stored statement about this function is not our own measurement and does not guarantee protection on every platform, browser configuration or app version.
true- Met
false- Not met
IPv6 usable through the tunnel without leaks
crypto.ipv6_handlingThe goal covers both using IPv6 inside the tunnel and preventing IPv6 leaks. Blocking prevents bypassing the tunnel, but removes IPv6 connectivity, so it meets only part of the goal. A leak does not meet the goal; unclear behavior stays neutral.
"full_support"- Met
"blocked"- Partially met
"leaks"- Not met
"unclear"- Neutral
System-wide block when the tunnel drops
features.killswitchThe goal is to block traffic for the whole device when the connection drops. A system-wide block meets the goal even without an additional app-level mode. Blocking only selected programs covers just part of it. Persistence after the app closes or the device restarts is recorded separately.
"system"- Met
"app"- Partially met
"both"- Met
"none"- Not met
Block persists after app exit and restart
features.killswitch_permanentThe goal is an operating-system-level traffic block that remains active after the app is closed or crashes and after a device restart. This statement does not replace checking the specific platform and configuration.
true- Met
false- Not met
Freely combinable multihop entry and exit
features.multihopThe functional goal is multihop with freely combinable entry and exit servers. Fixed routes provide multiple hops, but not free selection. Multihop is not a promise of additional anonymity; both servers may belong to the same provider.
"configurable"- Met
"fixed"- Partially met
"no"- Not met
Port forwarding available
features.port_forwardingThe functional goal is forwarding incoming connections to your own device. Restrictions on ports or locations count as partially met. Available forwarding is not a general security advantage and may create additional reachability.
"yes"- Met
"limited"- Partially met
"no"- Not met
Customizable DNS ad and tracker filter
features.adblock_dnsThe functional goal is a DNS filter with selectable lists or categories. A fixed list meets the filtering part, but not customization. The method filters domains and does not remove every ad or every form of tracking.
"yes_configurable"- Met
"yes_fixed"- Partially met
"no"- Not met
Malware and phishing domains filterable
features.malware_filterThe functional goal is blocking domains on malware or phishing lists. This does not scan downloaded files or provide complete protection against malware.
true- Met
false- Not met
Rule-based automatic connections available
features.autoconnect_rulesThe functional goal is configurable conditions for connecting, such as at startup or on specific networks. Availability does not mean these rules are already enabled or that every connection gap is prevented.
true- Met
false- Not met
IPv6 transport inside the tunnel available
features.ipv6_tunnelThe functional goal is using IPv6 through the tunnel. Merely blocking IPv6 does not meet this availability goal, even if it can prevent leaks. Behavior regarding IPv6 leaks is explained separately in the IPv6 handling criterion.
true- Met
false- Not met
Windows usable with a provider-maintained app
apps.windowsThe functional goal is use on Windows with the provider's own app. Config files alone allow use with other software, but do not meet the app part. This does not rate code quality, feature scope or supported Windows versions.
"native"- Met
"config_only"- Partially met
"no"- Not met
macOS usable with a provider-maintained app
apps.macosThe functional goal is use on macOS with the provider's own app. Manual configuration meets only the usability part. The store build and the directly downloaded app may differ; the color says nothing about that.
"native"- Met
"config_only"- Partially met
"no"- Not met
Linux usable with a graphical provider app
apps.linux_guiThe functional goal is a graphical Linux app from the provider. Config files allow setup with other tools, but do not provide such an interface. Supported distributions and package formats are not assessed.
"native"- Met
"config_only"- Partially met
"no"- Not met
Linux usable with a provider-maintained command-line tool
apps.linux_cliThe functional goal is a Linux command-line tool maintained by the provider. Connection profiles alone cover setup with other tools, not the provider's own client. Documentation and open source availability are separate properties.
"native"- Met
"config_only"- Partially met
"no"- Not met
Android usable with a provider-maintained app
apps.androidThe functional goal is use on Android with the provider's own app. Configuration with another client meets only the usability part. This mapping says nothing about trackers, distribution channels or supported Android versions.
"native"- Met
"config_only"- Partially met
"no"- Not met
iOS usable with a provider-maintained app
apps.iosThe functional goal is use on iOS with the provider's own app. Profiles or another client cover only the usability part. Availability does not establish the specific scope of protection on iOS.
"native"- Met
"config_only"- Partially met
"no"- Not met
Scripted connections documented
apps.cli_documentedThe functional goal is a published command or interface reference that enables scripted connections. A tool without this documentation does not meet the goal.
true- Met
false- Not met
Use without personal registration available
apps.no_account_neededThe goal is use without personal registration, including, as defined in the catalog, a randomly generated account number instead of an email address and password. This establishes neither an absence of connection logs nor an anonymous payment path.
true- Met
false- Not met