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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Preserve line endings in test data files (hashes depend on exact content)
**/test_data/** binary
**/fixtures/** binary
314 changes: 314 additions & 0 deletions .github/workflows/interop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,314 @@
name: Interoperability Tests

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
interop:
name: Interoperability Tests
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC token
contents: read
steps:
- uses: actions/checkout@v4

- uses: dtolnay/[email protected]

- name: Install Cosign
uses: sigstore/[email protected]
with:
cosign-release: 'v3.0.2'

- name: Build release binaries
run: cargo build --release -p sigstore-sign -p sigstore-verify --examples

# =========================================
# Setup: Create test artifacts
# =========================================
- name: Create test artifacts
run: |
echo "Hello from sigstore-rust interop test at $(date)" > test-artifact.txt
echo "Hello from sigstore-rust interop test V2 at $(date)" > test-artifact-v2.txt
echo "Digest-based verification test at $(date)" > digest-test.txt
echo "Test package content for attestation at $(date)" > test-package.txt

echo "Test artifacts created:"
sha256sum test-artifact.txt test-artifact-v2.txt digest-test.txt test-package.txt

# Store digest for later use
DIGEST=$(sha256sum digest-test.txt | cut -d' ' -f1)
echo "ARTIFACT_DIGEST=sha256:${DIGEST}" >> $GITHUB_ENV

# =========================================
# REKOR V1: Blob Signing Tests
# =========================================
- name: "[V1] Sign with sigstore-rust"
run: |
./target/release/examples/sign_blob test-artifact.txt -o rust-signed.sigstore.json
echo "Bundle created:"
cat rust-signed.sigstore.json | jq -r '.mediaType'

- name: "[V1] Verify sigstore-rust signature with cosign"
run: |
cosign verify-blob \
--bundle rust-signed.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact.txt
echo "✅ Cosign successfully verified sigstore-rust signature (V1)"

- name: "[V1] Verify sigstore-rust signature with sigstore-rust"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact.txt rust-signed.sigstore.json
echo "✅ sigstore-rust successfully verified its own signature (V1)"

- name: "[V1] Sign with cosign"
run: |
cosign version
cosign sign-blob \
--yes \
--bundle cosign-signed.sigstore.json \
test-artifact.txt
echo "Bundle created:"
cat cosign-signed.sigstore.json | jq -r '.mediaType'

- name: "[V1] Verify cosign signature with sigstore-rust"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact.txt cosign-signed.sigstore.json
echo "✅ sigstore-rust successfully verified cosign signature (V1)"

- name: "[V1] Verify cosign signature with cosign (sanity check)"
run: |
cosign verify-blob \
--bundle cosign-signed.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact.txt
echo "✅ Cosign successfully verified its own signature (V1)"

# =========================================
# REKOR V2: Blob Signing Tests
# =========================================
- name: "[V2] Sign with sigstore-rust --v2"
run: |
./target/release/examples/sign_blob --v2 test-artifact-v2.txt -o rust-signed-v2.sigstore.json
echo "Bundle created:"
cat rust-signed-v2.sigstore.json | jq -r '.mediaType'
echo "Entry kind/version:"
cat rust-signed-v2.sigstore.json | jq -r '.verificationMaterial.tlogEntries[0].kindVersion'

- name: "[V2] Verify sigstore-rust V2 signature with cosign"
run: |
# V2 bundles use RFC3161 timestamps instead of integratedTime
cosign verify-blob \
--bundle rust-signed-v2.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--use-signed-timestamps \
test-artifact-v2.txt
echo "✅ Cosign successfully verified sigstore-rust V2 signature"

- name: "[V2] Verify sigstore-rust V2 signature with sigstore-rust"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact-v2.txt rust-signed-v2.sigstore.json
echo "✅ sigstore-rust successfully verified its own V2 signature"

- name: "[V2] Sign with cosign"
run: |
cosign sign-blob \
--yes \
--bundle cosign-signed-v2.sigstore.json \
test-artifact-v2.txt
echo "Bundle created:"
cat cosign-signed-v2.sigstore.json | jq -r '.mediaType'

- name: "[V2] Verify cosign V2 signature with sigstore-rust"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact-v2.txt cosign-signed-v2.sigstore.json
echo "✅ sigstore-rust successfully verified cosign V2 signature"

- name: "[V2] Verify cosign V2 signature with cosign (sanity check)"
run: |
cosign verify-blob \
--bundle cosign-signed-v2.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact-v2.txt
echo "✅ Cosign successfully verified its own V2 signature"

# =========================================
# DIGEST: Digest-based Verification Tests
# =========================================
- name: "[Digest] Sign with sigstore-rust"
run: |
./target/release/examples/sign_blob digest-test.txt -o digest-bundle.sigstore.json

- name: "[Digest] Verify with cosign using digest"
run: |
cosign verify-blob \
--bundle digest-bundle.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
${{ env.ARTIFACT_DIGEST }}
echo "✅ Cosign verified using digest"

- name: "[Digest] Verify with sigstore-rust using digest"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
${{ env.ARTIFACT_DIGEST }} digest-bundle.sigstore.json
echo "✅ sigstore-rust verified using digest"

- name: "[Digest] Sign with cosign"
run: |
cosign sign-blob \
--yes \
--bundle cosign-digest-bundle.sigstore.json \
digest-test.txt

- name: "[Digest] Verify cosign bundle with sigstore-rust using digest"
run: |
./target/release/examples/verify_bundle \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
${{ env.ARTIFACT_DIGEST }} cosign-digest-bundle.sigstore.json
echo "✅ sigstore-rust verified cosign bundle using digest"

# =========================================
# DSSE: Attestation Tests
# =========================================
- name: "[DSSE] Attest with sigstore-rust"
run: |
./target/release/examples/sign_attestation \
--channel "https://example.com/test-channel" \
test-package.txt -o rust-attestation.sigstore.json
echo "Attestation bundle created:"
cat rust-attestation.sigstore.json | jq -r '.mediaType'
echo "Entry kind:"
cat rust-attestation.sigstore.json | jq -r '.verificationMaterial.tlogEntries[0].kindVersion.kind'

- name: "[DSSE] Verify sigstore-rust attestation with cosign"
run: |
cosign verify-blob-attestation \
--bundle rust-attestation.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--type "https://schemas.conda.org/attestations-publish-1.schema.json" \
test-package.txt
echo "✅ Cosign successfully verified sigstore-rust attestation"

- name: "[DSSE] Verify sigstore-rust attestation with sigstore-rust"
run: |
./target/release/examples/verify_conda_attestation \
test-package.txt rust-attestation.sigstore.json
echo "✅ sigstore-rust successfully verified its own attestation"

- name: "[DSSE] Attest with cosign"
run: |
# Create a predicate for cosign
cat > predicate.json << EOF
{
"targetChannel": "https://example.com/cosign-test-channel"
}
EOF

cosign attest-blob \
--yes \
--bundle cosign-attestation.sigstore.json \
--predicate predicate.json \
--type "https://schemas.conda.org/attestations-publish-1.schema.json" \
test-package.txt
echo "Attestation bundle created:"
cat cosign-attestation.sigstore.json | jq -r '.mediaType'

- name: "[DSSE] Verify cosign attestation with sigstore-rust"
run: |
./target/release/examples/verify_conda_attestation \
test-package.txt cosign-attestation.sigstore.json
echo "✅ sigstore-rust successfully verified cosign attestation"

- name: "[DSSE] Verify cosign attestation with cosign (sanity check)"
run: |
cosign verify-blob-attestation \
--bundle cosign-attestation.sigstore.json \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--type "https://schemas.conda.org/attestations-publish-1.schema.json" \
test-package.txt
echo "✅ Cosign successfully verified its own attestation"

# =========================================
# SIGSTORE-PYTHON: Cross-implementation verification
# =========================================
- name: Install sigstore-python
run: |
pip install sigstore
sigstore --version

- name: "[Python] Verify sigstore-rust V1 bundle"
run: |
# GitHub Actions identity is the workflow file URL
IDENTITY="https://github.com/${{ github.repository }}/.github/workflows/interop.yml@${{ github.ref }}"
echo "Expected identity: $IDENTITY"
sigstore verify identity \
--bundle rust-signed.sigstore.json \
--cert-identity "$IDENTITY" \
--cert-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact.txt
echo "✅ sigstore-python verified sigstore-rust V1 bundle"

- name: "[Python] Verify sigstore-rust V2 bundle"
run: |
IDENTITY="https://github.com/${{ github.repository }}/.github/workflows/interop.yml@${{ github.ref }}"
sigstore verify identity \
--bundle rust-signed-v2.sigstore.json \
--cert-identity "$IDENTITY" \
--cert-oidc-issuer "https://token.actions.githubusercontent.com" \
test-artifact-v2.txt
echo "✅ sigstore-python verified sigstore-rust V2 bundle"

- name: "[Python] Verify sigstore-rust attestation"
run: |
IDENTITY="https://github.com/${{ github.repository }}/.github/workflows/interop.yml@${{ github.ref }}"
sigstore verify identity \
--bundle rust-attestation.sigstore.json \
--cert-identity "$IDENTITY" \
--cert-oidc-issuer "https://token.actions.githubusercontent.com" \
test-package.txt
echo "✅ sigstore-python verified sigstore-rust attestation"

# =========================================
# BUNDLE FORMAT: Structural compatibility checks
# =========================================
- name: "[Format] Check sigstore-rust V1 bundle format"
run: python scripts/compare_bundles.py --check rust-signed.sigstore.json

- name: "[Format] Check sigstore-rust V2 bundle format"
run: python scripts/compare_bundles.py --check rust-signed-v2.sigstore.json

- name: "[Format] Compare V1 bundles (sigstore-rust vs cosign)"
run: python scripts/compare_bundles.py rust-signed.sigstore.json cosign-signed.sigstore.json

- name: "[Format] Compare attestation bundles (sigstore-rust vs cosign)"
run: python scripts/compare_bundles.py rust-attestation.sigstore.json cosign-attestation.sigstore.json
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ chrono = { version = "0.4", features = ["serde"] }
# Testing
hex = "0.4"
rstest = { version = "0.26", default-features = false }
regex = "1.11"

# Logging
tracing = { version = "0.1" }
Expand Down
Loading