Methodology

How map data is collected, classified and updated.

Background & Motivation

A TLS certificate authority (CA) can in principle revoke a certificate it has issued, or refuse to renew it. This is called the kill-switch risk. Nordic and Baltic municipal websites largely depend on US-based CA services that are subject to the US CLOUD Act, creating a potential single point of failure for public digital infrastructure.

This project is inspired by mxmap.ch (David Huser) and its Dutch counterpart mxmap.nl. Where those projects map email providers, this one maps TLS certificate authorities.

Demonstrative Purpose

Municipal public websites are rarely mission-critical in themselves. An outage on a municipal homepage is an inconvenience; it does not stop an ambulance, disable a water treatment plant or block a hospital’s patient records system.

The real significance of this map lies in what it suggests: the CA choices visible on public-facing websites are a reliable proxy for the procurement and infrastructure practices of the same organisations. Municipalities that rely on US-controlled certificate authorities for their public websites very likely apply the same procurement patterns across their internal systems β€” including IT infrastructure used by hospitals, emergency dispatch, social services and utilities. Those systems typically share the same cloud vendors, the same managed DNS providers and, consequently, the same certificate authorities.

The US CLOUD Act grants American authorities the power to compel any US-headquartered company to produce data or β€” in the case of a CA β€” to revoke or withhold certificates, regardless of where the data or service is physically located. A municipality that has unknowingly embedded US-controlled PKI throughout its infrastructure has created a structural dependency that could, in an extreme scenario, be leveraged against the continuity of its services.

This map is therefore an invitation to ask the question: if our public website certificate is US-controlled, what else is? It is a starting point for a broader audit of digital sovereignty in the public sector, not a complete picture of operational risk.

Conflict of Interest Disclosure

The author, Mikko Koljander, has a direct professional interest in the subject matter of this application. He is involved in certificate authority product development and operations at Telia, a Nordic telecommunications company whose CA services (Telia Certificate Service) are classified in this map as Minimal risk under Nordic jurisdiction.

This disclosure is made in the interest of transparency. The data collection methodology, the CA classification database and the risk taxonomy are derived from verifiable public information β€” certificate chain inspection, the CCADB registry and DNS records β€” and apply identical criteria to all certificate authorities including Telia. The author's professional background informs the technical design of the scanner but does not alter the classification results, which are computed automatically from certificate data.

Readers are encouraged to inspect the open source code, reproduce the scan results independently and raise any concerns via a GitHub issue.

Coverage

1 093 of 1 313 mapped municipalities (84%) have a resolvable domain. Of those, 1 000 (91%) are successfully classified. The remaining 9% fall into labelled categories explained below.

Data Sources

Municipality boundaries

Polygon boundaries come from the Eurostat GISCO LAU 2021 dataset (Local Administrative Units, CC BY 4.0). Converted to 614 KB TopoJSON by scripts/generate_topojson.py. Covers 1 313 municipalities: Finland (310), Sweden (290), Norway (356), Denmark (99), Estonia (79), Latvia (119), Lithuania (60), Estonia (79), Latvia (119), Lithuania (60).

Municipality domains

Each municipality's official web domain is resolved in three priority steps:

  1. Manual overrides (overrides.json) β€” highest priority
  2. Wikidata SPARQL β€” official website property (P856) per municipality
  3. Domain guessing β€” name slugification + DNS A/AAAA validation (e.g. Espoo β†’ espoo.fi; Oslo β†’ oslo.kommune.no)

Country-specific domain patterns are applied: Finnish municipalities predominantly use {name}.fi; Swedish ones use {name}.se or {name}.kommun.se; Norwegian ones use {name}.kommune.no; Danish ones use {name}.dk.

Certificate scanning

Each domain is scanned over asyncio SSL with explicit IPv4 resolution. This is important: many Nordic municipal servers advertise AAAA (IPv6) DNS records but their IPv6 port 443 endpoints are silently firewalled. Python's asyncio prefers IPv6 by default, causing 15-second timeouts for servers that respond in under 300 ms on IPv4. By resolving the A record explicitly and connecting to the IPv4 address (while still passing the domain name for SNI), the scanner avoids these spurious timeouts entirely.

