◇ OpenCyber Academy
Technologist · Chapter 22 · English

Chapter 22 — Cloud and container security: automation

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 22 — Cloud and container security: automation

Lesson map

Lesson 22 published. Map, example, EX064.

flowchart TD
  N0["Learning outcomes"]
  N1["22.1 Shift checks earlier"]
  N2["22.2 IaC smells"]
  N3["Lab — pipeline checks"]
  N4["22.3 Reading the result"]
  N5["22.4 Explaining blocks"]
  N6["22.5 Exceptions"]
  N7["Measuring the checks"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX064"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["22.1 Shift checks earlier"]
  N2["22.2 IaC smells"]
  N3["Lab — pipeline checks"]
  N4["22.3 Reading the result"]
  N5["22.4 Explaining blocks"]
  N6["22.5 Exceptions"]
  N7["Measuring the checks"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX064"]
[Learning outcomes]
    |
    v
[22.1 Shift checks earlier]
    |
    v
[22.2 IaC smells]
    |
    v
[Lab — pipeline checks]
    |
    v
[22.3 Reading the result]
    |
    v
[22.4 Explaining blocks]
    |
    v
[22.5 Exceptions]
    |
    v
[Measuring the checks]
    |
    v
[Worked example] --> [Exercise EX064]

Learning outcomes

You will (1) add security checks to the deployment pipeline; (2) block risky changes before merge; (3) keep checks explainable.

22.1 Shift checks earlier

Finding a public bucket after deployment means it was exposed for a time. Checking infrastructure code before merge stops it reaching production. Detecting a problem after deployment depends on a scheduled check running and someone reading the result, and the data may already have been exposed by then. A pipeline check runs on every proposed change before merge, and the developer sees the problem while the change is still fresh in mind. Detection after deployment remains necessary for changes that bypass the pipeline.

22.2 IaC smells

Rahman et al. (2019) studied infrastructure-as-code scripts and found recurring security smells, such as hard-coded secrets and admin by default. Cobalt's rules target similar patterns. Rahman et al. name seven such smells, including hard-coded secrets, admin by default, suspicious comments, empty passwords and invalid IP address binding. Cobalt's four rules are a deliberately small selection matched to its own risks: a public bucket, a mutable image tag, a container running as root and a secret written in a file. Each corresponds to a scenario or finding from earlier chapters.

Lab — pipeline checks

"""Flag risky settings in synthetic infrastructure-as-code records before merge (stdlib only)."""
changes = [
 {"id": "PR-41", "bucket_public": False, "image_tag": "2.5", "run_as_root": False, "secret_in_file": False},
 {"id": "PR-42", "bucket_public": True, "image_tag": "2.5", "run_as_root": False, "secret_in_file": False},
 {"id": "PR-43", "bucket_public": False, "image_tag": "latest", "run_as_root": True, "secret_in_file": False},
 {"id": "PR-44", "bucket_public": False, "image_tag": "1.2", "run_as_root": False, "secret_in_file": True},
 {"id": "PR-45", "bucket_public": False, "image_tag": "3.0", "run_as_root": False, "secret_in_file": False}]
rules = {"bucket_public": lambda c: c["bucket_public"], "mutable tag": lambda c: c["image_tag"] == "latest",
         "run_as_root": lambda c: c["run_as_root"], "secret_in_file": lambda c: c["secret_in_file"]}
blocked = 0
for c in changes:
    hits = [n for n, f in rules.items() if f(c)]
    blocked += bool(hits); print(f"{c['id']}: {'BLOCK ' + ', '.join(hits) if hits else 'pass'}")
print(f"{blocked}/{len(changes)} changes blocked")

Run with python3 lab_iac.py. Verified output:

PR-41: pass
PR-42: BLOCK bucket_public
PR-43: BLOCK mutable tag, run_as_root
PR-44: BLOCK secret_in_file
PR-45: pass
3/5 changes blocked

22.3 Reading the result

Of 5 proposed changes, 3 are blocked: PR-42 makes a bucket public, PR-43 uses the mutable latest tag and runs as root, and PR-44 puts a secret in a file. PR-41 and PR-45 pass. PR-43 triggers two rules at once, which shows the rules are evaluated independently and each hit is reported, so the developer can fix both in one round. PR-41 and PR-45 pin specific tags, keep buckets private, run as non-root and keep secrets out of files. The rule set is small enough that a developer can read all four rules and predict whether a change will pass.

22.4 Explaining blocks

Each blocked change gets a message stating the rule, why it matters and how to fix it. Developers fix most within the day. For PR-44, the message says that a secret was found in a configuration file, that anything in the repository is readable by everyone with access to it and stays in history, and that the secret should be stored in the cluster's secret store and referenced by name. Because the message explains the fix, developers rarely need to ask the platform team for help.

22.5 Exceptions

A rare legitimate need, such as a public bucket for website images, uses an approved exception label reviewed by Kwame. The exception label alone does not let a change through the pipeline. Kwame reviews the reason, confirms that the bucket will hold only public content such as website images, and records the exception with an owner and expiry date. The pipeline then skips that single rule for that single resource, while all other rules still apply to the change. Expired exceptions make the rule apply again automatically on the next change.

Measuring the checks

Priya tracks how many changes are blocked each week and how long fixes take. Early on, many changes are blocked; after a month the number falls as developers learn the rules. A rule that blocks often without finding real problems is reviewed, because false blocks make developers resent the checks.

She also confirms that checks run quickly, under a minute, so they do not slow the pipeline.

Detecting console changes

A nightly comparison of live settings with the repository flags any change made outside the pipeline.

Worked example

The developer of PR-43 asks why latest is blocked. Priya explains that latest can point to different content over time, so the inventory could not say what is running; pinning a version or digest fixes this.

Synthetic case. Changes are synthetic.

Errors and limits

Pipeline checks only cover changes made through the pipeline; console changes need detection too.

Exercises

Synthesis

Block risky changes early with clear explanations and keep detection for the rest.

Continue studying — chapter 22 of 30

← Chapter 21 (draft) · Course chapter index · Chapter 23 (draft) →