Microservice vulnerabilities: secure deployments and runtime — this is about protecting the tiny, independent applications that make up modern software from being hacked or misbehaving while they are running. For your CKS exam, you need to know exactly how to use runtime security tools like Falco, AppArmor, and Seccomp to lock down each microservice so that even if an attacker gets inside one, they cannot spread to the others.
Jump to a section
A simple way to picture Microservice Vulnerabilities: Secure Deployments and Runtime
Have you ever wondered how a single apartment building can safely house dozens of different families without one tenant accidentally walking into the wrong flat or causing a fire that spreads everywhere?
Imagine you live in a large apartment building. Each flat has its own front door with a lock (a microservice). Now imagine the building manager installs a security guard at the main entrance who checks everyone's ID card before they can even enter the lobby — that is like a runtime security tool called Falco, which watches every request coming into your system. The manager also puts special locks on each flat's door that only open for the specific key of the person who lives there — that is like AppArmor, a security profile that controls exactly what each application is allowed to do. And finally, the manager installs a rule that the plumbing system can only carry water, not chemicals — that is like Seccomp, which restricts what system calls a program can make.
If a delivery person tries to enter Flat 3B but is not authorised, the guard stops them (Falco alerts on suspicious activity). If someone breaks into a flat and tries to open the safe, the special lock on the safe might refuse because the intruder's key does not have the right permissions (AppArmor blocks the action). And if a program inside the flat tries to call a dangerous system function — like turning on the gas without the right paperwork — Seccomp blocks that specific call. Together, these three layers keep each microservice isolated and safe, even if one gets compromised.
When you build software today, you rarely create one giant program. Instead, you break it into many small, independent services that talk to each other over a network. Each of these small services is called a microservice. Think of them like separate workers in a factory: one worker only puts wheels on cars, another only paints the car body, another only tests the engine. If one worker gets sick (or compromised by a hacker), the others can keep working. But this design creates a new problem: how do you stop a compromised microservice from damaging others?
That is where runtime security tools come in. Runtime means the period when the software is actually running and doing its job — not when it is being written or installed. Vulnerabilities are weaknesses that an attacker could exploit. So 'microservice vulnerabilities' are the gaps that let an attacker break a microservice while it is running.
The CKS exam focuses on three specific tools that secure microservices at runtime: Falco, AppArmor, and Seccomp. Let us break down each one.
Falco is a runtime security monitoring tool created by Sysdig. It acts like a security camera that watches every action happening inside your containers (containers are lightweight, portable environments that run each microservice). Falco looks for unexpected behaviour — for example, a microservice that suddenly starts writing to the system's password file, or a process that tries to open a network connection to an unknown server. When Falco detects something suspicious, it can send an alert to your security team or even trigger an automatic response, like stopping the container. Falco uses 'rules' — simple text files that define what is normal and what is suspicious. You can write your own custom rules to match your specific application.
AppArmor is a Linux kernel security module that lets you restrict what a program can do. Think of it as a strict rule book for each application. When you create an AppArmor profile for a microservice, you define exactly which files it can read, which directories it can write to, which network connections it can make, and which other programs it can run. If the microservice tries to do anything not in the profile, the kernel blocks it immediately. For example, if your microservice is a simple web server and its AppArmor profile says it can only read files in the /var/www directory, and then an attacker tricks it into trying to read /etc/shadow (where passwords are stored), AppArmor stops that action. AppArmor profiles are enforced at the kernel level, so even if the microservice itself is hacked, the hacker cannot bypass AppArmor unless they also break out of the kernel — which is extremely difficult.
Seccomp (short for secure computing mode) is another Linux kernel security feature. It filters the 'system calls' that a program can make. System calls are the way a program asks the operating system to do something — like open a file, send data over a network, or create a new process. Every program needs some system calls, but many programs do not need dangerous ones like 'ptrace' (which can be used to debug or hijack other programs) or 'mount' (which lets you attach filesystems). With Seccomp, you create a profile that lists exactly which system calls are allowed (whitelist) or which are blocked (blacklist). If your microservice tries to make a blocked system call, the kernel kills the process or prevents the call. This is especially important because many container exploits rely on calling unusual system calls to break out of the container.
Why do you need all three? Because each tool covers a different layer. Falco watches behaviour at a high level (processes, network, files) and alerts you. AppArmor restricts access to files and capabilities at the kernel level. Seccomp controls the lowest level — the system calls themselves. Using them together gives you 'defence in depth', meaning if one layer fails, the others still protect you.
In the old days, before microservices, you might have run one big application on a physical server. You could trust that application implicitly because it was the only thing running. But today, with dozens or hundreds of microservices running on the same machine in containers, you cannot trust any single one. That is why runtime security tools are essential. They enforce the principle of least privilege, which means giving each microservice only the permissions it absolutely needs to do its job — nothing more.
When you deploy a microservice in Kubernetes (the system that manages containers), you can attach AppArmor and Seccomp profiles to your pods (a pod is the smallest unit in Kubernetes, usually containing one container). You can also install Falco as a DaemonSet (a special Kubernetes object that runs on every node in the cluster) to monitor all activity. The CKS exam expects you to know how to configure these for a deployment.
Identify the microservice's required resources
Before you can create a security profile, you need to know exactly what the microservice needs to do. Run the container in a test environment with full permissions and use tools like 'strace' to capture all system calls, or 'aa-logprof' to log AppArmor-denied actions. This gives you the baseline for creating a minimal profile.
Create a custom AppArmor profile
Write an AppArmor profile that only grants access to the files, directories, and capabilities the microservice needs. For example, a web server might need read access to /var/www and network access to bind to port 80. Save the profile to /etc/apparmor.d/ on each node in the cluster.
Load the AppArmor profile
Use the command 'apparmor_parser -r -W /etc/apparmor.d/<profile_name>' to load the profile into the kernel. If you skip this step, the kernel does not know about the profile, and the pod will fail to start when it tries to use it.
Configure the Kubernetes pod to use the AppArmor profile
Add an annotation to the pod spec: 'container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_name>'. Deploy the pod. If the profile is not loaded, the pod will stay in a 'ContainerCreating' state. Check the events to debug.
Create and apply a Seccomp profile
Write a JSON file that whitelists only the system calls your microservice needs (using 'strace' to determine them). Set 'defaultAction' to 'SCMP_ACT_ERRNO'. Then reference this file in the pod's securityContext under 'seccompProfile.type: Localhost' and 'seccompProfile.localhostProfile: <path>'. Deploy and verify the pod starts successfully.
Install Falco and configure custom rules
Deploy Falco as a DaemonSet in your cluster using the official Helm chart or YAML files. Write custom Falco rules to detect behaviours like shell access, privilege escalation, or outbound connections to unknown IPs. Test the rules by simulating an attack (e.g., 'kubectl exec' into a pod and run a shell command) and confirm the alert appears in Falco's output.
Imagine you are the security engineer at a mid-sized online retail company. Your team has built a microservices-based application that handles customer orders, payments, inventory, and shipping. Each microservice runs in its own container on a Kubernetes cluster. One day, a developer accidentally exposes a debug endpoint in the payment microservice, and an attacker discovers it. The attacker sends a crafted request that lets them execute arbitrary commands inside the payment container.
Here is what happens step by step when you have runtime security in place:
The attacker tries to read the secret keys stored in the container's environment variables. The payment microservice does not actually need those keys — they are for the authentication service — but they are present because of a misconfiguration. However, the AppArmor profile for the payment microservice restricts file access to only the /app directory. The attacker's command tries to read /proc/self/environ (where environment variables are stored), but AppArmor blocks that system call immediately. The attacker gets an error instead of the keys.
Frustrated, the attacker tries to break out of the container by calling the 'mount' system call to attach the host filesystem. But the Seccomp profile for all containers only allows a strict whitelist of system calls — 'mount' is not on that list. The kernel kills the attacker's process. The attacker's command fails silently.
At the same time, Falco is watching. It has a rule that triggers whenever a process inside a container tries to read /proc/self/environ. Falco sees the blocked attempt and sends an alert to your security operations centre (SOC). The alert includes metadata like which node, which pod, which container, and the exact command that was blocked. Your SOC team can now investigate and patch the debug endpoint before any real damage occurs.
Later, the team deploys a new version of the inventory microservice. The developer forgot to include the AppArmor profile. Your CI/CD pipeline (the automated process that tests and deploys code) has a check that rejects any deployment without an explicit AppArmor profile for each container. The deployment fails, and the team must fix the configuration before it goes live. This is a common practice called 'enforcing security policy at admission time' using an admission controller like OPA Gatekeeper or Kyverno.
Every month, you review the Falco alerts and the AppArmor/Seccomp profiles. You find that many profiles are too permissive — for example, they allow network access to external IPs that the microservices do not need. You tighten those profiles, further reducing the attack surface.
In a real organisation, you would also use tools like:
Falco to monitor for shell access inside containers (a common attack pattern)
AppArmor to prevent microservices from writing to system directories
Seccomp to block dangerous system calls like 'clone' with certain flags
Admission controllers to enforce that every pod has these profiles before it can run
Centralised logging to collect Falco alerts and correlate them with other security events
The CKS exam tests your ability to secure microservice deployments using runtime security tools, specifically Falco, AppArmor, and Seccomp. This is a hands-on exam where you might be asked to apply profiles, interpret alerts, or configure rules. Here is exactly what you need to know.
Falco exam focus: You may be given a scenario where a container exhibits suspicious behaviour, and you must read a Falco alert output to determine what happened. You might also be asked to write a custom Falco rule that detects a specific pattern, such as a container writing to /etc/shadow or spawning a shell. Key concepts: macro, rule, output, priority. The exam loves to test that you understand the difference between a 'macro' (a reusable condition snippet) and a 'rule' (the complete detection logic). Another trap: Falco rules are written in YAML, and they must be loaded correctly. You might be asked to edit a falco_rules.yaml file and apply it.
AppArmor exam focus: You will need to generate an AppArmor profile for a given containerised application. The exam provides a tool like 'aa-genprof' or 'aa-logprof' that profiles an application by watching its behaviour. You may be given a log of denied actions and asked to create a profile that allows only those necessary actions. Common trap: AppArmor profiles must be loaded (using apparmor_parser) and then referenced in the pod's annotation. The annotation format is: container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_name>. You must remember that the profile path on disk is /etc/apparmor.d/<profile_name>. Another trap: If you forget to load the profile before referencing it, the pod will fail to start.
Seccomp exam focus: You may be asked to create a Seccomp profile for a container. Unlike AppArmor, Seccomp profiles are JSON files. You might need to use a tool like 'strace' or 'audit2allow' to list the system calls a program makes, then write a profile that only allows those calls. The exam might give you a list of blocked system calls and ask you to modify the profile to allow one of them. Common trap: Seccomp profiles can be scoped to a pod or container level, and you must set the correct seccompProfile type (RuntimeDefault, Localhost, or Unconfined). The exam expects you to know that 'RuntimeDefault' uses the container runtime's default profile, which is safe but not custom. 'Localhost' lets you specify a custom file. 'Unconfined' disables Seccomp — never use this in production, but the exam might test that you recognise it as insecure.
Integration traps: The exam may combine these tools. For example, you might be asked to explain why a container is failing to start. The answer could be because the Seccomp profile blocks a system call required by the container's entrypoint. Or you might have to choose the right tool for a specific scenario: if the requirement is to detect anomalous behaviour, the answer is Falco. If the requirement is to restrict file access, the answer is AppArmor. If the requirement is to filter system calls, the answer is Seccomp.
Key definitions to memorise:
Falco rule structure: rule, condition, output, priority, tags
AppArmor profile syntax: /path/to/file rw, capability (like cap_net_admin), network (like inet tcp)
Seccomp JSON schema: defaultAction (SCMP_ACT_ALLOW or SCMP_ACT_ERRNO), archMap, syscalls (names, action)
The annotation for AppArmor in Kubernetes
The seccompProfile field in a pod's securityContext
Exam tip: The CKS is a performance-based exam. You will not get multiple-choice questions about these tools. You will actually edit YAML files, run commands, and interpret output. So practise with a real Kubernetes cluster and real tools. Install Falco, create AppArmor profiles, and test Seccomp policies until you are comfortable.
Falco detects suspicious behaviour at runtime using custom rules, but it does not automatically block attacks unless you configure an output plugin.
AppArmor restricts a container's access to files, networks, and Linux capabilities using profiles written in AppArmor's own syntax.
Seccomp filters system calls (the lowest-level requests a program makes to the kernel) and uses JSON profiles with a whitelist (defaultAction: SCMP_ACT_ERRNO) for maximum security.
In Kubernetes, you attach an AppArmor profile to a pod using the annotation container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_name>.
Seccomp is configured in a pod's securityContext field under seccompProfile, with types RuntimeDefault, Localhost, or Unconfined — never use Unconfined in production.
Always test your AppArmor and Seccomp profiles with a tool like 'strace' or 'aa-logprof' to ensure your application can still run correctly after applying the policy.
Defence in depth means using Falco for detection, AppArmor for file and capability control, and Seccomp for system call filtering — all three together provide layered security.
Admission controllers (like OPA Gatekeeper) can enforce that every pod has an AppArmor or Seccomp profile before it is deployed, preventing misconfigured containers from running.
These come up on the exam all the time. Here's how to tell them apart.
Falco
Monitors runtime behaviour and alerts on suspicious activity
Does not block actions by default — only detection
Rules written in YAML, can be customised per environment
AppArmor
Restricts file access, capabilities, and network at kernel level
Blocks actions automatically based on profile
Profiles written in AppArmor syntax (plain text, not YAML)
AppArmor
Controls high-level resources like files and network
Profile is per application or container
Syntax is plain-text, loaded with apparmor_parser
Seccomp
Controls low-level system calls to the kernel
Profile can be per container or pod-wide
Syntax is JSON, stored as a file or ConfigMap
Whitelist Seccomp Profile
defaultAction set to SCMP_ACT_ERRNO (block all unlisted)
Only explicitly listed system calls are allowed
More secure because it reduces attack surface significantly
Blacklist Seccomp Profile
defaultAction set to SCMP_ACT_ALLOW (allow all unlisted)
Only explicitly listed system calls are blocked
Less secure because dangerous calls might be missed from the blacklist
Kubernetes Annotation for AppArmor
Format: container.apparmor.security.beta.kubernetes.io/<container_name>
Value: localhost/<profile_name>
Profile must exist on node's filesystem before pod starts
Kubernetes securityContext for Seccomp
Configured under seccompProfile in pod spec
Type can be RuntimeDefault, Localhost, or Unconfined
Localhost profiles require file on node or can be embedded via ConfigMap
Mistake
Falco can block attacks automatically without any extra configuration.
Correct
Falco is primarily a monitoring and alerting tool. By default, it only detects and logs suspicious activity. To automatically block or kill a container, you need to configure a Falco output plugin (like Falco Sidekick) or integrate it with a tool like Kubernetes pod security policies.
Many beginners see 'security tool' and assume it automatically prevents attacks, but Falco's main job is detection — blocking requires additional setup.
Mistake
AppArmor and Seccomp profiles are the same thing and you only need one of them.
Correct
They operate at different layers. AppArmor controls file access, network access, and capabilities. Seccomp controls system calls. They complement each other: AppArmor cannot block a specific system call (like ptrace) unless you use a capability rule, but Seccomp can. You need both for full protection.
Both are Linux security modules, so beginners lump them together. But the CKS exam explicitly tests them as separate technologies.
Mistake
You can create a Seccomp profile by just listing the system calls you want to block.
Correct
Best practice is to use a whitelist (defaultAction: SCMP_ACT_ERRNO) and list only the system calls you want to allow. Blacklisting is dangerous because you might miss a risky call. The exam expects you to understand whitelist vs blacklist approaches.
Blacklisting seems easier, but it is less secure. Beginners default to blacklisting because it feels more intuitive.
Mistake
If you use Docker's default Seccomp profile, your container is completely safe.
Correct
Docker's default profile blocks around 44 dangerous system calls, but it still allows many that are not needed for a specific microservice. For example, a simple web server does not need 'mount' or 'reboot', but the default profile might allow them. Customising the profile for each microservice provides much stronger security.
Docker's documentation highlights the default profile as secure, so beginners think it is sufficient. But the CKS exam tests custom profiles.
Mistake
AppArmor profiles are written in JSON format.
Correct
AppArmor profiles are written in a plain-text language specific to AppArmor, not JSON. Seccomp profiles are written in JSON. Mixing these up is a common exam mistake.
Both tools are configured via files, but the file formats are completely different. The exam might present a JSON file and ask you to identify it as Seccomp or AppArmor.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Falco monitors behaviour and sends alerts when it detects suspicious activity. AppArmor restricts what files and capabilities a container can access. Seccomp restricts which system calls a container can make to the kernel. Use all three together for layered security.
Yes, the AppArmor profile file must exist on every node where a pod using that profile might be scheduled. Seccomp profiles can be stored in a file on each node or embedded in the pod spec via a ConfigMap, but localhost profiles require the file on the node.
Run the container with an unconfined profile first, then use 'aa-logprof' to review denied actions and generate a profile that allows only what the application attempted. You can also use a tool like 'bane' from the Sysdig team to auto-generate profiles from container images.
The container will crash or hang, and you will see an error in the pod logs like 'operation not permitted'. You need to check the application's strace output and add the missing system call to the allowed list in the JSON profile.
Not by default. Falco only detects and alerts. You can configure it to trigger a response, like killing the pod, by using a tool like Falco Sidekick with a custom webhook or integration with Kubernetes pod security policies.
It defines what happens when a system call is not explicitly listed. Set it to 'SCMP_ACT_ERRNO' to block all unlisted calls (whitelist approach). Set it to 'SCMP_ACT_ALLOW' to allow all unlisted calls (blacklist approach — less secure).
Yes, you may be asked to modify or create a Falco rule in a YAML file. You should understand the structure: rule name, condition (the macro or expression), output (the alert message), priority (e.g., WARNING, CRITICAL), and tags.
You've finished Microservice Vulnerabilities: Secure Deployments and Runtime. Continue through the CKS study guide to build a complete picture of the exam.
Done with this chapter?