Legal
Privacy policy
This policy applies to every KOSCHE website: kosche.wtf, kosche.dev, kosche.ai, kosche.app, kosche.io, kosche.sh, kosche.cloud and kosche.me. It is the same on each of them and also applies to quake2vault.app and mime-inspector.dev. What applies to all of them comes first; what concerns one website only is under The individual websites.
This is an English translation for convenience. Only the German text is binding: Datenschutzerklärung.
Last updated:
Controller
Daniel Konieczny
IT-Consulting und Softwareentwicklung (KOSCHE)
Zum Kummerbrink 8
31089 Duingen
Germany
Email: mail@kosche.wtf
At a glance
- Every website runs on servers I rent from Hetzner in Falkenstein (Germany) and operate myself.
- There are no analytics or tracking services, no advertising, no social media plugins and no embedded third-party content. Fonts and all other files come from the website itself. Two websites also send something to Cloudflare, only if you want it, and both say so in their section: quake2vault.app reports the game’s starts and errors if you turn that on, mime-inspector.dev looks up DNS records when you click.
- As long as a website is not public, a door stands in front of it that opens only with a passkey; anyone can read the legal notice and the privacy policy without one. Whoever opens the door receives a technically necessary cookie for that one website. The websites set no other cookies; only my internal tools have their own (see yard.kosche.cloud and slip.kosche.cloud).
- The web servers keep no access logs. Error messages and the messages of the passkey door are kept for 30 days.
- There are no visitor accounts. If you want to reach me, write an email or use the contact form in the legal notice.
Hosting
The websites run on servers of Hetzner Online GmbH, Industriestraße 25, 91710 Gunzenhausen, Germany. Servers, load balancer, databases and storage are located in Hetzner’s data centre in Falkenstein (Germany). Hetzner provides the machines, network and storage and processes data on my behalf in doing so (Art. 28 GDPR); I operate the software on these servers myself.
The legal basis for everything that delivering the pages involves is my legitimate interest in providing the websites reliably and securely (Art. 6 (1) (f) GDPR).
Page requests and logs
When you open a page, your browser necessarily sends data to the server: your IP address, the requested address, date and time, your browser’s identifier (user agent), the page you came from (referrer) if your browser sends it, and, where applicable, the cookie of the passkey door. Without this data the page cannot be delivered.
The websites can only be reached encrypted (HTTPS); an unencrypted request is redirected to HTTPS. The encrypted connection ends at a proxy on the same servers, which passes the request with your IP address (in the X-Forwarded-For header) to the website’s web server. The web servers keep no access logs. Only the following is recorded:
- Error messages. If a request fails because of a server error, the web server may write an error message. It contains the details of the request: method, requested address and the headers, including your IP address, your browser’s identifier and the referrer. Cookies are masked in it.
- Messages of the passkey door. Every step of a sign-in at the door is recorded with its time, its outcome and the first 120 characters of the browser identifier, without IP address and without cookie (see The passkey door).
A logging service on the same servers collects these messages and deletes them after 30 days. I use them to find faults and recognise attacks (Art. 6 (1) (f) GDPR).
The servers’ network layer also holds connection data (IP addresses, ports and details of the request) in memory to route traffic and investigate network faults. This data is not written to disk and is continuously overwritten.
The passkey door
As long as a website is not public, its server answers every request without a valid cookie with a door instead of the page. Only the legal notice and this policy it shows to everyone, with the files they need to display; the door links both. Only people whose passkey I set up myself can open the door; visitors cannot register.
Signing in. The door uses passkeys (WebAuthn). Your device signs a random number (challenge) with a key whose private part never leaves your device. The answer (the passkey’s identifier, the signature, information from your authenticator and the address of the page on which it was made) goes to the website’s door and from there to the sign-in service of yard, my own system on the same servers. It verifies the signature with the public key stored there. For each passkey it stores only its identifier, the public key, a counter, the supported transports, a label and the times it was set up and last used, but no IP address. It keeps challenges in memory only; they expire after two minutes. It records every verified sign-in as an event with its outcome and website and deletes it after 30 days; backups of this database are deleted after 90 days.
Signing in through kosche.dev. The passkeys belong to kosche.dev. When another website asks for a passkey, your browser first fetches the list of permitted websites from kosche.dev (/.well-known/webauthn). For browsers that cannot do this, the door leads through kosche.dev/gate/relay/: the answer is made there and comes back in the fragment of the address, which your browser does not send to any server.
The cookie. After a successful sign-in, the door sets a cookie for that one website:
- Name
kosche_wtf,kosche_dev,kosche_ai,kosche_app,kosche_io,kosche_sh,kosche_cloud,kosche_me; for quake2vault.appquake2vaultand for mime-inspector.devmime_inspector. Each website has its own, valid for it alone; the archive at kosche.ai/archive/ opens with kosche.ai’s.- Content
- Version, expiry time, a random number and a signature. It contains no information about you and is not stored on the server; the door recognises it by its signature alone.
- Lifetime
- 30 days, or until you sign out
- Attributes
HttpOnly,Secure,SameSite=Lax, valid only for the website that set it
The cookie is strictly necessary so that a non-public website can be shown to you after you sign in (Sec. 25 (2) no. 2 TDDDG). The processing during sign-in is based on my legitimate interest in showing non-public websites to authorised people only (Art. 6 (1) (f) GDPR).
Storage in your browser
Some pages keep settings, and where you want it your files too, in your browser’s storage (localStorage, sessionStorage, IndexedDB, the origin private file system or a service worker’s cache). They stay on your device, are not sent to me and are used neither for analytics nor for recognising you. Which ones a website uses is listed under The individual websites. You can delete them at any time in your browser’s settings.
This storage is strictly necessary for the function you are using (Sec. 25 (2) no. 2 TDDDG).
Fonts, third-party content and links
All fonts are served by the website itself. The pages load no files from other servers, including images, scripts or videos; their security policy (Content Security Policy) lets your browser connect to the website itself only. The exceptions are described under quake2vault.app and mime-inspector.dev.
Links to other services (for example GitHub, LinkedIn, Xing or articles) are ordinary links. Only when you follow one does your browser connect to the other provider; its own privacy policy applies there.
Domains and certificates
The name servers of all domains are run by Cloudflare, Inc. (USA). Cloudflare only answers the question at which address the servers can be found; the websites’ traffic does not pass through Cloudflare. This question is usually asked not by your browser but by the DNS resolver of your internet provider or your device.
The certificates for the encrypted connection are issued by Let’s Encrypt. No visitor data is involved.
If you write to me, I process your email address, your name if you give it, and the content of your message in order to reply: to prepare or perform a contract (Art. 6 (1) (b) GDPR), otherwise on the basis of my legitimate interest in answering enquiries (Art. 6 (1) (f) GDPR). I do not pass your message on without your consent and delete it once it is no longer needed and no statutory retention obligation applies.
The address mail@kosche.wtf and its mailbox are hosted by ALL-INKL.COM - Neue Medien Münnich, owner René Münnich, Hauptstraße 68, 02742 Friedersdorf, Germany, which runs them on my behalf (Art. 28 GDPR).
Contact form
The legal notice of every website has a contact form. What you enter there (name, email address, message) is shown back to you by the service behind it before it is sent; only when you send it does the service email it to my mailbox, and I process it like an email to me (see Email). The service runs on my servers at Hetzner. Until the mailbox has accepted the message it is kept there, usually for seconds only; not after that. If the mail server refuses a message for good (as spam, for example), it is kept there for at most 30 days so that I can still read it, and then deleted.
So that nobody misuses the form in bulk, the service counts how many messages came from one connection in the last hour. For that it keeps a hash of your IP address, made with a secret key, in memory for one hour, never on disk and never in a log (Art. 6 (1) (f) GDPR; my legitimate interest is keeping the form reachable and free of spam). The form sets no cookie, loads nothing from third parties and needs no JavaScript.
The individual websites
What concerns one website only, in addition to everything above.
kosche.wtf
My practice: my work, my offers and how to hire me. The site remembers in localStorage that you closed the one-time language hint (kosche_lang_hint). Hidden effects that you switch on yourself, such as sound or animations from the command palette, remember their settings in localStorage or sessionStorage (keys starting with kosche).
A service worker keeps pages and files of this website in your browser’s cache so that they load faster and also work offline. It stores files from kosche.wtf itself only.
kosche.dev
The tools. The scanner examines texts and files that you paste, drop or choose entirely in your browser; they are not uploaded. It loads its sample files from kosche.dev itself.
The passkeys of all websites belong to kosche.dev. It serves the list of permitted websites and the sign-in for browsers that cannot ask for a passkey from another website (see The passkey door).
kosche.ai
The research: the paper Marked with its figures and print editions, all served by kosche.ai itself.
The archive (kosche.ai/archive/) keeps documents that providers of AI models have published about their models (model cards, system cards, reports), as original files with information about their origin. It shows them as the providers published them; they may contain the names of the people involved. The files are stored on my servers and are compared with the source archive on GitHub every 30 minutes; no visitor data is involved. When you compare two versions, the archive remembers the result in your browser’s storage (IndexedDB kosche-archive).
If a document names you. If you are named in an archived document and do not want to be, write to me at mail@kosche.wtf. I will then make your name unreadable in the version the archive shows, or take the document out. The legal basis for the archive is my legitimate interest in keeping published documents unchanged and verifiable (Art. 6 (1) (f) GDPR); you may object to this processing (Art. 21 GDPR).
kosche.app
Currently a page that introduces the tools and leads to them. It processes nothing beyond what every page request involves.
kosche.io
Currently a page that describes the feeds and the interface. The archive’s feeds (catalog.v1.json and models.v1.json) contain information about the archived documents and the models, no information about visitors. Fetching them is processed like any other page request.
kosche.sh
Currently a page that describes the kosche command. It processes nothing beyond what every page request involves.
kosche.cloud
How KOSCHE is built: yard and the machines. The site processes nothing beyond what every page request involves.
yard.kosche.cloud, slip.kosche.cloud
My internal tools: yard’s bench and Slip. Only I use the bench; Slip is not open to everybody yet, and what is said below about Slip’s visitors applies once it is.
yard.kosche.cloud. The bench signs me in with a passkey and sets its own cookie for it, yard_session: a random session identifier with a signature, HttpOnly, Secure, SameSite=Lax, valid for 30 days from signing in. For each session yard stores the IP address, the first 120 characters of the browser identifier and the device derived from it, so that I can see where I am signed in. A session is deleted when I sign out, otherwise shortly after its 30 days run out; backups of the database are deleted after 90 days. Messages to my own devices go through their push services (Apple, Google) and through ntfy.sh; they are about yard, not about visitors.
slip.kosche.cloud. With Slip I have a single web page written from a short description. The description goes to a language model service of Hetzner; the page appears publicly at its own address below slip.kosche.cloud, and a public repository on GitHub keeps the description and the page. After 30 minutes Slip deletes the page and the repository unless I explicitly keep them. The pages set no cookies and load nothing from other servers: Slip refuses a page that embeds files from other servers, and every page carries a security policy (Content Security Policy) that forbids your browser any connection to another server. Anyone who opens such a page is processed as with any page request (see Page requests and logs).
How Slip writes and checks. Pages are written by a language model on Hetzner’s language model service. For a website of several pages, a second model then reads every page against its plan: for that, the description, the text of every page and two screenshots of it go to the Gemini API of Google LLC (USA), on its free tier. On the free tier Google’s terms allow it to use the content to improve its services too, and people at Google may read it; Google is itself responsible for that use, and how long it keeps the content for it is set by Google’s terms for the Gemini API; so write nothing in a description that should not become public (the page and the repository are public anyway). When Gemini cannot be reached, Workers AI by Cloudflare, Inc. (USA) checks instead, with one screenshot per page. When neither can be reached, Slip checks with its own measurements only and says so.
With your own key. If you enter your own API key for OpenAI, Anthropic, Google or OpenRouter under “Use your own model”, your description, pages and screenshots go to that provider, on your own account and under its terms. The key stays in your browser’s storage (localStorage) and is sent only when you launch, encrypted over TLS. Slip uses it for that one page’s calls, neither stores nor logs it, and forgets it as soon as the page is done. “Forget my keys” deletes it from your browser.
How often. So that the free way lasts for everybody, Slip counts how many pages are launched from the same IP address in a day. For that it keeps only a hash of the address and a random value it makes anew at every restart, in memory; at the change of day (UTC) or a restart the count is gone. Launches with your own key are not counted. The legal basis for writing and checking is that you ask Slip to (Art. 6 (1) (b) GDPR). That I use Gemini’s free tier for checking, on which Google may use the content itself too, rests on my legitimate interest in offering Slip free of charge (Art. 6 (1) (f) GDPR); so does the count, which keeps the free way open to everybody.
Slip itself stands behind a passkey door of its own, whose cookie slip_kosche_cloud is like the door’s above (30 days, HttpOnly, Secure, SameSite=Lax). Slip sets a second cookie, slip_key, only when a link carrying the key yard uses to operate it is opened; it is valid for one year. Slip writes no access logs and keeps descriptions and histories in memory only.
kosche.me
My card. The contact file (/daniel.vcf) contains my contact details; nothing about you is added when you download it. If you choose a language, the page remembers your choice in localStorage (kosche-lang).
quake2vault.app
Quake II in the browser. Saves, settings and game files you import stay in your browser’s storage (origin private file system, IndexedDB, the service worker’s cache, localStorage and sessionStorage), and so does your answer about error reports (quake2-vault-reports). The site itself sets no cookies; the only one is the passkey door’s.
Start and error reports, only if you want them. The page can tell me whether the game starts and why it fails, but only if you turn that on: with the switch on the About card, or in answer to the question the page asks once, the first time something goes wrong. Until you agree, no report leaves your browser; a fault from before is held in memory only and sent with your yes. Turned on, it sends to api.quake2vault.app once per page load that the game has drawn its first frame, and every fault at start or in the page’s script, at most eight per page load. A report contains the kind of event, the chosen game and the version of the page; for an error also the first line of the error message, the top lines of the call stack and the last, shortened lines of the console, which may exceptionally contain something you typed in the game, such as a player name. The page assigns no identifier for this. If your browser signals “Do Not Track” or “Global Privacy Control”, it does not ask and sends nothing, and the same goes with ?beacon=0 in the address.
The reports are received by a service I run at Cloudflare, Inc. (USA) (Cloudflare Workers and Durable Objects). It groups them by kind of fault: count, first and last occurrence, affected versions and games, and the newest report as an example. A kind of fault that has not occurred for 90 days counts as expired and is deleted when the next report arrives. I copy individual examples into the project’s non-public task list to fix the fault. Cloudflare sees your IP address in the process. The logs Cloudflare otherwise keeps of every request to the service are switched off, and the line the service itself writes for each report contains no IP address. If a request to this service fails, your browser may report that to Cloudflare (Network Error Logging).
Multiplayer and pairing. When you host a game, join one or pair a phone, the page connects to the same service (wss://api.quake2vault.app). It keeps the room code, the connection and the game in memory only while the room is open; the codes of open rooms can be read publicly. Paired devices then exchange the game data directly with each other.
The legal basis for the reports is your consent (Art. 6 (1) (a) GDPR), which you can withdraw at any time with the same switch; for multiplayer and pairing, my legitimate interest in offering the function you use (Art. 6 (1) (f) GDPR). Cloudflare processes the data on my behalf (Art. 28 GDPR); for the transfer to the USA see Recipients and third countries.
mime-inspector.dev
MIME Inspector takes apart emails that you paste, drop or choose entirely in your browser; a message never leaves your device. The app also explains what it does in detail in its own privacy notice.
Only on your explicit click does anything go out. Live DNS checks, which you switch on in the settings and then start per message, look up names from the message (the sender’s domain, its DMARC and DKIM records and the reverse name of the delivering IP address) at Cloudflare, Inc. (USA) via DNS over HTTPS, without cookie and without referrer; the app shows the names before you click, and Cloudflare sees your IP address. Remote images in an HTML message are loaded only when you allow them for that one message, and the servers are named first; those servers then see your IP address and browser identifier, and such an image can tell the sender that the message was opened.
Settings, bookmarks (with the message’s source), notes and investigations stay in your browser’s storage (localStorage, sessionStorage and the service worker’s cache). The legal basis for the lookups and the images is your consent, which you give with the click, each time for that one message only (Art. 6 (1) (a) GDPR).
Recipients and third countries
I process the data from running the websites myself, on the servers at Hetzner in Germany. My processors are Hetzner for hosting and for the language model service Slip uses, ALL-INKL.COM for the mailbox and Cloudflare for the service behind api.quake2vault.app and for Workers AI, which Slip checks with when Gemini is out. Google receives descriptions, pages and screenshots for Slip through the Gemini API’s free tier and may use them for its own purposes under its terms (see yard.kosche.cloud and slip.kosche.cloud); with your own key they go to the provider you chose. Beyond that I pass on no data unless a law obliges me to.
Delivering the websites transfers no data to countries outside the European Union. Cloudflare, Inc. (USA), as name server, only answers the question of the servers’ address (see Domains and certificates). Cloudflare also carries quake2vault.app’s reports and multiplayer network, and the DNS checks you start yourself in mime-inspector.dev. For Slip, descriptions, pages and screenshots go to Google LLC (USA) and, as the fallback, to Cloudflare. With your own key they go to the provider you chose: OpenAI, Anthropic, OpenRouter and Google are based in the USA. That transfer happens only because you ask for it with your key, and is necessary to do what you ask Slip to do (Art. 49 (1) (b) GDPR). Cloudflare and Google LLC are certified under the EU-U.S. Data Privacy Framework; a transfer to the USA rests on the European Commission’s adequacy decision (Art. 45 GDPR). Images you allow in mime-inspector.dev come from servers the message’s sender chose, possibly outside the European Union.
Your rights
You have the right of access (Art. 15 GDPR), rectification (Art. 16), erasure (Art. 17), restriction of processing (Art. 18) and data portability (Art. 20). Where processing is based on my legitimate interest, you may object to it at any time on grounds relating to your particular situation (Art. 21). To do so, write to me at mail@kosche.wtf.
You may also lodge a complaint with a data protection supervisory authority (Art. 77 GDPR). The authority responsible for me is the State Commissioner for Data Protection of Lower Saxony:
Der Landesbeauftragte für den Datenschutz Niedersachsen
Prinzenstraße 5
30159 Hannover
lfd.niedersachsen.de
There is no automated decision-making and no profiling. You are not obliged to give me any data; without the technically necessary data of a page request, however, I cannot deliver a page to you.
Changes
I adapt this policy when something changes about the websites or the processing. The version on this page applies; the date above gives its state.