---
title: "Identity Without Secrets in the App"
slug: "chapter-14-identity-without-secrets-in-the-app"
kind: "chapter"
order: 15
label: "Chapter 14"
chapter: 14
part: "The Client Layer"
partLabel: "Part IV"
partNumber: 4
epigraph: "The application that never held a secret is the application that cannot leak one."
summary: "Every application an institution builds or buys has to answer the same question: who is this, and what are they allowed to do? Answer it badly and the institution ends up with credentials scattered…"
words: 1160
topics:
  - "Two kinds of credential"
  - "The hosted sign-in hand-off"
  - "Why the organization's key never reaches the client"
  - "Organizations, switching and visiting"
  - "Native shells and the system browser"
  - "The threat model, honestly"
---

Every application an institution builds or buys has to answer the same question: who is this, and what are they allowed to do? Answer it badly and the institution ends up with credentials scattered across code, configuration files and laptops. Answer it once, in a shared identity layer, and a new application can be built in a day by someone who never touches a secret. This chapter describes the design that makes the second outcome the default.

## Two kinds of credential

Start by separating two things that are usually confused.

A **session token** represents a signed-in person. It carries exactly that person's permissions in exactly their organization. It is short-lived, it expires, and it is refreshed by signing in again. If it leaks, the attacker is that one person for a short time.

An **organization credential** represents the institution itself. It has administrative authority over an organization's agents, users and data. It lives until someone deletes it. If it leaks, the attacker is the institution.

The entire design follows from where each of these may live. Session tokens live with the person, in the client they are using. Organization credentials live on a server the institution controls, and nowhere else. No client, web, browser extension, desktop or mobile, ever holds an organization credential. A platform that hands a client an organization key, even "just for the demo," has already failed.

## The hosted sign-in hand-off

The mechanism that delivers a session token to a client without the client ever seeing a password or a secret is a hand-off through a hosted sign-in service.

An application that needs a signed-in user does not show a password form of its own. It redirects the person to the platform's sign-in service, carrying one piece of information: where to return to, an origin the organization's administrator has placed on an allow-list. The sign-in service authenticates the person, by password, by the institution's single sign-on, by Google or Apple, however the organization has configured it, and returns the person to the application with a bundle of session material: user-scoped tokens with expiry times, the person's profile, and the list of organizations they belong to.

The application stores that bundle locally, scoped to its own origin, and uses the tokens on every request. When they expire, the application sends the person back through the same hand-off. The application never saw a password. It never held anything with more authority than the person in front of it. And the sign-in flow, the one piece of security-sensitive code in the whole system, exists in one place, maintained by the platform, and shared by every client.

The practical consequence is the one the chapter title promises. A team building a new application, for a department, for a semester, for an experiment, mounts the platform's sign-in component and a session provider, lists their application's origin with the administrator, and has working single sign-on with roles and organization scoping in an afternoon. They wrote no authentication code and they hold no secret.

## Why the organization's key never reaches the client

Some applications need to act as the organization rather than as a person: a nightly job that reads every agent's analytics, a service that provisions users, an integration that another system calls. Those need the organization credential.

The rule is that such code runs on a server. The credential lives in the server's environment, is read by the server, and is never sent to a browser or a device. The platform's own client library enforces this by construction: the function that returns the organization key returns an empty value when it runs in a browser, so a developer who tries to use it in client code gets nothing rather than a leak.

A server route therefore acts in one of two ways. As the person, by forwarding the session token the browser sent and letting the platform verify it. Or as the organization, with the credential from its own environment. Each path is explicit; neither leaks into the other.

## Organizations, switching and visiting

Real institutions are not one organization. A university system has campuses; a company has subsidiaries; a consortium has members. A person may belong to several and may visit others.

The identity layer carries, with each session, the list of organizations the person belongs to and which one is current. An application that needs to operate in a different organization re-authenticates for it, receiving a fresh token pair scoped to that organization. A person opening an agent that belongs to an organization they are not a member of is a visitor: they may reach it if its visibility allows, and organization-scoped calls that the agent would normally make are refused. All of this is handled by the shared session provider; an application built on it inherits the behaviour.

This matters to a CIO for a specific reason. Multi-organization support is where home-grown identity goes wrong, and it is the area where a leaked token does the most damage. Having it solved once, in a component every client uses, removes an entire category of incident.

## Native shells and the system browser

Mobile and desktop shells complicate the hand-off, because single sign-on providers refuse to run inside an embedded web view. The platform's answer is to open the sign-in service in the system browser and return to the application through a registered scheme, the same pattern the operating systems themselves recommend. A desktop build can also be locked to one organization at build time, so that an institution's own build of the application never shows anyone another organization's sign-in.

The browser extension from the next chapter uses the browser's own identity API for the same hand-off, which is why it needs no password form and holds no secret either.

## The threat model, honestly

Session tokens in a client are exposed to one thing: code running on that client's origin. A cross-site scripting flaw in an application built on the platform would let an attacker read that application's tokens and act as the signed-in person until they expire. This is the standard exposure of every web application that keeps a session, and the mitigations are standard: a strict content security policy, short token lifetimes, no third-party scripts on sensitive origins, and the one rule this chapter has repeated, that nothing with more authority than the person ever reaches the client.

What the design removes is the catastrophic case. There is no organization key in any client to steal. There is no password form in any application to phish. There is one sign-in flow to audit instead of fifty. And the application a department built last week is exactly as secure as the platform itself, because it reused the platform's identity rather than inventing its own.

The next chapter takes the hardest client, the browser extension, and shows how these guarantees hold when the agent is reading and acting on whatever page a person happens to have open.
