Skip to content

Explore your first Domain

In this lesson you will walk the demo tenant that make dev seeded for you. By the end you will have read a Domain, its Projects, its identities, and its audit log from the command line, and built a working mental model of how plexsphere's tenancy fits together.

You will not change anything. This is a guided look around a known-good system — exactly the right thing to do before you start running how-to guides that do change things.

This lesson takes about fifteen minutes.

Before you start

You need the result of the first lesson, Set up your local plexsphere: a running plexsphere kind cluster and a plexctl that is built, on $PATH, and logged in. If make dev is not currently up, complete that lesson first and come back.

Recreate the shell environment from that lesson so the commands below work in a fresh terminal:

bash
export PATH="$PWD/bin:$PATH"
export PLEXSPHERE_URL=http://localhost:8080

DOMAIN_ID=$(kubectl exec statefulset/postgres -- \
  env PGPASSWORD=plexsphere psql -U plexsphere -d plexsphere -tAc \
  "SELECT id FROM plexsphere.domains WHERE slug='acme-corp'")

$DOMAIN_ID now holds the UUID of the Acme Corp demo Domain. We will use Acme Corp throughout — Beta LLC and Gamma Cooperative are identical, so once you have done this for one you have done it for all three.

Step 1 — Confirm who you are

Every plexsphere call is made as someone, in some Domain. Ask the platform who it thinks you are:

bash
plexctl whoami

You should see exactly one principal — the seeded admin — scoped to the Acme Corp Domain:

text
PRINCIPAL  SUBJECT                               DOMAIN                                ACR  AMR
user       <seed-user-uuid>                      <acme-corp-uuid>                      -    -

This is the single most important idea in plexsphere: identity is per-Domain. The same human signing into Beta LLC would be a different principal there. Hold on to that — every step below is a consequence of it.

Step 2 — List the Domains you can see

bash
plexctl domain list

The three seeded Domains come back — Acme Corp, Beta LLC, and Gamma Cooperative — because the bootstrap job granted your seed user the admin relation on each one. A Domain is the top of the tenancy tree: nothing — no Project, no identity, no Node — exists outside a Domain.

You did not get an empty list and you did not get a permission error. That is the seed working as designed. If you did get an error, the stack is not healthy — return to Set up your local plexsphere and run the reset recipe.

Step 3 — Look inside the Domain

A Domain contains Projects. Ask Acme Corp for its Projects, then its identities:

bash
plexctl project list  --domain "$DOMAIN_ID"
plexctl identity list --domain "$DOMAIN_ID"

identity list shows the seeded admin@example.com user — the same identity plexctl whoami reported in step 1, now seen from the Domain's side rather than the caller's. You are looking at one fact from two directions: who am I and who is in this Domain.

Notice that every command so far has needed --domain "$DOMAIN_ID" once you looked inside a Domain. That is not boilerplate — it is the tenancy boundary asserting itself. There is no "list all Projects everywhere" call, because a Project only has meaning relative to its Domain.

Step 4 — Read the audit log

Every state-changing call in plexsphere is recorded in a per-Domain, hash-chained audit log. Read Acme Corp's:

bash
plexctl audit entries list --domain "$DOMAIN_ID"

You are seeing the trail the bootstrap job itself left when it created the Domain and wrote your permissions. The audit log is per-Domain for the same reason identity is: one tenant can never read another tenant's history.

Step 5 — Cross a tenancy boundary

Re-read the same IDs for Beta LLC and re-run a list call against it:

bash
BETA_ID=$(kubectl exec statefulset/postgres -- \
  env PGPASSWORD=plexsphere psql -U plexsphere -d plexsphere -tAc \
  "SELECT id FROM plexsphere.domains WHERE slug='beta-llc'")
plexctl project list  --domain "$BETA_ID"
plexctl identity list --domain "$BETA_ID"

The Projects and identities change, because you have crossed a tenancy boundary — exactly what swapping --domain does. Every list call goes through the same /v1 API, gated by the same per-Domain permissions; there is no second source of truth behind it.

Step 6 — Ask for machine-readable output

Everything you have run prints a human table by default. Add --output json (long form only — plexctl does not bind it to -o) to get a structured payload instead:

bash
plexctl project list --domain "$DOMAIN_ID" --output json

The shape is always { "items": [ ... ] }. This is the form you would script against — and the bridge from "I am learning plexsphere" to "I am automating plexsphere".

What you learned

You now have a working mental model:

  • A Domain is the tenancy boundary. Projects, identities, and audit history all live inside exactly one Domain and never leak across.
  • Identity is per-Domain. The same person is a different principal in a different Domain; plexctl whoami always answers in the Domain you are scoped to.
  • The CLI and the /v1 API are one system. plexctl is a window onto the same data and the same permission checks the API enforces, not a separate store.
  • Everything that changes state is audited, per-Domain and hash-chained.

Where to go next

You have outgrown the tutorials for this topic. Pick the quadrant that matches what you need now: