skip to content

Your client pins a server's key rather than trusting the whole anchor list - what exactly should the pin cover, and why?

level: seniorimportance: should knowfreq 46%

answer

  1. narrow trust from any anchor to one key
  2. digest the key, not the certificate
  3. SubjectPublicKeyInfo in DER, base64 encoded
  4. backup pin generated before the first deploy
  5. a lawful re-key still bricks the client

basics

~20 s

Pin a digest over the DER-encoded SubjectPublicKeyInfo - the public key - not a fingerprint of the whole certificate. A certificate fingerprint changes at every renewal; an SPKI fingerprint survives a renewal that reuses the key pair.

solid answer

~50 s

Pinning narrows the decision from "any anchor in the list" to "this specific key". What you pin should be an **SPKI fingerprint** - a digest computed over the DER encoding of the certificate's `SubjectPublicKeyInfo` - rather than a fingerprint over the whole encoded certificate. The reason is operational: a certificate fingerprint changes on every reissue, including a routine renewal that keeps the same key pair, so a certificate pin turns each renewal into an outage. An SPKI pin covers only the key, so it survives that renewal. It does **not** survive a legitimate re-key, which is why you configure **backup pins** - a second key you already hold and can move to - before you deploy the first one. The failure mode to respect is that pinning is a client-side refusal: if the pinned key is gone and no backup matches, the client refuses a genuinely correct server, and the fix requires shipping new client configuration.

code

http · 3 lines
http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Public-Key-Pins-Report-Only: pin-sha256="K1r9mDSk+0lUTVQpnJWRZ7mXwCk3Nz2bqQeH8oXpAaE="; pin-sha256="9Ht2vQsLd4pRmXo1YbKcJ3wEuN6zA0fTgS5iPqVrDwU="; max-age=5184000; includeSubDomains; report-uri="https://reports.example.net/pin"

go deeper

for a junior

Recall that pinning means accepting only a specific key rather than anything the anchor list would allow, and that the pin covers the public key rather than the certificate.

for a middle

Explain why the digest is taken over the DER-encoded SubjectPublicKeyInfo: a renewal that reuses the key pair leaves that structure unchanged while the encoded certificate changes.

for a senior

Show the operational discipline - backup pins generated before deployment, a known update path for client configuration, and a clear-eyed account of the outage a re-key causes.

for a principal

Decide where pinning is worth its brittleness. Weigh the narrowed trust against the update latency of the client population that will carry the pin for years.

Pinning is a deliberate narrowing of the trust decision. The ordinary decision is "did the path end at *any* entry in my anchor list?" - a list that may hold well over a hundred authorities. A pin replaces that with "and it must also involve *this* key". It is the answer to the observation that your own service never legitimately gets a certificate from an arbitrary authority. ## What is pinned, exactly The unit is a **public key**, identified by a digest over the DER encoding of the certificate's `SubjectPublicKeyInfo` structure - the field that carries the algorithm identifier and the key itself. `RFC 7469` names this the **SPKI Fingerprint** and defines it as a SHA-256 digest of that DER encoding, base64-encoded. The alternative - a fingerprint over the whole encoded certificate - is the natural first instinct and the one that fails in production: | Pinned object | Survives a renewal that reuses the key pair | Survives a re-key | Typical failure | |---|---|---|---| | whole-certificate fingerprint | no | no | outage at every renewal, including routine ones | | SPKI fingerprint over the public key | yes | no | outage at the next key change, which is rarer and plannable | The difference is not subtle: a certificate is re-signed with a new serial number and new validity dates every time it is reissued, so its fingerprint changes even when nothing about the key did. ## Which key in the path to pin A pin can name the end-entity key, an intermediate issuer's key, or the anchor's key, and the choice is a trade between precision and churn: - **The end-entity key** is the tightest and the most brittle - it changes whenever that key changes. - **An issuing intermediate's key** changes far less often and still excludes every other authority in the list, at the cost of accepting anything that issuer signs for the name. - **The anchor's key** is the loosest useful pin and mostly restates "only our own authority". `RFC 7469`'s model is that the connection is acceptable if **at least one** pinned fingerprint matches **some** key in the path the client built, which is what makes a mixed set of end-entity and issuer pins workable. ## Backup pins are not optional A pin set with one entry is a single point of failure that you built deliberately. The rule is to pin at least one key you are **not currently serving** - a generated, stored, ready-to-deploy key pair - so that a compromise or a forced re-key has somewhere to land without new client configuration. Deploying a single pin and generating the backup later means that at the moment you most need to move, you cannot. ## The outage mode, stated honestly Pinning inverts the usual risk. Everywhere else in this subject a misconfiguration means you accepted something you should not have; with pinning, a misconfiguration means you **refuse something that is completely correct**: 1. The key is compromised and must be replaced, and no backup pin matches the replacement. 2. Someone rotates the key as routine hygiene without knowing a pin exists. 3. The client configuration is embedded in something slow to update - an appliance, a field device, an image with a long refresh cycle. 4. The pin outlives the person who set it, which is the ordinary case after a year or two. In all four, the server is serving a valid, correctly issued certificate and the client refuses it. There is no server-side fix; the fix ships to clients. ## The header-based form, and its status `RFC 7469` also defines a way for a **server** to declare pins in a response, through the `Public-Key-Pins` and `Public-Key-Pins-Report-Only` header fields, carrying `pin-sha256` values plus the `max-age`, `includeSubDomains` and `report-uri` directives. It is worth knowing as the specification it is, and worth knowing for its lesson: a server-declared pin is a policy a client caches for `max-age` seconds, so an operator can lock their own users out of their own site for the remaining lifetime of that cache with no way to retract it. **Do not assume any current client enforces these header fields.** The durable form of pinning is the one you compile into a client you control, where you can also ship the retraction. ## Where pinning earns its place A client you build, talking to an endpoint you run, over a relationship that is not a general-purpose web session: a collector reporting to a historian, a device calling home, an internal agent. There the population of legitimate keys is small and known, the client ships on a schedule you control, and the narrowing is real. Pinning a third-party endpoint you do not operate, from a client you cannot update quickly, is how the outage mode above finds you.

  • A team pinned a whole-certificate fingerprint and the client broke at the next renewal even though the key never changed. Why?
    Reissuing a certificate produces a new serial number and new validity dates and re-signs the structure, so the encoded bytes differ and any digest over the whole certificate differs with them. The key was untouched, which is precisely the case an SPKI fingerprint covers: it digests only the `SubjectPublicKeyInfo`, so a renewal that reuses the key pair leaves the pin matching.
  • What has to exist before you deploy the first pin, and why is generating it later not equivalent?
    A backup key pair, already generated and stored, whose SPKI fingerprint is in the pin set from day one. Generating it later does not help, because the moment you need it is the moment the current key is unusable - and a pin set that does not already list the replacement cannot be satisfied by one. Adding a pin requires shipping client configuration, which is exactly what is slow during an incident.
  • Why is a server-declared pin policy riskier for the operator than a pin compiled into a client you control?
    A declared policy is cached by the client for the stated `max-age`, so a wrong or stale pin keeps refusing your own correct server for the remainder of that cache with no server-side retraction. A pin inside a client you build fails the same way, but you control the release that fixes it - and you can stage, test and roll back that release.

saying these in an interview costs you the question

  • Pins a fingerprint of the whole certificate
  • Says one pin is enough because we control renewals
  • Believes pinning survives any key change
  • Treats the RFC 7469 header fields as currently enforced
  • Pins a third-party endpoint from a slow-updating client
  • Thinks a bad pin can be fixed on the server