tfpdev
4.6Part 4 · Links

The Link That Never Dies

Someone who left the project can still open an old link to a file. One kind of link works for anyone, forever. The other works for 10 minutes, only for the right person, and stops the moment their access is removed.

01Try it

Vlas sent the freelancer a link to a project file. There are two kinds: a plain one, and one that lasts 10 minutes and only works for them. See what happens to each as the project goes on and ends.

A message from the project

Vlas Koerbatski to the freelancer:“Here's the proposal, have a look before Thursday.”

Change a character in either link first, if you like.
What happens next
Whoever has it, gets in

Press a step to see what happens.

Checks every time it's clicked

Press a step to see what happens.

Real: the signature, the time limit and the database check. Simulated: step 3 moves the clock instead of making you wait 11 minutes.

02Step 2

What happened every time

Each thing was tried on a fresh pair of links. Yellow means the file opened.

What happenedPlain linkSigned link
1. The freelancer opens it200200
2. They forward it to a friend200403
3. Eleven minutes later · simulated clock200410
4. The project ends, access removed200403
5. Someone changes the link200400
Made-up links—0 / 1,000 opened
03Step 3

What actually happened

The plain link never said no

Forwarded, later, after the project ended, even changed to point at a different file: it opened every time. Taking away the freelancer's access did nothing to it.

Forwarding doesn't help

The signed link knows who it's for. Anyone else gets turned away.

Gone after 10 minutes

Long enough to open it, too short for an old copy to be any use. Need it again? Ask for a new one.

Removing access works straight away

This link was brand new and would have worked for another ten minutes. It stopped because Harbor checks, at every click, whether the access still exists.

It can't be changed

Change one character and it stops working. I made up 1,000 fake versions; 0 opened.

04Step 4

The code

What the two approaches do, in one sentence. The code itself is one click away.

The plain link is just the file's address, so whoever has it gets the file. The signed one carries who it's for and when it ends, sealed with a key only Harbor has, and Harbor checks the access still exists every time it's clicked.

Show the code anyway
BreaksPublic, forever
The path is the permission.
careless · the address is the keyts
const link = `https://harbor…/f/${project}/${encodeURIComponent(file.name)}`;// GET /f/:project/:nameconst file = await sql("SELECT * FROM files WHERE project_id = $1 AND name = $2", [project, name]);return serve(file);
The link names the file, and the handler serves whatever the link names. Nothing about who is asking, or when, or whether they still should.
HoldsSigned, short, revocable
Who, until when, still shared.
careful · signed, short, checked at the clickts
const exp = Math.floor(Date.now() / 1000) + 10 * 60;const sig = hmac(key, `${file}|${person}|${exp}|${grant}`);const link = `https://harbor…/s/${file}?for=${person}&exp=${exp}&g=${grant}&sig=${sig}`;// GET /s/:fileif (!timingSafeEqual(sig, hmac(key, `${file}|${forWho}|${exp}|${grant}`))) return status(400);if (Date.now() / 1000 > exp) return status(410);if (viewer !== forWho) return status(403);const share = await sql("SELECT revoked_at FROM link_grants WHERE id = $1 AND file_id = $2", [grant, file]);if (!share || share.revoked_at) return status(403);return serve(file);
The signature covers the file, the person, the expiry and the share. Change any of them and it stops matching. The share is looked up on every click, so revoking works now, not when the link expires.
05Step 5

Still curious?

A few more questions people ask. Open what you need.

What if the link is just very hard to guess?

Hard to guess isn't the same as private. Links get forwarded, saved and pasted around. A random link still works for anyone who has it, forever.

Why check every click?

The seal proves the link is real, not that access still stands. Checking every click is what makes removing access work straight away instead of up to 10 minutes later.

What about files they already saved?

Nothing can reach a file once it's on someone's laptop. That's why Sofie's deletion email in Chapter 3 says downloaded copies stay. Contracts cover the rest.

How does the link know who's clicking?

In the real portal it's whoever is logged in. The lab has no logins, so the demo just says who is clicking. The check is the same.

Who checks the result?

Plain code checks the links, not an AI, so the result is the same every time. The wait in step 3 is pretend: I told the check the clock was 11 minutes later.

Not sure this could happen to you?

That's what the call is for. Tell me how your product works, and I'll tell you what applies to you and what I'd check first.