---
title: 'Certificate Authorities and the Chain of Trust'
source: 'https://academia.sh/en/courses/identity-and-cryptography/certificate-authorities-and-chain-of-trust'
course: 'Identity, Access and Cryptography'
language: en
updated: '2026-09-26T03:02:53+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Builds the chain-of-trust graph and counts the leaf items and trust store copies a single root carries'
    - 'Calculates how many items adding an intermediate authority adds per verification'
    - 'Measures separately the items dropped, machines touched, and renewal time when a root versus an intermediate authority breaks'
---

# Certificate Authorities and the Chain of Trust

The load a single root carries is measured in numbers: 4,397 leaf items and 4,400 trust store copies tied to one root under four intermediate authorities, an intermediate authority breaking drops between 10 and 4,101 items while a root breaking drops 8,802 items and takes 95 workdays of manual touch; a backup root zeroes out the outage but does not change the touch count.

The previous lesson measured the certificate as a set of claims and left one item as an
assumption: the verifying party already held the issuer's public key. That key did not get there
on its own. A leaf item is signed by an intermediate authority, the intermediate authority is
signed by a root; nobody signs the root — the root signs itself, and it is valid **not because
it is verified, but because it is accepted outright**. This is exactly where the trust root sits:
the first link of the chain is placed by decision, not by proof.

This lesson counts the load that decision carries. The fictional regional measurement network's
certificate inventory is built as a graph, and three things are measured: how many items a single
root carries at once, how many items adding an intermediate authority adds to every verification,
and how many items drop — and how many touches renewing them takes — when an authority breaks.

- **PK6.** An authority **breaking** means its private key has gone outside its control, or the
  authority has signed an unauthorized item. Both have the same result: that authority's
  signature no longer carries evidence.
- **PK7.** The trust store is where the root item is written. Each machine holds one copy, and
  the number of copies equals the number of machines.
- **PK8.** A machine class is reached either remotely or by hand. In the remotely-reached class,
  renewal goes through the distribution channel; in the manually-reached class, each machine
  needs one touch, and the touch's duration in minutes is a fictional model value.
- **PK9.** A severed leaf is a leaf item that cannot be verified from the break until renewal
  finishes; the connection that item carries cannot be established during that span.
- **PK10.** A backup root means a second root item has already been written to every store **in
  advance**, and the intermediate authorities have also been signed with this second root. The
  counts, classes, and minutes are fictional.

## The Items the Root Carries

The graph carries two kinds of node: authorities and machines. An authority is an item that can
sign other certificates; a machine is a node that carries a leaf item and holds a copy of the
root in its trust store.

```js
// chain.mjs — fictional chain-of-trust graph and machine inventory. THIS IS A MODEL.
// The regional measurement network is FICTIONAL: authority names are role names, counts and minutes are made up.
export const AUTHORITY = [
  // id, issuer, type, where the private key sits (fictional)
  ["org-root", null, "root", "offline vault"],
  ["device-intermediate", "org-root", "intermediate", "hardware security module"],
  ["server-intermediate", "org-root", "intermediate", "hardware security module"],
  ["staff-intermediate", "org-root", "intermediate", "directory server disk"],
  ["signing-intermediate", "org-root", "intermediate", "hardware security module"],
].map(([id, issuer, type, location]) => ({ id, issuer, type, location }));

export const MACHINE = [
  // class, count, issuer of the leaf item it carries, has root store?, reached remotely?, manual min
  ["meter endpoint", 4100, "device-intermediate", true, false, 11],
  ["internal service", 26, "server-intermediate", true, true, 2],
  ["staff workstation", 262, "staff-intermediate", true, true, 1],
  ["branch gateway", 9, "signing-intermediate", true, true, 4],
  ["partner verifier", 3, null, true, false, 90],
].map(([cls, count, issuer, store, remote, min]) => ({ class: cls, count, issuer, store, remote, min }));

export const intermediate = () => AUTHORITY.filter((o) => o.type === "intermediate");
export const subLeaves = (id) =>
  MACHINE.filter((m) => m.issuer === id).reduce((t, m) => t + m.count, 0);
export const LEAF = intermediate().reduce((t, o) => t + subLeaves(o.id), 0);
export const STORE = MACHINE.filter((m) => m.store).reduce((t, m) => t + m.count, 0);

// The number of items that must hold true at once in a verification.
// validity per certificate + signature per link + basic constraints per authority
// + name and usage for the leaf item + secrecy per key + store record + clock
export const itemCount = (chain) => chain + (chain - 1) + (chain - 1) + 2 + chain + 1 + 1;

export const write = (g) => (h) =>
  h.map((v, i) => (i ? String(v).padStart(g[i]) : String(v).padEnd(g[0]))).join("");
```

