Output Validation and Guardrails: Structured Outputs, Constrained Decoding and Sanitization

Treat model output as untrusted input: enforce schemas, sanitize for every destination, fail closed and prove it with tests

A cybersecurity course from ibl.ai (self-paced, 10 to 12 hours, free). A hands-on, self-paced course for security and engineering teams on controlling what LLM applications output: OWASP LLM05 and LLM09, structured outputs and constrained decoding, local schema validation, sanitizing for browsers, shells, databases and tools, guards that fail closed, NeMo Guardrails, and logging and testing every decision, in eight local labs on synthetic data.

Last updated:

Course description

Output Validation and Guardrails teaches security engineers, AppSec and platform teams, ML engineers and security leaders to control what happens to model output before anything acts on it. You will learn improper output handling (OWASP LLM05:2025) and misinformation (LLM09:2025), why a system prompt is not a security control, how provider structured outputs and constrained or grammar-guided decoding work and what they leave unenforced, and how to validate, sanitize and encode output for each destination: a browser, a shell, a database, a file path or another tool. In eight local labs you build a guardrail layer in Python and JavaScript that enforces a schema, strips links, images and code blocks from user-facing text, escapes output for HTML, keeps output away from the shell and the SQL parser, runs as a NeMo Guardrails output rail, fails closed, logs every reject without logging the content, and passes a synthetic test set. The course ends with an output-handling control design for one of your own applications. Last verified 2026-11-03.

About this course

Every LLM application ends with model text reaching something that acts on it: a browser that renders it, a shell that runs it, a database that executes it, a tool or another agent that takes it as instructions. OWASP calls the failure LLM05:2025 Improper Output Handling, and its sibling LLM09:2025 Misinformation covers replies that are well formed and false. This course teaches security and engineering teams to treat model output as untrusted input and to control it outside the model: closed schemas validated locally, provider structured outputs and constrained decoding used for what they actually guarantee, sanitization for every destination, guards that fail closed, rail frameworks placed in a layered pipeline, and logs and tests that prove it all works. It is grounded in the OWASP Top 10 for LLM Applications 2025, OWASP ASVS 5.0 and the OWASP Cheat Sheet Series, NIST AI 600-1, NIST AI 100-2e2025, MITRE ATLAS and the joint guidance Deploying AI Systems Securely, with model providers' and libraries' own documentation labelled as such. Eight local labs in Python and JavaScript build a working guardrail layer on synthetic data, with no API keys and no model required.

What you will be able to do

  1. Explain improper output handling (OWASP LLM05:2025) and misinformation (LLM09:2025), map every place an application's model output lands to its threat and control, and show why a system prompt is not a security control.
  2. Define a closed output contract in JSON Schema or Pydantic and enforce it locally on every reply, including the constraints that provider structured outputs and constrained decoding leave unenforced.
  3. Sanitize model output for each destination: strip links, images, code blocks and hidden characters from user-facing text, escape it for HTML, sanitize rendered markup with an explicit allowlist and back it with a Content Security Policy.
  4. Keep model output out of shells, SQL parsers, file paths and tool arguments with library calls, parameterized queries, path containment and argument schemas that forbid extra fields.
  5. Design output guards that fail closed, place rail frameworks such as NeMo Guardrails and platform guardrails in a layered pipeline, and log every decision without logging the content.
  6. Prove the controls work with a synthetic test set, mutation checks and honest reporting, and write an output-handling control design, test plan and monitoring runbook for your own application.

Who this course is for

Roles: security engineers, application security and platform teams, ML engineers and security leaders who build, run or review LLM applications and agents.

Organizations: any sector deploying LLM features whose output reaches a user interface, a database, a shell, a tool or another system.

Before you start: working knowledge of web application security (XSS, injection) and basic Python. The labs need Python 3.12 and, for one lab, Node.js; all data is synthetic and supplied in the course, and every test runs on your own machine or in a sandbox you are authorized to use.

Format

Time: about 10 to 12 hours, self-paced. Level: intermediate to advanced. Hands-on: eight local labs that enforce a schema, find unenforced constraints, strip links, images and code from user-facing text, escape for HTML, sanitize in JavaScript, keep output out of shells and SQL, run an output rail and log and test every decision, with an AI tutor that coaches each step from the output you paste.

Structure: a Start here section, four content sections of readings, worked examples, templates and hands-on labs, each ending in an AI assessment, and a capstone in which you design the output-handling controls for one of your own applications, followed by a reading list.

Grading: the four section AI assessments count for 60 percent of the grade and the capstone assessment for 40 percent. The pass mark is 70 percent.

Currency

Last verified 2026-11-03 against the OWASP Top 10 for LLM Applications 2025, the OWASP Top 10 for Agentic Applications for 2026, OWASP ASVS 5.0.0, the OWASP AI Testing Guide version 1, NIST AI 100-1, NIST AI 600-1, NIST AI 100-2e2025, MITRE ATLAS release 2026.10, the Model Context Protocol specification 2026-07-28, vendor documentation from OpenAI, Anthropic and Google, NeMo Guardrails 0.24.1, and the ibl.ai documentation.

This field changes quickly. Standards are revised, providers change what their structured outputs enforce, and libraries change their defaults between releases. Check the current versions before relying on any page or template, and test only systems you own or are authorized to test. This course is training, not a security assessment of your systems.

Outline

  1. Section 0 · Start here

    • 0.1 Welcome and orientation
  2. Section 1 · Treat model output as untrusted input

    • 1.1 Where model output goes
    • 1.2 Why the system prompt is not the control
    • 1.3 Section 1 assessment
  3. Section 2 · Constrain and validate the shape of output

    • 2.1 Structured outputs and constrained decoding
    • 2.2 Validate locally anyway
    • 2.3 Section 2 assessment
  4. Section 3 · Sanitize for every destination and fail closed

    • 3.1 Rendered output in browsers and chat
    • 3.2 Shells, databases, tools and failing closed
    • 3.3 Section 3 assessment
  5. Section 4 · Add rails, monitor and prove the controls work

    • 4.1 Rail frameworks and layering
    • 4.2 Logging, testing and monitoring
    • 4.3 Section 4 assessment
  6. Section 5 · Capstone and wrap-up

    • 5.1 Capstone: an output-handling control design for your application
    • 5.2 Capstone assessment
    • 5.3 Reading list and next steps