# Internal Developer Platform

**Solution Architecture v1.0 · Microsoft Azure · Platform Architecture · 2026-09 · 21 views · 16 architecture decision records**

The platform that takes a product engineer from "we need a new service" to running, observable, compliant production code without filing a ticket. Today that journey takes nineteen working days and touches seven teams — repository, pipeline, namespace, database, DNS and certificate, secrets, and a security review that arrives after the architecture is already built. This package is the architecture that replaces it: golden paths that scaffold a component in one action, self-service provisioning by declared intent, a shared build and deploy path producing signed and attested artefacts, and guardrails that hold whether or not a team stayed on the road. It is built on AKS as the shared runtime, Entra ID as the identity and entitlement spine, management groups and subscriptions as the tenancy boundary, Terraform against Azure Resource Manager for infrastructure, GitHub Actions for builds, Argo CD for workload reconciliation and a Backstage-derived portal as the developer surface.

The design rests on one rule: **the paved road is a product a team may decline, and the guardrails are controls it cannot.** Generation and enforcement are separate planes, share no component, and meet only at the runtime — because a control that lives inside a template is deleted by the fork that removes the template, and forking is a normal, reasonable act.

The decisions that carry the design:

- **Guardrails are enforced at the runtime, never inside templates.** Coverage then describes what is running rather than how something was created, which is the only claim that is still true a year later (ADR-05).
- **One policy source, two evaluation points.** Advisory in the pull request to teach, binding at admission to hold; a CI-pass-then-admission-fail is defined as a platform defect and measured as one (ADR-06).
- **Fail closed on new admissions, open on running workloads.** An unevaluated change must not land, and a running service must never be evicted because the platform cannot think (ADR-06).
- **Intent lives in the team's repository.** The portal writes intent and owns nothing, which is what makes the platform's own catalog a rebuildable projection rather than somebody else's source of truth (ADR-01).
- **Provision by reconciliation, not by calling the cloud from the portal.** Partial failures resume from the declaration, and a console edit becomes a detected event instead of invisible drift (ADR-02).
- **Components track their template by default; forking is a recorded choice.** The fork ratio is the number that predicts migration cost, and the pipeline is consumed by reference so it is not part of the fork surface (ADR-03).
- **Attribution at creation.** Owner, cost centre, tier and data classification are enforced properties applied when a thing is made, because nothing acquires an owner afterwards (ADR-11).
- **Entitlement derives from catalog ownership.** Ownership resolves to a live identity group, so a reorganisation moves access with the components and there is no second list to decay (ADR-10).
- **The platform is never in the critical path of running production.** A portal outage costs the ability to change, never the ability to serve (ADR-12).
- **Exceptions are named, approved by someone else, expiring and published.** Relief always exists; making it visible is what stops it becoming a quiet policy edit for the loudest team (ADR-08).
- **A thin abstraction with a designed escape hatch.** Every concept a golden path hides is met for the first time at 03:00, so the substrate stays addressable and access to it is an entitlement rather than an incident favour (ADR-07).
- **Storage is classified by what a loss would cost.** Only provisioning state, audit evidence and the supply chain carry RPO 0; the catalog is rebuildable and says so (ADR-16).

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) (~13 min) and [docs/decision-record.md](docs/decision-record.md) (~53 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 16 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, 165 edges routed with 0 routing
errors and 2 clutter warnings, 389 icons embedded across 21 views, all 166 relative links
resolve.** Both clutter warnings are on view 09, where the hub layout fans four edges from one
node and two labels land close to a neighbouring line; the alternatives were shorter labels
that said less or a deleted dependency, and both were tried and rejected.

## The seven acts

| # | View | What it answers |
|---|---|---|
| 01 | System Context | Who asks the platform for things, and what belongs to the landing zone instead |
| 02 | High-Level Architecture | The seven stages between an engineer's intent and an attributed running workload |
| 03 | Actors and Their Core Journeys | Who this is for, including the three engineer personas who want opposite things |
| 04 | Journey — Create and Ship a New Service | The journey the platform exists for, and the quota rejection that is its trough |
| 05 | Journey — Drive a Change Across 1,400 Components | Whether twelve platform engineers can serve nine hundred |
| 06 | Journey — Debug a Service the Platform Generated | What the abstraction costs at 03:00, and why the escape hatch is designed |
| 07 | Layered Architecture | Eight layers, of which exactly two hold truth |
| 08 | Container and Component View | The five planes, and the fact that generation and enforcement share nothing |
| 09 | Integration Surface | One API behind every surface, and the four systems the platform actually drives |
| 10 | Data Flow | From declaration to projection, and the direction data may not travel |
| 11 | Storage Zones by Ownership | Four bands drawn by what a loss would cost, not by technology |
| 12 | Core Data Model | Twelve entities, and the one edge every attribution resolves through |
| 13 | Critical Flow — Golden Path to First Deploy | Eighteen messages, including the deny that must never be a surprise |
| 14 | Self-Service Provisioning | Declared, admitted against quota, reconciled — never called imperatively |
| 15 | One Policy Source, Two Evaluation Points | The off-road lane, which is the point of the whole design |
| 16 | Deployment Architecture on Azure | Where the shared-fate boundary actually sits, and who can staff it |
| 17 | Shared Pipeline and Environments | One artefact promoted unchanged, and recovery that outlives the pipeline |
| 18 | Observability Matrix | Six signal families, including the platform's own honest scoreboard |
| 19 | Component Lifecycle | Seven states, and no state in which a component has no owner |
| 20 | Trust Zones | Five zones, and why the highest-privilege one is the platform's own |
| 21 | Identity and Access | From a person's group claim to a workload's short-lived token |

## Evidence and limits

This is a design, not a report on a running system. Every rate, latency, volume, retention and
target 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 19-working-day baseline the whole business
case rests on, the 16% fork ratio that predicts migration cost, the ≥ 70% adoption target at
month 12, and the assumption that twelve platform engineers can serve nine hundred.

Two questions are left genuinely open rather than quietly resolved. How much of the substrate a
golden path should hide is the decision most likely to be revisited, and it turns on the
seniority mix of the engineering population and on who is actually on the rota at 03:00
(ADR-07). And whether the platform is mandatory — and who pays for it — is an organisational
choice that changes the business case rather than the architecture: a mandate would raise
coverage and destroy the only honest measurement of whether the paved road is any good
(ADR-12).
