Why architecture matters here
The architecture matters because it changes the trust model from 'anyone a CA vouches for' to 'exactly the keys I chose,' and that shift is the entire security value. Standard TLS answers the question 'did a trusted authority sign this?' Pinning answers the far stricter question 'is this the specific server I have talked to before?' For a mobile banking app or an API client that only ever talks to your own backend, the second question is the one that matters, because you have no reason to accept a certificate from any authority for a server you already know. Narrowing trust to a key you pinned removes an entire class of CA-compromise and mis-issuance attacks in one stroke.
It matters because the threat it addresses is not hypothetical. Corporate TLS-inspection proxies, nation-state interception, breached intermediate CAs, and malware that installs its own root certificate all produce the same situation: a certificate that chains to a 'trusted' root but is not yours. Every one of those attacks is invisible to normal validation and is stopped cold by a pin, because the attacker cannot make their key hash to a value you baked into the binary. Pinning is one of the few controls that meaningfully raises the bar against an adversary who can obtain fraudulent-but-valid certificates.
It matters because what you pin is an architectural decision with long consequences. Pinning the whole certificate is brittle — it breaks on every renewal even when the key is unchanged. Pinning the Subject Public Key Info (SPKI) is the industry norm, because the same key survives certificate renewals, so you can renew freely as long as you reuse the key, and you only touch the pinset when you actually rotate the key. Pinning too high in the chain (an intermediate or root) is safer against outages but weaker security; pinning the leaf is strongest but demands the most operational care. The choice trades survivability against strictness, and you must make it deliberately.
Finally, it matters because pinning couples your client release cycle to your key management, and getting that coupling wrong is how pinning causes outages instead of preventing breaches. A pinset embedded in a shipped mobile binary cannot be changed without an app-store release that can take days to roll out and that users may never install. That reality forces the whole design around it: you must pin backups, you must be able to update pins remotely through a signed channel, and you must have a way to disable pinning in an emergency. The security benefit is real, but it is only worth taking if the operational architecture around rotation and recovery is built first.
The architecture: every piece explained
Start with the app and its pinset. The pinset is a small list of SHA-256 hashes, each computed over a certificate's Subject Public Key Info — the DER-encoded blob that holds the public key and its algorithm. Hashing the SPKI rather than the raw certificate is the crucial detail: two certificates issued a year apart for the same key produce the same SPKI hash, so a routine renewal does not invalidate the pin. The pinset ships with the app, ideally delivered as signed configuration rather than a hardcoded constant so it can be updated without a full binary release.
When the client opens a connection, the TLS handshake proceeds normally and the server presents its certificate chain. Before pinning does anything, the platform performs standard validation: it checks that the chain builds to a trusted root, that nothing is expired or revoked, and that the leaf's names match the hostname. Pinning never replaces these checks — a common and dangerous mistake is to pin while accidentally disabling hostname or trust validation, which leaves you worse off than before.
Only after the chain passes does the pinning gate run. The client extracts the SPKI from each certificate in the presented chain, hashes it with SHA-256, and compares against the pinset. The match is deliberately permissive about position: if any certificate in the chain — leaf, intermediate, or a pinned CA — matches any hash in the pinset, the check passes. That any-of-set logic is what makes backup pins work: you can list the current key and one or more future keys, and a chain presenting either is accepted.
The outcome forks sharply. On a match, the session proceeds and application data flows as normal. On a mismatch, the connection is aborted immediately — critically, before any application data is sent, so a man in the middle never receives the request body or credentials. This fail-closed behavior is the whole point, but it is also the source of every pinning outage, which is why the two supporting boxes exist.
The backup pin is a hash of a key you have generated but not yet deployed, staged in the pinset ahead of any rotation so that when you finally switch to the new key the already-installed clients keep working. The failure report path turns rejections into telemetry: the client posts pin-validation failures to a report endpoint or your own analytics, so you learn about a misconfiguration or an attack in the field instead of only from support tickets. The bottom ops strip names the disciplines — overlapping rotation, a remote kill-switch, monitoring, and signed pin delivery — that keep the whole mechanism from becoming a self-inflicted outage.
End-to-end flow
Walk a single request. The user launches the app, which already holds a pinset delivered with its last signed configuration update. The app initiates a TLS connection to the API host and completes the cryptographic handshake up to the point where the server has presented its certificate chain: a leaf for the hostname, one or two intermediates, chaining to a public root.
The platform's TLS stack validates that chain in the ordinary way — builds the path to a trusted root, confirms none of the certificates is expired or revoked, and checks that the leaf's Subject Alternative Names cover the hostname being contacted. If any of that fails, the connection dies here for the usual reasons and pinning is never consulted. Assume it all passes.
Now the pinning layer takes each certificate the server sent, pulls out its SPKI, computes the SHA-256 hash, and base64-encodes it into the same canonical form the pinset uses. It walks the pinset looking for any equal value. Suppose the leaf's key was rotated last week: the leaf hash is not in the pinset, but the backup pin you staged two releases ago is that key's hash, so the comparison finds a match on the leaf and the gate opens. The handshake completes and the request is sent over the now-trusted channel.
Contrast the attack case. A corporate proxy or a piece of malware intercepts the connection and presents a certificate that chains to a root the OS trusts — perhaps one the malware itself installed. Standard validation passes, because the certificate is technically valid for the hostname under a trusted root. But the proxy's key hashes to a value that is nowhere in your pinset. The comparison finds no match, the client aborts the connection, and because the abort happens before application data is transmitted, the interceptor learns nothing beyond the fact that a connection was attempted. The client, meanwhile, fires a pin-failure report so your telemetry shows a spike from that network.
The rotation flow is the third path to understand. Weeks before you plan to switch keys, you generate the new key pair, compute its SPKI hash, and add it to the pinset as a backup — pushed to every client through signed remote config. Clients now accept either the current or the future key. Once you have confirmed the new pin is deployed broadly enough, you cut the server over to the new certificate. Existing clients keep working because they already trust the new key; only then do you retire the old pin in a later config update. The overlap window is what turns a rotation from a cliff into a smooth handoff.