```js
// breaking.mjs — the items the graph carries, the items a broken authority drops, and the renewal cost
import { AUTHORITY, MACHINE, intermediate, subLeaves, LEAF, STORE, itemCount, write } from "./chain.mjs";

const fmt1 = write([22, 10, 15, 26, 8]);
console.log(`graph: 1 root, ${intermediate().length} intermediate authorities, ${LEAF} leaf items, ` +
  `${STORE} trust store copies, ${MACHINE.reduce((t, m) => t + m.count, 0)} machines`);
console.log("\n" + fmt1(["authority", "leaf items", "machine class", "private key", "chain"]));
for (const o of AUTHORITY) {
  const sub = o.type === "root" ? LEAF : subLeaves(o.id);
  const classes = MACHINE.filter((m) => m.issuer === o.id).length;
  console.log(fmt1([o.id, sub, o.type === "root" ? MACHINE.length : classes, o.location,
    o.type === "root" ? 1 : 2]));
}
console.log(`\nitems that must hold at once while verifying a leaf item:`);
for (const z of [2, 3]) console.log(`  ${z}-certificate chain (${z === 2 ? "root signs directly"
  : "root -> intermediate -> leaf"}): ${itemCount(z)} items`);
console.log(`  cost of adding an intermediate authority per verification: ` +
  `${itemCount(3) - itemCount(2)} items`);

// Breaking: which authority breaking drops how many items, touches how many machines, takes how many minutes.
const touched = (classes) => classes.reduce((t, m) => t + m.count, 0);
const minutes = (classes) =>
  classes.filter((m) => !m.remote).reduce((t, m) => t + m.count * m.min, 0);
const ROOT_STORE = MACHINE.filter((m) => m.store);

const SCENARIO = [];
for (const o of intermediate()) {
  const s = MACHINE.filter((m) => m.issuer === o.id);
  SCENARIO.push([`${o.id} breaks`, 1 + subLeaves(o.id), subLeaves(o.id), s, subLeaves(o.id)]);
}
SCENARIO.push(["org-root breaks", 1 + intermediate().length + LEAF + STORE, LEAF, ROOT_STORE, LEAF]);
SCENARIO.push(["org-root breaks, backup root exists", 1 + STORE, 0, ROOT_STORE, 0]);

const fmt2 = write([34, 10, 11, 11, 12, 14]);
console.log("\n" + fmt2(["scenario", "dropped", "renewed", "touched", "manual min", "severed leaf"]));
for (const [name, dropped, renewed, classes, severed] of SCENARIO)
  console.log(fmt2([name, dropped, renewed, touched(classes), minutes(classes), severed]));

// Manually-reached and remotely-reached store copies.
const manual = ROOT_STORE.filter((m) => !m.remote);
const remote = ROOT_STORE.filter((m) => m.remote);
console.log(`\nroot store ${STORE} copies: remote ${touched(remote)}, manual ${touched(manual)}`);
for (const m of manual)
  console.log(`  ${m.class.padEnd(24)}${String(m.count).padStart(6)} copies, ` +
    `${String(m.count * m.min).padStart(6)} min`);
console.log(`manual touch total ${minutes(ROOT_STORE)} min = ` +
  `${Math.round(minutes(ROOT_STORE) / 60)} hours = ${Math.round(minutes(ROOT_STORE) / 480)} workdays`);
console.log(`machines that keep accepting the broken root until it is removed: ` +
  `${touched(manual)}`);
```

```
graph: 1 root, 4 intermediate authorities, 4397 leaf items, 4400 trust store copies, 4400 machines

authority             leaf items  machine class               private key   chain
org-root                    4397              5             offline vault       1
device-intermediate         4100              1  hardware security module       2
server-intermediate           26              1  hardware security module       2
staff-intermediate           262              1     directory server disk       2
signing-intermediate           9              1  hardware security module       2

items that must hold at once while verifying a leaf item:
  2-certificate chain (root signs directly): 10 items
  3-certificate chain (root -> intermediate -> leaf): 14 items
  cost of adding an intermediate authority per verification: 4 items

scenario                             dropped    renewed    touched  manual min  severed leaf
device-intermediate breaks              4101       4100       4100       45100          4100
server-intermediate breaks                27         26         26           0            26
staff-intermediate breaks                263        262        262           0           262
signing-intermediate breaks               10          9          9           0             9
org-root breaks                         8802       4397       4400       45370          4397
org-root breaks, backup root exists      4401          0       4400       45370             0

root store 4400 copies: remote 297, manual 4103
  meter endpoint            4100 copies,  45100 min
  partner verifier             3 copies,    270 min
manual touch total 45370 min = 756 hours = 95 workdays
machines that keep accepting the broken root until it is removed: 4103
```

The first table gives the root's load in a single row: 4,397 leaf items stand under the four
intermediate authorities, and all of them trace back to a single item's signature. The root
itself does not sign a single leaf item directly; even so, it sits above all four thousand three
hundred ninety-seven of them, because it is at the end of the chain.

More than half the load is not even a certificate. The **4,400 trust store copies** are copies of
the same root item written to machines, and in the graph they are tied in by **distribution**, not
signature. Each of these copies is an independent item: if one is missing, that machine cannot
verify any chain; if one is extra, that machine accepts an extra root. The partner verifiers show
this plainly — three machines carry no leaf item at all, only a root store, meaning their role in
the network is purely to verify.

The column showing where the private key sits says something the shape of the graph cannot. The
root key sits in an offline vault and is only brought out to sign an intermediate authority; a
key used a few times a year has no reason to sit online. Three intermediate authorities' keys sit
in a hardware security module — the key never leaves the module, the signing request is sent in.
The fourth, `staff-intermediate`, keeps its key on a directory server's disk. In the graph, these
four nodes are equals; their odds of breaking are not equal, and this is the only column that
carries that difference. 262 leaf items stand under the key on disk.

The chain-length measure builds the second table. If the root signed leaf items directly, the
number of items that must hold at once in a verification would be ten. Once an authority is
inserted in between, that number climbs to fourteen: one more certificate's validity window, one
more signature link, one more basic constraints check, and one more private key staying secret.
**An intermediate authority is not free**; it adds four items to every verification, and that cost
is paid again on every verification of each of the four thousand three hundred ninety-seven items.

## Breaking: Which Root, How Many Items

The payoff shows up in the second table. The same graph produces completely different numbers
depending on which authority breaks. When `signing-intermediate` breaks, the number of items
dropped is **ten**; when `device-intermediate` breaks, it is **4,101**. The gap between them is
more than four-hundred-fold, and it has nothing to do with the graph's shape — it is about the
size of the subtrees. This is the real job of splitting into intermediate authorities: it
confines the break to a single subtree.

The manual-touch column does not tell the same story. The manual-touch cost of `server-intermediate`,
`staff-intermediate`, and `signing-intermediate` breaking is zero, because these three classes'
machines are reached remotely and renewal goes through the distribution channel. A
`device-intermediate` break, on the other hand, means 4,100 site visits: 45,100 minutes. There is
no fixed ratio between the number of items dropped and the renewal cost; what decides it is not
the item count, it is **how the machines those items sit on are reached**.

On the device side, there is one more reason for this. For a meter endpoint to receive its new
item, it has to establish a connection with the collector; and the item it presents to establish
that connection is exactly the item that needs renewing. If the renewal channel depends on the
very item being renewed, remote renewal cannot happen. This is a limit in the measurement network
that is independent of item count, and it takes the site visit out of being a choice.

