◇ OpenCyber Academy
Technical · Chapter 12 · English

Chapter 12 — Contained laboratory I

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 12 — Contained laboratory I

Lesson map

Lesson 12 published. Map, example, EX045.

flowchart TD
  N0["Learning outcomes"]
  N1["12.1 Purpose"]
  N2["Lab — secret-like keys"]
  N3["12.2 Reading the result"]
  N4["12.3 Handling"]
  N5["12.4 Kubernetes secrets"]
  N6["12.5 Containment"]
  N7["Why secrets end up in files"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX045"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["12.1 Purpose"]
  N2["Lab — secret-like keys"]
  N3["12.2 Reading the result"]
  N4["12.3 Handling"]
  N5["12.4 Kubernetes secrets"]
  N6["12.5 Containment"]
  N7["Why secrets end up in files"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX045"]
[Learning outcomes]
    |
    v
[12.1 Purpose]
    |
    v
[Lab — secret-like keys]
    |
    v
[12.2 Reading the result]
    |
    v
[12.3 Handling]
    |
    v
[12.4 Kubernetes secrets]
    |
    v
[12.5 Containment]
    |
    v
[Why secrets end up in files]
    |
    v
[Worked example] --> [Exercise EX045]

Learning outcomes

You will (1) search synthetic configuration files for secret-like keys; (2) handle findings safely; (3) move secrets to a vault.

12.1 Purpose

During verification Tomás saw a note mentioning a storage key. He checks whether secrets sit in configuration files. The note on the verification share said only that a storage key had been moved to the vault, but it raised the question of where else keys might sit. Searching configuration files by key name is a quick first pass. The lab uses synthetic copies so that no real secret value is ever read or printed during practice. The search covers environment files, deployment files and notes in the synthetic set.

Lab — secret-like keys

"""Find secret-like key names in synthetic config files without printing values (stdlib only)."""
import re
files = {"app.env": "DB_HOST=db.internal\nDB_PASSWORD=<redacted>\nLOG_LEVEL=info",
         "deploy.yaml": "image: registry.fairway.example/tracker:4.2\nreplicas: 2",
         "notes.txt": "storage key moved to vault on 03-06",
         "worker.env": "QUEUE=jobs\nAPI_TOKEN=<redacted>\nCLOUD_SECRET_KEY=<redacted>"}
pat = re.compile(r"^([A-Z_]*(PASSWORD|TOKEN|SECRET)[A-Z_]*)=", re.M)
hits = {f: [m.group(1) for m in pat.finditer(t)] for f, t in files.items()}
for f, h in hits.items():
    if h: print(f"{f}: {', '.join(h)}")
print(f"{sum(len(h) for h in hits.values())} secret-like keys in {sum(1 for h in hits.values() if h)} of {len(files)} files")

Run with python3 lab_secrets.py. Verified output:

app.env: DB_PASSWORD
worker.env: API_TOKEN, CLOUD_SECRET_KEY
3 secret-like keys in 2 of 4 files

12.2 Reading the result

Three secret-like keys appear in two of four files: DB_PASSWORD in app.env, API_TOKEN and CLOUD_SECRET_KEY in worker.env. Values are not printed. Both environment files contain credentials, while deploy.yaml and notes.txt do not match the pattern. notes.txt mentions a storage key in prose, which the pattern ignores because it looks only for KEY= lines. That is a reminder that the search finds names in assignments, not every mention of a secret. The output gives Grace exactly what she needs to plan rotation and nothing more.

12.3 Handling

Each secret is moved to the provider's secret manager and the old values are rotated, since anyone who saw the files could have copied them. Moving a secret to the secret manager only stops future exposure; anyone who saw the old file may still hold the value. Rotation makes those old values useless to anyone who copied them earlier. Each rotation is planned with the owning developer, because the application must read the new reference from the vault before the old value is revoked. The old values are confirmed as no longer working before each rotation is closed.

12.4 Kubernetes secrets

The Kubernetes good-practice guide advises encrypting secrets at rest and limiting who can read them. For Fairway's cluster, this means checking that secrets are encrypted at rest in the cluster's store and that only the tracker and worker service accounts can read their own secrets. Tomás compares the cluster's RBAC rules against that list and notes any role that can read every secret as a finding for Grace. He also checks that no secret is mounted into a container that does not need it. Any change to these rules goes through the configuration repository like other cluster settings.

12.5 Containment

The lab uses synthetic files; the real search is run read-only by Grace. Tomás runs the pattern only on synthetic files during the lab. The real search across Fairway's repositories is run by Grace with read-only access, and its output, which contains file names and key names but no values, is shared with him afterwards. This arrangement keeps a learner's practice work well away from live credentials. The lab and the real search use the same pattern, so the lab's limits apply to both. Grace records the date and scope of the real search in the evidence register.

Why secrets end up in files

Developers often put credentials in environment files during testing and forget to remove them. Rahman et al. (2019) identified hard-coded secrets as a common security smell in infrastructure scripts. Fairway's files matched this pattern: the worker file was copied from a test setup.

Tomás adds a pipeline check that blocks commits containing secret-like key names with values, giving developers a message pointing to the secret manager instructions.

Access to the secret manager

Only the workloads that need each secret can read it, using their own identities.

Recording rotation

Each rotation is recorded with date, owner and confirmation that the old value no longer works.

False matches

A key named TOKEN_COUNT would match the pattern without being a secret; reviewers check each hit.

Worked example

Rotating CLOUD_SECRET_KEY breaks the worker until its new reference is deployed. Tomás schedules rotation for a quiet hour with the developer present.

Synthetic case. Synthetic.

Errors and limits

Name-based search misses secrets with unusual names; it is a first pass.

Exercises

Synthesis

Find secrets by name, move them, and rotate.

Continue studying — chapter 12 of 18

← Chapter 11 (draft) · Course chapter index · Chapter 13 (draft) →