feat(setup-python): update Python installation script with Sigstore verification and improved signature handling; add support for downloading cosign based on architecture

This commit is contained in:
Ivan
2026-04-13 18:21:39 -05:00
parent 1b7051a810
commit c77629dc10
+74 -7
View File
@@ -1,6 +1,7 @@
#!/bin/sh
# Build and install Python from official python.org source with GPG verification.
# Source: https://www.python.org
# Build and install Python from official python.org source.
# Verifies: OpenPGP (.asc) when present, otherwise Sigstore (.sigstore) with cosign.
# https://www.python.org/download/sigstore/ PEP 761 (3.14+): PGP removed; Sigstore only.
#
# Usage: setup-python.sh [version]
# version: exact (3.14.x) or minor (3.14, resolved to latest patch).
@@ -8,6 +9,42 @@ set -eu
. "$(dirname "$0")/priv.sh"
# Sigstore identity and OIDC issuer per release (see python.org/download/sigstore).
sigstore_identity_for() {
_v="$1"
case "$_v" in
3.7.*) echo "nad@python.org|https://github.com/login/oauth" ;;
3.8.*|3.9.*) echo "lukasz@langa.pl|https://github.com/login/oauth" ;;
3.10.*|3.11.*) echo "pablogsal@python.org|https://accounts.google.com" ;;
3.12.*|3.13.*) echo "thomas@python.org|https://accounts.google.com" ;;
3.14.*|3.15.*) echo "hugo@python.org|https://github.com/login/oauth" ;;
3.16.*|3.17.*) echo "savannah@python.org|https://github.com/login/oauth" ;;
3.*.*) echo "savannah@python.org|https://github.com/login/oauth" ;;
*) echo "" ;;
esac
}
download_cosign() {
COSIGN_VERSION="${COSIGN_VERSION:-2.4.1}"
COSIGN_ARCH="linux-amd64"
case "$(uname -m)" in
aarch64|arm64) COSIGN_ARCH="linux-arm64" ;;
x86_64|amd64) COSIGN_ARCH="linux-amd64" ;;
x86_64-gnu) COSIGN_ARCH="linux-amd64" ;;
*)
echo "unsupported uname -m for cosign: $(uname -m)" >&2
exit 1
;;
esac
COSIGN_BIN="/tmp/cosign-${COSIGN_VERSION}-${COSIGN_ARCH}"
if [ ! -x "$COSIGN_BIN" ]; then
curl -fsSL "https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-${COSIGN_ARCH}" \
-o "$COSIGN_BIN"
chmod +x "$COSIGN_BIN"
fi
echo "$COSIGN_BIN"
}
PY_INPUT="${1:-3.14}"
CURRENT="$(python3 --version 2>/dev/null | sed 's/Python //')" || true
@@ -50,7 +87,11 @@ SRC_URL="https://www.python.org/ftp/python/${PY_VERSION}/${TARBALL}"
SIG_URL="${SRC_URL}.asc"
curl -fsSL "$SRC_URL" -o "/tmp/${TARBALL}"
curl -fsSL "$SIG_URL" -o "/tmp/${TARBALL}.asc"
SIG_HTTP="$(curl -sS -o "/tmp/${TARBALL}.asc" -w "%{http_code}" "$SIG_URL" || true)"
if [ "$SIG_HTTP" != "200" ]; then
rm -f "/tmp/${TARBALL}.asc"
fi
GPG_KEYS=""
case "$PY_VERSION" in
@@ -64,11 +105,12 @@ case "$PY_VERSION" in
GPG_KEYS="E3FF2839C048B25C084DEBE9B26995E310250568"
;;
*)
echo "No known GPG key for Python ${PY_VERSION}; skipping signature check" >&2
echo "No known GPG key for Python ${PY_VERSION}; skipping OpenPGP signature check" >&2
;;
esac
if [ -n "$GPG_KEYS" ]; then
GPG_VERIFIED=0
if [ "$SIG_HTTP" = "200" ] && [ -n "$GPG_KEYS" ]; then
export GNUPGHOME="$(mktemp -d)"
for key in $GPG_KEYS; do
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" 2>/dev/null || \
@@ -77,7 +119,32 @@ if [ -n "$GPG_KEYS" ]; then
gpg --batch --verify "/tmp/${TARBALL}.asc" "/tmp/${TARBALL}"
rm -rf "$GNUPGHOME"
unset GNUPGHOME
echo "GPG signature verified"
echo "OpenPGP signature verified"
GPG_VERIFIED=1
fi
if [ "$GPG_VERIFIED" != "1" ]; then
SIGSTORE_URL="${SRC_URL}.sigstore"
SIGSTORE_HTTP="$(curl -sS -o "/tmp/${TARBALL}.sigstore" -w "%{http_code}" "$SIGSTORE_URL" || true)"
if [ "$SIGSTORE_HTTP" != "200" ]; then
rm -f "/tmp/${TARBALL}.sigstore"
echo "No OpenPGP signature (HTTP ${SIG_HTTP}) and no Sigstore bundle at ${SIGSTORE_URL} (HTTP ${SIGSTORE_HTTP})" >&2
exit 1
fi
II="$(sigstore_identity_for "$PY_VERSION")"
if [ -z "$II" ]; then
echo "No Sigstore identity mapping for Python ${PY_VERSION}" >&2
exit 1
fi
SIG_IDENTITY="$(echo "$II" | cut -d'|' -f1)"
SIG_ISSUER="$(echo "$II" | cut -d'|' -f2)"
COSIGN_BIN="$(download_cosign)"
"$COSIGN_BIN" verify-blob --new-bundle-format \
--certificate-oidc-issuer "$SIG_ISSUER" \
--certificate-identity "$SIG_IDENTITY" \
--bundle "/tmp/${TARBALL}.sigstore" \
"/tmp/${TARBALL}"
echo "Sigstore signature verified"
fi
cd /tmp
@@ -93,7 +160,7 @@ run_priv ln -sf /usr/local/bin/python3 /usr/local/bin/python
run_priv ln -sf /usr/local/bin/pip3 /usr/local/bin/pip
cd /
rm -rf "/tmp/${TARBALL}" "/tmp/${TARBALL}.asc" "/tmp/Python-${PY_VERSION}" "$BUILD_LOG"
rm -rf "/tmp/${TARBALL}" "/tmp/${TARBALL}.asc" "/tmp/${TARBALL}.sigstore" "/tmp/Python-${PY_VERSION}" "$BUILD_LOG"
python3 --version
pip3 --version