Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/dev-tools/mise-lock.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ mise use node@24
Backend support for lockfile features varies:

- ✅ **Full support** (version + checksum + size + URL): `aqua`, `http`, `github`, `gitlab`
- _Provenance support_: `aqua`, `github`, `core:ruby` (precompiled binaries), `core:zig` (install-time)
- _Provenance support_: `aqua`, `github`, `core:python` (precompiled binaries), `core:ruby` (precompiled binaries), `core:zig` (install-time)
- ⚠️ **Partial support** (version + URL + provenance): `vfox` (tool plugins only)
- ⚠️ **Partial support** (version + checksum + size): `ubi`
- 📝 **Basic support** (version + checksum): `core` (some tools)
Expand Down
4 changes: 4 additions & 0 deletions e2e-win/python.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

Describe 'python' {
BeforeAll {
$env:MISE_PYTHON_GITHUB_ATTESTATIONS = "0"
}

It 'executes python 3.12.0' {
mise x python@3.12.0 -- where python
mise x python@3.12.0 -- python --version | Should -Be "Python 3.12.0"
Expand Down
4 changes: 4 additions & 0 deletions e2e-win/uv.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

Describe 'uv' {
BeforeAll {
$env:MISE_PYTHON_GITHUB_ATTESTATIONS = "0"
}

BeforeEach {
$originalPath = Get-Location
Set-Location TestDrive:
Expand Down
1 change: 1 addition & 0 deletions e2e/backend/test_pipx_deep_dependencies_slow
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ assert_fail "pipx"

# Use only precompiled python
export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

# Set up a 3-step installation: python@3.12.3 > pipx@1.5.0 > pipx:mkdocs@1.6.0
cat >.mise.toml <<EOF
Expand Down
1 change: 1 addition & 0 deletions e2e/backend/test_pipx_postinstall_hook
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ assert_fail "pipx"

# Use precompiled python and uvx (the default)
export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
export MISE_PIPX_UVX=1

# Set up mise-managed Python with a pipx package that has a postinstall hook
Expand Down
1 change: 1 addition & 0 deletions e2e/backend/test_pipx_uvx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ assert_fail "pipx"

# Use precompiled python
export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
export MISE_PIPX_UVX=1

# Set up a 2-step installation: pipx@1.5.0 > pipx:mkdocs@1.6.0
Expand Down
1 change: 1 addition & 0 deletions e2e/backend/test_pipx_venv_symlink
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ assert_fail "pipx"

# Use precompiled python and disable uvx to use pipx (which uses mise's Python)
export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
export MISE_PIPX_UVX=0

# Set up mise-managed Python and pipx
Expand Down
18 changes: 18 additions & 0 deletions e2e/core/test_python_github_attestations
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Test GitHub artifact attestations verification for Python precompiled binaries
# Depends on GitHub Releases and Attestations APIs; may fail due to rate limits or outages.

export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=1

# Use a recent Python version that has attestations in python-build-standalone.
# Older releases (e.g. 3.12.3) predate GitHub attestation support and will fail.
output=$(mise install python@3.13.5 2>&1) || true
echo "$output"

# Verify attestation verification was attempted and succeeded
assert_contains "echo \"$output\"" "verify GitHub artifact attestations"
assert_contains "echo \"$output\"" "✓ GitHub artifact attestations verified"

# Verify the installed Python works
assert "mise x python@3.13.5 -- python --version" "Python 3.13.5"
1 change: 1 addition & 0 deletions e2e/core/test_python_precompiled
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash

export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
assert_contains "mise use python@3.12.3 2>&1" "cpython-"
assert_contains "mise x -- python --version" "Python 3.12.3"

Expand Down
1 change: 1 addition & 0 deletions e2e/core/test_python_uv_venv
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set -euo pipefail

export MISE_EXPERIMENTAL=1
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

# Test uv is used for manually defined venv
cat >mise.toml <<EOF
Expand Down
1 change: 1 addition & 0 deletions e2e/core/test_python_uv_venv_x_tiny
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -euo pipefail

export MISE_EXPERIMENTAL=1
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

cat >.mise.toml <<EOF
[tools]
Expand Down
1 change: 1 addition & 0 deletions e2e/core/test_python_venv
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash

export MISE_PYTHON_DEFAULT_PACKAGES_FILE="$HOME/.default-python-packages"
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

cat >.mise.toml <<EOF
[env._.python]
Expand Down
1 change: 1 addition & 0 deletions e2e/core/test_python_venv_with_go_backend_deadlock_slow
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# a circular dependency during environment resolution while creating Python venv.
# fixes https://github.com/jdx/mise/discussions/7059
set -euo pipefail
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

cat >.mise.toml <<EOF
[tools]
Expand Down
1 change: 1 addition & 0 deletions e2e/core/test_python_version_comments
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Test that .python-version files with comments are parsed correctly
export MISE_PYTHON_COMPILE=0
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

# Enable idiomatic version files for python
mise settings set idiomatic_version_file_enable_tools python
Expand Down
75 changes: 75 additions & 0 deletions e2e/lockfile/test_lockfile_python
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Test that core:python generates lockfile URLs from python-build-standalone
export MISE_LOCKFILE=1
export MISE_PYTHON_GITHUB_ATTESTATIONS=0

detect_platform

Expand Down Expand Up @@ -49,3 +50,77 @@ assert_fail "mise install python -f" "Checksum mismatch"
rm -f mise.lock mise.toml

echo "Python lockfile URL test passed!"

echo "=== Testing provenance recorded in lockfile when enabled ==="
export MISE_PYTHON_GITHUB_ATTESTATIONS=1

cat <<EOF >mise.toml
[tools]
python = "3.13.5"
EOF

mise lock --platform "$MISE_PLATFORM"
assert "test -f mise.lock"
assert_contains "cat mise.lock" 'provenance = "github-attestations"'

echo "Lockfile with provenance:"
cat mise.lock

rm -f mise.lock mise.toml
unset MISE_PYTHON_GITHUB_ATTESTATIONS

echo "Python provenance lockfile test passed!"

echo "=== Testing provenance NOT recorded when disabled ==="
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
export MISE_GITHUB_ATTESTATIONS=0

cat <<EOF >mise.toml
[tools]
python = "3.13.5"
EOF

mise lock --platform "$MISE_PLATFORM"
assert "test -f mise.lock"
# provenance should not appear in lockfile when disabled
assert_fail "grep -q 'provenance' mise.lock"

rm -f mise.lock mise.toml
unset MISE_PYTHON_GITHUB_ATTESTATIONS
unset MISE_GITHUB_ATTESTATIONS

echo "Python provenance disabled test passed!"

echo "=== Testing provenance downgrade attack detection ==="
cat <<EOF >mise.toml
[tools]
python = "3.13.5"
EOF

# Generate lockfile with all platforms (so the current platform is included)
mise lock
assert "test -f mise.lock"

# Inject provenance into ALL platform sections (simulating a previously-verified install)
awk '
/^provenance/ && in_section { next }
{ print }
/^\[tools\.python\."platforms\./ { in_section=1; print "provenance = \"github-attestations\"" }
/^\[/ && !/^\[tools\.python\."platforms\./ { in_section=0 }
' mise.lock >mise.lock.tmp && mv mise.lock.tmp mise.lock
assert_contains "cat mise.lock" 'provenance = "github-attestations"'

# Attempt install with provenance verification disabled.
# The lockfile says provenance was verified, but settings are off,
# so mise should refuse to install (downgrade/stripping attack).
rm -rf "$MISE_DATA_DIR/installs/python"
export MISE_PYTHON_GITHUB_ATTESTATIONS=0
export MISE_GITHUB_ATTESTATIONS=0
assert_fail_contains "mise install 2>&1" "downgrade attack"

echo "=== Cleanup ==="
unset MISE_PYTHON_GITHUB_ATTESTATIONS
unset MISE_GITHUB_ATTESTATIONS
rm -f mise.lock mise.toml

echo "Python provenance downgrade attack test passed!"
1 change: 1 addition & 0 deletions e2e/sync/test_sync_python_uv
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash

export MISE_PYTHON_GITHUB_ATTESTATIONS=0
assert "mise use -g uv python@3.11.3"
assert "mise x -- uv python install 3.11.1"
export UV_PYTHON_DOWNLOADS=never
Expand Down
4 changes: 4 additions & 0 deletions schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,10 @@
"description": "Path to a file containing default python packages to install when installing a python version.",
"type": "string"
},
"github_attestations": {
"description": "Enable GitHub Artifact Attestations verification for precompiled Python binaries.",
"type": "boolean"
},
"patch_url": {
"description": "URL to fetch python patches from to pass to python-build.",
"type": "string"
Expand Down
12 changes: 12 additions & 0 deletions settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,18 @@ env = "MISE_PYTHON_DEFAULT_PACKAGES_FILE"
optional = true
type = "Path"

[python.github_attestations]
description = "Enable GitHub Artifact Attestations verification for precompiled Python binaries."
docs = """
Override the global `github_attestations` setting for Python precompiled binaries.
When enabled, mise will verify the authenticity of precompiled Python binaries from astral-sh/python-build-standalone.

Defaults to the global `github_attestations` setting if not specified.
"""
env = "MISE_PYTHON_GITHUB_ATTESTATIONS"
optional = true
type = "Bool"

[python.patch_url]
description = "URL to fetch python patches from to pass to python-build."
env = "MISE_PYTHON_PATCH_URL"
Expand Down
Loading
Loading