This document covers security architecture, contributor guidelines, and vulnerability reporting for the agentic-sdlc-demo repository.
If you discover a security vulnerability, please report it responsibly:
- Do not open a public GitHub issue
- Email security@kosli.com with a description of the vulnerability, steps to reproduce, and potential impact
- Allow reasonable time for a fix before public disclosure
All secrets are stored as GitHub repository secrets and injected into
workflows via environment variables. The Kosli API token is passed to
subprocess calls via the KOSLI_API_TOKEN environment variable — never
as a CLI argument (prevents exposure in process listings and CI logs).
Both pr-loop.yml and pr-resolve.yml use pull_request_target, which
grants write tokens and secret access. The checkout step in both workflows
deliberately omits ref: so that it defaults to the base branch (main),
never the PR head. This prevents the classic "pwn request" attack where a
malicious PR executes its own code with elevated privileges.
A security lint check in pipeline-tests.yml detects any
pull_request_target workflow that checks out PR head code, preventing
regression.
All user-controlled text (issue bodies, review finding bodies, resolver
inputs) is wrapped with boundary markers and scanned for injection patterns
before entering any AI prompt. The injection scanner
(scripts/review/pipeline_steps/injection_scanner.py) provides:
scan_text()— scans arbitrary text for instruction overrides, role-switching markers, Unicode tricks, encoded payloads, and anomalous comment densitysanitise_prompt_input()— wraps text with boundary markers and prepends a WARNING header if injection candidates are detected
The diff-level injection scan runs as a trail-level attestation before any review agent sees the code.
The coding agent workflow (agentic-code.yml) requires the
approved-for-agent label on the GitHub issue before it will process it.
This prevents the agent from being triggered on issues that haven't been
reviewed by a human.
All third-party GitHub Actions are pinned to commit SHAs (not version tags) to prevent supply chain attacks via tag mutation. Dependabot is configured for weekly automated updates.
actionlint runs in pipeline-tests.yml to catch script injection
patterns (direct github.event.* interpolation in run: blocks) and
workflow syntax errors.
- Pin actions to commit SHAs with a version comment:
action@SHA # vX - Pass secrets via environment variables, not CLI arguments
- Use specific exception types in route handlers — never expose
str(e)from a genericexcept Exception - Run
pip install ".[dev]"(notpip install -e) in CI workflows
- Never add
ref:to checkout steps inpull_request_targetworkflows — this checks out untrusted PR code with secret access - Never interpolate
${{ github.event.* }}directly inrun:blocks — use environment variables or pass via API - Never pass secrets as CLI arguments (visible via
ps//proc) - Never return raw exception messages in API error responses
- All text from external sources (issue bodies, PR descriptions, review
findings) must be wrapped with
sanitise_prompt_input()before inclusion in any AI prompt - The
approved-for-agentlabel is required before the coding agent will process any issue — never remove this gate - The injection scanner is deterministic (regex-based, not LLM-based) so it cannot itself be manipulated by the content it scans
An external security audit was conducted in March 2026, resulting in 13 remediation tickets (#156-#168). All critical and high severity findings have been addressed. See the CHANGELOG for details of each fix.