Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions .github/workflows/docs-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Documentation Quality

on:
pull_request:
paths:
- "docs/**"
- "*.md"
- "tests/README.md"
- "scripts/*.md"
- "scripts/check-*.py"
- ".github/workflows/docs-quality.yml"
- ".markdownlint-cli2.yaml"
- "cspell.json"
- "lychee.toml"
- "requirements-test.txt"
- "pytest.ini"
push:
branches: [main]
paths:
- "docs/**"
- "*.md"
- "tests/README.md"
- "scripts/*.md"
- "scripts/check-*.py"
- ".github/workflows/docs-quality.yml"

permissions:
contents: read

jobs:
markdown-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: DavidAnson/markdownlint-cli2-action@v19
with:
globs: |
**/*.md
!venv/**
!.venv/**
!node_modules/**
!site/**
!docs/tmp/**

link-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check external links
uses: lycheeverse/lychee-action@v2
with:
args: --config lychee.toml --no-progress .
fail: true
jobSummary: true

spell-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check spelling
uses: streetsidesoftware/cspell-action@v6
with:
config: cspell.json
files: "**/*.md"
inline: error
incremental_files_only: false
strict: true

validate-codeblocks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Validate Python code blocks in markdown
run: python3 scripts/check-codeblocks.py

check-doc-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Check documentation covers all routes and modules
run: python3 scripts/check-doc-coverage.py
45 changes: 45 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Deploy Documentation

on:
push:
branches:
- main
paths:
- "docs/**"
- "mkdocs.yml"
- ".github/workflows/docs.yml"

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install mkdocs-material mkdocstrings mkdocstrings-python pymdown-extensions
- run: python3 scripts/sync-docs.py
- run: mkdocs build --site-dir site
- uses: actions/upload-pages-artifact@v3
with:
path: site

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ tmp/
docs/tmp/
CTFd-Docker-Challenges/

# MkDocs build output
site/

# Database
instance/
uploads/
Expand All @@ -29,4 +32,7 @@ catering_sql_lab.db
# OS files
.DS_Store

# Command Code (AI coding assistant state)
.commandcode/

# Core maintainers only: optional commit-msg in .git/hooks/ (local-only, never pushed).
41 changes: 41 additions & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Markdownlint configuration for PwnzzAI docs
# See: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md

default: true

# Allow inline HTML (needed for <img>, <a>, <video> embeds)
MD033: false

# Allow line length (URLs and table rows exceed 80 chars)
MD013: false

# Allow duplicate headings (labs reuse "Overview", "Setup")
MD024: false

# Allow bare URLs without angle brackets
MD034: false

# Allow emphasis used instead of heading
MD036: false

# Allow trailing punctuation in headings ("Why?")
MD026: false

# Allow first line not being H1
MD041: false

# Allow code blocks without language spec
MD040: false

# Allow dollar signs in code blocks (command examples)
MD014: false

# Allow spaces after hash for atx-style headings
MD019: false
MD021: false

# Allow underscore in filenames (doc_standards.md)
MD045: false

