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.

Claim a defended territory with security labels

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"

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
Stop casual privilege sprawl with namespace RBAC

Bind a team to edit only inside this project. That scopes privilege to the boundary you just created—not the whole cluster.

oc create rolebinding dev-team --clusterrole=edit --group=dev-team -n 101-02-demo

Now prove the project’s default service account cannot create pods until you grant it. 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.
Cap a noisy-neighbor DoS with ResourceQuota

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

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:

  1. One OpenShift project per team/environment (not a shared sandbox).

  2. Consistent labels so policy and reporting can find the tenant.

  3. A namespace-scoped RoleBinding for the team’s IdP group (edit only in that project).

  4. 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

team-payments-dev

Display name

Payments Team (Dev)

Description

Default project for Payments team development workloads

Labels

team=payments, environment=dev, security-tier=basic

RBAC

RoleBinding named payments-devs granting ClusterRole edit to group payments-devs in team-payments-dev

ResourceQuota name

team-quota

ResourceQuota hard limits

requests.cpu=1, requests.memory=1Gi, limits.cpu=2, limits.memory=2Gi, pods=5

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-dev still cannot create pods (oc auth can-i should return no).

  • oc describe quota team-quota -n team-payments-dev shows the hard limits above.

Solution (try yourself first)

Click each step only if you need a hint.

Step 1 — Create the project
oc new-project team-payments-dev \
  --display-name="Payments Team (Dev)" \
  --description="Default project for Payments team development workloads"
Step 2 — Apply standard tenant labels
oc label namespace team-payments-dev team=payments environment=dev security-tier=basic
oc get namespace team-payments-dev --show-labels
Step 3 — Bind the team group to edit in this project only
oc create rolebinding payments-devs \
  --clusterrole=edit \
  --group=payments-devs \
  -n team-payments-dev
Step 4 — Confirm the default SA is still denied
oc auth can-i create pods \
  --as=system:serviceaccount:team-payments-dev:default \
  -n team-payments-dev

Expect no.

Step 5 — Apply the team ResourceQuota and inspect it
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

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

giphy

Cleanup

Before moving to the next module, run the lab cleanup script to reset transient resources from this module.

cd ~/openshift-security-roadshow
bash setup/lab-cleanup.sh --module 101-02