Tested in Blink and WebKit.

Which browsers, and when · How all of this works

geodzkdocs

reading plane · What this is, what it keeps, and how to drive it without a browser.

Masked links

A short link whose target this service cannot read and whose maker it cannot name — and, stated as plainly, what that still leaves visible.

A masked link is a short link with three properties an ordinary one does not have: this service cannot read where it points, it cannot tell who made it, and its code carries enough randomness that the set of masked links cannot be counted by guessing at it. It lives under /x/, apart from every account's namespace.

It does not hide the destination from the person who follows it. That is the property in this space that is mostly a phishing tool, and it is not what masking means here.

How it works

  • Your browser draws a key and a code, seals the target under both, and sends only the result. The key travels in the link you hand out and is kept nowhere on this service.
  • Your dashboard finds your masked links through an index sealed under a masking key you save once, when you enroll — shown once, the way backup codes are. Every account holds an index of the same size whether it has made fifty masked links or none, so its size says neither how many nor whether.
  • A masked link has no owner. Changing or deleting it takes the manage token kept in your index — not your account, and not the link's own key, which everybody you sent it to holds.
  • A masked code cannot be renamed: the seal is bound to the code. Changing where one points is a fresh seal under the link's own key, sent with its manage token. The dashboard has no control for it: retargeting is done through the API (PUT /api/masked/{code}, in the API), by a client holding both — and your index keeps showing the old destination unless that client rewrites the index too.

Two modes

Chosen per link when you make it, because they trade different things and only you know which you need.

ModeWhat it trades
Strict — the key in the fragment, /x/code#k=…The key never leaves the browser, and the link needs JavaScript, so curl, unfurlers and no-JS clients get a page rather than a redirect. An unmodified copy of this service never holds the key in any form — not in a log, not in memory. (A modified one could; see the limits below.)
Compatible — the key in the path, /x/code/keyA real redirect that works everywhere, and the key reaches the server on every click, so this defends the data at rest, not the running service: a stolen disk or backup reveals nothing, but an operator who wanted to could log the key as it arrives — and so could Cloudflare, which terminates TLS in front of this service and sees every path.

The custom part

You may put a word of your own in front of the random part. It is stored in the clear, because this service routes on it — so a link named tax-return-2026 tells the operator what the sealed target is about, and undoes the thing it is attached to. This part is readable and the target is not. Sometimes a memorable link matters more; the choice is yours, and the dashboard says so where you type it.

What the operator can and cannot do

  • Can turn a masked link off, by its code, to answer an abuse report. Both of its addresses then answer the same 404 as a code that was never issued. A strict link's page is cacheable, so a copy already at the edge can keep resolving for up to 30 seconds after it is turned off.
  • Cannot see where a masked link goes, or who made it. The moderation answer and its audit row carry the code and the decision, and no target, because there is none to give.
  • Nothing is written to the audit log or to the service's own log when a masked link is made, changed or deleted, or when an index is saved. An audited "who made code X" is exactly the attribution this removes.
  • Masked links cannot be put in an orbit, so no published collection can list them: a public page would have to show a target this service cannot read.

The honest limits

  • A single copy of the database cannot say whose a masked link is; a series of copies (nightly backups, or the WAL sidecar), at a handful of users, may. An account whose index changed between two nightly copies used the feature in between, and the day it changed can be matched against the day a masked link appeared. The WAL sidecar is the -wal file SQLite keeps beside the database, and it is more precise than that: it holds writes in the order they were made, and a masked link's own write is followed at once by its maker's index write, so one copy of it pairs a link with an account, not just a day, until the WAL is overwritten. The fixed size hides how many masked links you hold, not whether you touched the feature in a given window.
  • Masked links outlive a deleted account. This service cannot know whose they were, so deleting an account cannot delete them: they stay resolvable, and because their manage tokens were in that account's index, nobody can change or delete them any more. An admin can still turn one off.
  • Lose your masking key and nobody can open your index, this service included. Your links keep working; you can no longer list or manage them.
  • Sealing and strict-mode opening use the browser's crypto.subtle, which browsers offer only in a secure context — HTTPS, or localhost. On a plain-HTTP address, such as a LAN IP, the dashboard cannot make a masked link and a strict link cannot open; the page says why. Following a compatible link needs nothing of the browser.
  • The custom part, the mode, the day a link was made and whether it is turned off are stored in the clear. What is sealed is the target.
  • A sealed target's length is hidden only to its bucket. It is padded to 256 bytes, or 512, 1024 and so on up to the longest target accepted, so the stored size still says which of those it fits in.
  • Both modes trust the page this service sends your browser. An operator who changed that code could send a strict link's key home at its next click, or read your masking key — kept on this browser until you tell it to forget, which signing out does not — at your next dashboard visit, and with it every link, key and manage token in your index. Cloudflare, which terminates TLS in front of this service, sees every compatible link's key in the path. What strict mode removes is the record: no database row, log line or backup ever holds its key.
  • Masked links are not checked against the target-host denylist (DENYLIST_HOSTS): the service is never shown a masked target when the link is made, so any account can point one anywhere the denylist would have refused.

Back to top

The same page as text, for a program: GET https://geodzk.com/api/docs/masked — needs a key holding docs:read.

Sign in · geodzk.com