# Allow indented code blocks (some legacy)
MD046: false
42 changes: 40 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ You can contribute to PwnzzAI Shop in several ways:
- **New Vulnerabilities**: Add demonstrations of additional LLM vulnerabilities
- **Documentation**: Improve explanations, tutorials, or documentation
- **Test Coverage**: Add or improve test cases
- **Security Mitigations**: Enhance security soutions in the mitigation strategies sections
- **Security Mitigations**: Enhance security solutions in the mitigation strategies sections
- **Model Support**: Add support for additional LLM models
- **UI/UX Improvements**: Enhance the user interface or user experience
- **Code Quality**: Refactor code for better maintainability
Expand Down Expand Up @@ -118,4 +118,42 @@ Use the Docker smoke test routine before pushing to GitHub. It validates local D
APP_IMAGE=pwnzzai:my-local-test ./scripts/docker-smoke-test.sh
```

The script cleans up test containers automatically when it exits.
The script cleans up test containers automatically when it exits.

## Coding Standards

- Follow [PEP 8](https://peps.python.org/pep-0008/) with a soft 100-character line limit.
- Use meaningful variable and function names.
- Add type hints to function signatures where practical.
- Write docstrings for public functions and classes.
- Use `snake_case` for variables and functions, `PascalCase` for classes.
- Keep functions small and single-purpose.
- Avoid adding comments that describe what the code does — let the code speak for itself. Use comments only for non-obvious intent.

For docs contributions, see [Doc Standards](docs/community/doc-standards.md).

## Submitting Changes

1. Ensure all tests pass: `pytest -v`
2. Run the Docker smoke test if you changed infrastructure: `./scripts/docker-smoke-test.sh`
3. Rebase your branch onto the latest `main` before opening a PR
4. Write a clear PR title and description
5. Reference any related issues in the PR body
6. Keep PRs focused — one change per PR

## Reporting Issues

Use GitHub Issues to report bugs, suggest features, or ask questions.

- **Bug report**: Include steps to reproduce, expected vs actual behavior, and your environment (OS, Python version, Docker version)
- **Feature request**: Describe the problem you're solving and how your suggestion helps
- **Question**: Use the [OWASP AI Exchange Discussions](https://github.com/OWASP/PwnzzAI/discussions)

## Security Considerations

This project contains intentional vulnerabilities for educational purposes.

- **Never** submit a PR that fixes a documented lab vulnerability without prior discussion — these are features
- New vulnerability contributions must include a hardened alternative (mode flag or separate endpoint)
- Do not commit real API keys, credentials, or PII — use example values
- If you discover an accidental vulnerability that is not part of the curriculum, follow the [Responsible Disclosure](docs/security/disclosure.md) process
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PWNZZAI_IMAGE ?= ghcr.io/maryammouzarani2024/pwnzzai:latest
LOCAL_IMAGE ?= pwnzzai-local:dev
TEST_IMAGE ?= pwnzzai:test-ci
APP_PORT ?= 8080
DOCS_SITE_DIR ?= site
OLLAMA_MODEL ?= llama3.2:1b

export FLASK_APP ?= main.py
Expand Down Expand Up @@ -353,3 +354,53 @@ register-challenge-py: ## python3 deploy/register_pwnzzai_challenge.py (env from
.PHONY: reregister-challenge-py
reregister-challenge-py: ## python3 deploy/reregister_pwnzzai_challenge.py
python3 deploy/reregister_pwnzzai_challenge.py

# =============================================================================
# Documentation (MkDocs)
# =============================================================================

.PHONY: sync-docs
sync-docs: ## Copy canonical files into docs/ before build (single source of truth)
python3 scripts/sync-docs.py

.PHONY: docs
docs: sync-docs ## Build MkDocs site (runs sync-docs first)
mkdocs build --site-dir $(DOCS_SITE_DIR)

.PHONY: docs-serve
docs-serve: sync-docs ## Serve MkDocs locally with live reload (runs sync-docs first)
mkdocs serve

# =============================================================================
# Documentation Quality (local)
# =============================================================================

.PHONY: install-docs-qa
install-docs-qa: ## Install doc quality tools (pytest-codeblocks)
"$(PYTHON)" -m pip install pytest-codeblocks

.PHONY: check-codeblocks
check-codeblocks: ## Validate Python code blocks in documentation (scripts/check-codeblocks.py)
python3 scripts/check-codeblocks.py

.PHONY: check-doc-coverage
check-doc-coverage: ## Check all routes and vulnerability modules are documented (scripts/check-doc-coverage.py)
python3 scripts/check-doc-coverage.py

.PHONY: check-links
check-links: ## Check external links in markdown (requires lychee, or runs in CI)
@if command -v lychee >/dev/null 2>&1; then lychee --config lychee.toml .; \
else printf '%s\n' "lychee not found. Install: cargo install lychee, or let CI run this check." >&2; fi

.PHONY: check-spelling
check-spelling: ## Spell-check docs (requires cspell, or runs in CI)
@if command -v cspell >/dev/null 2>&1; then cspell --config cspell.json "**/*.md" --no-summary; \
else printf '%s\n' "cspell not found. Install: npm install -g cspell, or let CI run this check." >&2; fi

.PHONY: check-markdown
check-markdown: ## Lint markdown style (requires markdownlint-cli2, or runs in CI)
@if command -v markdownlint-cli2 >/dev/null 2>&1; then markdownlint-cli2 "**/*.md" "#venv" "#.venv" "#node_modules" "#site" "#docs/tmp"; \
else printf '%s\n' "markdownlint-cli2 not found. Install: npm install -g markdownlint-cli2, or let CI run this check." >&2; fi

.PHONY: check-docs
check-docs: check-markdown check-links check-spelling check-codeblocks check-doc-coverage ## Run all doc quality checks (best-effort locally, authoritative in CI)
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Here, you'll explore **practical examples** of how vulnerabilities are created,
- [Option 2: Docker (Your Own Ollama + PwnzzAI Image)](#option-2-docker-your-own-ollama--pwnzzai-image)
- [Option 3: Run Source Code Yourself](#option-3-run-source-code-yourself)
- [Troubleshooting: Ollama Connection (WSL + Docker)](OLLAMA_CONNECTION_TROUBLESHOOTING.md)
- [Workshop hosts: choosing OpenAI, Claude, Gemini, or other cloud models](docs/workshop-cloud-llm-setup.md)
- [Workshop hosts: choosing OpenAI, Claude, Gemini, or other cloud models](docs/ops/cloud-setup.md)
- [Features](#features)
- [AI Security Coverage](#ai-security-coverage)
- [Learning Framework](#learning-framework)
Expand Down Expand Up @@ -79,7 +79,7 @@ cp .env.example .env
# (or LITELLM_MODEL=gemini/gemini-2.5-flash, etc.)
```

