2026-05-18

Expiry and Revocation: Make Unlisted HTML Links Safe to Share

Unlisted links are powerful, but they need lifecycle controls. Here is a practical checklist for expiry, revocation, caching, and noindex defaults for shared HTML artifacts.

developer toolsunlisted linksHTML artifactssecuritydeveloper workflow

Table of contents

  1. Treat share links like capabilities
  2. Add expiry as the default
  3. Make revocation and rotation a first-class action
  4. Reduce accidental leakage (cache + referrer)
  5. Keep shared artifacts out of search
  6. Fit lifecycle controls into API and MCP workflows

Treat share links like capabilities

An unlisted artifact link is not the same thing as a public web page. It is closer to an access token: anyone who has the URL can open it.

That mental model matters because it changes what “done” looks like. It is not enough to generate an HTML file and return a link. A safe sharing workflow needs a lifecycle: who can view it, how long it should exist, how it can be revoked, and what happens when the agent regenerates a newer version.

If you are evaluating tools in this space, look for a workflow that treats “publish” as a product action (not “deploy”), and that gives the owner controls without turning every artifact into a long-lived website. BinHTML sits in that narrow lane: publish an HTML artifact, review it in a sandboxed viewer, and manage the link over time.

Add expiry as the default

Most artifacts are inherently time-bound. A one-off report for a PR review should not live forever. A prototype for a stakeholder should not become a permanent public endpoint by accident.

A practical default is: every unlisted link gets an expiry unless the owner explicitly chooses otherwise. The exact retention depends on the use case, but the product posture stays the same: temporary by default, extendable when needed.

Expiry should be enforced server-side. It is not enough to hide an expired artifact in the UI if the URL still works. When the expiry time passes, the share route should stop rendering the artifact.

If you are using BinHTML project links to share a whole batch of artifacts, expiry still matters. A project share URL is a convenient index, but it should still reflect the lifecycle of the underlying artifacts.

Make revocation and rotation a first-class action

Expiry handles time. Revocation handles mistakes. You need both.

Two practical rules:

  • Revocation should be immediate and owner-controlled (disable the link and it stops resolving).
  • Rotation should be cheap (re-issue a new link without changing the artifact’s content).

If you treat unlisted URLs like capabilities, the token part of the URL must also be hard to guess. OWASP’s session guidance calls out why unpredictability matters for tokens that represent authenticated state. The same basic idea applies to share links: do not generate share URLs that are easy to enumerate.

Reduce accidental leakage (cache + referrer)

Most leaks are boring. Someone pastes a link into a ticket. A browser preloads a preview. A shared computer keeps a copy in its cache.

Two web primitives help reduce these foot-guns:

Cache-Control

MDN documents Cache-Control response directives such as no-store, private, and max-age=0 for controlling caching behavior. RFC 9111 defines the caching model more formally.

For sensitive artifacts, prefer responses that discourage storage in shared caches. If your artifact viewer supports “private” visibility, it is reasonable to be stricter about caching than for ordinary marketing pages.

Referrer-Policy

MDN documents Referrer-Policy and the default strict-origin-when-cross-origin. For unlisted artifacts, it is often worth being explicit so that outgoing navigation does not leak full paths in referrer headers.

Even if your artifacts are unlisted, referrers can still end up in logs, analytics, or third-party endpoints if the artifact contains links out to the wider web.

Keep shared artifacts out of search

Unlisted should also mean “not discoverable”. Indexing controls are part of that posture.

MDN documents both:

  • the <meta name="robots"> directives (noindex, nofollow, noarchive)
  • the X-Robots-Tag HTTP header, which can apply the same directives at the response level

In practice, you usually want both the page-level intent and the response-level header where you control it. If you are running a platform like BinHTML, you can standardize this at the route layer so every artifact and project share page stays out of public indexes by default.

Fit lifecycle controls into API and MCP workflows

The “daily driver” for many teams is not a UI click. It is an agent publishing artifacts during an automated run.

So the lifecycle controls need to be part of the publish interface:

  • Let the agent provide an expiry time when it publishes (or let the server apply a plan default).
  • Return the share URL plus the expiry and visibility state so the agent can include it in the handoff message.
  • Keep the owner controls separate from the artifact HTML so the artifact stays reviewable and sandboxed.

This is where MCP matters: it gives agent clients a structured way to call tools like “publish artifact” and receive structured results. If you are using BinHTML’s MCP server, the publish call can be part of the same run that generated the HTML, and the returned link becomes the durable reference you pass to reviewers.

If you want examples, start with API docs, MCP docs, and the earlier post on project links. For a broader security framing, see why sandboxing matters.

Final thought

Unlisted links are a great fit for AI-generated HTML, but only if you give them the guardrails they deserve. Expiry, revocation, noindex defaults, and basic leak-reduction headers are not “enterprise extras”. They are what makes sharing a generated artifact feel safe enough to become a habit.

Sources