diff --git a/docs/AGENT_COURSE_GUIDE.md b/docs/AGENT_COURSE_GUIDE.md
index 58c6754..c59bf19 100644
--- a/docs/AGENT_COURSE_GUIDE.md
+++ b/docs/AGENT_COURSE_GUIDE.md
@@ -235,10 +235,15 @@ Select the root `learningObject` node. Set:
menu + next/back).
- **Tracking**: the pass mark is the **Tracking** optional property on the root
(`trackingPassed="80%"`), set via the property panel. `trackingMode` defaults
- to `full_first`. There is **no per-quiz weighting UI** in Nottingham; the LMS
- receives the aggregate score across all scored interactions. (A 25/75
- theme/final weighting would require custom JS in the SCO — not exposed in the
- editor.)
+ to `full_first` (first completed attempt of each quiz is locked in); this
+ course sets it to `full` so the **last** attempt counts (retries can
+ improve). There is **no per-quiz weighting UI** in Nottingham, but per-quiz
+ weighting **is** supported via the `trackingWeight` attribute on each ``
+ (read by `quiz.rlm`'s setup script and passed to `XTSetPageType`), set as a
+ direct attribute write on `data.xml`/`preview.xml`. This course uses
+ `trackingWeight="1"` × 7 theme quizzes + `trackingWeight="21"` for the
+ final → final is 75% of the LMS grade, themes 25%. See
+ `PROJECT_CONTEXT.md` § "SCORM scoring".
### 4.5 Changing attributes the UI widget won't allow (e.g. delaySecs=0)
Some property widgets clamp values (e.g. the Bullets "Delay (secs)"
@@ -362,7 +367,10 @@ Check/Next/Restart work and the score is reported.
preview.xml can overwrite published content on the next Publish.
- **Lockfiles** are left by interrupted editor sessions; clear them.
- **SCORM export needs a guest cookie** (bare curl → 0 bytes).
-- **No per-quiz weighting UI** in Nottingham; LMS gets the aggregate score.
+- **No per-quiz weighting UI** in Nottingham, but `trackingWeight` on each
+ `` works as a direct attribute write; verified to survive an editor
+ open + Publish round-trip (the `lo_data` loader preserves it and the Publish
+ serializer writes it back), so editor-based edits do not drop it.
- **Ampersands in titles** are stored as `&` in `name=` attributes but
render correctly in the player — don't "fix" them.
- **`access_to_whom`**: new projects are Private; set `Public` in the DB if
diff --git a/docs/COURSE_VERIFICATION.md b/docs/COURSE_VERIFICATION.md
index b45189a..868881c 100644
--- a/docs/COURSE_VERIFICATION.md
+++ b/docs/COURSE_VERIFICATION.md
@@ -82,6 +82,19 @@ Two fixes applied per user request, then re-exported:
2. **Final comprehensive quiz expanded from 6 to 18 questions** ✅ — covers all
themes with single-answer, multiple-response, and true/false items; correct
answers verified on all 18. Total questions now 41 (23 theme + 18 final).
+3. **Per-quiz weighting + last-attempt scoring applied** ✅ — `trackingWeight`
+ added to every `` (7 theme quizzes `="1"`, final `="21"` → final is
+ 75% of the LMS grade, themes 25%), and root `trackingMode` changed from
+ `full_first` to `full` so the **last** attempt of each quiz counts (learners
+ can retry tricky questions without being trapped by a bad first attempt).
+ Nottingham has no UI for `trackingWeight`; it is set directly on
+ `source/data.xml` + `source/preview.xml`. **Validated through XOT**
+ (2026-06-30): pushed into a running XOT instance, `play.php` returned 200,
+ the HTML5 editor opened and loaded `trackingWeight` into `lo_data`, a
+ Publish round-trip preserved all 8 `trackingWeight` values in `data.xml`,
+ and the SCORM export carried `trackingMode="full"` + `trackingWeight`
+ 1×7 + 21 into `template.xml`. See `PROJECT_CONTEXT.md` § "SCORM scoring"
+ and convention 9 (XOT validation is now mandatory before merge).
Remaining minor deviations (not requested to fix):
@@ -89,9 +102,6 @@ Remaining minor deviations (not requested to fix):
Theme 2 Quiz node (Nottingham's `quiz` only accepts `question` children;
nesting failed for Theme 2). Functionally equivalent — still scored and
SCORM-tracked. Structural deviation from other themes' nested pattern.
-- **Theme/final weighting (25%/75%) not applied** (per user, not a concern).
- The 80% pass mark is set; the LMS receives the aggregate score across all
- quiz interactions.
- **Content page type**: item pages from Theme 2 onward are "Bullets / Timed
Content" pages rather than "Plain Text". Cosmetic only — rich HTML renders
correctly in the player (verified).
@@ -99,5 +109,6 @@ Remaining minor deviations (not requested to fix):
## Final SCORM export
`Secure_code_development_scorm.zip` (13 MB, SCORM 1.2, one SCO,
`scormRLO.htm`, `apiwrapper_1.2.js` + `xttracking_scorm1.2.js` for LMS scoring,
-`trackingPassed="80%"`). Backups in `course_backup/`. The course now fulfills
+`trackingPassed="80%"`, `trackingMode="full"`, per-quiz `trackingWeight`
+1×7 + 21). Backups in `course_backup/`. The course now fulfills
the specification in all major respects.
diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md
index c3ada64..0ba96b6 100644
--- a/docs/PROJECT_CONTEXT.md
+++ b/docs/PROJECT_CONTEXT.md
@@ -62,9 +62,10 @@ with agents and building agents.
- **Final quiz** has **18 distinct questions** (fresh scenarios, not duplicates
of the theme-quiz questions), mix of single-answer risk-identification and
true/false.
-- **Pass mark**: `trackingPassed="80%"`, `trackingMode="full_first"`, all quizzes
- `judge="true"`. SCORM 1.2 score reporting verified (`apiwrapper_1.2.js` +
- `xttracking_scorm1.2.js` → `cmi.core.score.raw` + `lesson_status`).
+- **Pass mark**: `trackingPassed="80%"`, `trackingMode="full"` (last attempt
+ counts; see "SCORM scoring" below), all quizzes `judge="true"`. SCORM 1.2
+ score reporting verified (`apiwrapper_1.2.js` + `xttracking_scorm1.2.js` →
+ `cmi.core.score.raw` + `lesson_status`).
- **No Trial MCQ** (an early trial page was removed).
- `play.php` returns 200; the export is `Secure_code_development_scorm.zip`.
@@ -109,46 +110,118 @@ These were agreed with the course owner and must be preserved:
8. **Ambiguous questions are not acceptable**: each scenario must point to
exactly one correct answer (the RCE and supply-chain questions were
rewritten to be unambiguous — see `COURSE_SPEC.md`).
+9. **Validate every `source/data.xml` change through XOT before shipping**
+ (MANDATORY). The release workflow builds the SCORM zip by importing
+ `source/data.xml` into a real XOT instance and exporting, so the file must
+ be accepted by XOT — not just well-formed XML. After any edit, run the
+ XOT validation in §"How to make changes" (push the file into a running
+ XOT instance, confirm `play.php` returns 200 and the editor opens without
+ error, export a SCORM package, and grep the exported `template.xml` to
+ confirm `trackingMode`, `trackingWeight`, `trackingPassed`, the question
+ count, and the empty-option count are all as expected). Do not merge a
+ `source/data.xml` change that has not passed this validation.
## Known deviations (acknowledged, not to "fix" without asking)
-- **No per-quiz weighting (25%/75%)**: Nottingham has no weighting UI; the LMS
- receives the **aggregate** score across all quiz interactions. The owner
- accepted this. (A 25/75 split would need custom JS in the SCO.)
+- **Per-quiz weighting is set via the `trackingWeight` attribute** on each
+ `` node (7 theme quizzes `trackingWeight="1"`, final quiz
+ `trackingWeight="21"` → final is 21/28 = 75% of the LMS grade, themes
+ 7/28 = 25%, matching `COURSE_SPEC.md`). Nottingham has **no UI** for
+ `trackingWeight`; it is set as a direct attribute on `source/data.xml` +
+ `source/preview.xml`. The Xerte HTML5 editor **does** preserve it: the
+ `lo_data` loader reads `trackingWeight` into the in-memory model and the
+ Publish serializer writes it back to `data.xml`/`preview.xml` (verified by
+ an editor open + Publish round-trip — all 8 `trackingWeight` values survived).
+ So editor-based edits are safe; no re-application needed. See "SCORM
+ scoring" below for the full rationale.
- **Item pages from Theme 2 onward use the "Bullets" page type** (cosmetic;
rich HTML renders correctly, and `delaySecs="0"` disables the timed reveal).
Plain Text would be "purer" but converting 27 pages is not worth the risk.
+## SCORM scoring (how the LMS grade is computed)
+
+SCORM 1.2 reports **one** `cmi.core.score.raw` (0–100) and **one**
+`cmi.core.lesson_status` for the whole package (SCO). Xerte's
+`xttracking_scorm1.2.js` computes the single score as a **weighted average**
+across all quiz pages, where each quiz's weight is its `trackingWeight`
+attribute (default `1.0` when absent — read by `quiz.rlm`'s setup script and
+passed to `XTSetPageType(..., trackingWeight)`). The `trackingMode` attribute
+on the root controls which attempt is locked in:
+
+| `trackingMode` | `trackingmode` | `scoremode` | effect |
+|---|---|---|---|
+| `full_first` | `full` | `first` | first completed attempt of each quiz counts |
+| `full` | `full` | `last` | **last** completed attempt of each quiz counts (retries can improve) |
+| `minimal_first` | `minimal` | `first` | completion only, first attempt |
+| `minimal` | `minimal` | `last` | completion only, last attempt |
+| `none` | `none` | — | no tracking |
+
+This course uses `trackingMode="full"` (last attempt counts — the questions
+are tricky and learners should not be trapped by a bad first attempt) and
+`trackingWeight` 1/1/…/1/21 so the final comprehensive quiz is **75%** of the
+LMS grade and the seven theme quizzes are **25%** in total, per `COURSE_SPEC.md`.
+
+`cmi.core.lesson_status` is `incomplete` until **every** page in
+`toCompletePages` is completed (all 48 pages are marked for completion — no
+`unmarkForCompletion="true"`); it then becomes `passed`/`failed` against
+`trackingPassed="80%"`. Some LMSs only display/record a grade once status
+leaves `incomplete`, so learners must finish the final quiz and let the
+package fire `LMSFinish` for the grade to post.
+
## How to make changes (workflow)
-1. `docker start xerte` (if stopped). `curl -s -o /dev/null -w '%{http_code}' http://localhost:8081/` → 200.
+> Host port: the examples use `8081`; on this machine 8081 is taken by another
+> service, so XOT runs on **`8088`** (`-p 8088:80`). Any free host port works —
+> use it consistently. `docker ps` shows the mapped port.
+
+1. `docker start xerte` (if stopped). `curl -s -o /dev/null -w '%{http_code}' http://localhost:8088/` → 200.
2. Sync preview to data so the editor opens with the latest published content:
`docker exec xerte sh -c 'cp /var/www/xerte/USER-FILES/1-guest2-Nottingham/data.xml /var/www/xerte/USER-FILES/1-guest2-Nottingham/preview.xml; rm -f /var/www/xerte/USER-FILES/1-guest2-Nottingham/lockfile.txt'`.
-3. `agent-browser open http://localhost:8081/index.php` then
- `agent-browser open http://localhost:8081/edithtml.php?template_id=1`
+3. `agent-browser open http://localhost:8088/index.php` then
+ `agent-browser open http://localhost:8088/edithtml.php?template_id=1`
(click "Delete lockfile and continue" if prompted).
4. Make edits via the UI (`snapshot -i` + `eval`; CKEditor via `setData`).
- See `AGENT_COURSE_GUIDE.md` §4. **Do not edit `data.xml`/`preview.xml`
- directly** — author through the editor UI and Publish. (The only legitimate
- out-of-band file op is the `cp data.xml preview.xml` sync above, and
- `lo_data` attribute writes via `eval`, which go through the editor's own
- data model + Publish.)
-5. **Publish** (`eval` click the Publish button).
-6. **Verify**: read-only `docker exec xerte cat …/data.xml`; `curl play.php`;
- walk the affected pages/quizzes in `play.php` (complete a quiz to check
- Check/Next/Restart).
+ See `AGENT_COURSE_GUIDE.md` §4. Author through the editor UI and Publish
+ for content changes. The only legitimate out-of-band file ops are: (a) the
+ `cp data.xml preview.xml` sync above, (b) `lo_data` attribute writes via
+ `eval` (which go through the editor's own data model + Publish), and (c)
+ direct attribute edits to `source/data.xml` + `source/preview.xml` for
+ attributes the editor UI does not expose — notably `trackingWeight` (which
+ the editor *does* round-trip safely; see convention 9 + "SCORM scoring").
+ For (c), keep `data.xml` and `preview.xml` byte-identical and push both
+ into the container as in step 4b below.
+5. **Publish** (`eval` click the Publish button) — only needed for UI edits;
+ skip for direct-attribute edits (already in `data.xml`).
+6. **XOT validation (MANDATORY before merge — see convention 9):**
+ - `curl -s -o /dev/null -w 'play=%{http_code}\n' http://localhost:8088/play.php?template_id=1` → 200.
+ - Export a SCORM package (next step) and grep the exported `template.xml`
+ to confirm `trackingMode`, `trackingWeight` (7×`1` + 1×`21`),
+ `trackingPassed="80%"`, question count (45), and empty-option count (0).
+ - If `play.php` is not 200 or the export is missing tracking attrs, the
+ `data.xml` is not valid for XOT — do not merge.
7. **Re-export SCORM** (needs guest cookie — see guide §7) and update
`course_backup/` (`cp` the zip + `docker exec xerte cat data.xml > course_backup/data.xml` + same for preview.xml).
8. Update `COURSE_VERIFICATION.md` if the change affects conformance.
+### 4b. Pushing a direct `source/data.xml` edit into XOT (for `trackingWeight` etc.)
+
+```bash
+FOLDER=/var/www/xerte/USER-FILES/1-guest2-Nottingham
+docker cp source/data.xml "xerte:${FOLDER}/data.xml"
+docker cp source/preview.xml "xerte:${FOLDER}/preview.xml"
+docker exec xerte sh -c "chown www-data:www-data '${FOLDER}/data.xml' '${FOLDER}/preview.xml'; chmod 664 '${FOLDER}/data.xml' '${FOLDER}/preview.xml'; rm -f '${FOLDER}/lockfile.txt'"
+docker exec xerte mariadb --socket=/run/mysqld/mysqld.sock -uroot -proot xerte -e "UPDATE templatedetails SET access_to_whom='Public' WHERE template_id=1;"
+```
+Then continue at step 6 (XOT validation).
+
## Re-export command (copy-paste)
```bash
COOKIE=/tmp/x.cookies
-curl -s -c "$COOKIE" http://localhost:8081/index.php -o /dev/null
+curl -s -c "$COOKIE" http://localhost:8088/index.php -o /dev/null
curl -sL -b "$COOKIE" -o Secure_code_development_scorm.zip \
-w "export HTTP=%{http_code}, size=%{size_download} bytes\n" \
- "http://localhost:8081/website_code/php/scorm/export.php?scorm=true&template_id=1"
+ "http://localhost:8088/website_code/php/scorm/export.php?scorm=true&template_id=1"
cp Secure_code_development_scorm.zip course_backup/
docker exec xerte cat /var/www/xerte/USER-FILES/1-guest2-Nottingham/data.xml > course_backup/data.xml
docker exec xerte cat /var/www/xerte/USER-FILES/1-guest2-Nottingham/preview.xml > course_backup/preview.xml
@@ -165,10 +238,12 @@ grep -c "Trial MCQ" /tmp/c.xml # 0
grep -oE ']*?)/>',x) if H.unescape(H.unescape(re.search(r'text=\"([^\"]*)\"',m.group(1)).group(1)).replace('
','').replace('
','').strip())==''))"
-curl -s -o /dev/null -w "play=%{http_code}\n" http://localhost:8081/play.php?template_id=1 # 200
+curl -s -o /dev/null -w "play=%{http_code}\n" http://localhost:8088/play.php?template_id=1 # 200
```
Then open `play.php` in a browser, walk a theme quiz and the final quiz
end-to-end (answer → Check → Next → complete → Restart) to confirm the UI works.
@@ -177,8 +252,7 @@ end-to-end (answer → Check → Next → complete → Restart) to confirm the U
- Convert the 27 Bullets content pages to Plain Text for "purer" page types
(cosmetic only; current state renders fine with no auto-play).
-- Add the 25%/75% theme/final weighting via custom SCO JS (Nottingham has no
- UI for it; owner declined).
+
- Rewrite the remaining incident callouts (Replit, Gemini, Amazon Q, etc.) in
the same plain self-contained style as the ASI03 callout — they already
explain their scenario in the body, but could be made more uniform.
diff --git a/source/data.xml b/source/data.xml
index 2e99aaa..8a76d83 100644
--- a/source/data.xml
+++ b/source/data.xml
@@ -1,5 +1,5 @@
-Welcome to Secure code development
+Welcome to Secure code development
This course is for engineers building software with agents and for engineers building agents. Whether you are designing agentic systems, integrating LLMs, or writing the services that agents call, secure code development matters.
@@ -203,7 +203,7 @@
Detect delegated and transitive permissions — model the full delegation chain. If agent A delegates to agent B, the effective permissions should be the intersection of what A and B are each allowed to do.
Managed NHI (Non-Human Identity) — place agent identities in a dedicated identity platform such as Entra, AWS Bedrock, or Agentforce. Use lifecycle management, rotation, and audit for non-human accounts just as you would for human employees.
-]]>This theme traces how untrusted input becomes unintended action. We start with classic injection, then follow the chain into agentic territory: agents whose goals can be hijacked, whose tools can be misused, and whose generated code can execute unexpectedly.
+]]>This theme traces how untrusted input becomes unintended action. We start with classic injection, then follow the chain into agentic territory: agents whose goals can be hijacked, whose tools can be misused, and whose generated code can execute unexpectedly.
For engineers building agents, the lesson is that input validation, intent checks, and execution boundaries matter at every layer.
]]>Injection
@@ -325,7 +325,7 @@
Static scans before execution. Run security scanners and dependency checks on generated code before it is executed.
Runtime monitoring. Observe file, network, and process activity during code execution and terminate anomalous behaviour.
-]]>Theme 3: Supply Chain & Integrity looks at trust in code, data, and context. In classic software, the supply chain is mostly static: libraries, packages, build tools, and the CI/CD (Continuous Integration / Continuous Deployment) pipeline that produces your artefact. If any of those ingredients are tampered with, the final application carries the flaw. The OWASP Top 10:2025 tracks this as Software Supply Chain Failures (A03:2025) and Software or Data Integrity Failures (A08:2025).
+]]>Theme 3: Supply Chain & Integrity looks at trust in code, data, and context. In classic software, the supply chain is mostly static: libraries, packages, build tools, and the CI/CD (Continuous Integration / Continuous Deployment) pipeline that produces your artefact. If any of those ingredients are tampered with, the final application carries the flaw. The OWASP Top 10:2025 tracks this as Software Supply Chain Failures (A03:2025) and Software or Data Integrity Failures (A08:2025).
Agentic systems extend that same idea into a dynamic, runtime supply chain. An agent does not just import a dependency at build time; it can discover and compose tools, models, prompts, and other agents at runtime. This composition happens through protocols such as the Model Context Protocol (MCP) and Agent-to-Agent (A2A) frameworks, and through registries that advertise tool or agent capabilities. Each extra capability is a dependency that can be malicious, misconfigured, or compromised.
@@ -488,7 +488,7 @@
Decay / expire unverified memory. Reduce the trust weight of unverified entries over time and eventually remove them.
Trust-weighted retrieval. Rank search results by source trust and confidence, not just embedding similarity.
Theme 4 explores Cryptographic Failures (A04:2025) from the OWASP Top 10:2025, plus what those failures mean for agents and Non-Human Identities (NHI).
@@ -531,7 +531,7 @@
Private keys should never be directly accessible to agents. Use an orchestrator or trusted signer to perform operations on behalf of the agent.
Treat Non-Human Identity (NHI) credentials as a full lifecycle asset: issue with least privilege, monitor use, rotate frequently, and revoke immediately when an agent is decommissioned or suspected of compromise.
Theme 5 brings together three overlapping risks from the OWASP Top 10:2025 — Security Misconfiguration (A02:2025), Insecure Design (A06:2025), and Mishandling of Exceptional Conditions (A10:2025) — and adds the agentic risk of Cascading Failures (ASI08).
@@ -645,7 +645,7 @@
Use digital-twin replay and policy gating to test risky decisions before live execution.
Keep tamper-evident logging and non-repudiation so every propagated action can be traced and audited.
-]]>Theme 6 covers the risks that are unique to agentic systems, where software does not just respond to a single user but can act on its own, talk to other agents, and influence the people around it.
+]]>Theme 6 covers the risks that are unique to agentic systems, where software does not just respond to a single user but can act on its own, talk to other agents, and influence the people around it.
Where earlier themes mapped classic application risks to the agent world, this theme is different: it focuses on three risks that only appear when multiple agents, or a human and an agent, share responsibility.
@@ -747,7 +747,7 @@
Require periodic behavioural attestation and per-run ephemeral credentials, so compromise is time-bound.
Tie recovery or reintegration to fresh attestation and explicit human approval.
-]]>Theme 7 brings the focus onto observability, logging and detection. These controls are cross-cutting: they support almost every other theme in this course.
+]]>Theme 7 brings the focus onto observability, logging and detection. These controls are cross-cutting: they support almost every other theme in this course.
For traditional applications, good logging and alerting helps you detect breaches, investigate incidents and prove compliance. For agentic systems, the need is even stronger. Agents make sequences of decisions, call tools, talk to other agents and influence humans. Without a clear, tamper-evident record of what happened, you cannot attribute actions, detect drift or recover from failure.
@@ -781,7 +781,7 @@
For agents, the same principles apply, but the events are different. You should log tool calls, inter-agent messages, goal state and action sequences against a baseline. Track a stable goal identifier across the lifetime of a task so that every action can be traced back to the original request. Alert on goal drift and anomalous tool chains, and ensure non-repudiation and lineage for every propagated action.
Strong observability turns an opaque agent into an accountable one: it is not enough to know what the agent said; you must be able to reconstruct what it did.
-]]>Putting it together: secure SDLC and threat modelling
+]]>Putting it together: secure SDLC and threat modelling
Secure code development is not a single step; it is threaded through the whole SDLC (Software Development Life Cycle). The two OWASP lists in this course — the OWASP Top 10:2025 for classic applications and the OWASP Top 10 for Agentic Applications 2026 — give you concrete risks to address at each phase.
@@ -982,4 +982,4 @@
License of this course
This course is licensed under CC BY-SA 4.0 (Creative Commons Attribution-ShareAlike 4.0). It is an adapted summary/derivative; changes were made; it is not endorsed by OWASP. Generated with the pi coding-agent harness v0.79.8 using LLM models glm-5.2 and kimi k2.7-coder.
-]]>
+]]>
diff --git a/source/preview.xml b/source/preview.xml
index 2e99aaa..8a76d83 100644
--- a/source/preview.xml
+++ b/source/preview.xml
@@ -1,5 +1,5 @@
-Welcome to Secure code development
+Welcome to Secure code development
This course is for engineers building software with agents and for engineers building agents. Whether you are designing agentic systems, integrating LLMs, or writing the services that agents call, secure code development matters.
@@ -203,7 +203,7 @@
Detect delegated and transitive permissions — model the full delegation chain. If agent A delegates to agent B, the effective permissions should be the intersection of what A and B are each allowed to do.
Managed NHI (Non-Human Identity) — place agent identities in a dedicated identity platform such as Entra, AWS Bedrock, or Agentforce. Use lifecycle management, rotation, and audit for non-human accounts just as you would for human employees.
-]]>This theme traces how untrusted input becomes unintended action. We start with classic injection, then follow the chain into agentic territory: agents whose goals can be hijacked, whose tools can be misused, and whose generated code can execute unexpectedly.
+]]>This theme traces how untrusted input becomes unintended action. We start with classic injection, then follow the chain into agentic territory: agents whose goals can be hijacked, whose tools can be misused, and whose generated code can execute unexpectedly.
For engineers building agents, the lesson is that input validation, intent checks, and execution boundaries matter at every layer.
]]>Injection
@@ -325,7 +325,7 @@
Static scans before execution. Run security scanners and dependency checks on generated code before it is executed.
Runtime monitoring. Observe file, network, and process activity during code execution and terminate anomalous behaviour.
-]]>Theme 3: Supply Chain & Integrity looks at trust in code, data, and context. In classic software, the supply chain is mostly static: libraries, packages, build tools, and the CI/CD (Continuous Integration / Continuous Deployment) pipeline that produces your artefact. If any of those ingredients are tampered with, the final application carries the flaw. The OWASP Top 10:2025 tracks this as Software Supply Chain Failures (A03:2025) and Software or Data Integrity Failures (A08:2025).
+]]>Theme 3: Supply Chain & Integrity looks at trust in code, data, and context. In classic software, the supply chain is mostly static: libraries, packages, build tools, and the CI/CD (Continuous Integration / Continuous Deployment) pipeline that produces your artefact. If any of those ingredients are tampered with, the final application carries the flaw. The OWASP Top 10:2025 tracks this as Software Supply Chain Failures (A03:2025) and Software or Data Integrity Failures (A08:2025).
Agentic systems extend that same idea into a dynamic, runtime supply chain. An agent does not just import a dependency at build time; it can discover and compose tools, models, prompts, and other agents at runtime. This composition happens through protocols such as the Model Context Protocol (MCP) and Agent-to-Agent (A2A) frameworks, and through registries that advertise tool or agent capabilities. Each extra capability is a dependency that can be malicious, misconfigured, or compromised.
@@ -488,7 +488,7 @@
Decay / expire unverified memory. Reduce the trust weight of unverified entries over time and eventually remove them.
Trust-weighted retrieval. Rank search results by source trust and confidence, not just embedding similarity.
Theme 4 explores Cryptographic Failures (A04:2025) from the OWASP Top 10:2025, plus what those failures mean for agents and Non-Human Identities (NHI).
@@ -531,7 +531,7 @@
Private keys should never be directly accessible to agents. Use an orchestrator or trusted signer to perform operations on behalf of the agent.
Treat Non-Human Identity (NHI) credentials as a full lifecycle asset: issue with least privilege, monitor use, rotate frequently, and revoke immediately when an agent is decommissioned or suspected of compromise.
Theme 5 brings together three overlapping risks from the OWASP Top 10:2025 — Security Misconfiguration (A02:2025), Insecure Design (A06:2025), and Mishandling of Exceptional Conditions (A10:2025) — and adds the agentic risk of Cascading Failures (ASI08).
@@ -645,7 +645,7 @@
Use digital-twin replay and policy gating to test risky decisions before live execution.
Keep tamper-evident logging and non-repudiation so every propagated action can be traced and audited.
-]]>Theme 6 covers the risks that are unique to agentic systems, where software does not just respond to a single user but can act on its own, talk to other agents, and influence the people around it.
+]]>Theme 6 covers the risks that are unique to agentic systems, where software does not just respond to a single user but can act on its own, talk to other agents, and influence the people around it.
Where earlier themes mapped classic application risks to the agent world, this theme is different: it focuses on three risks that only appear when multiple agents, or a human and an agent, share responsibility.
@@ -747,7 +747,7 @@
Require periodic behavioural attestation and per-run ephemeral credentials, so compromise is time-bound.
Tie recovery or reintegration to fresh attestation and explicit human approval.
-]]>Theme 7 brings the focus onto observability, logging and detection. These controls are cross-cutting: they support almost every other theme in this course.
+]]>Theme 7 brings the focus onto observability, logging and detection. These controls are cross-cutting: they support almost every other theme in this course.
For traditional applications, good logging and alerting helps you detect breaches, investigate incidents and prove compliance. For agentic systems, the need is even stronger. Agents make sequences of decisions, call tools, talk to other agents and influence humans. Without a clear, tamper-evident record of what happened, you cannot attribute actions, detect drift or recover from failure.
@@ -781,7 +781,7 @@
For agents, the same principles apply, but the events are different. You should log tool calls, inter-agent messages, goal state and action sequences against a baseline. Track a stable goal identifier across the lifetime of a task so that every action can be traced back to the original request. Alert on goal drift and anomalous tool chains, and ensure non-repudiation and lineage for every propagated action.
Strong observability turns an opaque agent into an accountable one: it is not enough to know what the agent said; you must be able to reconstruct what it did.
-]]>Putting it together: secure SDLC and threat modelling
+]]>Putting it together: secure SDLC and threat modelling
Secure code development is not a single step; it is threaded through the whole SDLC (Software Development Life Cycle). The two OWASP lists in this course — the OWASP Top 10:2025 for classic applications and the OWASP Top 10 for Agentic Applications 2026 — give you concrete risks to address at each phase.
@@ -982,4 +982,4 @@
License of this course
This course is licensed under CC BY-SA 4.0 (Creative Commons Attribution-ShareAlike 4.0). It is an adapted summary/derivative; changes were made; it is not endorsed by OWASP. Generated with the pi coding-agent harness v0.79.8 using LLM models glm-5.2 and kimi k2.7-coder.