Restart the app after editing `.env`. For a full provider/model walkthrough, see [Workshop hosts: choosing OpenAI, Claude, Gemini, or other cloud models](docs/workshop-cloud-llm-setup.md).
Restart the app after editing `.env`. For a full provider/model walkthrough, see [Workshop hosts: choosing OpenAI, Claude, Gemini, or other cloud models](docs/ops/cloud-setup.md).

### Option 1: Docker (PwnzzAI + Ollama)

Expand Down Expand Up @@ -335,4 +335,25 @@ and,
- **Ollama Models**: Free models, such as Mistral 7B and LLaMA 3.2 1B, are accessible through Ollama.


## Documentation

Full MkDocs site in `docs/` (built with Material theme, Mermaid diagrams, mkdocstrings).

**Single source of truth rule:** content lives in one place — root files (`README.md`, `CONTRIBUTING.md`, `OLLAMA_CONNECTION_TROUBLESHOOTING.md`, `tests/README.md`, `.env.example`) are the canonical versions. Copying into `docs/` happens automatically before every build via:

```bash
make docs # sync + mkdocs build
make docs-serve # sync + mkdocs serve
```

Available docs:

- **[Architecture](docs/ARCHITECTURE.md)** — System design, module dependencies, request lifecycle (Mermaid diagrams)
- **[API Reference](docs/API_REFERENCE.md)** — Complete endpoint documentation with request/response formats
- **[Developer Guide](docs/DEVELOPER_GUIDE.md)** — Adding new vulnerabilities, doc workflow, coding conventions
- **[Escalation Ladder](docs/ESCALATION_LADDER.md)** — B0–B9 prompt injection stages, defense techniques
- **[Environment Variables](docs/ENVIRONMENT_VARIABLES.md)** — Precedence chains for all config vars
- **[Challenge Solutions](docs/CHALLENGE_SOLUTIONS.md)** — Walkthrough scaffold for all challenges
- **[Cloud LLM Setup](docs/ops/cloud-setup.md)** — Workshop provider configuration

**⚠️ Educational Purpose Only**: This application contains intentional security vulnerabilities. Do not use in production environments.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading