Documenting Your One Deliberate Exception to Your Own Security Rule

Photo Cleaner's rule is that it never stores a Google credential. Rendering private thumbnails from lh3.googleusercontent.com needed exactly one narrow, named exception — and it belongs in the README, not buried in a diff.

Documenting Your One Deliberate Exception to Your Own Security Rule

The central design rule for this app is simple to state: it never stores a Google credential, and every API call is made by the WebView page rather than by app code. I believe that rule, and the app mostly holds to it exactly. "Mostly" is doing real work in that sentence, and I'd rather say so plainly than let someone find the exception by reading App.kt themselves and wondering what else isn't documented.

One rule, one documented exception
One rule, one documented exception

The rule holds everywhere except one narrow, named, unavoidable case.

Why thumbnails are the exception

Photo thumbnails live on lh3.googleusercontent.com, and they are private to your account. A browser tab loads them successfully only because it automatically attaches your Google session cookie to the request — that's just how a private image host works. A plain HTTP client, with no cookie, gets nothing back, and the image renders as a blank card. For an app whose entire interface is a deck of photo thumbnails, a blank card for every photo is not a workable trade-off.

What the exception actually does

In App.kt, the Coil image loader is configured with an OkHttp interceptor that, for Google media hosts only, reads the session cookie out of the WebView's own CookieManager at request time and attaches it to that one outgoing request:

private fun isGoogleMediaHost(host: String): Boolean =
    host.endsWith(".googleusercontent.com") ||
        host.endsWith(".ggpht.com") ||
        host.endsWith(".google.com")

if (isGoogleMediaHost(request.url.host)) {
    val cookie = runCatching {
        CookieManager.getInstance().getCookie(request.url.toString())
    }.getOrNull()
    if (!cookie.isNullOrEmpty()) builder.header("Cookie", cookie)
    builder.header("Referer", "${GPhotosSession.ORIGIN}/")
}

Three things make this narrower than it might sound:

  1. Scoped to Google media hosts. The isGoogleMediaHost check means the cookie is never attached to a request going anywhere else.
  2. Read, not copied. The cookie is fetched from the WebView's jar at the moment of the request. It is never written into app storage, the database, or a log line.
  3. Nothing is retained. Once the request completes, the app holds no reference to the cookie value.

Why call it out instead of letting it slide

It would have been easy to leave "the app never stores a Google credential" as an unqualified claim in the README and let this detail live quietly in a comment in App.kt. I think that's the wrong instinct for a security claim that people might actually rely on when deciding whether to sideload this app onto a phone with their real photo library.

The README states the exception explicitly, right next to the rule it narrows: "One deliberate exception, worth knowing about... This narrows the original guarantee and is called out here rather than buried." That sentence costs nothing to write and changes what the guarantee actually means for someone deciding whether to trust it.

The general principle

Absolute security claims that turn out to have quiet exceptions are worse than qualified claims that name their exceptions up front. The first kind erodes trust when someone finds the gap themselves — and for an app handling this much account access, someone reading the source is not a hypothetical threat model, it's a certainty. The second kind is what a security-literate user actually wants to see: not "we never touch a credential," but "here is the one place we do, here is exactly what it does, and here is why it can't be avoided."

If your design has exactly one deliberate exception to a rule, the fix isn't to eliminate the exception at all costs. It's to make it small, scoped, non-persistent, and impossible to miss in the docs.

Series: Google Photos Cleaner.