# Certificate Lifecycle Service

**Solution Architecture v1.0 · Amazon Web Services · Security Platform Architecture · 2026-09 · 21 views · 20 architecture decision records**

The system that keeps every X.509 certificate a mid-size B2B SaaS depends on from ever expiring in front of a customer. Two populations live under it and behave nothing alike: 24,000 customer-owned domains pointed at the platform by tenants who expect a padlock in browsers the platform has no relationship with, and 3,800 internal workloads authenticating each other over mTLS under a certificate authority the platform runs itself. It issues, renews, installs, distributes trust, revokes, and keeps the evidence — on AWS Private CA under CloudHSM custody for the private hierarchy, an ACME client against two pre-validated public CA accounts for customer domains, EKS and Lambda for the control and verification planes, DynamoDB as the registry, S3 with Object Lock as the ledger, and EventBridge as the lifecycle spine.

The design rests on one rule: **the issuance log is not the truth, the endpoint is.** A certificate reaches SERVING because a prober opened a TLS connection and saw it, never because an issuance succeeded. That single inversion is what closes the gap almost every certificate expiry outage actually lives in — a renewal written to a secret store, a task marked complete, and a process still holding the old certificate in memory with nobody to tell it otherwise.

The decisions that carry the design:

- **The endpoint is the system of record.** The registry is a projection of what endpoints are observed presenting, reconciled against what was issued (ADR-01).
- **ISSUED and SERVING are distinct states** reached by different mechanisms, and only the prober's role can write the second — enforced by access control rather than discipline (ADR-02).
- **Verification does not share a failure domain with issuance.** Probers run per region, outside the control plane, and their own liveness is a signal, because an absence of findings is not good news (ADR-03).
- **Discovery is an input to the state machine, not an audit feature.** A certificate the platform never issued is still the platform's outage, and it is disproportionately the one that expires (ADR-04).
- **One control plane, two trust domains.** Public and private trust share a registry, an escalation ladder and a verify step, and share no issuance mechanics at all (ADR-05).
- **Renewal at a fraction of lifetime remaining, never a fixed number of days**, so the policy survives the next industry-wide shortening of certificate lifetimes without a change (ADR-09).
- **A failed renewal is an incident from the first failed attempt**, with severity driven by remaining validity — which is what moves discovery from T-0 to T-30 (ADR-10).
- **The reload trigger is inside the renewal transaction.** Delivery without a reload path is not a supported integration (ADR-11).
- **Fail static.** An outage of this platform stops change and changes nothing already serving, and the estate's survival time without the control plane — 8 hours — is a published metric (ADR-12).
- **Trust distribution is gated ahead of issuance**, and a relying party that cannot report its bundle version blocks the rotation by name (ADR-13).
- **Re-issue precedes revoke**, inverted only for a key known to be compromised, and that inversion is pre-decided with an approver (ADR-15).
- **Bulk re-issuance is a designed, rehearsed capacity** — ≤ 18 hours inside a 24-hour CA mandate, rehearsed twice a year (ADR-16).
- **Private keys never travel.** Keys are generated in the consuming workload and only CSRs cross the network, so the platform's databases hold no key material to lose (ADR-18).
- **Authorisation is policy over attested identity**, and every denial is recorded — a refusal nobody can investigate is not a control (ADR-20).

The architecture one-pager (including why the design should still hold up in ten years) and the full decision record appear on the landing page of the diagram set, directly below the index of views. The same content is published as [docs/architecture-one-pager.md](docs/architecture-one-pager.md) (~14 min) and [docs/decision-record.md](docs/decision-record.md) (~64 min).

---

## What is here

| Path | Contents |
|---|---|
| `diagrams/index.html` | The landing page: 21 views in seven acts with every format linked, then the **architecture one-pager** and the **decision record** |
| `diagrams/*.html` | One self-contained page per view: the inlined diagram plus the reasoning cards, with copy / PNG / PDF export |
| `diagrams/svg/*.svg` | The same views as SVG with the diagram XML embedded; they re-open fully editable in diagrams.net |
| `diagrams/drawio/*.drawio` | draw.io source |
| `docs/architecture-one-pager.md` | The one-pager as markdown |
| `docs/decision-record.md` | The 20 decision records, the capability-to-technology table and the package glossary as markdown |
| `specs/part-a..f.json` | Diagram specifications, the source of truth for every view |
| `specs/manifest-a..b.json` | Acts, page titles, subtitles and reasoning cards |
| `specs/adr-onepager.json`, `specs/adr-records-a..b.json` | The one-pager, the decision records, the capability-to-technology table and the glossary |
| `scripts/build.sh` | Rebuilds every deliverable from the specs (Node only) |
| `ask.md` | The requirement |

