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
12 changes: 6 additions & 6 deletions crates/vfox/src/hooks/pre_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl FromLua for PreInstallAttestation {
fn from_lua(value: Value, _: &Lua) -> std::result::Result<Self, LuaError> {
match value {
Value::Table(table) => {
validate_github_attestation_params(&table)?;
validate_github_artifact_attestation_params(&table)?;
validate_cosign_attestation_params(&table)?;
validate_slsa_attestation_params(&table)?;

Expand All @@ -103,25 +103,25 @@ impl FromLua for PreInstallAttestation {
}
}

/// Validates that if one of the GitHub attestation parameters are set, the other requisite
/// Validates that if one of the GitHub artifact attestation parameters are set, the other requisite
/// parameters are also set.
///
/// `github_repo` requires `github_owner` and vice versa, and `github_signer_workflow` requires
/// both aforementioned parameters.
fn validate_github_attestation_params(table: &Table) -> std::result::Result<(), LuaError> {
fn validate_github_artifact_attestation_params(table: &Table) -> std::result::Result<(), LuaError> {
if table.contains_key("github_owner")? && !table.contains_key("github_repo")? {
return Err(LuaError::FromLuaConversionError {
from: "table",
to: "PreInstallAttestation".into(),
message: Some("github_owner requires github_repo for attestation".to_string()),
message: Some("github_owner requires github_repo for artifact attestation".to_string()),
});
}

if table.contains_key("github_repo")? && !table.contains_key("github_owner")? {
return Err(LuaError::FromLuaConversionError {
from: "table",
to: "PreInstallAttestation".into(),
message: Some("github_repo requires github_owner for attestation".to_string()),
message: Some("github_repo requires github_owner for artifact attestation".to_string()),
});
}

Expand All @@ -132,7 +132,7 @@ fn validate_github_attestation_params(table: &Table) -> std::result::Result<(),
from: "table",
to: "PreInstallAttestation".into(),
message: Some(
"github_signer_workflow requires github_owner and github_repo for attestation"
"github_signer_workflow requires github_owner and github_repo for artifact attestation"
.to_string(),
),
});
Expand Down
2 changes: 1 addition & 1 deletion crates/vfox/src/vfox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ impl Vfox {
{
let token = std::env::var("MISE_GITHUB_TOKEN")
.or_else(|_| std::env::var("GITHUB_TOKEN"))
.or(Err("GitHub attestation verification requires either the MISE_GITHUB_TOKEN or GITHUB_TOKEN environment variable set"))?;
.or(Err("GitHub artifact attestation verification requires either the MISE_GITHUB_TOKEN or GITHUB_TOKEN environment variable set"))?;
sigstore_verification::verify_github_attestation(
file,
owner.as_str(),
Expand Down
4 changes: 2 additions & 2 deletions docs/dev-tools/backends/aqua.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ GitHub Artifact Attestations provide cryptographic proof that artifacts were bui
**Configuration:**

```bash
# Enable/disable GitHub attestations verification (default: true)
# Enable/disable GitHub artifact attestations verification (default: true)
export MISE_AQUA_GITHUB_ATTESTATIONS=true
```

Expand Down Expand Up @@ -146,7 +146,7 @@ During tool installation, mise will:

```
✓ Downloaded cli/cli v2.50.0
✓ GitHub attestations verified
✓ GitHub artifact attestations verified
✓ Tool installed successfully
```

Expand Down
2 changes: 1 addition & 1 deletion docs/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Don't do this inside of scripts because mise may add a command in a future versi

## Software verification

mise provides **native software verification** for aqua tools without requiring external dependencies. For aqua tools, Cosign/Minisign signatures, SLSA provenance, and GitHub attestations are verified automatically using mise's built-in implementation.
mise provides **native software verification** for aqua tools without requiring external dependencies. For aqua tools, Cosign/Minisign signatures, SLSA provenance, and GitHub artifact attestations are verified automatically using mise's built-in implementation.

For other verification needs (like GPG), you can install additional tools:

Expand Down
16 changes: 8 additions & 8 deletions e2e/backend/test_aqua_github_attestations
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
#!/usr/bin/env bash
# Test native GitHub attestations verification for aqua packages
# Test native GitHub artifact attestations verification for aqua packages

set -euo pipefail

export MISE_EXPERIMENTAL=1
export MISE_AQUA_GITHUB_ATTESTATIONS=true

echo "=== Testing Native GitHub Attestations Verification ==="
echo "=== Testing Native GitHub Artifact Attestations Verification ==="

# Test: Install goreleaser which has GitHub artifact attestations configured (v2.7.0+)
echo "Installing goreleaser with native GitHub attestations verification..."
echo "Installing goreleaser with native GitHub artifact attestations verification..."

# Capture the installation output to verify the native verification is being used
output=$(mise install aqua:goreleaser/goreleaser@latest 2>&1)
echo "$output"

# Verify the native GitHub attestations verification was used
if echo "$output" | grep -q "verify GitHub attestations"; then
echo "✅ Native GitHub attestations verification was used"
# Verify the native GitHub artifact attestations verification was used
if echo "$output" | grep -q "verify GitHub artifact attestations"; then
echo "✅ Native GitHub artifact attestations verification was used"
else
echo "❌ ERROR: GitHub attestations verification message not found in output"
echo "❌ ERROR: GitHub artifact attestations verification message not found in output"
echo "Output was:"
echo "$output"
exit 1
Expand All @@ -35,4 +35,4 @@ else
fi

echo ""
echo "=== Native GitHub Attestations Verification Test Passed ✓ ==="
echo "=== Native GitHub Artifact Attestations Verification Test Passed ✓ ==="
16 changes: 8 additions & 8 deletions e2e/core/test_ruby_github_attestations
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
#!/usr/bin/env bash
# Test GitHub attestations verification for precompiled Ruby binaries
# Test GitHub artifact attestations verification for precompiled Ruby binaries

set -euo pipefail

export MISE_RUBY_COMPILE=false
export MISE_RUBY_GITHUB_ATTESTATIONS=true

echo "=== Testing Ruby GitHub Attestations Verification ==="
echo "=== Testing Ruby GitHub Artifact Attestations Verification ==="

# Test: Install Ruby with GitHub attestations verification enabled
echo "Installing Ruby with GitHub attestations verification enabled..."
# Test: Install Ruby with GitHub artifact attestations verification enabled
echo "Installing Ruby with GitHub artifact attestations verification enabled..."

output=$(mise install ruby@3.4.8 2>&1) || true
echo "$output"

# Check if attestation verification was attempted
if echo "$output" | grep -q "verify GitHub attestations"; then
echo "✅ GitHub attestations verification was attempted"
if echo "$output" | grep -q "verify GitHub artifact attestations"; then
echo "✅ GitHub artifact attestations verification was attempted"
else
echo "❌ ERROR: Attestation verification message not found"
echo "❌ ERROR: GitHub artifact attestation verification message not found"
exit 1
fi

# Cleanup
mise uninstall ruby@3.4.8 2>/dev/null || true

echo ""
echo "=== Ruby GitHub Attestations Test Passed ✓ ==="
echo "=== Ruby GitHub Artifact Attestations Test Passed ✓ ==="
23 changes: 12 additions & 11 deletions src/backend/aqua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl Backend for AquaBackend {
features.push(SecurityFeature::Checksum { algorithm });
}

// GitHub Attestations - check registry config OR actual release assets
// GitHub Artifact Attestations - check registry config OR actual release assets

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with the rest of the codebase, could you please use "artifact attestations" in lowercase?

Suggested change
// GitHub Artifact Attestations - check registry config OR actual release assets
// GitHub artifact attestations - check registry config OR actual release assets

let has_attestations_config = all_pkgs.iter().any(|p| {
p.github_artifact_attestations
.as_ref()
Expand Down Expand Up @@ -920,7 +920,7 @@ impl AquaBackend {
) -> Result<()> {
self.verify_slsa(ctx, tv, pkg, v, filename).await?;
self.verify_minisign(ctx, tv, pkg, v, filename).await?;
self.verify_github_attestations(ctx, tv, pkg, v, filename)
self.verify_github_artifact_attestations(ctx, tv, pkg, v, filename)
.await?;

let download_path = tv.download_path();
Expand Down Expand Up @@ -1116,7 +1116,7 @@ impl AquaBackend {
Ok(())
}

async fn verify_github_attestations(
async fn verify_github_artifact_attestations(
&self,
ctx: &InstallContext,
tv: &ToolVersion,
Expand All @@ -1127,17 +1127,18 @@ impl AquaBackend {
// Check if attestations are enabled via global and aqua-specific settings
let settings = Settings::get();
if !settings.github_attestations || !settings.aqua.github_attestations {
debug!("GitHub attestations verification disabled");
debug!("GitHub artifact attestations verification disabled");
return Ok(());
}

if let Some(github_attestations) = &pkg.github_artifact_attestations {
if github_attestations.enabled == Some(false) {
debug!("GitHub attestations verification is disabled for {tv}");
debug!("GitHub artifact attestations verification is disabled for {tv}");
return Ok(());
}

ctx.pr.set_message("verify GitHub attestations".to_string());
ctx.pr
.set_message("verify GitHub artifact attestations".to_string());

let artifact_path = tv.download_path().join(filename);

Expand All @@ -1158,22 +1159,22 @@ impl AquaBackend {
{
Ok(true) => {
ctx.pr
.set_message("✓ GitHub attestations verified".to_string());
debug!("GitHub attestations verified successfully for {tv}");
.set_message("✓ GitHub artifact attestations verified".to_string());
debug!("GitHub artifact attestations verified successfully for {tv}");
}
Ok(false) => {
return Err(eyre!(
"GitHub attestations verification returned false for {tv}"
"GitHub artifact attestations verification returned false for {tv}"
));
}
Err(sigstore_verification::AttestationError::NoAttestations) => {
return Err(eyre!(
"No GitHub attestations found for {tv}, but attestations are expected per aqua registry configuration"
"No GitHub artifact attestations found for {tv}, but they are expected per aqua registry configuration"
));
}
Err(e) => {
return Err(eyre!(
"GitHub attestations verification failed for {tv}: {e}"
"GitHub artifact attestations verification failed for {tv}: {e}"
));
}
}
Expand Down
21 changes: 11 additions & 10 deletions src/backend/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl Backend for UnifiedGitBackend {
}
}

// Check for GitHub Attestations (assets with .sigstore.json or .sigstore extension)
// Check for GitHub artifact Attestations (assets with .sigstore.json or .sigstore extension)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with the rest of the codebase, could you please use "artifact attestations" in lowercase?

Suggested change
// Check for GitHub artifact Attestations (assets with .sigstore.json or .sigstore extension)
// Check for GitHub artifact attestations (assets with .sigstore.json or .sigstore extension)

if let Some(release) = latest_release {
let has_attestations = release.assets.iter().any(|a| {
let name = a.name.to_lowercase();
Expand Down Expand Up @@ -1058,7 +1058,7 @@ impl UnifiedGitBackend {
Ok(())
}

/// Verify artifact using GitHub attestations or SLSA provenance.
/// Verify artifact using GitHub artifact attestations or SLSA provenance.
/// Tries attestations first, falls back to SLSA if no attestations found.
/// If verification is attempted and fails, it's a hard error.
async fn verify_attestations_or_slsa(
Expand All @@ -1074,7 +1074,7 @@ impl UnifiedGitBackend {
return Ok(());
}

// Try GitHub attestations first (if enabled globally and for github backend)
// Try GitHub artifact attestations first (if enabled globally and for github backend)
if settings.github_attestations && settings.github.github_attestations {
match self
.try_verify_github_attestations(ctx, tv, file_path)
Expand All @@ -1084,17 +1084,17 @@ impl UnifiedGitBackend {
Ok(false) => {
// Attestations exist but verification failed - hard error
return Err(eyre::eyre!(
"GitHub attestations verification failed for {tv}"
"GitHub artifact attestations verification failed for {tv}"
));
}
Err(VerificationStatus::NoAttestations) => {
// No attestations - fall through to try SLSA
debug!("No GitHub attestations found for {tv}, trying SLSA");
debug!("No GitHub artifact attestations found for {tv}, trying SLSA");
}
Err(VerificationStatus::Error(e)) => {
// Error during verification - hard error
return Err(eyre::eyre!(
"GitHub attestations verification error for {tv}: {e}"
"GitHub artifact attestations verification error for {tv}: {e}"
));
}
}
Expand Down Expand Up @@ -1122,7 +1122,7 @@ impl UnifiedGitBackend {
Ok(())
}

/// Try to verify GitHub attestations. Returns:
/// Try to verify GitHub artifact attestations. Returns:
/// - Ok(true) if attestations exist and verified successfully
/// - Ok(false) if attestations exist but verification failed
/// - Err(NoAttestations) if no attestations found
Expand All @@ -1133,7 +1133,8 @@ impl UnifiedGitBackend {
tv: &ToolVersion,
file_path: &std::path::Path,
) -> std::result::Result<bool, VerificationStatus> {
ctx.pr.set_message("verify GitHub attestations".to_string());
ctx.pr
.set_message("verify GitHub artifact attestations".to_string());

// Parse owner/repo from the repo string
let repo = self.repo();
Expand All @@ -1157,8 +1158,8 @@ impl UnifiedGitBackend {
Ok(verified) => {
if verified {
ctx.pr
.set_message("✓ GitHub attestations verified".to_string());
debug!("GitHub attestations verified successfully for {tv}");
.set_message("✓ GitHub artifact attestations verified".to_string());
debug!("GitHub artifact attestations verified successfully for {tv}");
}
Ok(verified)
}
Expand Down
25 changes: 13 additions & 12 deletions src/plugins/core/ruby.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,8 @@ impl RubyPlugin {
hash::ensure_checksum(&tarball_path, hash_str, Some(ctx.pr.as_ref()), "sha256")?;
}

// Verify GitHub attestations for precompiled binaries
self.verify_github_attestations(ctx, &tarball_path, &tv.version)
// Verify GitHub artifact attestations for precompiled binaries
self.verify_github_artifact_attestations(ctx, &tarball_path, &tv.version)
.await?;

ctx.pr.set_message(format!("extract {}", filename));
Expand All @@ -638,7 +638,7 @@ impl RubyPlugin {
/// Verify GitHub artifact attestations for precompiled Ruby binary
/// Returns Ok(()) if verification succeeds or is skipped (attestations unavailable)
/// Returns Err if verification is enabled and fails
async fn verify_github_attestations(
async fn verify_github_artifact_attestations(
&self,
ctx: &InstallContext,
tarball_path: &std::path::Path,
Expand All @@ -652,15 +652,15 @@ impl RubyPlugin {
.github_attestations
.unwrap_or(settings.github_attestations);
if !enabled {
debug!("GitHub attestations verification disabled for Ruby");
debug!("GitHub artifact attestations verification disabled for Ruby");
return Ok(());
}

let source = &settings.ruby.precompiled_url;

// Skip for custom URL templates (not GitHub repos)
if source.contains("://") {
debug!("Skipping attestation verification for custom URL template");
debug!("Skipping GitHub artifact attestation verification for custom URL template");
return Ok(());
}

Expand All @@ -672,7 +672,8 @@ impl RubyPlugin {
}
};

ctx.pr.set_message("verify GitHub attestations".to_string());
ctx.pr
.set_message("verify GitHub artifact attestations".to_string());

match sigstore_verification::verify_github_attestation(
tarball_path,
Expand All @@ -685,21 +686,21 @@ impl RubyPlugin {
{
Ok(true) => {
ctx.pr
.set_message("✓ GitHub attestations verified".to_string());
.set_message("✓ GitHub artifact attestations verified".to_string());
debug!(
"GitHub attestations verified successfully for ruby@{}",
"GitHub artifact attestations verified successfully for ruby@{}",
version
);
Ok(())
}
Ok(false) => Err(eyre!(
"GitHub attestations verification failed for ruby@{version}\n{ATTESTATION_HELP}"
"GitHub artifact attestations verification failed for ruby@{version}\n{ATTESTATION_HELP}"
)),
Err(sigstore_verification::AttestationError::NoAttestations) => Err(eyre!(
"No GitHub attestations found for ruby@{version}\n{ATTESTATION_HELP}"
"No GitHub artifact attestations found for ruby@{version}\n{ATTESTATION_HELP}"
)),
Err(e) => Err(eyre!(
"GitHub attestations verification failed for ruby@{version}: {e}\n{ATTESTATION_HELP}"
"GitHub artifact attestations verification failed for ruby@{version}: {e}\n{ATTESTATION_HELP}"
)),
}
}
Expand All @@ -719,7 +720,7 @@ impl Backend for RubyPlugin {
algorithm: Some("sha256".to_string()),
}];

// Report GitHub attestations if enabled for precompiled binaries
// Report GitHub artifact attestations if enabled for precompiled binaries
let github_attestations_enabled = settings
.ruby
.github_attestations
Expand Down
Loading