OPSRUNG / RECORDS API LEARNING PROJECT

Extract this ZIP into a folder named opsrung-lab. Keep all eight files together.
Open threat-model.txt in a text editor for lab 01. No runtime is needed for that worksheet.

CHOOSE ONE RUNTIME FOR LABS 02-06
Local machine: Node.js 24. No npm install is needed.
Docker: Docker Engine 23 or newer running Linux containers. Node.js runs inside
the container; no host Node.js installation is needed. Start the Docker engine.
Edit files on your computer for either route. The website remembers your choice.

OPEN A TERMINAL IN THE EXTRACTED FOLDER
Windows: open the folder in File Explorer. Type powershell in the address bar and
press Enter. VS Code: open this folder, then Terminal > New Terminal.
macOS/Linux: open Terminal and cd to the extracted folder.

LAB 02 / REPRODUCE, FIX, VERIFY
Local machine:
  node verify-lab.mjs baseline
Docker:
  docker run --rm --mount "type=bind,source=.,target=/app,readonly" -w /app node:24-alpine node verify-lab.mjs baseline
Expect 3 passing tests and 2 failures, followed by a baseline PASS message.
This confirms the expected starting bug; it does not mean the starter is secure.

In app.mjs, below the LAB 02 comment and above the successful return, insert:
  if (record.owner !== user) {
    return { status: 403, body: { error: 'Forbidden' } };
  }
Save app.mjs. Keep the security tests unchanged.
Local machine:
  node verify-lab.mjs fixed
Docker:
  docker run --rm --mount "type=bind,source=.,target=/app,readonly" -w /app node:24-alpine node verify-lab.mjs fixed
Expect 5 passing tests and a fixed-API PASS message. The first Docker run may
download node:24-alpine. All commands above run from the extracted project folder.

LAB 03 / CHECK THE RUNTIME
Local machine: node --version, then node --check app.mjs, then the fixed verifier.
Docker:
  docker build -t opsrung-lab:local .
  docker image inspect opsrung-lab:local --format "{{.Config.User}}"
Expect user node. A failing security test must stop the image build.

LAB 04 / PROVE THE REGRESSION CHECK
Temporarily remove only the ownership guard. Run the baseline verifier for your
route: it should confirm 3 passes and 2 failures. Restore the guard, save, then
run the fixed verifier. Leave the app with all five tests passing.

OPTIONAL GITHUB ACTIONS
Use your own lab repository. Keep app.mjs and security.test.mjs at the root and
copy security.yml to .github/workflows/security.yml. Commit and push using your
normal Git workflow. Open Actions > Security regression tests > security-tests.
This uploads exercise files to GitHub; it does not publish the website.
A hosted run is optional. Required merge checks need separate repository rules.

LAB 05 / START AND CHECK THE API
Local machine, Terminal 1:
  node app.mjs
Docker, Terminal 1 (rebuild after editing source):
  docker build -t opsrung-lab:local .
  docker run --rm --name opsrung-lab -p 127.0.0.1:3000:3000 opsrung-lab:local
Keep Terminal 1 open. Verify the running API from Terminal 2:
Local machine:
  node verify-lab.mjs release
Docker:
  docker exec opsrung-lab node verify-lab.mjs release
Expect PASS with four checks. This verifier contacts only 127.0.0.1:3000.
If port 3000 is busy, stop only an earlier exercise server you started, then retry.
Stop Node with Ctrl+C in Terminal 1. For Docker, run in Terminal 2:
  docker stop opsrung-lab
The --rm container is removed when it stops. Your source and image remain.

LAB 06 / OBSERVE AND RESPOND
Start the API for your chosen route again. Send Alice and Bob requests as shown
on the website. Find record_read events with statuses 200 and 403 in Terminal 1.
Open incident-playbook.txt, fill in the roles and all four prompts, and save.
Stop the exercise server or container when finished.

The fixture intentionally starts with an authorization flaw and uses synthetic
identities. Never add real data or credentials. It is an exercise, not production
authentication. Completion marks are your own browser record, not certificates.
