Skip to content

Demo Data Seeding

./scripts/seed-demo.sh builds a realistic multi-institution / multi-witness Diogenes state by shelling out only to the documented diogenes CLI commands. After it runs, the portal has enough content for an end-to-end demo: institutions with profiles, individuals with institutional endorsements, an authorized witness, and (optionally) a federation follower.

The script doubles as living documentation for the CLI surface. Every command it runs is one a contributor or operator could run by hand.

Prerequisites

  • The Diogenes server is running and reachable. Start it from the repo root:
    ./start.sh
    
  • The diogenes CLI is installed and on PATH:
    pip install -e ".[dev]"
    
  • (Optional) You have pg_isready available if you want to verify the database first; start.sh does this automatically.

Quickstart

./scripts/seed-demo.sh

That's it. After ~30-60 seconds you'll get a summary like this:

============================================================
  DIOGENES DEMO SEED — SUMMARY
============================================================

Individuals (5):
  alice         8cecbf81efc9fe4e...
  bob           643938d142818914...
  ...

Institutions (5):
  MIT                 b1c23f48e4503087...  endorsed=2
  Stanford            4321387684594501...  endorsed=1
  Oxford              183938a843788af2...  endorsed=2
  CERN                dcbe6169e71e2140...  endorsed=1
  Internet Archive    7d33834a136d0be8...  endorsed=1

Witness:
  fingerprint:  06829643b4b1085f
  display name: Demo Witness
  proofs:       2

Visit the portal:
  https://localhost:8000/institutions
  https://localhost:8000/log
  https://localhost:8000/keys/<alice-fp>
============================================================

A demo-state.json artifact is written in the working directory containing all generated fingerprints. The witness key lives in a script-local ./demo-witness/ directory so it does not collide with a real witness key in ~/.diogenes/witness/.

What it does

The script runs five (or six, with --with-federation) sequential phases:

  1. Register keys — Creates 5 individuals (alice, bob, carol, dave, eve) and 5 institution keys via diogenes key register.
  2. Designate institutions — The operator designates each institution key via diogenes operator designate-institution with realistic name/domain pairs (MIT, Stanford, Oxford, CERN, Internet Archive).
  3. Set institution profiles — Each institution sets its profile (description, website, contact email) via diogenes institution set-profile.
  4. Issue institutional endorsements — Institutions endorse individual keys with varied roles (release-signer, security-reviewer, alumnus, affiliated, curator). Each endorsement uses the offer/accept flow: diogenes key endorse followed by diogenes key accept-offer.
  5. Set up the witness — Generates a dedicated witness key (in ./demo-witness/), authorizes it via diogenes operator authorize-witness, sets the witness operator profile (diogenes operator set-profile --type witness), and submits two consistency proofs.
  6. Set up federation follower (only with --with-federation) — Registers a follower key, authorizes it via diogenes operator authorize-federation, and sets its operator profile.

After completion you can verify with:

diogenes operator list-institutions     # 5 demo institutions + others
diogenes operator list-witnesses        # demo witness with 2 proofs
diogenes operator list-followers        # demo follower (with --with-federation)
diogenes institution show <fingerprint> # institution profile + endorsed keys

Idempotency

The script is idempotent on a dirty database. Re-running it does not duplicate keys, profiles, or endorsements; instead it detects existing entities and skips them with a Skipped (N): block in the summary. This means:

  • You can run the script repeatedly during development without resetting the DB.
  • A failed run can be re-run after fixing the underlying issue, and earlier phases will pick up where they left off.
  • To start from a truly clean state, use --clear (see Clearing and resetting).

Detection rules:

Phase Detection On detect
Register key diogenes key list matches the pseudonym Reuse fingerprint
Designate institution diogenes operator list-institutions matches the fingerprint Skip designation
Set institution profile GET /api/v1/institutions/{fp} returns 200 Skip set-profile
Endorse member The institution's endorsements API already lists the member Skip the offer + accept
Authorize witness diogenes operator list-witnesses already includes the witness Skip authorization
Witness proof witness submit reports "no new entries" Skip the second proof
Federation diogenes operator list-followers matches the fingerprint Skip authorization

Environment variables

Variable Default Purpose
DIOGENES_SERVER_URL https://localhost:8000 Diogenes server URL
DIOGENES_DEMO_PASSWORD demo Password used to encrypt every demo private key
DIOGENES_VERIFY_TLS unset (TLS not verified) Honored unchanged by the underlying CLI

