L45 · The shared responsibility model
Module 7: Cloud, Containers, and Kubernetes · ~20 min · Lesson 45 of 71
🎯 What you'll learn
- The line between "security of the cloud" (the provider) and "security in the cloud" (you)
- How that line moves between IaaS, PaaS and SaaS, and the three things that never move
- Exactly what EKS, MongoDB Atlas and MWAA take off your plate, and what they leave on it
🔥 Why this matters
An auditor asks a team how its payments cluster is patched. Someone answers: "It's EKS. AWS is SOC 2 and PCI DSS certified, so that's covered." It isn't. AWS patches the Kubernetes control plane, but the worker nodes running the team's pods were last updated in March, and the cluster's API endpoint is open to the whole internet because that was the default. Gartner predicted in 2019 that through 2025, 99% of cloud security failures would be the customer's fault: a forecast, not a measurement, but breach reports keep pointing at misconfiguration, not broken hypervisors.
1. Security of the cloud vs security in the cloud
Think of renting a flat. The landlord owns the building and the wiring. You decide who gets a key and whether you leave the window open.
AWS's version is the shared responsibility model: AWS handles security of the cloud (data centers, hardware, hypervisor, network, and the managed services themselves), and you handle security in the cloud (what you build and configure on top). Some controls are shared, each side at its own layer: AWS patches its hosts, you patch your guest OS.
Layer On-prem IaaS PaaS SaaS
(EC2) (MWAA, (GitHub.com)
Atlas)
────────────────────── ──────── ─────── ───────── ────────────
Data, classification YOU YOU YOU YOU
Identities, access YOU YOU YOU YOU
Settings you choose YOU YOU YOU YOU
App code (DAGs, APIs) YOU YOU YOU vendor
Runtime, middleware YOU YOU vendor vendor
OS and its patches YOU YOU vendor vendor
Hypervisor, hosts YOU vendor vendor vendor
Network hardware YOU vendor vendor vendor
Buildings, power YOU vendor vendor vendor
Read it from the top. The first three rows are yours in every column:
- Your data: what you store, how you classify it, who can read it.
- Your identities: users, roles, keys, and what they're allowed to do (L46).
- Your settings: every option the provider lets you choose, including the insecure ones.
A managed service removes rows from the bottom of your list. It never removes the top three.
2. "Managed" is a spectrum, not a switch
IaaS (infrastructure as a service) rents you virtual machines, disks and networks; you run everything from the OS up. PaaS (platform as a service) runs the platform, such as a database or a scheduler, and you bring code and configuration. SaaS (software as a service) is a finished application; you manage users and settings.
Real services rarely sit cleanly in one column, so ask per layer: who installs the patch, and who decides when? GitHub patches GitHub.com, but branch protection, org admins and personal access tokens are yours. Kong Konnect hosts the control plane, but you usually run the data planes, so those gateway nodes are yours to patch.
The provider's SOC 2 and PCI DSS reports cover their rows. Your auditor still wants yours.
3. EKS: AWS runs the brain, you run the body
┌──────────────── AWS-managed account ─────────────────┐
│ EKS control plane, spread over several AZs │
│ API server · etcd · scheduler · controller manager │
│ AWS: runs it, patches it, scales it, encrypts etcd │
└──────────────────────────┬───────────────────────────┘
│ cluster endpoint: public by
│ default, YOUR choice to change
┌──────────────────────────┴───── your account/VPC ────┐
│ worker nodes: AMI, kubelet, containerd ──── YOU * │
│ add-ons: VPC CNI, CoreDNS, kube-proxy ───── YOU │
│ cluster version upgrades ────────────────── YOU │
│ access entries, RBAC (L27) ──────────────── YOU │
│ pod security, network policies (L12, L51) ─ YOU │
│ pod IAM roles, images, Secrets, app code ── YOU │
└──────────────────────────────────────────────────────┘
* Fargate and EKS Auto Mode move most node work to AWS
AWS operates the control plane in an AWS-owned account. On Kubernetes 1.28 and later, EKS also envelope-encrypts all API data in etcd by default (L19), optionally with your own KMS key.
Everything that runs your workloads is the data plane, and that's yours. Details that surprise people:
- Managed node groups aren't self-patching. AWS publishes updated EKS-optimized AMIs; you start the node group update. Self-managed nodes are entirely yours.
- Add-ons such as the VPC CNI and CoreDNS aren't upgraded automatically when new versions ship.
- Cluster versions: you start the upgrade. If you wait past the end of extended support, AWS upgrades the control plane for you, ready or not (check the current EKS version calendar).
- Defaults: the API endpoint is public, control plane logging is off, and no Pod Security Standard is enforced until you add a namespace label. Each one is your setting.
Fargate changes the node rows. Each pod gets its own VM-isolated environment with its own
kernel, and AWS patches it (occasionally evicting pods to do so, so set PodDisruptionBudgets).
The trade-offs, from the EKS docs: no privileged containers, no DaemonSets, no hostNetwork or
hostPort, and no IMDS, so pods get AWS access through IRSA (EKS Pod Identity isn't supported on
Fargate at the time of writing). VPC CNI network policies don't apply to Fargate pods either; use
security groups for pods. Your pod spec, images, RBAC and IAM role are still yours.
EKS Auto Mode (December 2024) goes further: AWS patches the node OS, runs core add-ons and replaces nodes on a schedule.
4. Two more lines to draw: MongoDB and Airflow
MongoDB Atlas vs self-managed MongoDB (on EC2 or in a Kubernetes cluster):
| Concern | Atlas | Self-managed |
|---|---|---|
Hosts, OS, mongod patches |
MongoDB, in a window you can set | You |
| TLS in transit | Always on | You configure it |
| Encryption at rest | On by default; your own KMS key optional | You (EBS encryption, etc.) |
| Network exposure | Closed until you add an IP access list entry or private endpoint | Binds to localhost by default (3.6+); you open it |
| Authentication | Database users required | Access control is off by default; you enable it |
| Users, roles, least privilege | You | You |
| Database auditing | You enable it (M10+ tiers) | You (an Enterprise feature, not in Community) |
| Queries, injection (L31), data | You | You |
Airflow on MWAA vs self-hosted (for example, the Helm chart on EKS):
| Concern | MWAA | Self-hosted |
|---|---|---|
| Scheduler, workers, web server, metadata DB patches | AWS, in a maintenance window | You |
| Airflow version upgrades | You choose and start them | You |
DAG code and requirements.txt |
You | You |
| DAG bucket (versioning, public access blocked) | You | n/a (image or git-sync) |
| Execution role: what every task can do in AWS | You | You (the worker's IRSA role) |
| Web server public or private | You choose | You |
| Who gets Admin, Op, User, Viewer | You, via IAM (airflow:CreateWebLoginToken per role) |
You |
| Connections and Variables | You (Secrets Manager backend, L28) | You, plus the Fernet key |
Note one row: on MWAA, whoever can write to the DAGs bucket can run Python as the execution role. Write access to that bucket is deployment access.
🧪 Worked example: who owns each finding?
A review of a fictional payments platform at example.com produced six findings. The skill is assigning each one before anyone argues about it.
| Finding | Owner | Why |
|---|---|---|
| CVE in the EKS API server | AWS | Control plane; AWS patches it (check the EKS security bulletins) |
CVE in containerd on managed node groups |
You | AWS ships a patched AMI; you roll the node groups |
| Same CVE, pods on Fargate | AWS | AWS patches Fargate; you tolerate pod restarts |
EKS endpoint open to 0.0.0.0/0 |
You | A default you never changed |
Atlas cluster with 0.0.0.0/0 in its IP access list |
You | Atlas closes the network by default; someone opened it |
MWAA execution role has s3:* on * |
You | IAM is always the customer's (L46) |
Five of the six are yours, three of them on "managed" services. That's typical.
🛠 Try it (optional, ~5 min)
A thought exercise, no commands. For one service you work on, fill this in on paper (no real hostnames or account numbers):
Layer Who patches? Who decides when? Evidence?
Container base image
Node OS / Fargate
Kubernetes version
Mongo server / Atlas
Airflow / MWAA
IAM roles it uses
Network exposure
Look for rows where the honest answer is "I'm not sure", or where nobody could show evidence (a dashboard, a ticket, a config file). That's where "it's managed" hides work that's actually yours.
🧠 Key takeaways
- The provider secures the cloud; you secure what you put in it and how you configure it.
- Data, identities and configuration are yours in every model, IaaS to SaaS.
- EKS manages the control plane only: nodes, add-ons, upgrades, RBAC, pod security and network policy are yours. Fargate hands node patching to AWS but adds limits.
- Atlas and MWAA close many doors by default; your settings and code can reopen them.
- A provider's SOC 2 report covers its rows, not yours.
📖 Words to know
| Term | Meaning |
|---|---|
| Shared responsibility model | The split of security duties between a cloud provider and its customer |
| Security of / in the cloud | AWS's phrases for the provider's part (infrastructure) and the customer's part (what you build on it) |
| IaaS / PaaS / SaaS | Renting infrastructure / a managed platform / a finished application |
| Control plane | The Kubernetes API server, etcd, scheduler and controllers; managed by AWS in EKS |
| Data plane | The nodes and pods that run your workloads; yours in EKS |
| Managed node group | EKS nodes whose AMIs AWS publishes, but whose updates you start |
| Fargate | Serverless compute for pods: one isolated environment per pod, patched by AWS |
| MWAA execution role | The IAM role every MWAA task runs as |
⏭ Next time
L46 goes deep on the row that's always yours: AWS IAM, with roles, AssumeRole, trust policies and how to get to least privilege.
Reading a vendor's SOC 2 report (and the controls it hands back to you)
What the report is
A SOC 2 report is an independent auditor's opinion on a service organization's controls, measured against the AICPA's Trust Services Criteria (Security always; Availability, Processing Integrity, Confidentiality and Privacy optional). AWS's reports are downloadable from AWS Artifact; MongoDB and most SaaS vendors share theirs through a trust portal, usually under NDA.
Two types matter:
- Type I: the controls were designed properly at one point in time.
- Type II: the controls operated effectively over a period, often 6 to 12 months. For a vendor holding customer financial data, ask for Type II.
The section people skip
Near the end is a list of complementary user entity controls (CUECs): controls the vendor assumes you perform. The auditor's opinion only holds if you do them. They are the shared responsibility model written down by an auditor.
vendor's SOC 2 Type II
│
├── auditor's opinion "controls operated effectively..."
├── vendor's controls tested, with any exceptions listed
├── subservice orgs e.g. "hosted on AWS (carve-out)"
│ └─▶ read THAT provider's report too
└── CUECs "user entities are responsible for..."
└─▶ YOUR to-do list
A carve-out means the vendor's report excludes a subservice organization (such as its cloud host), so you need that provider's report as well. A bridge letter is the vendor's statement covering the gap between the report's end date and today.
Worked example: CUECs for a managed database
Here are the kinds of CUECs you'd typically find for a managed database service, paraphrased and mapped to owners (made-up wording, not quoted from any real report):
| CUEC (typical wording) | What it means for you |
|---|---|
| "Customers are responsible for managing database user accounts and privileges" | Least-privilege DB users per service, reviewed quarterly |
| "Customers are responsible for configuring network access restrictions" | No 0.0.0.0/0; private endpoints for prod |
| "Customers are responsible for the security of credentials used to access the service" | Connection strings in Secrets Manager, rotated (L19) |
| "Customers are responsible for enabling and reviewing audit logs" | Turn on database auditing and send it to your SIEM |
| "Customers are responsible for notifying the vendor of unauthorized access" | Your incident runbook includes the vendor's contact |
Also read the exceptions: controls the auditor found didn't work during the period. An exception about late employee offboarding at the vendor is worth a question; ten of them is a pattern.
🧠 Extra takeaways
- Prefer SOC 2 Type II (operated over time) over Type I (designed at a point in time).
- CUECs are the vendor's list of your responsibilities; turn them into tickets.
- Check for carve-outs, and get the subservice provider's report too.
- Read the exceptions and ask for a bridge letter if the report is old.
Logs across the line: what you can see after an incident
The uncomfortable rule
When something goes wrong in a managed service, the provider investigates its layers, and you investigate yours. You can only investigate with logs you switched on before the incident. Many of the most useful ones are off by default, because they cost money.
What exists, per service
Layer you'd ask about Where the evidence lives Default
────────────────────────── ───────────────────────────── ────────
AWS API calls (all svcs) CloudTrail event history 90 days
kubectl calls to EKS EKS control plane "audit" OFF
log → CloudWatch Logs
Who mapped to which RBAC EKS "authenticator" log OFF
Node and container logs Your agent (Fluent Bit); OFF
Fargate: built-in log router
Atlas admin actions Atlas project activity feed ON
Mongo reads and writes Atlas database auditing OFF
(M10+) or Enterprise audit
MWAA task and scheduler CloudWatch Logs, per log you pick
logs type and level
The trap is the second row. CloudTrail records EKS service calls such as CreateCluster or
UpdateNodegroupConfig, but not the Kubernetes API calls your pods and engineers make. Without
the audit log, "who ran kubectl get secrets in payments?" has no answer. (L52 covers
CloudTrail, VPC Flow Logs and GuardDuty in depth.)
Worked example: the 02:14 question
GuardDuty flags that a pod's service account listed every Secret in the payments namespace at
02:14. What can you find?
| If you had... | You can answer |
|---|---|
| Nothing enabled | Only that GuardDuty saw it (if EKS protection was on); not who, or what else |
| EKS audit log | Which service account, from which pod IP, every other call it made |
| Plus container logs | What the application was doing just before |
| Plus CloudTrail data events on the secrets' targets | Whether the stolen credentials were then used against S3 or other AWS services |
The provider will tell you its control plane wasn't breached. Proving what happened in your namespace is up to you, and it depends on decisions made months earlier.
What AWS will and won't do
AWS allows you to run penetration tests against a published list of its services, on your own resources, without asking first; check the current policy before testing. AWS Support (and, for some customers, the AWS Customer Incident Response Team) can help during an active event, but they don't run your investigation or restore your data. Your incident response plan (L63) needs a section per managed service: which logs, who to call, and what the vendor can see.
🧠 Extra takeaways
- CloudTrail doesn't record Kubernetes API calls; enable the EKS audit log.
- Database auditing and control plane logs are usually off by default and cost money; decide deliberately.
- Logs must exist before the incident; turn them on for prod now, not during the outage.
- Each managed service needs its own line in your incident runbook.
The quiz for this lesson and the Tests section need JavaScript.