Report security issues privately. Do not open public GitHub issues for undisclosed vulnerabilities.
- Organization policy: CaptorAB SECURITY.md
- This repository: use GitHub private vulnerability reporting when enabled, or contact the maintainers listed on PyPI.
- PyPI publishing uses Trusted Publishing (OIDC from GitHub Actions), not long-lived API tokens in CI.
- CI workflows use hash-pinned actions, default read-only
contents, and zizmor audits. - Dependencies are locked in
uv.lock; CI runsuv sync --lockedand supply-chain scans (supply-chain.yml) on pull requests that change lockfiles and on a weekly schedule. - Releases build from the signed git tag, record
SHA256SUMSfor artifacts, and verify checksums before publish. pull_request_targetis not used; PR CI runs onpull_requestwith read-only defaults and fork guards on cache restore and issue creation.- Validation workflows (
tests.yml,supply-chain.yml,zizmor.yml,codeql.yml) run on pull requests, not again on merge tomaster. Path filters skip heavy steps when the PR does not touch relevant files, while the jobs still report success so required checks are not left pending. - CodeQL full analysis runs on pull requests that change Python sources and
on a weekly schedule; it is not repeated on every push to
master. - Documentation is published at
openseries.readthedocs.io (the URL in
PyPI and conda-forge metadata) and also deployed to GitHub Pages by
docs.yml. Pull requests build docs without deploying Pages. - Release tagging is isolated in a reusable workflow (
release-tag.yml); build and PyPI publish run indeploy.ymlbecause PyPI Trusted Publishing does not support reusable workflows.deploy.ymlis the only manual entry point and requires themasterbranch. - Runners are GitHub-hosted (
ubuntu-latest,windows-latest,macos-latest); each job gets a fresh ephemeral VM with no persistent state. - OIDC (
id-token: write) is granted only on GitHub Pages and PyPI publish jobs; all other workflows omit it.
These settings require org/repo admin access and cannot be enforced from workflow YAML alone:
- Actions → General → Workflow permissions: set default to Read repository contents and packages permissions (read-only).
- Actions → General → Fork pull request workflows: require approval for outside collaborators (or all first-time contributors) before running workflows from forks.
- Environments (
release,testpypi,pypi,github-pages,codecov):- Required reviewers before deployment
- Restrict deployment branches to
master - Do not expose secrets to fork PR workflows
codecovis used only bycodecov.ymlonmaster(not PR tests ordeploy.yml)
- Branch protection on
master:- Require status checks from
tests.yml,supply-chain.yml, andzizmor.ymlbefore merge. Do not require the Read the Docs PR check. CodeQL may remain required; thecodeql.ymljob no-ops on PRs that do not change Python sources. - Require review for changes under
.github/workflows/ - Keep the Read the Docs GitHub integration so
lateststill builds; turn off Build pull requests in the RTD project so PRs are not double-built.
- Require status checks from
- Dependabot: keep weekly updates with cooldown enabled (see
.github/dependabot.yml). - Audit log: periodically review GitHub audit log for workflow or secret changes, especially around releases.
- Confirm GitHub environment protection on
release,testpypi, andpypi(required reviewers). - Run
make auditlocally after dependency changes. - Run deploy workflow only from
masterwith an intentional version bump inpyproject.toml. - After PyPI publish, verify the new version on pypi.org/project/openseries and update conda-forge feedstock from that sdist.
- Stop: Disable compromised workflows or revoke PyPI Trusted Publishers; do not publish further versions.
- PyPI: Yank malicious versions; rotate/remove API tokens if any exist on the account.
- GitHub: Rotate
GPG_PRIVATE_KEY,CODECOV_TOKEN, and review audit log for workflow or secret changes. - Notify: GitHub Security Advisory + user-facing release/issue explaining affected versions and remediation.
- Conda-forge: Request feedstock repodata/outdated markers for affected builds.
- Prefer installing a specific version:
pip install openseries==<version>. - Compare PyPI artifacts to the signed git tag and
SHA256SUMSfrom the GitHub Actions release workflow when investigating tampering.