Chapter 23Lesson 05240–300 min

Checkpoint Lab — Secrets, Credentials, Environment Isolation, and Security Hygiene

Prove a complete fake-secret operating contract: allowlisted target, Secret-aware handling, one controlled disclosure, automated artifact scan, environment cleanup, and a threat model spanning source through retention.

Checkpoint labThreat modelEvidence ledgerSecurity gateChapter 24 bridge

Checkpoint outcomes

  • Build and run a safe fake-secret pipeline entirely on the local machine.
  • Predict and verify source, scope, runtime, artifact, and cleanup changes.
  • Inject one intentional fake disclosure and prove the scanner detects it.
  • Produce an evidence ledger and threat model without publishing the fake plaintext unnecessarily.
  • Define production controls that remain outside Robot Framework.

Current compatibility baseline — verified 2026-08-31. Robot Framework 7.4.2 is the stable course baseline and requires Python 3.8+. Secret variables and robot.api.types.Secret are new in Robot Framework 7.4. Secret values are masked in Robot's own argument/return representations, but they are not encrypted, and code can access the real value through .value. The mandatory labs use only a deliberately fake value, a synthetic allowlisted target, local files under an isolated temporary/project directory, and Robot Framework core/standard libraries. No real account, browser, API, database, SSH service, Pabot, CI provider, container runtime, secret manager, paid platform, or production system is required. Robot Framework 7.5b1 is prerelease and is not required.

1. Checkpoint architecture

Checkpoint: functional status and security evidence are separate gates
flowchart TD
  A["Parent shell — RF23_FAKE_TOKEN"] --> B["Robot ${TOKEN: Secret}"]
  B --> C{"Target allowlisted?"}
  C -->|no| X["FAIL before secret use"]
  C -->|yes| D["Secret-aware custom keyword"]
  D --> E["Safe non-secret status"]
  E --> F["Safe output.xml / log.html / report.html"]
  B --> G["Unsafe demo unwraps .value"]
  G --> H["Unsafe artifact"]
  F --> I["Artifact scanner: 0 hits"]
  H --> J["Artifact scanner: hit -> policy FAIL"]
  I --> K["Cleanup + threat model"]
  J --> K

The safe and unsafe branches share the same fake source but must produce different evidence. This is intentional: the checkpoint demonstrates that Robot functional PASS cannot replace a security artifact gate.

2. Preflight and exact assumptions

  • Python 3.8+ and Robot Framework 7.4.2 in an isolated virtual environment.
  • No real credentials. Use exactly the fake sentinel RF23_FAKE_ONLY_7z9q.
  • No network target. The only allowed target is local-synthetic.
  • Run from a disposable rf23-checkpoint directory you own.
  • Do not upload evidence/unsafe anywhere; it intentionally contains the fake disclosure.
python --version
python -m robot --version
python -c "from robot.api.types import Secret; print(Secret('FAKE'))"
python -c "import os; print('source present:', 'RF23_FAKE_TOKEN' in os.environ)"

3. Predict before acting

Prediction Expected change Independent verification
P1 — Safe Robot variable Environment string becomes a Secret object inside Robot. Safe logs show masked representation; scanner finds zero raw sentinel hits.
P2 — Target guard Unauthorized target fails before secret-aware keyword runs. Run one negative test with target=production fake string; observe guard failure and no leak.
P3 — Unsafe demo Unwrapping creates plaintext in Robot evidence. Unsafe scan returns non-zero and names the contaminated artifact.
P4 — Cleanup Parent environment variable is removed only by the parent shell. Presence-only Python check prints False after shell cleanup.

4. Build the checkpoint files

Reuse the secret_guard.py and scan_artifacts.py from Lesson 2. Add this suite:

*** Settings ***
Library    libraries/secret_guard.py

*** Variables ***
${TOKEN: Secret}    %{RF23_FAKE_TOKEN}

*** Test Cases ***
Safe Pipeline
    [Tags]    safe
    Assert Allowed Target    local-synthetic
    ${result}=    Use Fake Secret Safely    ${TOKEN}
    Should Be Equal    ${result}    synthetic-operation-accepted
    Log    SECURITY_EVIDENCE target=local-synthetic secret_representation=masked

Wrong Target Is Blocked
    [Tags]    guard-negative
    Run Keyword And Expect Error
    ...    Target 'production' is not allowlisted.
    ...    Assert Allowed Target    production

Unsafe Fake Disclosure
    [Tags]    unsafe-demo
    Assert Allowed Target    local-synthetic
    ${raw}=    Unsafe Unwrap For Demonstration    ${TOKEN}
    Log    INTENTIONAL_FAKE_DISCLOSURE=${raw}

Run Keyword And Expect Error is acceptable here because the guard failure itself is the expected test outcome; it does not swallow a real authentication/TLS failure. The unsafe test remains isolated by tag.