## Rebuilding

```bash
bash scripts/build.sh
```

Node 20+ and nothing else — no draw.io Desktop, no browser, no network. The build assembles
`specs/views.json` and `specs/manifest.json` from the authoring parts, then runs generate →
validate → route check → SVG → draw.io → HTML → link check, and finally renders the one-pager
and decision record into `diagrams/index.html` and `docs/`. Edit the parts, never the
assembled files.

Current state: **0 validator errors, 0 validator warnings, 148 edges routed with 0 routing
errors and 0 clutter warnings, 362 icons embedded across 21 views, all 166 relative links
resolve.**

## The seven acts

| # | View | What it answers |
|---|---|---|
| 01 | System Context | What the platform is asked for, and the two trust authorities it can never be independent of |
| 02 | High-Level Architecture | The six stages every certificate passes through, and where the loop closes |
| 03 | Actors and Their Core Journeys | Who this is for — including the two actors that are not people |
| 04 | Journey — A Tenant Brings Their Own Domain | Five phases, one trough, and why the trough is paid once rather than every 90 days |
| 05 | Journey — The Expiry That Did Not Happen | The SRE's path through a failure most designs only reveal as an outage |
| 06 | Layered Architecture | Eight layers, and why trust distribution sits above the thing it gates |
| 07 | Container View | Three planes that are deliberately not allowed to be each other |
| 08 | Integration Architecture | Every surface in and out, and the one genuinely synchronous obligation |
| 09 | Data Flow | Five stages that record intent, and the one that records fact |
| 10 | Data Architecture and Ownership | Four zones with four write rules, and the data deliberately absent |
| 11 | Core Data Model | Twelve entities and the foreign key that carries the architecture |
| 12 | A Customer Domain from CNAME to Padlock | The public issuance flow, and the three messages the customer is in |
| 13 | Renewal Is Not Done Until It Is Observed | The critical flow, including the path where everything succeeded and nothing changed |
| 14 | Issuance Paths by Trust Domain | Exactly how much public and private trust share, across six stages |
| 15 | Revocation and Bulk Re-Issuance | What happens when someone else sets a 24-hour clock |
| 16 | Deployment Architecture | Where it runs, and how long the estate survives without it |
| 17 | Authority Rotation and Policy Release | How a new authority reaches the estate without breaking the half that has not heard |
| 18 | Observability and the Expiry Clock | Six signal families, including the canary that proves the machinery works on a quiet day |
| 19 | The Certificate Lifecycle Loop | Six steps around an identity that outlives every certificate it holds |
| 20 | Security Trust Zones and Key Custody | Five zones by exposure, and a root inside them with no path to any of them |
| 21 | Identity and Authorisation | Who may ask for what, and the request the platform exists to refuse |

## Evidence and limits

This is a design, not a report on a running system. Every rate, latency, volume, retention and
threshold is a **stated assumption** from `ask.md`, invented to be defensible and arguable
rather than absent, and to be replaced by measured telemetry before build. Four numbers in
particular are the first that real data should overturn: the 24-hour private leaf lifetime,
which sets both the issuance volume and the 8-hour control-plane survival time; the 15-minute
probe cadence, which sets the expiry detection delay; the 18-hour bulk re-issuance target
inside a 24-hour mandate; and the ≥ 99.5% managed-coverage figure, which depends entirely on
how much of the estate the prober can actually reach.

Three questions are left genuinely open rather than quietly resolved. Whether the verification
plane can reach enough of the estate decides whether the headline rule holds everywhere or only
where probing works — the unreachable remainder degrades to belief, and the requirement says so
rather than averaging it away. Whether the platform should be given a veto at the 7-day wall —
blocking a deployment or failing a readiness check for a service about to expire — is deferred
to Phase 3 because it turns on trust the platform has not yet earned. And whether regionally
independent issuance is worth the wider key exposure it buys is left to measured control-plane
availability rather than settled in advance (ADR-12).