Each can be overridden on the command line:

./scripts/seed-demo.sh \
  --server-url https://my-host:8443 \
  --password supersecret \
  --with-federation

CLI flags

./scripts/seed-demo.sh --help

Important flags:

  • --server-url URL — Override the server URL (also picks up DIOGENES_SERVER_URL).
  • --password PW — Override the demo key password (also picks up DIOGENES_DEMO_PASSWORD).
  • --with-federation — Run phase 6 (federation follower setup). Off by default.
  • --state-file PATH — Where to write the JSON artifact (default: ./demo-state.json).
  • --witness-key-dir PATH — Where to put the witness key (default: ./demo-witness/). Must be isolated from ~/.diogenes/witness/ so it does not clobber a real key.
  • --quiet — Suppress per-command output. The summary still prints.
  • --clear — Clear the database, local demo keys, and demo artifacts before seeding. See Clearing and resetting below.
  • --no-seed — Skip the seeding phases. Only meaningful with --clear (wipe-only mode).

Output: demo-state.json

The script writes a structured artifact containing every fingerprint and metadata, suitable for downstream tooling:

{
  "version": 1,
  "started_at": "2026-04-10T12:00:00+00:00",
  "completed_at": "2026-04-10T12:00:42+00:00",
  "server_url": "https://localhost:8000",
  "individuals": {
    "alice": "<64-char fp>",
    "bob": "<64-char fp>"
  },
  "institutions": {
    "MIT": "<64-char fp>",
    "Stanford": "<64-char fp>"
  },
  "endorsements": [
    {
      "institution": "MIT",
      "individual": "alice",
      "role": "release-signer",
      "status": "active"
    }
  ],
  "witness": {
    "fingerprint": "<16-char fp>",
    "display_name": "Demo Witness",
    "proofs_submitted": 2
  },
  "federation": null,
  "skipped": []
}

Clearing and resetting

The --clear flag wipes the database and local demo state before re-seeding:

# Clear and re-seed fresh
./scripts/seed-demo.sh --clear

# Clear only (no seeding)
./scripts/seed-demo.sh --clear --no-seed

When --clear is passed, the script:

  1. Runs diogenes operator reset-db --yes to drop all tables and recreate the schema.
  2. Removes demo keys from the local keystore (~/.diogenes/keys/) — only keys matching the demo pseudonyms are deleted; other keys are left untouched.
  3. Removes ./demo-witness/ and ./demo-state.json.

diogenes operator reset-db

The database wipe is implemented as a standalone CLI command that can also be used directly:

# Interactive (prompts for confirmation)
diogenes operator reset-db

# Scriptable (skips confirmation)
diogenes operator reset-db --yes

Safety rails:

  • Hostname allowlist: The command refuses to run against databases hosted on anything other than localhost, 127.0.0.1, ::1, or db (the Docker Compose service name). Pass --allow-remote to override.
  • Confirmation prompt: Without --yes, the command displays the (password-redacted) database URL and table count, then asks for explicit yes confirmation.

Troubleshooting

ERROR: could not reach Diogenes server at https://localhost:8000 The server is not running. Start it with ./start.sh from the repo root.

server rate-limited the individual key registration You've registered more than 10 keys in the last hour from this IP. Wait an hour, or restart the server with a higher limit:

DIOGENES_RATE_LIMIT_KEY_REGISTRATION=200 ./start.sh

witness 'XXX' already in proof history This is a successful no-op skip. The script detected the witness was already authorized and had submitted proofs.

Could not connect to https://localhost:8002 (default CLI port) The CLI defaults to port 8002 for some commands but the dev server runs on 8000. The script always passes --server-url explicitly, so this shouldn't happen — but if you run any of the printed CLI commands by hand, set DIOGENES_SERVER_URL=https://localhost:8000 first.

Limitations

  • Full DB wipe. --clear drops all tables, not just demo-seeded rows. This is intentional for dev databases but should never be pointed at a shared or production DB (the hostname allowlist prevents this by default).
  • No human attestation chain. The 7-day Sybil-defense activation delay for human attestations cannot be bypassed via the CLI. Manual operator intervention is required for that flow.
  • No trust-config seeding. Trust profiles are out of scope for this script. Use diogenes trust list-profiles and diogenes trust use-profile directly.
  • No volume seeding. For thousands of randomized institutions/profiles, use scripts/seed_institution_profiles.py (which writes directly to the DB).