Projects & Namespaces as Security Boundaries
Duration: ~15 minutes
Overview
Projects and namespaces draw hard lines between teams and apps. Use them to keep RBAC, quotas, and network rules scoped so one tenant cannot casually reach another.
Create a project with security labels, bind RBAC, and apply a ResourceQuota so you can see how namespaces isolate ownership and capacity.
| An OpenShift project is a namespace plus metadata/access controls; create one boundary per team/environment/app; namespaces can talk by default—restrict with NetworkPolicy. |
Why it matters
On a shared cluster, a single flat namespace becomes everyone’s problem
-
Shared secrets access
-
Contested CPU
-
Tangled NetworkPolicies
Clear project boundaries make ownership obvious and keep mistakes contained.
What does it solve
-
Multi-tenant isolation
-
Resource conflict prevention
-
Access control boundaries
-
Compliance and audit organization
-
Network segmentation foundation
Your Mission
Without project boundaries, one compromised identity or runaway workload can reach every tenant’s Secrets, CPU, and pods. Draw hard lines—labels, RBAC, and quotas—so a break-in stays trapped in one namespace instead of becoming a cluster-wide outage.
Click each step only if you need a hint.
Create project 101-02-demo
Stand up a dedicated project so this tenant has its own boundary — not shared free-for-all space.
oc new-project 101-02-demo --display-name="Security Demo" --description="101-02 Lab Project"
Now using project "101-02-demo".
|
Label namespace 101-02-demo security-tier and environment
Label the namespace so policy engines (and operators) can target this tenant by security tier and environment.
oc label namespace 101-02-demo security-tier=basic environment=dev
Confirm the labels stuck on the project:
oc get namespace 101-02-demo --show-labels
Labels should include security-tier=basic and environment=dev.
|
Create RoleBinding dev-team with clusterrole edit
Bind group dev-team to edit only inside this project.
oc create rolebinding dev-team --clusterrole=edit --group=dev-team -n 101-02-demo
rolebinding.rbac.authorization.k8s.io/dev-team created.
|
Confirm the default SA cannot create pods
The default service account is still denied. That closes the "any SA can do anything" path.
oc auth can-i create pods --as=system:serviceaccount:101-02-demo:default -n 101-02-demo
Expect no. The RoleBinding targets the dev-team group; the default service account is still denied.
|
Create ResourceQuota demo-quota in 101-02-demo
Buggy apps (and noisy neighbors) burn the cluster with oversized requests. Put a ceiling on CPU, memory, and pods so one namespace cannot starve the rest.
oc create quota demo-quota --hard=requests.cpu=2,requests.memory=2Gi,limits.cpu=4,limits.memory=4Gi,pods=10 -n 101-02-demo
Inspect the quota to confirm the hard limits and current usage:
oc describe quota demo-quota -n 101-02-demo
| Hard limits should show 2 CPU request, 2Gi memory, 10 pods. |
Challenge: onboard a new team
Platform ops just approved a new application team. You must stand up their default project the same way you did for 101-02-demo—without copying the demo commands blindly. Work from the requirements below first. Use the hidden solution only if you get stuck.
Scenario
The Payments team is joining the shared cluster. They need a dedicated development project before they deploy anything. Your platform standard for every new team is:
-
One OpenShift project per team/environment (not a shared sandbox).
-
Consistent labels so policy and reporting can find the tenant.
-
A namespace-scoped RoleBinding for the team’s IdP group (
editonly in that project). -
A ResourceQuota so a runaway deploy cannot starve other tenants.
Requirements
Create and configure a project that meets all of these checks:
| Requirement | Target value |
|---|---|
Project name |
|
Display name |
|
Description |
|
Labels |
|
RBAC |
RoleBinding named |
ResourceQuota name |
|
ResourceQuota hard limits |
|
Prove it works
Before you open the solution, verify your own work:
-
Labels are present on the namespace.
-
The default service account in
team-payments-devstill cannot create pods (oc auth can-ishould returnno). -
oc describe quota team-quota -n team-payments-devshows the hard limits above.
Solution (try yourself first)
Click each step only if you need a hint.
Create project team-payments-dev
Use the display name and description from the requirements table.
oc new-project team-payments-dev \
--display-name="Payments Team (Dev)" \
--description="Default project for Payments team development workloads"
Now using project "team-payments-dev".
|
Label team-payments-dev with team, environment, and security-tier
Labels: team=payments, environment=dev, security-tier=basic.
oc label namespace team-payments-dev team=payments environment=dev security-tier=basic
oc get namespace team-payments-dev --show-labels
| All three labels should appear on the namespace. |
Create RoleBinding payments-devs with clusterrole edit
Grant ClusterRole edit to group payments-devs in this project only.
oc create rolebinding payments-devs \
--clusterrole=edit \
--group=payments-devs \
-n team-payments-dev
rolebinding.rbac.authorization.k8s.io/payments-devs created.
|
Confirm the default SA cannot create pods
The default service account in team-payments-dev should still be denied.
oc auth can-i create pods \
--as=system:serviceaccount:team-payments-dev:default \
-n team-payments-dev
Expect no.
|
Create ResourceQuota team-quota and describe it
Hard limits: requests.cpu=1, requests.memory=1Gi, limits.cpu=2, limits.memory=2Gi, pods=5.
oc create quota team-quota \
--hard=requests.cpu=1,requests.memory=1Gi,limits.cpu=2,limits.memory=2Gi,pods=5 \
-n team-payments-dev
oc describe quota team-quota -n team-payments-dev
oc describe should list the hard limits from the table.
|
Debrief
You drew a project boundary, scoped edit RBAC inside it, and capped CPU/memory/pods with a ResourceQuota. This traps a compromise or a runaway workload in one namespace instead of the whole cluster.
What breaks without this:
-
No RBAC scope → lateral access and Secret theft across teams
-
No ResourceQuota → noisy-neighbor DoS
-
No NetworkPolicy (next labs) → open east-west traffic by default
-
Inconsistent labels → policy engines like Red Hat Advanced Cluster Security miss the tenant
