Skip to content

ci: publish with a pip that excludes the compromised eMudhra/emSign CA - #6161

Open
mday-io wants to merge 1 commit into
SQLMesh:mainfrom
mday-io:claude/sqlmesh-security-review-hignxb
Open

mday-io wants to merge 1 commit into
SQLMesh:mainfrom
mday-io:claude/sqlmesh-security-review-hignxb

Conversation

@mday-io

@mday-io mday-io commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Hardens the release publish job in response to the eMudhra / emSign CA certificate incident (see the PSF's "Information for Python users regarding eMudhra / emSign CA certificate security incident" post on discuss.python.org). The compromised root was removed in certifi 2026.10.19 and pip 26.2.2. pip vendors its own CA bundle, so the pip that ships with an older Python keeps trusting the root until pip itself is upgraded.

The publish job ran on Python 3.10, whose bundled pip predates the fix. That pip installs build and twine, the make package / make publish installs (pip3, since UV isn't set), and python -m build's isolated setuptools environment. All of this runs in a job that holds the PyPI and private-index credentials.

Changes:

  • python-version: '3.10' → '3.13'. 3.13.17 is available in setup-python's version list and bundles pip 26.2.2+. Changing the interpreter avoids upgrading pip through the vulnerable pip.
  • A new step fails the job if pip is older than 26.2.2, so we never publish with an unfixed pip.

User impact: none. The interpreter only runs build/twine. The package is pure Python and requires-python stays >=3.9.

Test Plan

  • Built the package on Python 3.13 (pyproject-build): it produces the sdist and sqlmesh-…-py3-none-any.whl with Requires-Python: >=3.9.
  • Built the wheel from the same commit on 3.10 and compared. Same file list, byte-identical contents (excluding RECORD), same version.
  • Checked the version gate: it passes pip 26.2.2 and 26.10 and fails 26.2.1 and 25.3.
  • Checked that the workflow YAML parses.
  • Not yet exercised end to end. The first real run is the next release tag.

Checklist

  • I have run make style and fixed any issues (workflow YAML only)
  • I have added tests for my changes (if applicable) (N/A, CI config)
  • All existing tests pass (make fast-test) (no Python changes)
  • My commits are signed off (git commit -s) per the DCO

Follow-up worth considering separately: switch publishing to PyPI Trusted Publishing so the job holds no long-lived PyPI password.

Summary by CodeRabbit

  • Chores
    • Updated the release publishing process to use a newer Python version and check that the package installer meets a minimum version requirement.
    • No user-facing functionality changes are included.

The publish job ran on Python 3.10, whose bundled pip still trusts the
compromised eMudhra/emSign root. Build and upload on Python 3.13, whose
latest patch bundles pip 26.2.2+, and fail the job if pip is older.

Signed-off-by: mday-io <mdaytn@gmail.com>
@mday-io
mday-io force-pushed the claude/sqlmesh-security-review-hignxb branch from 64a6bc0 to 3ea4856 Compare October 23, 2026 05:06
@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 47e9df19-3d99-4acf-afeb-8c5526e11b2e
Commits

Reviewing files that changed from the base of the PR and between f6527ff and 3ea4856.

Files selected for processing: 1
  • .github/workflows/release.yaml

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The publish job now uses Python 3.13 and checks that the installed pip version is at least 26.2.2.

Changes: Release environment

Layer / File(s) Summary
Configure publish environment
.github/workflows/release.yaml
The publish job uses Python 3.13. It exits with an error if pip is older than 26.2.2.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Other

Suggested reviewers: eakmanrq

Merge Risk: Minimal · up to 3ea48

The release job is expected to use the selected Python runtime and proceed when its pip meets the required version. No actionable merge-blocking risk remains after normal checks.

Security architecture risk: Low · up to 3ea48

The change adds a fail-closed prerequisite before package publication without expanding publishing authority. A retained low-severity concern remains about whether the checked package manager is exactly the one used downstream. The command bindings and credential exposure predate this PR; no increased exposure was demonstrated. Effective certificate trust and release-run behavior remain partially unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Compromise of code executing during the credential-bearing publishing steps could affect public or private package publication within the supplied credentials’ permissions. The workflow also has repository contents-write authority. Exact credential scopes and downstream consumer exposure are not established, and this PR does not visibly expand that authority.

Security Findings and Attack Paths

  • observed — The supplied security assessment retains a low-severity finding about whether the gated pip identity matches downstream publishing commands, with reachability unknown. Separate command bindings and credential-bearing installations are present in the base as well as the head; no concrete attacker-controlled substitution or PR-expanded exposure was established.
  • inferred — A malicious dependency or build backend executing in the publish step would run while public credentials are available; private publication occurs after private credentials are written to the runner. This is a pre-existing supply-chain exposure, not a newly demonstrated attack path. The deferred cache and certificate-trust candidates remain unresolved rather than verified vulnerabilities.

Trust Boundaries and Controls

  • inferred — Setup-python’s documented PATH selection and the absence of a visible UV override support the normal downstream commands using the selected Python installation. However, the version check alone does not prove executable identity, isolated-build installer identity, or the effective CA set used by pip and Twine.

Resilience and Maintainability Implications

  • observed — The private-index script appends credentials to ~/.pypirc without an explicit cleanup or transactional recovery path. Together with sequential uploads, this leaves interruption and repetition dependent on existing runner and repository behavior; these lifecycle properties were not changed by the PR.
Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the primary change: updating the publish workflow to use a pip version that avoids the compromised eMudhra/emSign CA trust issue.
Description check Passed The description is complete and relevant. It explains the security issue, implementation changes, user impact, and test plan. It also includes the required checklist and clearly states that end-to-end…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is complete and relevant. It explains the security issue, implementation changes, user impact, and test plan. It also includes the required checklist and clearly states that end-to-end testing remains pending.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.)

Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@mday-io

mday-io commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant