CyberNugget

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:

  1. Your data: what you store, how you classify it, who can read it.
  2. Your identities: users, roles, keys, and what they're allowed to do (L46).
  3. 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.

Deep dive 1

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.
Deep dive 2

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.