Privacy
What this instance stores, in which form, and for how long. This page is generated from the server's running configuration, so the settings below are the ones actually in effect.
Current settings
@if(pv.ip_mode === 'hashed')IP addresses are logged, but only ever written to the database as HMAC-SHA256(ip, server_secret). The raw address is not persisted.@endif
@if(pv.ip_mode === 'raw')IP addresses are logged and written to the database in plain text.@endif
@if(pv.ip_mode === 'off')IP addresses are not written to the database. They are only held in memory while a request is processed (e.g. to check bans and rate limits).@endif
Retention
A cleanup job runs hourly and deletes or blanks data older than these periods.
user_ips rows deleted; IP columns on sessions, anonymous identities, uploads, comments, reports and ToS acceptances set to NULL.IP addresses
The client IP is taken from the first of CF-Connecting-IP, True-Client-IP, X-Client-IP, X-Real-IP, X-Forwarded-For (first entry) or the TCP peer address.
With IP logging on, the IP is recorded @if(pv.hash_ips)as an HMAC@else in plain text@endif in:
user_sessions.ip: updated on each request of a logged-in sessionuser_ips: one row per account and IP with first/last seen timeanon_identities.created_ip / last_ipandanon_activity_log.ipfor anonymous identitiesitems.uploader_ip,comments.ip,reports.reporter_ip
Hashing: HMAC-SHA256 keyed with a server-side secret, stored as 64 hex characters. The same IP always yields the same hash, which is what makes bans and abuse correlation work; without the secret the hash can't be reversed or recomputed. This is pseudonymisation, not anonymisation: whoever holds the secret could test candidate IPs against it.
Always, regardless of the logging setting: login and registration attempts store an HMAC of the IP in login_attempts for brute-force rate limiting, and a moderator ban stores the banned IP's hash in banned_ips.
Anonymous login (WebAuthn passkey)
No email, password or name is involved. Login as Anonymous creates a standard WebAuthn passkey in your authenticator (browser, OS, Bitwarden, iCloud Keychain, …).
Registration
- The server sends creation options: relying party
{{ pv.domain }}, a random single-use challenge, algorithm ES256 (ECDSA P-256, COSE-7),attestation: "none", and a user handle of 16 random bytes namedanon@{{ pv.domain }}/ "Anonymous". Nothing about you goes into it. - Your authenticator generates a key pair. The private key never leaves the authenticator.
- The server verifies the response and stores: the credential ID, the public key (SPKI), the signature counter, and the authenticator's AAGUID (identifies the authenticator model, e.g. a password manager; with attestation "none" it is often all zeros).
- Your identity is derived from the credential ID:
SHA256:base64(SHA-256(credential_id)); the account name isanon_plus the first 8 hex characters of that hash (e.g.anon_1ad1e20c).
Login
The server issues a random single-use challenge; your authenticator signs it with the private key and the server verifies the signature with the stored public key. Up to 4 passkeys can be attached to one identity. If all of them are lost, the identity cannot be recovered: nothing else links it to you.
Device fingerprint
At anonymous login and when adding a passkey, your browser computes a device fingerprint used only for ban enforcement (so a banned user can't just create a new identity). It is not used for advertising or cross-site tracking.
Inputs, all read locally in your browser:
- WebGL: unmasked GPU vendor and renderer, 6 capability limits (max texture/renderbuffer size, vertex attribs, uniform/varying vectors, texture units)
- WebGPU adapter info (architecture, vendor, description), where available
navigator.hardwareConcurrency,deviceMemory,platform,maxTouchPoints- Screen width × height, colour depth, device pixel ratio
- Canvas 2D: checksum of a small rendered test image (text + shapes)
- Audio: sum of samples from an
OfflineAudioContextrendering a test tone through a compressor
The values are concatenated and hashed in the browser with SHA-256; only HW:<64 hex> is sent. The raw values never reach the server. The hash is cached in localStorage (f0ck_anon_hw_fp) and stored server-side in anon_identities.hw_fingerprint and the activity log, and compared against banned device hashes.
Anonymous activity log
anon_activity_log records these actions of anonymous identities: login/session handshake, favourite, unfavourite, favourites import. Each row holds the action, target item, time, identity fingerprint, device fingerprint, and the IP @if(pv.ip_mode === 'hashed')(hashed)@endif @if(pv.ip_mode === 'off')(empty, as IP logging is off)@endif. It exists for moderation and ban cascades.
Sessions, cookies and browser storage
sessioncookie: 32 random bytes; the server stores only its SHA-256, so a database leak doesn't expose usable sessions. Flags:HttpOnly,SameSite=Lax@if(pv.https),Secure@endif.- Per session the server keeps: user agent string, creation time, last-used time, the last path requested, a CSRF token@if(pv.log_ips), and the IP@endif.
localStorage: UI preferences, and for anonymous users the device fingerprint hash.f0ck_bannedcookie /f0ck_anon_tombstone: only set if you are banned, to show the ban notice.
Registered accounts: passwords are hashed with scrypt (random 16-byte salt, 64-byte key). The plain password is never stored.
Not collected
For anonymous identities: no email, real name, phone number or password. No third-party analytics, trackers or ad networks are involved in authentication.
Questions? See About@if(mail) or write to {!! mail !!}@endif.