Skip to content

Run it

Try it in one command. With Docker installed, this brings up the stack, writes an environment file with generated secrets if none exists, imports the seven sample estates, writes the authorized record, opens a review campaign, and prints the sign-in once:

./scripts/try.sh

Everything below is the same path taken by hand.

Coming from a role-call checkout: the variables in .env are MANIFEST_IDENTITY_* (see .env.example), the database and its roles are manifest_identity and manifest_identity_app, and an existing data volume does not carry over: run docker compose down -v and start fresh, or restore a backup under the new role names using the procedure below (D-064).

Requires Docker with the compose plugin, and nothing else.

cp .env.example .env
# set POSTGRES_PASSWORD and MANIFEST_IDENTITY_APP_DB_PASSWORD (D-051), and set
# MANIFEST_IDENTITY_ADMIN_USERNAME and MANIFEST_IDENTITY_ADMIN_PASSWORD so startup
# creates your administrator
docker compose up --build

Three deliberate behaviors sit behind that block. The compose file refuses to start while a key is missing, because the tempting alternative, a hardcoded default, becomes the production secret the day someone forgets to set the real one; failing at startup is loud where a default is silent. A separate migration step runs first, as the database's owner role, and a failed migration stops the start rather than letting anything serve against a schema it does not understand; the application's own role holds data rights only (D-013), so the serving container could not change the schema even through an injection flaw the ORM has no path for. And the image build installs the dependency tree by cryptographic hash, so a package that differs from the reviewed one, from any source, for any reason, fails to install instead of running.

Open http://127.0.0.1:8000 and sign in with the administrator from your .env. No password or secret is written anywhere in this repository; you create all of them locally.

Then import the sample estate that ships in sample-data: three import generations of seven estates, an AWS account in both file formats, a GitHub organization, a Kubernetes cluster, a Google Cloud project, an Azure tenant, an Okta organization, and an Active Directory domain through both of its doors, the capture time in each file's name, plus one table per recipe for the door. Import them oldest first from the Imports view, because state is derived from history and the history should arrive in the order it happened; then read the inventory.

The sample account is synthetic and deterministic, generated by python -m manifest_identity.sample_data, and it is built to trigger every finding the engine can produce, including the ones that need history: an identity that stops being used, a group that gains a member, and a name that comes back under a new identifier. It is generated rather than typed because hand-typed demo data was wrong three times in three subphases before this became a rule; a test regenerates it and fails if the shipped files and the generator disagree.

The committed account stays small on purpose: one identity per archetype, so every finding is readable. For load work the same generator scales: python -m manifest_identity.sample_data out --scale 1000 adds a thousand bulk identities to each generation, one third people with passwords and two thirds services with keys, every variation derived from the identity's index so the output is byte-identical on every run. Scaled sets ship as release artifacts, never as commits.

Without Docker. Requires Python 3.11 or newer; developed and tested on 3.14, and the whole suite runs against 3.11 in the pipeline so the floor is held by execution, not assertion. SQLite serves a local look; PostgreSQL is what the compose file runs.

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
export MANIFEST_IDENTITY_DATABASE_URL="sqlite+pysqlite:///rc.db"
export MANIFEST_IDENTITY_ADMIN_USERNAME=admin MANIFEST_IDENTITY_ADMIN_PASSWORD=<yours>
.venv/bin/python -m manifest_identity.demo
.venv/bin/uvicorn manifest_identity.main:app

The demo command migrates, creates the administrator from the environment, imports the shipped sample months oldest first, writes the authorized record as an operator it creates (most of what is held authorized, with an owner and an expiry, and a few cases planted so every class of difference shows), and opens one review campaign; it converges when run again, so it is safe to repeat (D-085). To prepare an empty instance instead, replace it with .venv/bin/alembic upgrade head.

To stop the compose stack, docker compose down; add -v to also delete the database and start clean. The care of a running instance is in Backup, restore, and retention, next.