The scanner applies a four-stage recovery chain for every domain:

  1. www fallback β€” if the bare domain fails, retry with www.{domain}. Some municipalities only serve TLS on the www subdomain.
  2. Shared hosting recovery β€” if SSL certificate verification fails (the cert's Subject Alternative Name does not include the municipality domain), the scanner reconnects without certificate verification to read the actual cert. This happens when a municipality's DNS points to a shared hosting platform whose wildcard cert covers *.platform.example but not the municipality's own domain. The hosting platform's CA is still identifiable and is used for classification; the popup shows a blue "Shared hosting" notice.
  3. HTTP-only detection β€” if port 443 times out or is refused, a quick TCP probe is sent to port 80. If it responds, the municipality is labelled HTTP only β€” no TLS certificate is present at all. A yellow notice is shown in the popup.
  4. HTTPS redirect following β€” after a successful TLS scan, an httpx HEAD request is made to detect cross-domain redirects. If the final URL is on a different hostname (e.g. stockholm.se β†’ start.stockholm), the redirect target is scanned instead, since it hosts the actual municipal content. The popup notes the scanned domain when it differs from the registered domain.

Additional signals queried per domain:

Classification

CA fingerprint database

An internal CA signature database (signatures.py) contains pattern-matching rules for 18 known CAs (issuer CN/O field, OCSP URL, CAA tag values). The CCADB (Mozilla/Linux Foundation) is used as an authoritative jurisdiction source when fingerprints match.

After each scan run, municipalities that share the same leaf certificate SHA-256 fingerprint are grouped. Five or more sharing the same cert indicates a shared hosting platform β€” currently three such groups are detected.

Signal weights

SignalWeightDescription
Leaf certificate issuer0.35 Strongest β€” the active CA
Intermediate issuer0.25 CA hierarchy
Root CA0.15 Root certificate
DNS CAA record0.10 Domain owner's explicit CA authorisation
CT logs0.08 Historical issuance data
OCSP endpoint0.04Revocation service jurisdiction
CRL endpoint0.03Certificate revocation list

Confidence scoring

Every classification carries a confidence score (shown as a percentage in each municipality popup). It is a rule-based epistemic measure β€” not a statistical probability β€” that reflects how much independent, mutually-corroborating evidence supports the winner CA.

The score is determined by matching the set of signal types collected for the winning CA against a lookup table of rules, from highest to lowest priority:

Signal combinationConfidenceExample
Leaf issuer + intermediate issuer + root CA95 %Full verified cert chain, all 3 positions match the same CA
Leaf issuer + intermediate issuer + DNS CAA95 %Live cert chain corroborated by domain owner's CAA record
Leaf issuer + intermediate issuer90 %Two cert positions agree; root not retrieved
Leaf issuer + CT log history80 %Live cert matches historical issuance pattern
Intermediate issuer + root CA85 %Academic chains where leaf CA is unlisted (e.g. GÉANT under HARICA)
Leaf issuer only75 %Single cert position, no corroboration
Intermediate issuer only65 %Only intermediate retrieved
CAA record only50 %Domain owner authorisation, no live cert available
No matching signals30 %Fallback; CA identified but evidence is minimal or conflicting

Why 95 % is the maximum

The confidence score deliberately never reaches 100 %. Even with three mutually corroborating signals β€” a full certificate chain whose leaf, intermediate and root all identify the same CA β€” five percent of uncertainty remains. This is not a technical limitation; it is an intentional acknowledgement of irreducible unknowns:

In practice, a 95 % confidence classification should be read as: "multiple independent, automatically-collected signals agree on this CA, and we have no reason from the available evidence to doubt it." The 5 % gap is the space reserved for what automated scanning cannot know.

Risk Levels

RiskColourDescriptionExample CAs
CriticalRedUS CLOUD Act subject β€” direct revocation riskDigiCert, Amazon, Google, Cloudflare, Sectigo
HighOrange-redUS jurisdiction, nonprofit / limited reachLet's Encrypt (ISRG)
MediumOrangeAllied non-EU or multinationalGlobalSign (BE/JP), SwissSign (CH)
LowBlueEU-controlled jurisdictionHARICA (GR), Certum (PL), D-TRUST (DE)
MinimalGreenNordic / national CATelia (SE), Buypass (NO)
UnknownGreySee breakdown belowβ€”

Understanding "Unknown" Entries

The grey "Unknown" category is not monolithic. Each popup shows a specific reason:

Update Frequency

The certificate scanner runs automatically every night at 02:00 UTC via GitHub Actions (.github/workflows/nightly.yml). Results are committed to data.json and data.min.json and deployed to GitHub Pages within minutes.

Known Limitations

Open Source

Source code and data are openly available on GitHub under the MIT/EUPL licence. Pull requests and overrides.json corrections are welcome.

Attribution