C.W.K.
Stream
Lesson 04 of 04 · published

Reduce Capability, Never Authentication

~13 min · firelink, read-only-lock, device-scoped, path-traversal

Level 0Cold Ash
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Turning off what a session can do is not the same as turning down how sure you are who it is."

The Launcher Credential Is Scoped Down, Not Trusted Less

After the family PIN is approved, the Native Launcher receives a device-scoped, read-only catalog credential. It can read the launch catalog and it can write exactly one thing: its own device-local recents and favorite flags. It cannot call any mutation endpoint, and its writes never touch repositories, services, or another principal's preferences. This is capability reduction done cleanly — the launcher is fully authenticated (it went through the PIN), it's just scoped to a tiny, harmless surface. Strong identity, small power.

A Read-Only Lock Is Orthogonal to Auth

The same idea gives travel a safe browsing mode. A revocable Web read-only lock disables all mutations for a session — useful when you just want to look around from a hotel, or hand someone a sightseeing view — without weakening authentication at all. The lock lowers what the session can do; it doesn't lower how sure the system is about who the session is. Those are two independent dials, and conflating them is a common mistake: 'read-only' should never be implemented as 'less authenticated.' You can be fully verified and deliberately powerless at the same time.

Secrets and Static Files Stay in Their Lanes

Two hygiene rules finish the contract. First, secrets — credentials, command output that contains secrets, session tokens — never enter API responses, audit detail, logs, or the launcher cache. A secret that never travels can't leak in transit or at rest on a device. Second, static files are served only from the declared build root, and the single-page-app fallback returns the application shell, not an arbitrary filesystem candidate — so a crafted path can't walk out of the build directory and read something it shouldn't. Both are the same instinct: keep dangerous things confined to exactly where they belong.

Treat 'what a session can do' and 'how sure you are who it is' as independent dials — reduce capability freely, but never dress capability reduction up as weaker authentication. A read-only, fully-authenticated session is safe; a 'read-only because less-verified' session is a downgrade an attacker will happily accept on your behalf.

Code

Scoped-down power, unchanged identity; secrets never travel·typescript
type LauncherCredential = {
  deviceId: string;
  authenticated: true;          // went through the family PIN — fully verified
  scope: "read-only-catalog";   // reads the catalog...
  mayWrite: ["own-recents", "own-favorites"];  // ...writes ONLY its own device state
  // No mutation endpoint. Never touches repos, services, or others' prefs.
};

type WebSession = {
  authenticated: true;          // auth strength is a SEPARATE dial...
  readOnlyLock: boolean;        // ...from this capability dial (travel/sightseeing)
};
// read-only lock disables mutations WITHOUT weakening authentication.

// Hygiene, always: secrets/tokens/secret-bearing output NEVER appear in
//   API responses | audit detail | logs | launcher cache.
// Static served only from the declared build root; SPA fallback = app shell,
//   never an arbitrary filesystem path.

External links

Exercise

Find a 'read-only mode' or 'guest view' in a system you know. Check whether it's implemented as reduced capability on a still-fully-authenticated session, or whether 'read-only' quietly means 'less logged in / weaker check.' If the latter, describe the downgrade an attacker could prefer. Separately, look at any static-file or download endpoint: can a crafted path read outside its intended directory?
Hint
The dangerous pattern is 'read-only' sessions that skip some auth step because 'they can't do anything anyway.' Keep the authentication identical and remove only the write capability. And for files: the fix is always to resolve the path and confirm it's still inside the allowed root before serving.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.