5. Run the safe and guard-negative slice

mkdir -p evidence/safe
python -m robot --include safe --include guard-negative --outputdir evidence/safe checkpoint.robot
python tools/scan_artifacts.py evidence/safe
# Expected: Robot PASS, scanner PASS (exit 0).

Capture an evidence ledger with only non-secret facts: Robot/Python versions, target name, selected tags, result status, artifact paths, scanner exit code, and cleanup status.

6. Inject and detect the fake disclosure

FAKE SENTINEL ONLY. Do not use real credentials in this branch.

mkdir -p evidence/unsafe
python -m robot --include unsafe-demo --outputdir evidence/unsafe checkpoint.robot
python tools/scan_artifacts.py evidence/unsafe
# Expected: Robot test may PASS; scanner MUST exit 1.

Record only the contaminated filenames in the evidence ledger. Do not copy the fake raw token into the ledger. The scanner demonstrates a policy failure independently of Robot's execution status.

7. Evidence packet

api-version-manifest.txt
  python=<captured version>
  robot=7.4.2

security-evidence.txt
  source=environment (value not recorded)
  target=local-synthetic
  target_guard=PASS
  safe_robot_status=PASS
  safe_scan_exit=0
  unsafe_robot_status=PASS (expected demonstration)
  unsafe_scan_exit=1 (expected policy detection)
  parent_environment_cleanup=VERIFIED

threat-model.md
  source / process / downstream / network / logs / reports / CI / retention

Keep the unsafe Robot artifacts local to the disposable lab until the comparison is complete, then remove them. In a real incident, retention and access decisions belong to the security/incident process rather than a lesson cleanup script.

8. Threat-model checklist

Surface Question Checkpoint answer
Source Could value enter source/history? Environment injection; no literal in Robot/Python source.
Process memory Who can unwrap it? Robot process and trusted custom keyword; Secret is not encryption.
Child process Is inheritance controlled? No child required in checkpoint; Lesson 2 demonstrated explicit env.
Network Where is it sent? Nowhere; synthetic local target only.
Logs/reports Can Robot representation expose it? Safe branch masked; unsafe branch deliberately proves plaintext boundary.
Third-party tools Could they log raw data? None mandatory; production clients require separate review.
CI Who injects/reads it? Simulated locally; production uses CI/external store and least privilege.
Retention How long do artifacts survive? Safe evidence can be retained per policy; unsafe demo removed after local analysis.

9. Cleanup and rollback proof

# Bash/zsh
unset RF23_FAKE_TOKEN
python -c "import os; print('source present:', 'RF23_FAKE_TOKEN' in os.environ)"
# Expected: False
rm -rf evidence/unsafe
# Keep or remove safe evidence according to your local learning needs.
Remove-Item Env:RF23_FAKE_TOKEN -ErrorAction SilentlyContinue
python -c "import os; print('source present:', 'RF23_FAKE_TOKEN' in os.environ)"
Remove-Item evidence/unsafe -Recurse -Force -ErrorAction SilentlyContinue

10. Verification checklist

  • Exactly Robot Framework 7.4.2 (or explicitly documented compatible 7.4.x) was used.
  • No real secret or public/production target was introduced.
  • Safe branch passed target allowlist before secret use.
  • Safe scan found zero literal fake-token occurrences.
  • Wrong-target test proved guard failure before secret use.
  • Unsafe branch created a deliberate fake disclosure and scanner caught it.
  • Evidence ledger contains no raw secret value.
  • Parent environment variable was removed from the launching shell.
  • Unsafe artifacts were not uploaded and were removed after analysis.
  • Threat model distinguishes Robot masking from external security controls.

11. Production operating model added by Chapter 23

A production Robot platform now needs a credential contract alongside its execution contract: governed source, least-privilege identity, Secret-aware Robot paths, narrow unwrapping adapters, authenticated/verified downstream transport, target allowlists, artifact scanning, controlled retention, and incident-ready rotation. Chapter 24 adds parallel execution with Pabot, where these same principles must be applied per worker and per mutable resource rather than assuming one shared secret/state is safe.

Knowledge check

Safe Robot execution passes but the artifact scanner finds the sentinel. What is the pipeline status?

Why is the wrong-target test valuable even though no network request exists?

Can the evidence ledger store Secret.value if the file permissions are restrictive?

What new risk appears in Chapter 24 when Pabot workers run concurrently?

What should happen if this exercise accidentally used a real credential?

Next lesson

Parallel Execution with Pabot, Sharding, and Resource Contention: Core Concepts and Mental Model

Continue with Parallel Execution with Pabot, Sharding, and Resource Contention: Core Concepts and Mental Model. It builds directly on the state, evidence, and operating assumptions established here, so carry those constraints forward rather than treating the next page as an isolated topic.

References and version anchors

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.