Privacy Policy
This page explains what personal data crawford.dev processes when you read it, why, and for how long. The short version: no advertising, no tracking cookies, no third-party services, and everything runs on servers in my home in Germany.
Who is responsible
Steven Crawford
Stegstr. 36
60594 Frankfurt am Main
Email: steve@crawford.dev
Hosting
crawford.dev runs on my own hardware: a small Kubernetes cluster at home, behind my own router. No hosting provider, content delivery network or cloud service processes your visit. Fonts, scripts and images are all served from this site; nothing is loaded from third parties.
When you read a page
Connection data at the router
Every connection reaches my router (HAProxy on OPNsense) first. It forwards the encrypted connection to the cluster without decrypting it, so it never sees which pages you request. It logs your IP address, the time and the amount of data transferred, and deletes these logs after 31 days.
- Purpose: delivering the site, and detecting and fending off attacks.
- Legal basis: Art. 6(1)(f) GDPR (my legitimate interest in a secure, working site).
The blog software's own logs record errors and technical events, but not your IP address. They are rotated automatically and kept only briefly.
View counter
When you open a post, your browser sends a small request ("beacon") so I can count views. I store:
- which post was viewed, and the date and time;
- a hash of your IP address, made with a secret key and the current date. The same visitor on the same day produces the same hash, so a view is counted once per day. A new hash is produced each day, so visits can't be linked across days. Your IP address itself is not stored;
- your browser's user-agent string;
- the referring page, if your browser sends it.
Because I hold the key, the hash is pseudonymous rather than anonymous. I don't combine it with other data and can't identify you from it.
- Retention: 90 days, then deleted automatically. Only the total view count per post is kept.
- Purpose: knowing which posts are read and where readers come from.
- Legal basis: Art. 6(1)(f) GDPR.
Signed-in administrators (that is, me) are not counted.
Security reports
If your browser blocks something because of this site's security policy (Content Security Policy), it may send a report. I log which rule was violated, the blocked address and the page, with query strings removed. Your IP address is kept in memory for one minute only, to limit how many reports one address can send, and is never stored.
- Legal basis: Art. 6(1)(f) GDPR (keeping the site secure).
Cookies and local storage
This site uses no tracking or advertising cookies, and no consent banner is needed. It sets only these technically necessary cookies (§ 25(2) no. 2 TDDDG):
| Name | Purpose | Lifetime |
|---|---|---|
croft_affinity |
Sends your requests to the same server, which the site's interactive parts need | Until you close the browser |
.AspNetCore.Antiforgery.… |
Protects forms against cross-site request forgery | Until you close the browser |
If you use the theme switch or collapse the sidebar, your browser remembers that choice in its own local storage. That data never leaves your browser, and you can delete it at any time in your browser's settings.
Signing in is only for the site's administrator. It sets further cookies and uses my own sign-in service (Authentik), which also runs at home.
Your rights
You have the right to:
- access the data about you (Art. 15 GDPR);
- rectification (Art. 16);
- erasure (Art. 17);
- restriction of processing (Art. 18);
- data portability (Art. 20);
- object to processing based on legitimate interest (Art. 21).
Email me at the address above.
Please note that I generally can't link the stored data to a person: I have no names, accounts or emails of readers, and IP addresses are stored only as daily hashes.
You also have the right to lodge a complaint with a data protection supervisory authority. For me, that is Hessischer Beauftragter für Datenschutz und Informationsfreiheit (https://datenschutz.hessen.de/), Gustav-Stresemann-Ring 1, 65810 Wiesbaden.
Last updated: 18 October 2026