Skip to main content

Smuggling the Archive Through the Backend

One day the archive just broke. The historical-imagery tool (UCSD's Seeker, at tools.alertcalifornia.org) had been living in a simple iframe — until UCSD, fighting off a scraping attack, blocked outside IPs. Every operator's browser was an outside IP. The iframe went dark overnight.

The fix is a classic pattern worth learning beyond this feature: a reverse proxy. If users' browsers can't reach the archive, let the server reach it on their behalf — one whitelisted IP, one set of system credentials, and an iframe that never leaves home.

How a blocked site appears inside the app

The iframe now points at our own backend — /api/archive/seeker?id=…&timestamp=… — and pages/api/archive/[...path].ts does the smuggling:

Four moves make it work, and each solves a specific problem:

1. The user still has to be our user. The proxy checks the next-auth JWT before touching anything — unauthenticated requests get a 401. UCSD sees one system identity; access control stays on our side.

2. One login, shared by everyone. The proxy signs into the archive with system credentials and caches the session cookie in memory for 55 minutes (just under its 1-hour expiry). If the archive ever answers 401/403 anyway — an expired session — the proxy clears the cache, re-authenticates, and retries once, invisibly.

3. URL rewriting closes the loop. Here's the subtle part: the archive's HTML is full of absolute URLs back to tools.alertcalifornia.org — scripts, styles, images. Served as-is, every one of those would escape the proxy and hit the blocked host. So HTML responses (and redirect Location headers) get their absolute URLs rewritten to /api/archive/..., pulling every subsequent request back through the tunnel. Non-HTML passes through untouched.

4. Same origin, fewer problems. Since the iframe now loads from our own origin, the old sandbox attribute and its cross-origin contortions were simply deleted.

Configuration

Four env vars: ARCHIVE_BASE_URL, ARCHIVE_LOGIN_URL, ARCHIVE_USERNAME, ARCHIVE_PASSWORD. The credentials come from UCSD and are server-side only — in production they belong in Key Vault, never in source control. The route is also listed in proxy.ts's protected matcher, so the auth middleware guards it like any other API path.

Wrapping up

When the archive's front door closed, the app grew a tunnel: authenticate our user, borrow one system session, rewrite every URL so nothing escapes, and serve it all same-origin. If you ever need to embed another IP-restricted tool, this file is your template.

Back to the auth deep dive — the machinery that guards this tunnel.