Kort sagt
Vi mäter vad som händer på din sajt. Vi kan inte veta vem som gjorde det. Det är inte en policy, det är hur koden är byggd.
- Ingen cookie, ingen localStorage, ingen sessionStorage, ingen fingerprint. Ingenting skrivs eller läses på besökarens enhet.
- IP-adressen och user-agent-strängen finns bara i serverns minne under själva anropet. De skrivs aldrig till disk.
- Besökaren blir en hash som byts varje dygn. När dygnets salt är raderat går hashen inte att räkna fram igen, inte av oss heller.
- Geouppslaget görs mot en fil på vår egen disk. IP-adressen lämnar aldrig servern. Bara land, region och ort sparas.
- Databasen ligger på svensk disk hos svensk leverantör. Det finns inga tredjepartsanrop i mätvägen.
01Så går ett besök till, steg för steg
Din sajt laddar ett skript på knappt 2 kB, /fa.js. Det läser
adressen i webbläsarfältet, referrern och (om du slagit på det) tid på
sidan och läsdjup. Det läser inte skärmupplösning, installerade typsnitt,
canvas, batterinivå eller något annat som brukar användas för att bygga ett
fingeravtryck. Det skriver ingenting i webbläsaren. Skickar besökaren
Do-Not-Track avstår skriptet helt, trots att vi juridiskt inte
behöver bry oss om den signalen.
Sedan skickas en POST till /api/event.php. Där
händer följande, i den här ordningen:
-
0 ms
Botfiltret
User-agent-strängen matchas mot ett mönster för robotar, crawlers, övervakningstjänster och förhandsvisningar. Träffar det avvisas anropet direkt och ingenting skrivs. En tom user-agent räknas som bot. Riktiga webbläsare skickar alltid en.
-
1 ms
Domänen slås upp
Domänen måste finnas som en registrerad sajt hos oss, och sajten måste tillhöra ett konto som ryms inom sitt tak. Annars avvisas anropet. Vi tar aldrig emot mätdata för domäner ingen har lagt upp.
-
2 ms
Besöks-id:t räknas fram
IP-adressen hämtas ur anropet och user-agent-strängen ligger redan i minnet. Tillsammans med dygnets salt och kundens domän blir de en 32 tecken lång hash. Ingen av ingredienserna sparas, bara resultatet.
-
3 ms
Landet härleds lokalt
IP-adressen slås upp mot en geodatabasfil på vår egen disk. Inget anrop går ut. Resultatet (land, region, ort) sparas; IP-adressen kastas i samma andetag.
-
4 ms
Raden skrivs
Händelsen sparas med besöks-id:t, sidan, källan, webbläsare/OS/enhet, plats och engagemang. Varken IP eller den råa user-agent-strängen ingår i raden. De variablerna finns inte kvar när anropet är slut.
-
5 ms
Svar 202, utan kropp
Besökaren får ett tomt svar. Skulle något gå fel i mätningen ska det aldrig märkas på din sajt. Vi avvisar tyst i stället för att skriva ett fel i konsolen.
Hashen räknas fram exakt så här. Det är hela funktionen, ur lib/parse.php:
function visitor_hash($salt, $domain, $ip, $ua) {
return substr(hash('sha256', $salt . '|' . $domain . '|' . $ip . '|' . $ua), 0, 32);
}
Att domänen ingår i hashen är inte kosmetik: det gör att samma besökare får olika id på två sajter som mäts hos oss. Vi kan alltså inte följa någon mellan kundernas sajter, ens om vi ville. Det finns ingen tabell där det skulle gå att koppla ihop dem, för nyckeln existerar inte.
02Exakt vad som lagras, och vad som aldrig gör det
Det här är kolumnerna i events-tabellen, alltså allt som finns
kvar på disk efter en sidvisning. Inget mer, inget dolt.
| Kolumn | Innehåll | Exempel |
|---|---|---|
visitor_id | Dygnsfärsk hash. Byts varje natt. | a3f9c1e0b7d2… |
ts | Tidpunkt, unix-sekunder (UTC). | 1 763 041 200 |
hostname | Värdnamnet på sidan som visades. | dinsajt.se |
pathname | Sökvägen. Aldrig query-strängen. | /priser |
referrer | Bara hänvisarens värdnamn, aldrig hela adressen. | google.com |
source | Det läsbara kanalnamnet. | |
utm_* | De fem utm-fälten, om de finns i länken. Max 120 tecken vardera. | nyhetsbrev |
browser, os | Namn och huvudversion, inte hela versionssträngen. | Chrome 141 |
device | Tre värden. Inte modell, inte skärmstorlek. | mobile |
country, region, city | Härlett ur IP:n lokalt. Ort på stadsnivå, inget mer. | SE · Västra Götaland · Borås |
duration, scroll_depth | Sekunder på sidan (max 3 600) och läsdjup i procent. | 42 s · 80 % |
props | Egna egenskaper som du väljer att skicka. Se varningen nedan. | {"plan":"proffs"} |
revenue, currency | Belopp och valuta, om du mäter intäkter. | 199 SEK |
Och det här är vad som aldrig når disken:
| Uppgift | Vad som händer med den |
|---|---|
ip | Finns i minnet under anropet. Används till hashen och geouppslaget, sedan är variabeln borta. Skrivs aldrig, loggas aldrig. |
user_agent | Samma sak: tolkas till ”Chrome på macOS, dator” och kastas. Den råa strängen sparas inte. |
query | Query-strängen kan innehålla e-postadresser, ordernummer och sessionsnycklar. Vi plockar ut utm-fälten och slänger resten. |
cookie | Existerar inte. Vi sätter ingen och läser ingen på besökarens sajt. |
fingerprint | Vi frågar aldrig webbläsaren om skärm, typsnitt, canvas eller hårdvara. Det finns ingenting att bygga ett fingeravtryck av. |
cross_site_id | Går inte att skapa: domänen ingår i hashen, så samma person får olika id på olika sajter. |
Två saker som är ditt ansvar, inte vårt
Sökvägar. Vi sparar pathname rakt av. Har du
adresser som /konto/anna.svensson hamnar den strängen i
databasen, inte för att vi vill ha den, utan för att vi inte kan veta att
den är känslig. Bygger du sådana adresser: uteslut dem med
data-exclude på skripttaggen.
Egna egenskaper. props innehåller precis det
du skickar dit. Skickar du ett kund-id eller en e-postadress har du lagt en
personuppgift i vår databas, och då förändras hela bilden: då blir vi ditt
personuppgiftsbiträde för den datan. Låt bli. Skicka kategorier, inte
personer.
03Dygnssaltet: därför är hashen inte en personuppgift
En hash av en IP-adress är i sig en personuppgift. IPv4-rymden är liten nog att gå igenom på en eftermiddag: den som har hashen och saltet kan pröva sig fram till vilken IP som gav den. Det är just därför de flesta ”anonyma” analysverktyg inte är anonyma.
Så här gör vi i stället:
- Saltet är 32 slumpade byte och byts varje dygn (UTC-dygn).
- Ett salt raderas när det är två dygn gammalt, dels av nattjobbet i
cron/run.php, dels stickprovsvis under mätningen. - När saltet är borta finns ingen väg tillbaka från hashen till IP-adressen. Ingredienserna är utplånade, inte gömda.
Det betyder att en events-rad från förra veckan innehåller en
32 tecken lång sträng som ingen kan koppla till en person: inte vi, inte en
angripare med hela databasen, inte en myndighet med ett beslut i handen. Den datan är anonym i dataskyddsförordningens mening, och den kan
inte göras om till personuppgifter igen.
Enda undantaget är själva mätdygnet: så länge dagens salt lever skulle en angripare med tillgång till både saltet och en misstänkt IP kunna bekräfta att den IP:n besökt sajten. Det är därför saltet aldrig lämnar databasen, aldrig loggas och aldrig ingår i någon export. Vi säger inte att fönstret inte finns. Vi säger att det är ett dygn brett och att vi vaktar det.
04Geouppslaget sker på vår egen disk
Att slå upp land och ort mot ett moln-API hade varit enklare. Det hade också gjort produktlöftet osant: varje besökares IP-adress hade skickats till en tredje part, ofta i USA, i realtid.
I stället ligger en MaxMind-/DB-IP-databas som en fil på vår egen disk
(storage/geo.mmdb). Uppslaget är en läsning i den filen. Ingen
nätverkstrafik lämnar servern. Privata nät (utveckling, intranät) ger inget
resultat alls. Vi sparar landskoden, regionen och orten på stadsnivå, inte
koordinater, inte postnummer, inte IP-nät.
Ort på stadsnivå, kopplat till en hash som dör i natt, pekar inte ut en person. ”Någon i Borås läste /priser i tisdags” är statistik. Det blir aldrig mer än så hos oss.
06Vad du förlorar på att inte spåra
Här kommer den ärliga delen, som konkurrenterna gärna hoppar över.
Eftersom hashen byts varje natt kan vi inte se att samma person återkommer nästa dag. En besökare som var här på måndagen och kommer tillbaka på onsdagen räknas som två besökare. Vi har inga ”återkommande besökare”, ingen kohortanalys över veckor, ingen attribution som följer någon från första annonsklicket till köpet tre veckor senare.
Det är inte en bugg. Det är hela konstruktionen:
- Besökssiffran är konservativ. Din unika-besökare-siffra blir högre hos oss än den ”borde” vara över långa perioder, eftersom samma person räknas om varje dygn. Jämför inte rakt av med Google Analytics.
- Ett besök tar slut efter 30 minuters inaktivitet. Kommer samma hash tillbaka senare samma dygn blir det ett nytt besök.
- Intent-poängen lever bara inom besöket. Den är beteende (sidor, tid, läsdjup, vilka sidor), inte en profil som följer med någon.
- Ingen tratt som spänner över dagar. Vi kan visa vägen genom sajten under ett besök, inte över en månad.
Det du får i stället är statistik som ingen behöver samtycka till, som ingen klickar bort, och som inte tappar 30–40 % av mätningarna i en bannerruta. Vi tycker att det är ett bra byte. Tycker du inte det, är vi fel verktyg, och det är bättre att du vet det nu än efter tre månader.
07Vem ansvarar för vad
Den vanliga uppdelningen i analysverktyg är: kunden är personuppgiftsansvarig för besökarnas data, leverantören är personuppgiftsbiträde, och därför krävs ett personuppgiftsbiträdesavtal. Hos oss ser det annorlunda ut, av en enda anledning: det finns inga personuppgifter i mätdatan att vara biträde för.
- För mätdatan på din sajt
- Du är personuppgiftsansvarig för din webbplats och för vad som händer på den. Men det vi lagrar åt dig är anonym statistik, inte personuppgifter, och något biträdesavtal för den datan behövs därför inte. Vill du ändå ha ett skriftligt biträdesavtal, till exempel för att en upphandling kräver det, får du ett, utan kostnad. Hör av dig så skickar vi det.
- För ditt konto hos oss
- Din e-postadress, ditt namn och ditt företag är personuppgifter, och där är vi personuppgiftsansvariga, inte biträde. Vad vi gör med dem står i personuppgiftspolicyn.
- Om du själv lägger personuppgifter i mätdatan
-
Skickar du kund-id eller e-postadresser i
props, eller har sökvägar som pekar ut personer, då finns det plötsligt personuppgifter i databasen, och då är du ansvarig och vi biträde för just den datan. Hör av dig så tecknar vi ett biträdesavtal. Enklare: låt bli att skicka dem.
08Hur länge datan finns kvar
Lagringstiden är densamma för alla konton, och nattjobbet raderar faktiskt det som är
äldre. Det är inte ett löfte i en policy, det är en DELETE som
körs varje natt i cron/run.php.
| Uppgift | Historik | I koden |
|---|---|---|
| Händelser och besök | 5 år, samma för alla konton | 1 825 dygn |
| Dygnssalter | 2 dygn | 2 dygn |
| Dagliga nyckeltal | Ligger kvar | – |
Dygnssalterna raderas efter två dygn. De dagliga nyckeltalen i
daily (summor per dygn, utan besöks-id) får ligga kvar, så att
din långsiktiga trafikkurva överlever gallringen även när de enskilda
händelserna är borta.
Raderar du en sajt försvinner alla dess händelser och besök samma sekund. Raderar du ditt konto försvinner allt: konto, sajter, mätdata. Ingen papperskorg, ingen ångervecka.
09Färdig text till din egen integritetspolicy
Du behöver ingen cookiebanner, men du bör ändå berätta i din integritetspolicy att sajten mäts. Här är en text du kan klistra in rakt av. Den är skriven för att vara sann om vår tjänst, så ändra inget i sak.
Besöksstatistik
Vi mäter hur webbplatsen används med Statly, en svensk analystjänst. Mätningen sätter inga kakor och lagrar ingenting i din webbläsare. Det är också skälet till att du inte möts av någon cookiebanner här.
Din IP-adress och webbläsarens user-agent behandlas kortvarigt i tjänstens minne för att räkna fram en pseudonym besöksidentifierare och för att härleda vilket land och vilken ort besöket kommer ifrån. Varken IP-adressen eller user-agent-strängen lagras. Identifieraren bygger på ett salt som byts varje dygn och raderas efter två dygn, vilket gör att den inte kan kopplas tillbaka till en enskild person i efterhand.
Det som sparas är avidentifierad statistik: vilken sida som besöktes, varifrån besöket kom, ungefärlig plats på stadsnivå, typ av webbläsare och enhet samt tid på sidan. Uppgifterna kan inte användas för att identifiera dig och delas inte med någon för marknadsföring. All data lagras i Sverige.
Den rättsliga grunden för den kortvariga behandlingen av IP-adressen är vårt berättigade intresse av att föra anonym besöksstatistik över vår egen webbplats.
Behöver du en teknisk beskrivning att bifoga i en upphandling eller en konsekvensbedömning är det här dokumentet skrivet för att kunna bifogas som det är. Behöver du något mer specifikt: hör av dig, vi skriver det.
10Kontrollera oss
Det enklaste sättet att kontrollera det här dokumentet är att inte tro på det. Gör så här i stället:
- Öppna nätverksfliken på den här sidan. Vi mäts med vår egen spårare. Du ser ett anrop till
/api/event.phpoch inget annat. Svaret är tomt. - Titta i Lagring/Application. Inga kakor från oss, inget i localStorage, inget i sessionStorage.
- Läs
/fa.js. Den är okomprimerad och kommenterad, på svenska. Sju kilobyte. Det tar tio minuter. - Fråga oss om koden. Vill du se
api/event.php,lib/parse.phpellerlib/geo.phpi sin helhet inför ett beslut: skriv, så skickar vi dem.
Hittar du något i koden som inte stämmer med den här texten är det texten som är fel, och vi vill veta det. Skriv till security@frontness.se eller hej@frontness.se.
Kontakt
Frågor om mätningen: hej@frontness.se
Dataskyddsfrågor: petri@frontness.se
Sårbarheter: security@frontness.se
Life Flow AB (Statly), Borås, Sverige