There is one more number that shows up in none of the table's columns: **when the break is
noticed**. The model treats the moment of breaking and the start of renewal as the same instant.
In reality there is a span between the two, and throughout that span every item the broken
authority signs passes all fourteen of the verification's fourteen items — because breaking
leaves no trace in any of the fields being checked. This lesson's numbers give the cost of
renewal, not the length of time to notice; the latter is not measured in this course.

The root row changes the scale entirely. When the root breaks, the number of items dropped is
**8,802**: one root, four intermediate authorities, 4,397 leaf items, and 4,400 trust store
records. 4,400 of that is not certificates, it is records; meaning the work of renewing the root
is not just re-signing, it is changing the writing on four thousand four hundred machines. The
manual-touch total is 45,370 minutes, or **95 workdays**. What this number means is not a cost,
it is a **duration**: when the root breaks, closing the incident takes longer than three months.

## What a Backup Root Saves

The last row on its own is the most instructive part of the lesson. If a second root has already
been written to every store, and the intermediate authorities have also been signed with that
second root, then when the root breaks, the items dropped fall from 8,802 to 4,401, and **the
severed-leaf count falls from 4,397 to zero**. No connection breaks; the measurement network
keeps running, because every leaf item has a second path to the root.

The two columns that do not change are the ones that actually decide the outcome. The number of
machines touched is still 4,400, the manual touch is still 45,370 minutes. A backup root does not
eliminate the renewal work, because the broken root still has to be **removed** from the stores,
and that means touching every machine individually. What the backup root saves is not the work,
it is the **outage**: the same 95 workdays pass with service still up.

What decides the duration is not the number of store copies, it is their distribution. Of the four
thousand four hundred copies, 297 are reached remotely, and their touch cost does not enter the
total minutes at all; the remaining 4,103 produce the entire duration. Reducing the copy count
does not change this table, because the copies that would be reduced sit on the remotely-reached
side. The only thing that changes it is opening a distribution channel to the manually-reached
classes — and that channel itself needs a trust root too.

This is why the last row also shows where the root falls short. The 4,103 manually-reached
machines keep accepting the broken root, and that lasts until the very last machine, whatever the
touch order happens to be. A broken root is not considered revoked; **it stays valid on every
machine it has not been removed from.** If an average meter endpoint's visit falls somewhere in
the middle of that order, the window for that endpoint lasts roughly forty-seven workdays. During
that span, a new item signed with the broken root can be produced and it will be accepted on that
machine; nothing in the graph stops that.

This gap does not close with renewal. The only thing that can close it is the verifier being able
to ask "is this item still valid" **somewhere other than** the item's own fields. This is
information that is not written in any certificate field, and it stands outside the graph.

## Summary

- The fictional graph has 1 root, 4 intermediate authorities, and 4,397 leaf items; the root sits
  above all of them even though it signs none of them directly. 4,400 of the load's items are not
  certificates but trust store copies, tied into the graph by distribution rather than signature.
- If the root signed leaf items directly, a verification would need 10 items to hold; an
  intermediate authority raises that to 14. An intermediate authority confines a break to a
  single subtree, but it adds 4 items to every verification.
- Depending on which authority breaks, the items dropped range from 10 to 4,101; manual touch
  ranges from 0 to 45,100 minutes. What decides it is not the item count, it is how the machines
  are reached.
- When the root breaks, 8,802 items drop, 4,400 machines get touched, and manual touch takes 95
  workdays. Because the renewal channel depends on the item being renewed, remote renewal cannot
  happen on 4,100 meter endpoints.
- A backup root brings the items dropped down to 4,401 and severed leaves down to 0, but it
  does not change the machines touched or the duration at all: what it saves is the outage, not
  the work. A broken root keeps staying valid on the 4,103 machines it has not been removed from.

## Next Step

The gap that opens when the root breaks is not about the speed of renewal. When an item loses its
validity, the verifying party has to **learn** that, and there is no field inside the certificate
that says so; as long as its fields have not changed, an item keeps presenting itself as valid.
There are two ways to learn it: distribute a list of revoked items, or ask the authority
individually on every use. The next lesson compares the two on the same footing — how many hours
pass between the revocation decision and the client learning it, how many connections get
accepted in that window, and how many paths the decision opens when a query gets no answer.
