> For the complete documentation index, see [llms.txt](https://gyrinx.gitbook.io/gyrinx/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gyrinx.gitbook.io/gyrinx/technical-reference/security-baseline.md).

# Security Baseline

This document provides context for the Bandit security baseline established on 2025-06-28.

## Overview

The Gyrinx codebase uses [Bandit](https://bandit.readthedocs.io/) for automated security scanning. The baseline captures the current state of security findings to:

1. Track only new security issues in CI/CD
2. Document accepted security risks
3. Plan security improvements over time

## Baseline Files

* **`bandit/bandit-baseline.json`** - Machine-readable baseline for CI comparison (committed to git)
* **`bandit/bandit-baseline.txt`** - Human-readable report with detailed findings (committed to git)

## Running Bandit

```bash
# Run scan with baseline comparison (as CI does)
bandit -c pyproject.toml -r . --baseline bandit/bandit-baseline.json

# Generate new baseline files
bandit -c pyproject.toml -r . -f json -o bandit/bandit-baseline.json
bandit -c pyproject.toml -r . -f txt -o bandit/bandit-baseline.txt
```

## Updating the Baseline

When security issues are resolved or new acceptable findings are added:

1. Run Bandit to generate new baseline files
2. Review the changes carefully
3. Commit both JSON and TXT files with explanation

## Configuration

Bandit is configured in `pyproject.toml`:

### Excluded Directories

* `.venv`, `.git`, `__pycache__` - Infrastructure directories
* `*/migrations/*` - Django migrations (auto-generated)
* `*/tests/*` - Test files (assertions expected)
* `node_modules` - Node.js dependencies

### Skipped Checks

* **B101** (`assert_used`): Assertions are used in tests
* **B601** (`paramiko_calls`): Paramiko is not used
* **B603** (`subprocess_without_shell_equals_true`): Reviewed case-by-case

## Additional Security Practices

### Input Validation

* Use `safe_redirect()` helper for all redirect URLs to prevent open redirect vulnerabilities
* Validate user input at form level using Django forms
* Sanitise HTML content with appropriate filters

### Authentication

* Django's built-in authentication system with session management
* reCAPTCHA verification for registration (when enabled)
* Password validation using Django validators

### Django admin access

The admin has no login form of its own. `/admin/login/` redirects into the allauth login flow, so an admin session is created by the same code path — and the same second-factor challenge — as an ordinary app session. See `gyrinx/admin_site.py`.

Reaching the admin also requires a second factor. Left unset, `ADMIN_REQUIRE_MFA` follows `DEBUG`: on in production, off locally, where each worktree has its own database and requiring TOTP would mean enrolling a separate authenticator per worktree. Set `ADMIN_REQUIRE_MFA=True` to exercise the production gate locally, or `False` to switch it off. Only the second factor is relaxed — admin login goes through allauth in every environment.

Staff who do not meet the requirement are redirected into allauth to set up TOTP or to enter a code — they are never locked out. The requirement covers `/admin/doc/` as well as the admin proper.

Two consequences worth knowing:

* Enabling this in an environment where staff sign in with a password only will send them through TOTP setup on their next visit to the admin.
* `MFA_SUPPORTED_TYPES` is TOTP-only, so there are no recovery codes. Losing the authenticator means an admin has to reset it from the database.

### Pre-commit Hooks

Security checks run automatically on commit via pre-commit:

* `detect-private-key` - Prevents committing private keys
* `bandit` - Runs security scan on Python files

## Related Documentation

* [SECURITY.md](https://github.com/gyrinx-app/gyrinx/tree/main/SECURITY.md) - Security policy and vulnerability reporting


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gyrinx.gitbook.io/gyrinx/technical-reference/security-baseline.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
