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
6 changes: 6 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# JUnit reports from this profile are the evidence for assurance/assertions.toml.
[profile.ci]
fail-fast = false

[profile.ci.junit]
path = "junit.xml"
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: cargo
directories:
- /
- /fuzz
schedule:
interval: weekly
open-pull-requests-limit: 5
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
136 changes: 119 additions & 17 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,147 @@
name: Build and Run

on:
push
on: [push, pull_request]

permissions:
contents: read

jobs:
rust-stable:
runs-on: ubuntu-latest
runs-on: blacksmith-2vcpu-ubuntu-2404

steps:

- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: taiki-e/install-action@nextest

- name: Build & Test
run: |
cargo build --release
cargo test
cargo fmt --check
python3 scripts/test-check-assurance.py
python3 scripts/run-python-tests.py scripts/test-prepare-interop-prefix.py --junit target/installer-junit/junit.xml
cargo check --locked --all-targets --all-features
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo build --locked --release
cargo test --locked --doc
cargo nextest run --locked --profile ci

- name: Check API documentation
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --locked --no-deps

- name: Upload test evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-linux
path: target/nextest/ci/junit.xml
if-no-files-found: error

- name: Upload installer test evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-installer
path: target/installer-junit/junit.xml
if-no-files-found: error

rust-stable-windows:
runs-on: windows-latest

runs-on: blacksmith-2vcpu-windows-2025
steps:

- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable

- name: Build & Test
run: |
cargo build --release
cargo test

- uses: taiki-e/install-action@nextest
# Separate native-command steps propagate failures under PowerShell too.
- name: Check all targets
run: cargo check --locked --all-targets --all-features
- name: Build release
run: cargo build --locked --release
- name: Test documentation
run: cargo test --locked --doc
- name: Test Windows behavior
run: cargo nextest run --locked --profile ci
- name: Upload test evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-windows
path: target/nextest/ci/junit.xml
if-no-files-found: error

rust-msrv:
runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.85.1
- uses: dtolnay/rust-toolchain@1.88.0

- name: Build & Test
run: |
cargo build --release
cargo test
cargo check --locked --all-targets --all-features
cargo build --locked --release
cargo test --locked

clevis-interop:
runs-on: blacksmith-2vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@nextest
- name: Install interoperability tools
run: |
sudo apt-get update
sudo apt-get install -y clevis jose python3 curl
- name: Check independent fixtures and Clevis recovery
run: |
python3 scripts/check-fixtures.py
cargo nextest run --locked --profile ci --features interop --test clevis
- name: Upload test evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-interop
path: target/nextest/ci/junit.xml
if-no-files-found: error

# Every assertion in assurance/assertions.toml must be backed by passing tests.
assurance:
needs: [rust-stable, rust-stable-windows, clevis-interop]
if: ${{ !cancelled() }}
runs-on: blacksmith-2vcpu-ubuntu-2404
permissions:
contents: read
id-token: write
attestations: write
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
pattern: junit-*
path: ${{ runner.temp }}/junit
- name: Check assertions against test results
run: |
python3 scripts/check-assurance.py \
--junit linux=${{ runner.temp }}/junit/junit-linux/junit.xml \
--junit interop=${{ runner.temp }}/junit/junit-interop/junit.xml \
--junit installer=${{ runner.temp }}/junit/junit-installer/junit.xml \
--junit windows=${{ runner.temp }}/junit/junit-windows/junit.xml \
--out ${{ runner.temp }}/evidence.json
- name: Upload evidence record
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: assurance-evidence
path: |
${{ runner.temp }}/evidence.json
${{ runner.temp }}/junit
- name: Attest evidence record
if: github.event_name == 'push'
uses: actions/attest-build-provenance@v2
with:
subject-path: ${{ runner.temp }}/evidence.json
27 changes: 27 additions & 0 deletions .github/workflows/advisories.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Dependency advisories

on:
push:
pull_request:
schedule:
- cron: '23 6 * * *'
workflow_dispatch:

permissions:
contents: read

jobs:
audit:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@v2
with:
tool: cargo-audit
# Each call fetches RustSec's current database; fail on warnings as well.
- name: Audit library dependencies
run: cargo audit --deny warnings
- name: Audit fuzz dependencies
run: cargo audit --file fuzz/Cargo.lock --deny warnings
37 changes: 37 additions & 0 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Bounded fuzzing

on:
push:
pull_request:
schedule:
- cron: '41 6 * * 1'
workflow_dispatch:

permissions:
contents: read

jobs:
fuzz:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
- uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- name: Check fuzz formatting
run: cargo +nightly fmt --manifest-path fuzz/Cargo.toml --check
- name: Run both seeded targets within resource bounds
run: bash scripts/fuzz-smoke.sh
- name: Upload crash inputs and corpora
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-failures
path: |
fuzz/artifacts
fuzz/corpus
if-no-files-found: ignore
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
/target
/fuzz/target
/fuzz/corpus
/fuzz/artifacts
/fuzz/coverage
*.jwk
/.roadmap.md
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Changelog

## [1.0.0]

### Added

- Support for active and rotated Tang keys through `KeySource::KeySets`.
- Migration, key storage and test guides.
- Linux, Windows and Clevis tests, fuzz tests and automated assurance checks.

### Changed

- **Breaking:** Use typed errors and fallible key generation and conversion.
See [MIGRATING.md](MIGRATING.md) for API changes.
- Require Rust 1.88 and update cryptographic dependencies.
- Validate key material, key roles and permitted operations at initialization.
- Write complete key files before publication. Restrict Unix key permissions
and inherit Windows directory permissions.
- Hide private key values in debug output and error messages.
- Use Blacksmith CI runners and add dependency security checks.

### Fixed

- Return errors for invalid input and key storage failures instead of panicking
or ignoring failures.
- Prevent automatic key generation for invalid or incomplete key stores.
- Use unpadded Base64URL in advertisements and retain all active key signatures
when a signing key is selected.
- Advertise key operations and recovery key metadata compatible with Clevis.
Loading
Loading