Securing the cloud, containers and the supply chain
Lesson 2 of 5
2Securing the cloud, containers and the supply chain
The big pictureWhen companies moved to the cloud the risk did not vanish; it changed shape. The attacker no longer breaks a wall but finds an access key forgotten in a code repo, a storage bucket open to the world, or a * permission a rushed developer granted. And in March 2024 a backdoor in a small compression library called XZ Utils nearly reached most Linux servers in the world, after two years of building trust with the project's maintainer. Modern security means knowing your identities, your settings, and every line you did not write.
What the picture shows: Four layers you protect whatever the service, with automatic monitoring over all of them because settings change every day.
Map of this part
The concepts in order, click any one to jump to it:
Two ways into the same idea
You rent a flat in a luxury tower. The owner is responsible for the foundations, the lifts and the gate guard (the provider's share). But if you leave your door open, give a copy of your key to every delivery driver (broad permissions), or bring in furniture without knowing what is inside it (the supply chain), that is on you. And the smartest thief does not break the door; they wait for someone to hand them the key.
Shared responsibility: in IaaS you own the OS, app, data, identities and virtual network; in PaaS the app, data and identities; in SaaS the data, identities and settings. IAM: least privilege, no Action: "*" or Resource: "*", roles with temporary keys (STS or workload identities) instead of permanent keys, permission boundaries and organisation policies (SCPs). CSPM checks settings continuously against standards such as the CIS Benchmarks, and CNAPP joins CSPM with workload and identity protection. Kubernetes: Pod Security Standards at three levels (Privileged, Baseline and Restricted) enforced by Pod Security Admission; Restricted needs runAsNonRoot, no privilege escalation, all capabilities dropped and seccompProfile: RuntimeDefault; plus least-privilege RBAC and default-deny NetworkPolicy. Supply chain: SBOMs in SPDX or CycloneDX, SLSA v1.0 with build levels L1 to L3, and signing packages and images with Sigstore (cosign). CVE-2024-3094: a backdoor in XZ Utils 5.6.0 and 5.6.1, found by Andres Freund on 29 March 2024 because of half a second of extra delay in SSH.
Before You Start
🧱Systems and network security
You met shared responsibility briefly.
🏛️Zero Trust architecture
The previous lesson.
The Core Idea
1Who is responsible for what?
The higher you climb from IaaS to SaaS the more layers the provider takes, but three things always stay with you: your data, your identities and your settings. Most published cloud incidents sit in these three.
| Layer | IaaS | PaaS | SaaS |
|---|---|---|---|
| Data, identities, settings | You | You | You |
| Application | You | You | Provider |
| OS and patching | You | Provider | Provider |
| Virtual network and firewalls | You | Shared | Provider |
| Hardware and data centres | Provider | Provider | Provider |
2Identity is the new perimeter
In the cloud everything is an API, and every API is called with an identity. So an attacker holding a key for an identity with * owns the whole account. The rules: no permanent keys in code or on laptops (temporary roles instead), no wildcard in actions or resources, MFA for every human, and the root account locked away and unused. Automatic review catches what the eye misses:
Tools such as IAM Access Analyzer and CSPM do this for every policy in the account, every day.
import json
policy = json.loads("""{
"Version": "2012-10-17",
"Statement": [
{"Sid": "ReadReports", "Effect": "Allow", "Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::finance-reports/*"},
{"Sid": "QuickFix", "Effect": "Allow", "Action": "s3:*", "Resource": "*"},
{"Sid": "Admin", "Effect": "Allow", "Action": "*", "Resource": "*"},
{"Sid": "PassAny", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "*"}
]
}""")
def listify(x):
return x if isinstance(x, list) else [x]
for st in policy["Statement"]:
if st["Effect"] != "Allow":
continue
actions, resources = listify(st["Action"]), listify(st["Resource"])
problems = []
if "*" in actions:
problems.append("CRITICAL every action: full admin")
elif any(a.endswith(":*") for a in actions):
problems.append("HIGH every action of a service")
if "*" in resources:
problems.append("HIGH every resource")
if "iam:PassRole" in actions and "*" in resources:
problems.append("HIGH can hand any role to a service: privilege escalation")
print(f"{st['Sid']:<12}", "; ".join(problems) or "ok: narrow action and resource").env file pushed to GitHub. Bots scan public repos for keys within minutes of a push. Use temporary roles and secret scanning before every push.3Containers and Kubernetes
A container is not a virtual machine: they all share one kernel. A container running as root with special privileges may escape to the host and reach every other container. That is why Kubernetes set three levels: Privileged (no limits, for system tools only), Baseline (blocks the most dangerous settings) and Restricted (best practice, your target for every ordinary app). The level is enforced by a label on the namespace: pod-security.kubernetes.io/enforce: restricted.
A single Baseline violation is enough for the pod to be rejected in a namespace enforcing Baseline or Restricted.
pod = { # a pod spec as the cluster sees it, simplified
"name": "reports-api",
"hostNetwork": True,
"containers": [{
"name": "api", "image": "registry.local/reports:latest",
"securityContext": {"privileged": False, "runAsNonRoot": False,
"allowPrivilegeEscalation": True,
"capabilities": {"add": ["NET_ADMIN"]}},
}],
}
def check(pod):
out = []
if pod.get("hostNetwork"):
out.append(("baseline", "hostNetwork shares the node's network"))
for c in pod["containers"]:
sc = c.get("securityContext", {})
if sc.get("privileged"):
out.append(("baseline", f"{c['name']}: privileged container"))
if sc.get("capabilities", {}).get("add"):
out.append(("baseline", f"{c['name']}: adds {sc['capabilities']['add']}"))
if not sc.get("runAsNonRoot"):
out.append(("restricted", f"{c['name']}: may run as root"))
if sc.get("allowPrivilegeEscalation", True):
out.append(("restricted", f"{c['name']}: privilege escalation allowed"))
if "ALL" not in sc.get("capabilities", {}).get("drop", []):
out.append(("restricted", f"{c['name']}: capabilities not dropped"))
if not sc.get("seccompProfile"):
out.append(("restricted", f"{c['name']}: no seccomp profile"))
if c["image"].endswith(":latest"):
out.append(("advice", f"{c['name']}: pin the image by digest, not :latest"))
return out
for level, msg in check(pod):
print(f"[{level:<10}] {msg}")On top of that: least-privilege RBAC (do not give cluster-admin to a service account), a NetworkPolicy that denies all traffic by default then allows only what is needed, secrets in a secrets manager rather than plain variables, and images from a trusted registry, signed and pinned by digest.
4The supply chain: every line you did not write
Your modern app holds hundreds of open-source packages, each a possible door. Three questions: what is in my software? (an SBOM: a component list in SPDX or CycloneDX, compared against vulnerability lists). Who built it, and how? (SLSA: levels proving the build ran on a trusted platform and was not altered). Is it the same thing I received? (signing with Sigstore and verifying before deploying).
Worked example
The task: a CSPM alert: a storage bucket holding customer database backups became public two hours ago, and the logs show the CI/CD role with s3:* on * changed the policy. What do you do now, and what do you change after?
The answer: Now: shut public access (Block Public Access at account level), preserve the CloudTrail logs and the bucket access logs as evidence, and search them: did anyone outside the company download anything in those two hours? If yes, it is a personal data breach to be reported (under the PDPL: within 72 hours). Root cause: the CI/CD role holds far more permission than it needs, and the change skipped review. After: narrow the role to the buckets and actions it needs, make infrastructure as code (Terraform) pass a policy check before merge, lock public access with an organisation policy no role can override, and make this CSPM alert reach an on-call person within minutes, not two hours.
Myth vs Reality
| Myth | Reality |
|---|---|
| The cloud is safe because the provider is a big company. | The provider protects its layer. Your settings, identities and data are always on you. |
| A container is isolated like a virtual machine. | All containers share the host kernel; a container with broad privileges may escape to it. |
| Popular open-source packages are safe. | XZ Utils was a small package almost everywhere. Popularity does not mean review. |
Where you meet it at work
🏦Banks on the cloud
Cloud controls require identity management and settings monitoring.
📦Platform teams
Kubernetes at Restricted by default for every team.
🛒Buying software
Asking a vendor for an SBOM is now common practice in contracts.
Test your understanding
In SaaS, what always stays your responsibility?
The provider runs almost every layer, but who gets in, why, and how the service is set up stays on you.
A policy has Action: "*" and Resource: "*". What is the problem?
Whoever holds this identity owns the whole account.
Which Pod Security level is the target for ordinary apps?
Privileged is for system tools only; Restricted is best practice.
What question does an SBOM answer?
The component list is compared against vulnerability lists so you know at once whether you are affected.
How was the XZ Utils backdoor found?
Andres Freund noticed half a second of delay and odd CPU use, and traced the cause.
Quick review cards
Check Your Understanding
Why are temporary roles better than permanent keys?
Because a temporary key expires within hours, so a leak does less harm, and it is not forgotten in a file for years.
What is the danger of a container running as root with special privileges?
It may escape to the host through the shared kernel and reach every other container.
What are the three supply chain questions?
What is in my software? Who built it and how? Is it the same thing I received?
Resources for this lesson
Grouped by type. Start with the official docs for precision, or an article or video for the explanation.
reference3
Done with this lesson?
Sign in to save your progress.