Skip to content

Set up your local plexsphere

The shortest path from git clone to a running plexsphere on a local kind cluster, with the CLI authenticated against the seeded Dex IdP and ready to explore the /v1 API. One command brings up the stack and plants every fixture you need — no follow-up seed step.

Prerequisites

The following tools must be on $PATH before make dev is invoked. A newer patch release will almost always work, but the listed version is the one the test suite is proven against.

ToolPinned versionPurpose
Go1.26.6Pinned by .go-version; drives make docker-build and make e2e.
Docker>= 24.0Container runtime for the kind node and every dev-stack image.
kindv0.26.0Runs the local single-node Kubernetes cluster.
kubectl>= v1.32.0Applies the dev overlay, waits on readiness, and runs kubectl exec against Postgres.

Step 1 — Bring up the stack

bash
make dev

make dev builds every image, creates the plexsphere kind cluster, applies the dev overlay, and waits for readiness. The in-cluster plexsphere-bootstrap Job seeds three demo Domains (Acme Corp, Beta LLC, Gamma Cooperative), binds each one to the in-cluster Dex IdP, pre-creates the canonical admin@example.com user under every Domain keyed by the Dex sub claim, and writes the admin + auditor ReBAC tuples on each Domain for that user. After the Job finishes there is nothing left to seed.

Expected output on success:

text
==> plexsphere dev stack is up
    API ready:  http://localhost:8080/readyz
    Dex OIDC:   http://localhost:5556/dex/.well-known/openid-configuration

Step 2 — Build plexctl and read the seeded IDs

make dev does not compile the operator CLI itself — build it now and prepend $PWD/bin to $PATH for the rest of the shell session:

bash
make plexctl-build
export PATH="$PWD/bin:$PATH"
export PLEXSPHERE_URL=http://localhost:8080
plexctl --version

The build line proves the plexctl now on your $PATH is the one you just compiled:

text
version=f0206ae4 commit=f0206ae4 date=2026-07-31T18:00:57Z

make plexctl-build stamps that line from git describe --tags --always --dirty. This checkout carries no release tag, so version just repeats the short commit sha, and the date is the moment you built — yours will differ on both counts. A bare version=0.0.0-dev means the binary was built without the Makefile ldflags; rebuild with make plexctl-build.

plexctl login needs the Domain UUID it authenticates into. It does not exist in your shell yet, and it is not reachable through the authenticated /v1 API before you hold a token — so it is read straight from the seeded tables. make dev-ids does exactly that: it runs a read-only query against the dev Postgres for the Acme Corp Domain row (Beta LLC and Gamma Cooperative are equivalent) and prints its id as a ready-to-source export line. The IdP binding is no longer needed — plexctl login --domain-id <id> resolves the Domain's single active binding for you. Run it once to see what it emits:

bash
make dev-ids
text
export DOMAIN_ID=019ed19b-68dc-7aa9-8995-80e810444cce

That is the value plexctl login needs. Rather than copy it by hand, let eval run the line so the variable lands in your current shell — the -s flag keeps make quiet so only the export line reaches eval:

bash
eval "$(make -s dev-ids)"
echo "domain=$DOMAIN_ID"
text
domain=019ed19b-68dc-7aa9-8995-80e810444cce

Step 3 — Sign in with plexctl login

The same seeded Dex IdP that backs the API also backs the CLI. Start the RFC 8628 device-code flow against the Domain id you just read:

bash
plexctl login --domain-id "$DOMAIN_ID"

The command prints a verification URL and then blocks, polling until the device code is approved:

text
To complete sign-in, visit:
  http://localhost:8080/v1/device?user_code=VFOLL2SZ

The URL already carries the user code, so there is nothing to type in by hand — the code is different on every run. Open the printed /v1/device?user_code=… link in a browser: the control plane serves the approval page itself, so this local stack needs no external dashboard. Sign in through the seeded Dex IdP with the fixture credentials — username admin@example.com, password password — and click Approve; the waiting plexctl poll then receives its token and writes it to the default profile:

text
Logged in. Saved profile "default".

Those credentials are dev-only fixture values baked into the seeded Dex config (deploy/local/base/dex/configmap.yaml), not secrets — the same static admin@example.com user backs every demo Domain. The Dex form labels the first field Email Address; the account's short username is admin, but you sign in with the email.

Step 4 — Confirm who you are

The token now lives in your plexctl config. Confirm the sign-in worked by asking 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  SCOPE   SUBJECT                               DOMAIN                                ACR  AMR
user       domain  019ecc65-9f3a-7c14-8d2b-5f3e0a7b1c40  019ecc65-8622-7a7f-bfe1-0344c7a22dbd  -    -

Identity in plexsphere is per-Domain: this principal exists in Acme Corp and nowhere else — the same human signing into Beta LLC would be a different principal there, with a different subject UUID.

What you learned

You now have a complete, authenticated local plexsphere:

  • The stack is running on kind — every image built, the dev overlay applied, and the control plane answering on http://localhost:8080.
  • The seed is already in place — three demo Domains (Acme Corp, Beta LLC, Gamma Cooperative), each bound to the local Dex IdP, each carrying the admin@example.com user with its admin + auditor ReBAC tuples. There is no follow-up seed step.
  • plexctl is built, on $PATH, and logged in — a device-code token for your Acme Corp principal is on disk, so every /v1 call you make from here is an authenticated request.

Where to go next

You have a running stack and a logged-in CLI, but you have not read anything with it yet. That is the next lesson:

  • Keep learning by doingExplore your first Domain opens the core track and walks the seeded tenant end to end with plexctl: it reads a Domain, its Projects, its identities, and its audit log, and shows you exactly where the tenancy boundary stops you.

Or pick the quadrant that matches what you need now: