chore: import upstream snapshot with attribution
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
# OSSF Scorecard Compliance Notes
|
||||
|
||||
This document explains our compliance status with OSSF Scorecard checks
|
||||
and documents any accepted risks or false positives.
|
||||
|
||||
## Current Score: 8/10 for Pinned-Dependencies
|
||||
|
||||
**Summary:**
|
||||
- ✅ 196/196 GitHub Actions pinned by SHA
|
||||
- ✅ 4/4 Container images pinned by digest
|
||||
- ✅ 1/1 Security tools use official SHA-pinned actions (zizmor)
|
||||
- ⚠️ 2/27 pip commands pinned by hash (remainder version-pinned — accepted risk)
|
||||
- ⚠️ 21/24 npm commands pinned (3 are operational commands)
|
||||
- ⚠️ 1 false positive for downloadThenRun
|
||||
- ⚠️ APT packages intentionally unpinned (base image controls versions)
|
||||
|
||||
## Pinned-Dependencies
|
||||
|
||||
### GitHub Actions: COMPLIANT ✅
|
||||
|
||||
All GitHub Actions use commit SHA pinning (40-character hex):
|
||||
|
||||
```yaml
|
||||
# Examples from our workflows:
|
||||
actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6
|
||||
step-security/harden-runner@df199fb7be9f65074067a9eb93f12bb4c5547cf2 # v2.13.3
|
||||
```
|
||||
|
||||
### Docker Images: COMPLIANT ✅
|
||||
|
||||
All Docker images use SHA256 digest pinning:
|
||||
|
||||
```yaml
|
||||
# Examples from our workflows and docker-compose:
|
||||
python:3.13.9-slim@sha256:326df678c20c78d465db501563f3492d17c42a4afe33a1f2bf5406a1d56b0e86
|
||||
redis:alpine@sha256:8360960f5fb56a282d78686203dd875862cd4b52a4184c17ac753690252d6d31
|
||||
node:20-alpine@sha256:bcd88137d802e2482c9df3cdec71e0431857ebbbdba6973776b5593214056d86
|
||||
```
|
||||
|
||||
### Official GitHub Actions: COMPLIANT ✅
|
||||
|
||||
One security tool uses an official GitHub Action with SHA-pinning,
|
||||
which provides equivalent security to hash-pinned pip installs:
|
||||
|
||||
| Tool | Action | SHA |
|
||||
|------|--------|-----|
|
||||
| zizmor | `zizmorcore/zizmor-action` | `135698455da5c3b3e55f73f4419e481ab68cdd95` |
|
||||
|
||||
This official action runs the tool in a container with internal integrity verification,
|
||||
which OSSF Scorecard accepts as equivalent to hash pinning.
|
||||
|
||||
> **Note:** pip-audit was removed because it duplicates OSV-Scanner's coverage (both
|
||||
> query the OSV database) and its internal use of pip's dependency resolver conflicts
|
||||
> with PDM's `[tool.pdm.resolution.overrides]`, causing persistent CI failures.
|
||||
|
||||
> **Note:** Checkov previously used `bridgecrewio/checkov-action` but was reverted to CLI
|
||||
> installation (`pip install checkov==3.2.499`) due to a known bug with multiple
|
||||
> consecutive action calls. See [checkov-action#170](https://github.com/bridgecrewio/checkov-action/issues/170)
|
||||
> and [checkov#5866](https://github.com/bridgecrewio/checkov/issues/5866).
|
||||
|
||||
### pip install: VERSION-PINNED (Accepted Risk) ⚠️
|
||||
|
||||
Scorecard flags `pip install package==version` because it prefers hash pinning.
|
||||
The remaining pip commands use exact version pinning.
|
||||
|
||||
**Flagged commands and their status:**
|
||||
|
||||
| File | Line | Command | Status |
|
||||
|------|------|---------|--------|
|
||||
| Dockerfile | 49-50 | `pip3 install pip==26.0` `pip install pdm==2.26.2...` | Version-pinned |
|
||||
| Dockerfile | 194 | `pip3 install pip==26.0` | Version-pinned |
|
||||
| check-env-vars.yml | 36 | `pip install loguru==0.7.3 sqlalchemy==2.0.36...` | Version-pinned |
|
||||
| checkov.yml | 33 | `pip install checkov==3.2.499` | Version-pinned |
|
||||
| fuzz.yml | 51-52 | `pip install pip==25.0` `pip install pdm==2.26.2` | Version-pinned |
|
||||
| mypy-type-check.yml | 39,47-48 | `pip install pdm==2.26.2 mypy==1.14.1...` | Version-pinned |
|
||||
| publish.yml | 139,328 | `pip install pdm==2.26.2` `pip install wheel==0.46.2` | Version-pinned |
|
||||
| puppeteer-e2e-tests.yml | 65 | `pip install -e .` | Local package |
|
||||
| responsive-ui-tests-enhanced.yml | 97-98 | `pip install pip==25.0` `pip install -e .` | Version-pinned + local (Alert #5688) |
|
||||
| semgrep.yml | 36 | `pip install semgrep==1.87.0` | Version-pinned |
|
||||
| update-precommit-hooks.yml | 35-38 | `pip install pip==25.0` `pip install pre-commit-update==0.6.1` | **Hash-pinned** |
|
||||
| validate-image-pinning.yml | 67 | `pip install pyyaml==6.0.2` | Version-pinned |
|
||||
| backwards-compatibility.yml | 66-68 | `pip install --upgrade pip` `pip install pytest` `pip install -e .` | Intentionally unpinned |
|
||||
| backwards-compatibility.yml | 106-107 | `pip install --upgrade pip` `pip install pytest` | Intentionally unpinned |
|
||||
| backwards-compatibility.yml | 154-155 | `pip install --upgrade pip` `pip install "local-deep-research==..."` | Intentionally unpinned |
|
||||
| backwards-compatibility.yml | 169 | `pip install -e .` | Local package |
|
||||
|
||||
> **Note:** `backwards-compatibility.yml` intentionally uses unpinned pip commands
|
||||
> because it tests compatibility with prior PyPI releases of local-deep-research.
|
||||
> Pinning these commands would defeat the purpose of the compatibility tests.
|
||||
|
||||
**Why we don't use hash pinning:**
|
||||
|
||||
1. **Platform-specific hashes**: pip package hashes vary by Python version, OS, and architecture.
|
||||
A single hash won't work across different CI runners.
|
||||
|
||||
2. **Maintenance burden**: Every version update requires regenerating hashes for all platforms.
|
||||
|
||||
3. **Marginal security benefit**: These are dev/CI tools running in hardened CI environments
|
||||
(step-security/harden-runner) with egress auditing. Supply chain attacks on PyPI packages
|
||||
are mitigated by version pinning and short execution windows.
|
||||
|
||||
4. **Industry practice**: Version pinning (`==`) is the standard for CI tool installation.
|
||||
Hash pinning is typically reserved for production dependencies.
|
||||
|
||||
5. **Local packages**: `pip install -e .` installs the local source code and cannot be hash-pinned.
|
||||
|
||||
6. **Bootstrap commands**: `pip install pip==X.Y.Z` cannot be hash-pinned because pip is the
|
||||
tool performing the verification — it cannot verify its own integrity during a self-upgrade.
|
||||
|
||||
### Specific OSSF Scorecard Alerts
|
||||
|
||||
| Alert | File | Lines | Description | Status |
|
||||
|-------|------|-------|-------------|--------|
|
||||
| #5688 | responsive-ui-tests-enhanced.yml | 97-98 | `pip install pip==25.0` (bootstrap) and `pip install -e .` (local source) | Accepted limitation |
|
||||
|
||||
### npm Commands: MOSTLY COMPLIANT (21/24) ⚠️
|
||||
|
||||
The 3 "unpinned" npm commands are operational commands, not package installations:
|
||||
|
||||
| File | Line | Command | Reason Not Pinned |
|
||||
|------|------|---------|-------------------|
|
||||
| npm-audit.yml | 56 | `npm i --package-lock-only` | Generates lockfile only |
|
||||
| npm-audit.yml | 72 | `npm i --package-lock-only` | Generates lockfile only |
|
||||
| update-npm-dependencies.yml | 74 | `npm update` | Intentionally updates to latest |
|
||||
|
||||
These commands don't install packages directly - they either generate lockfiles
|
||||
or intentionally update packages. They cannot and should not be "pinned".
|
||||
|
||||
### downloadThenRun: FALSE POSITIVE ⚠️
|
||||
|
||||
**Flagged:** `examples/elasticsearch/test_elasticsearch.sh:60`
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:9200 | python3 -m json.tool | head -10
|
||||
```
|
||||
|
||||
**Why it's a false positive:**
|
||||
- This fetches JSON from localhost:9200 (local Elasticsearch)
|
||||
- Pipes to `python3 -m json.tool` (stdlib JSON formatter)
|
||||
- Shows first 10 lines of pretty-printed output
|
||||
|
||||
This is NOT downloading and running a remote script. It's formatting local JSON output.
|
||||
The scorecard pattern-matches `curl | python` as potentially dangerous, but this
|
||||
is a safe operation on localhost data.
|
||||
|
||||
**OSSF Scorecard Alert:** #4411
|
||||
|
||||
### APT Packages: INTENTIONALLY UNPINNED ⚠️
|
||||
|
||||
**Files affected:** `publish.yml`, `e2e-research-test.yml`, `responsive-ui-tests-enhanced.yml`, `Dockerfile`
|
||||
|
||||
| File | Packages | Runner/Base |
|
||||
|------|----------|-------------|
|
||||
| publish.yml | libsqlcipher-dev, patchelf | ubuntu-22.04 |
|
||||
| e2e-research-test.yml | jq | ubuntu-22.04 |
|
||||
| responsive-ui-tests-enhanced.yml | wget, gnupg, ca-certificates, fonts-liberation, etc. | ubuntu-latest |
|
||||
| Dockerfile | curl, git, build-essential, etc. | python:3.13.9-slim@sha256:... |
|
||||
|
||||
**Rationale for NOT pinning APT packages:**
|
||||
|
||||
1. **Version availability**: Old APT package versions are removed from Ubuntu archives after 6-12 months.
|
||||
Pinning to `package=1.2.3-1ubuntu1` causes builds to fail when that version is removed.
|
||||
|
||||
2. **Base image controls versions**: Docker base images are SHA-pinned, which deterministically controls
|
||||
which APT package versions are available. The combination of `python:3.13.9-slim@sha256:326df678...`
|
||||
and `apt-get install curl` produces the same result every time that base image is used.
|
||||
|
||||
3. **Runner stability**: GitHub workflow runners use pinned Ubuntu versions (e.g., `ubuntu-22.04`)
|
||||
which provide consistent package versions throughout the runner's lifecycle.
|
||||
|
||||
4. **Version variation**: APT package version strings vary between Ubuntu releases and architectures,
|
||||
making cross-platform pinning impractical.
|
||||
|
||||
5. **Industry consensus**: Security experts recommend pinning the base image/runner rather than
|
||||
individual packages. Base image pinning provides stronger guarantees with lower maintenance burden.
|
||||
|
||||
**Mitigations in place:**
|
||||
|
||||
- ✅ Docker base images pinned to SHA256 digests (see Docker Images section above)
|
||||
- ✅ GitHub runner versions pinned where practical (ubuntu-22.04)
|
||||
- ✅ Dependabot configured to monitor for security updates
|
||||
- ✅ Step-security/harden-runner audits all egress traffic
|
||||
- ✅ Minimal package sets installed (only what's needed)
|
||||
|
||||
### Enforcement
|
||||
|
||||
We have automated verification for our pinning strategy:
|
||||
- `.github/workflows/validate-image-pinning.yml` - Validates Docker image digests
|
||||
- Pre-commit hooks verify action SHA pinning
|
||||
- All pip install commands use explicit version specifiers (except `backwards-compatibility.yml` which intentionally tests with unpinned versions)
|
||||
|
||||
### Review Cadence
|
||||
|
||||
These decisions are reviewed quarterly to ensure they remain appropriate:
|
||||
- **Next review:** Q2 2026
|
||||
- **Owner:** Security team
|
||||
|
||||
## References
|
||||
|
||||
- [OSSF Scorecard Pinned-Dependencies Check](https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies)
|
||||
- [StepSecurity Harden Runner](https://github.com/step-security/harden-runner)
|
||||
- [pip Hash Checking Mode](https://pip.pypa.io/en/stable/topics/secure-installs/#hash-checking-mode)
|
||||
Reference in New Issue
Block a user