Skip to content
Spinoza

Documentation

Cluster mode

Preview: serve one cluster to a team through OIDC or an authenticated proxy.

Install the chart

The published OCI chart runs the same binary inside the cluster. It needs the public URL people open and an explicit authentication mode.

helm upgrade --install spinoza oci://ghcr.io/sophotechlabs/charts/spinoza \
  --namespace spinoza --create-namespace \
  --set publicURL=https://spinoza.example.com \
  --set auth.mode=oidc \
  --set auth.oidc.issuerURL=https://id.example.com/realms/main \
  --set auth.oidc.clientID=spinoza \
  --set auth.oidc.clientSecret=... \
  --set auth.adminGroups='{platform-admins}'

The chart can also render an Ingress or an HTTPRoute, a NetworkPolicy, a PodDisruptionBudget and a ServiceMonitor. A persistent volume keeps settings, the audit trail and the timeline across a pod replacement; without one they go with the pod.

Sign-in and roles

Use OIDC when Spinoza should run the login, or an authenticated proxy when one already fronts your internal tools. Anonymous administration is off unless you opt into it explicitly.

With OIDC, enabling back-channel logout means disabling somebody at the provider ends their Spinoza session at once rather than at cookie expiry.

Groups map to three roles. The strongest matching group wins, and anyone who matches none gets the default role, viewer unless you change it.

RoleMay
viewerRead permitted views and save personal settings. Changes no cluster objects.
editorEverything above, plus apply, delete, scale, restart, reconcile, and Helm install, upgrade, rollback and uninstall.
adminEverything above, plus exec, debug containers, node shells, cordon, drain, the RBAC index, the audit export, transcripts and protecting a cluster.

What the cluster permits

By default the chart runs Spinoza from a read-only service account with no access to Secrets and no right to impersonate anyone. Helm keeps its release history in Secrets, so the Helm view stays empty until the service account may read them, and custom resources need rules of their own.

Turn on impersonation, naming the users and groups it may act as, and every apiserver call for a request carries the signed-in account, so Kubernetes RBAC decides what that person may do. Buttons follow the same answer: what the account cannot do is greyed out with the reason.

With impersonation on, tables and search are scoped to namespaces the account may list, and live feeds, log streams and terminals recheck that access while they are open. Views that read the whole cluster need cluster-wide read, and say so rather than showing a partial answer.

The audit trail

Every change Spinoza makes is recorded with who asked for it, what it touched and whether the cluster allowed it, alongside sign-ins, sign-outs, expired sessions and refused roles. Each entry is also written as a structured log line, so it reaches your log store with nothing to integrate. Admins export the trail as CSV or JSON.

Terminal transcripts are off unless the deployment turns them on. Then each exec and node shell keeps what was typed and what came back, up to a megabyte, beside its audit entry, and only admins read them. A transcript holds whatever somebody typed, secrets included.

The trail, scheduled check runs and transcripts are kept for 90 days or 50,000 rows by default, whichever comes first.

Running and restarting

Spinoza logs JSON in cluster mode and serves /metrics in Prometheus format to admins, or on a separate port for a scrape. Every request gets a short name that is returned with the answer and logged with it, so somebody can quote what they saw and you can find it.

/readyz reports whether the resource catalog has been read, the caches have filled and the state store is open. The chart gates readiness on it, so a new pod takes no traffic while its tables would be empty. On the way down Spinoza reports not-ready first and drains, so a restart costs a reconnect rather than an error.

One replica is the supported shape, and the chart refuses to render more: the state store has one writer, and live sessions belong to the pod that accepted them.

What changes from local mode

  • One cluster, rather than several local kubeconfigs and tabs.
  • No desktop window or local port-forwarding.
  • No update check or self-install path inside the pod.
  • JSON logs rather than text.
  • Node shell stays off unless an administrator enables it.