Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# The program repository's gates: the writing rules and the link check
# The platform repository's gates: the writing rules and the link check
# over the documents, and the marker sweep. Tools arrive from their
# canonical releases and are checksum-verified before they run, the
# same bar as every repository in the program.
Expand All @@ -11,12 +11,6 @@ on:
push:
branches: [main]
pull_request:
# The figures check reads another repository, so what it guards against
# changes when nothing here does. On push alone it stayed quiet while
# this site's counts drifted by eighty-four tests and ten decisions, and
# would have stayed quiet until somebody happened to commit.
schedule:
- cron: "23 7 * * 1"
workflow_dispatch:

concurrency:
Expand All @@ -38,12 +32,6 @@ jobs:
tar -xzf vale.tar.gz vale
- name: writing rules
run: git ls-files -z "*.md" | xargs -0 "$RUNNER_TEMP/vale"
# The two figures this site states about manifest-identity are read
# from its README on main, so a copy typed by hand cannot go stale
# silently again; it did, twice, before this existed, and a third
# time between pushes, which is why this workflow also runs weekly.
- name: figures match manifest-identity
run: python3 scripts/check_figures.py
- name: forbid deferred-work markers
run: |
! grep -rnIE "\b(TODO|FIXME|HACK|XXX)\b" --exclude-dir=.git --exclude-dir=.github --exclude=.pre-commit-config.yaml .
Expand Down
7 changes: 0 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,3 @@ repos:
# The pipeline names the markers in order to forbid them, as this
# file does; both are excluded here as the pipeline excludes them.
exclude: '^(\.pre-commit-config\.yaml|\.github/workflows/ci\.yml)$'
# The figures this site states about manifest-identity are checked
# against its README on main, the same gate the pipeline runs.
- id: figures-match
name: figures match manifest-identity
entry: python3 scripts/check_figures.py
language: system
pass_filenames: false
28 changes: 28 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,31 @@ plainly: this repository's first commit predates this decision and is
signed by the application repository's key; it stays as it is, because
rewriting published history to repair a label would destroy the record
the signatures exist to protect.

## D-003: This repository is the platform, and the program has no repository

The program's page lived here for a month and repeated the two
repositories it pointed at, and its plan sections were amended in
those repositories and not here, because nothing checked them. A
document that is only evidence of a plan goes stale the moment the
plan moves.

What this repository held that nothing else did was about the
platform: the Phase 3 plan, what is monitored, how recovery is
drilled. So the repository becomes the platform, an AWS estate as
code with its choices explained, which is what the name and the
banner already said. The plan stays where the code will be, which is
the plan-before-code rule applied in place. The map of the program
moves to the account's own page, and the pipelines overview moves to
build-doctrine's enforcement record, where it is doctrine and where
its checks hold it.

Rejected: archiving this repository and creating another for the
platform, which would leave a copy of every document behind with a
banner on it; deleting it, which would lose the record of its
eighteen reviewed changes for nothing; and a second, private
repository for the estate's own values from the start, which waits
for the first value that must not be public.

The cost is a repository whose history opens with a program page it
no longer is, which this entry explains.
47 changes: 0 additions & 47 deletions PIPELINES.md

This file was deleted.

205 changes: 78 additions & 127 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,134 +2,85 @@

![control-plane: the shared platform grid behind the applications](images/control-plane-banner.png)

control-plane is a security engineering program that one person is
building in public with an AI coding agent. The agent writes the code
and the documents; the person reviews and approves every change; every
decision and every mistake is recorded. It has three parts.

build-doctrine is the rulebook for all the code. It is the standards
for letting an AI agent write code that a person is responsible for,
and it provides the tools that check any repository against them.

It carries:

- Rules where each one names the problem behind it and the check that
catches it.
- A scorer that grades any repository from 0 to 5 on each rule.
- A vetting tool that examines a dependency before it is adopted.
- A project template with the checks already switched on.
- Coverage of seven frameworks: OWASP Top 10, OWASP API Security Top
10, OWASP Top 10 for LLM Applications, STRIDE, NIST SSDF, OWASP ASVS,
and SLSA. Eighty items mapped to the rules, gaps listed.

manifest-identity is the application built under those rules. It
keeps two records about every identity in a cloud estate, what access
it holds and what access a named person authorized, and it shows
every difference between them.

It has:

- Seven providers read from their own export files: AWS, GitHub,
Kubernetes, Google Cloud, Azure and Entra, Okta, Active Directory.
Any other provider through a table.
- Review campaigns that put each difference in front of the person
responsible for it, one decision at a time.
- Twenty findings, each explaining itself: unused identities, keys past
their age, administrators by capability, trusts open to the world.
- A read-only API and a change feed, so other systems follow the
decisions.
- Figures: more than 400 tests, 84 recorded decisions, 34 controls proven by
mutation, five outside ratings, a release verifiable with one
command.

The cloud deployment is the part still to build, phases 3 to 7. It is
the application run in AWS the way the rulebook says.

It will have:

- An AWS organization defined as code.
- One account that persists; the workloads inside it torn down and
rebuilt daily, so recovery is routine.
- Deploys without stored credentials; the image promoted by digest.
- The pipeline tested by planting a flaw; the cloud's own monitoring
switched on.
- The ability to change a cloud account comes last, earned by
everything before it. Each phase's plan is published before the work.

secure-expense-mvp is a small application built before the program as
a learning exercise, kept as a reference.

This repository is the program's home. Its documents render as a site
with side navigation and search at
<https://tltaylor1.github.io/control-plane/>, generated from these files
at build time; the account's own page is at <https://tltaylor1.github.io>.

## The parts

The program is four repositories. Each is public, and each is scored
against the rulebook in its own pipeline.

They are:

- [manifest-identity](https://github.com/manifest-identity/manifest-identity):
the application.
- [build-doctrine](https://github.com/tltaylor1/build-doctrine): the
rulebook, the scorer, the vetting tool, and the template.
- aws-platform: the cloud deployment, arriving with Phase 3 as
reusable Terraform modules for an organization, its baseline,
account vending, and keyless deploys.
- [secure-expense-mvp](https://github.com/tltaylor1/secure-expense-mvp):
the learning exercise from before the program, kept as a reference.

## The program documents

Some things no single repository can answer for. They are kept here,
and each carries the date it was last checked, so it goes stale on a
schedule rather than quietly.

They are:

- [The plan](PHASE-3.md) for the current phase, published before the
work starts, so a change of plan is a recorded decision.
- [Monitoring](MONITORING.md): what is watched at each layer, what
signal it gives, and who hears it.
- [Recovery](BCDR.md): what is rebuilt from code and what real state
is backed up, with the date each drill last ran.
- [Pipelines](PIPELINES.md): how every repository blocks a bad change,
and how the blocking tools are verified before they run.

## The method

Every change takes the same path, whichever repository it is in. The
agent proposes, the checks run, and a person approves.

The rules of the path:
control-plane is the platform that manifest-identity and the
applications after it run on: an AWS estate defined as code, with
every security choice explained beside the code that makes it. It is
built in public by one person with an AI coding agent under
[build-doctrine](https://github.com/tltaylor1/build-doctrine), and it
is the part of the program still to build.

It will hold:

- The organization and its accounts as code: a near-empty management
account, organizational units, service control policies, budgets and
alarms before any resource exists.
- Two stacks side by side. A persistent foundation, the accounts,
state, and identity, and an ephemeral workload, the network, the
cluster, and the application, torn down and rebuilt daily so
recovery is routine rather than rehearsed.
- The network and why it is shaped that way: private subnets, a
database no route reaches from outside, egress controlled.
- Identity without stored keys: people through short-lived sessions,
pipelines through federation into scoped roles, workloads through
the cluster's own identity.
- The image promoted by digest and its attestation checked before it
runs.
- The cloud's own recorders switched on: an organization trail, threat
detection, a configuration baseline with drift alarms, the access
analyzer reading every role.
- Recovery drilled on a schedule, with the date each drill last ran.
- Write access to the estate last, because it is earned by everything
before it.

## Where it stands

No code exists yet. The plan for the first phase is written and
published before the work starts, so a change of plan is a recorded
decision and not a quiet edit.

The phases of the platform:

3. The cloud enclave as code: the organization, the accounts, the
foundation stack.
4. Managed Kubernetes: the image promoted into the enclave by digest.
5. The security-gated pipeline, proven by planting a flaw.
6. Runtime detection and response, with the first-hour procedure
written and exercised once.
7. Human-triggered remediation, last: a scoped action credential,
step-up authentication, every action shown as a diff before it
happens and verified against the provider afterwards.

Phases 0 to 2, design, the application, and local Kubernetes, were
manifest-identity's and are complete; the arc below shows all eight.

- Design first. The plan is public before the first line of code.
- Every change is a pull request under the agent's own identity. The
checks must pass, a person must approve, and the merge is the record.
- Every figure in a document is checked against the running system, or
a test fails.
- Every mistake becomes a rule, and the second time a fix is done by
hand it becomes automation.
- What was left out on purpose is written down beside what was built.
![The eight phases as a timeline, with the current position marked](diagrams/phase-journey-sketch.svg)

## The arc
## The documents

![The eight phases as a timeline, with the current position marked](diagrams/phase-journey-sketch.svg)
Each is kept here because it is about the platform, and each carries
the date it was last checked.

The program runs in eight phases, counted from zero to match the
repositories. Phases 0 to 2 are complete. The Phase 3 plan is written
in [PHASE-3.md](PHASE-3.md), and no Phase 3 code exists yet.

The phases:

0. Design, before any code.
1. The application: the observed half in twelve review-gated
subphases, then the authorized half in fourteen more.
2. Local Kubernetes: admission, network policy, identity.
3. The cloud enclave as code.
4. Managed Kubernetes.
5. The security-gated pipeline, proven by a planted flaw.
6. Runtime detection and response.
7. Human-triggered remediation, last, because write access is earned.
- [The Phase 3 plan](PHASE-3.md): the shape of the estate, the
subphases, and what done means for each.
- [Monitoring](MONITORING.md): what is watched at each layer, what
signal it gives, and who hears it.
- [Recovery](BCDR.md): what is rebuilt from code, what real state is
backed up, and when each drill last ran.
- [Decisions](DECISIONS.md): what was chosen, what was rejected, and
why, including why this repository is the platform.

## The posture

Terraform as the tool. State in versioned object storage with native
locking. No account identifier in a shipped module, so the modules
are generic and the estate's own values live apart. No stored cloud
credential anywhere. A plan is a claim about intent, so the cloud's
own configuration record is the independent reviewer of what exists.
The gates every repository shares, what a platform repository adds,
and this posture in full are in build-doctrine's enforcement record,
under [Every repository's pipeline](https://tltaylor1.github.io/build-doctrine/02-enforcement/#every-repositorys-pipeline).

The documents here render as a site with navigation and search at
<https://tltaylor1.github.io/control-plane/>. The program as a whole,
its rulebook, its application, and this platform, is mapped at
<https://tltaylor1.github.io>.
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# site has no source of its own to drift. Strict mode turns a broken
# link or anchor into a failed build.
site_name: control-plane
site_description: A security engineering program built in public, its rulebook, its application, and its cloud deployment
site_description: The platform the applications run on, an AWS estate as code with every security choice explained
site_url: https://tltaylor1.github.io/control-plane/
repo_url: https://github.com/tltaylor1/control-plane
repo_name: tltaylor1/control-plane
Expand Down
Binary file modified scripts/__pycache__/build_docs.cpython-314.pyc
Binary file not shown.
3 changes: 1 addition & 2 deletions scripts/build_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
("PHASE-3.md", "01-phase-3.md"),
("MONITORING.md", "02-monitoring.md"),
("BCDR.md", "03-recovery.md"),
("PIPELINES.md", "04-pipelines.md"),
("DECISIONS.md", "05-decisions.md"),
("DECISIONS.md", "04-decisions.md"),
]
NOT_PAGES: set[str] = set()
ASSET_DIRS = {"diagrams": "diagrams", "images": "images"}
Expand Down
Loading
Loading