Lab 7: A new project¶
Objectives: onboard project gamma the GitOps way, give a user access in Keycloak, and see which parts are automatic and which are deliberate. Then try to shortcut the process and watch it fail safely.
Part A: create project gamma¶
Edit gitops/apps/values.yaml and add a third entry under projects::
- name: gamma
displayName: Project Gamma
description: Genomics pilot (synthetic). Small or medium workspaces.
image: quay.io/jupyter/minimal-notebook:2026-08-10
sizes: [small, medium]
quota:
cpu: "2"
memory: 3Gi
pods: 4
storage: 5Gi
sharedStorage: 1Gi
Check the chart renders before you push:
Commit, push and nudge Argo CD:
git add gitops/apps/values.yaml
git commit -m "Onboard project gamma"
git push
tre sync
kubectl -n argocd get application project-gamma -w
In a real TRE this commit would be a pull request reviewed by the data governance team: the project's approval is on record next to its technical definition.
Now look at what appeared:
kubectl get ns project-gamma --show-labels
kubectl -n project-gamma get resourcequota,limitrange,pvc,rolebinding,cnp
You should see two CiliumNetworkPolicies: workspace-baseline from the chart and
default-deny, which Kyverno generated because the namespace is labelled k8tre.io/type=project.
Part B: give someone access¶
Nobody can use gamma yet: no one is in the gamma group.
- Open the Keycloak console (
/keycloak,admin/admin) and switch to realm tre. - Groups → Create group → name
gamma→ Create. - Users → researcher1 → Groups → Join Group → tick
gamma→ Join.
As researcher1 in JupyterHub: log out (/jupyter/hub/logout) and log back in. The spawn page
now offers Project Alpha and Project Gamma. If a workspace is already running, click Stop
My Server on the hub home page first — JupyterHub allows one server per user. Start gamma:
Keycloak dev mode
Keycloak changes made in the console disappear if the Keycloak pod restarts (see
Keycloak). To make gamma permanent, add it to
gitops/keycloak/realm-tre.json.
Part C: the shortcut that doesn't work¶
What if someone skips Git and just creates a namespace that looks like a project?
kubectl create namespace rogue
kubectl label namespace rogue k8tre.io/type=project k8tre.io/project=rogue
sleep 5
kubectl -n rogue get cnp
Kyverno has already put a default-deny policy there. Guardrails apply to namespaces nobody
declared.
Now in Keycloak create group rogue and add researcher4 to it. Log in to JupyterHub as
researcher4: "rogue" is offered (JupyterHub discovers projects from labels). Start it. The spawn
fails, and the hub log shows the Kubernetes API answering 403 Forbidden.
kubectl -n jupyterhub logs deploy/hub --since=5m | grep -i forbidden | head -3
kubectl auth can-i create pods -n rogue --as system:serviceaccount:jupyterhub:hub
kubectl auth can-i create pods -n project-gamma --as system:serviceaccount:jupyterhub:hub
The hub can only create workspaces where a project has granted it the right, through the RoleBinding in the project chart. A label alone isn't enough: a second, independent lock.
Clean up:
Also delete the rogue group in Keycloak (Groups → rogue → Delete), so researcher4 is back to
no project.
Part D: retire project gamma¶
Stop researcher1's workspace first (Stop My Server): deleting a namespace under a running workspace leaves the hub's state stale.
Then:
kubectl get ns project-gamma # Terminating, then gone
kubectl get pv | grep project-gamma # the project-shared PV is "Released", not deleted
The tre-project-shared StorageClass has reclaimPolicy: Retain, so the project's shared data
outlives the project until someone makes a deliberate archive-or-destroy decision. Clean it up
when you're done:
kubectl get pv -o jsonpath='{range .items[?(@.spec.claimRef.namespace=="project-gamma")]}{.metadata.name}{"\n"}{end}' \
| xargs -r kubectl delete pv
Also remove the gamma group in Keycloak.
Check your understanding¶
- List everything that had to happen for researcher1 to use gamma. Which steps were automated, and which were deliberate human decisions?
- Why is it good that JupyterHub discovers projects instead of keeping its own list?
- What would you add to the project chart for a real TRE? (Ideas: a project-specific data volume mounted read-only, an egress allow-list, a cost-centre label, a backup schedule.)