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
83 changes: 79 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
engine:
name: Image engine
name: Engine and services
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -31,14 +31,81 @@ jobs:
run: cargo fmt --all -- --check

- name: Clippy
run: cargo clippy -p imagecore --all-targets -- -D warnings
run: cargo clippy --workspace --all-targets -- -D warnings

- name: Test
run: cargo test -p imagecore
run: cargo test --workspace

- name: Check the WebAssembly target builds
run: cargo build -p imagecore --target wasm32-unknown-unknown --release

conformance:
name: C2PA conformance
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

# Produces the crJSON evidence the Conformance Program asks applicants to
# submit, from assets this repository signs itself. When the Program
# supplies its own asset library, point `--asset-dir` at it instead.
- name: Generate crJSON evidence
run: ./conformance/scripts/generate-evidence.sh

- name: Upload the evidence
uses: actions/upload-artifact@v4
with:
name: crjson-evidence
path: conformance/evidence/crjson/
if-no-files-found: error

supply-chain:
name: Supply chain
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.cargo/bin
key: ${{ runner.os }}-audit-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-audit-

# O.3 and O.4 at Assurance Level 1: an SBOM of everything in the Target
# of Evaluation, and a gate that refuses to release a CRITICAL or HIGH
# finding older than 90 days. `conformance/vulnerability-ledger.json` is
# what makes the clock survive a fresh runner.
- name: Software Bill of Materials
run: ./conformance/scripts/sbom.sh

- name: Vulnerability gate
run: ./conformance/scripts/vulnerability-scan.sh

- name: Upload the supply-chain evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: supply-chain-evidence
path: conformance/evidence/
if-no-files-found: warn

web:
name: Web app
runs-on: ubuntu-latest
Expand Down Expand Up @@ -69,5 +136,13 @@ jobs:

- run: npm ci
- run: npm run build:wasm

# The property that matters most in this repository, and the one a
# reviewer cannot check by reading: the module served to browsers must
# contain no private key. Runs here rather than in the `engine` job
# because it inspects the built artefact, which is what actually ships.
- name: Check the WebAssembly bundle carries no key material
run: ./conformance/scripts/check-no-key-material.sh

- run: npm run typecheck
- run: npx vite build
- run: npx vite build apps/editor
57 changes: 42 additions & 15 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@ jobs:
with:
version: 'latest'

- name: Test the image engine
run: cargo test -p imagecore
- name: Test the workspace
run: cargo test --workspace

# O.3 and O.4 at Assurance Level 1 require that the pipeline refuse to
# release a Claim Generator carrying a CRITICAL or HIGH vulnerability more
# than 90 days after detection. This is the point in the pipeline where
# that refusal has to happen, so the gate runs before the build, not
# alongside it.
- name: Supply-chain gate
run: ./conformance/scripts/vulnerability-scan.sh

- name: Setup Node.js
uses: actions/setup-node@v4
Expand All @@ -53,21 +61,40 @@ jobs:
- name: Install dependencies
run: npm ci

# The signing credentials for Content Credentials. When both secrets are
# set, `crates/imagecore/build.rs` compiles them into the engine instead
# of the demo key committed under `signing/`; when they are absent, as on
# a fork, the demo key is used and the build still works.
#
# To be clear about what this buys: a secret keeps a key out of public git
# history. It cannot make the key secret. This engine is served to
# browsers, so whichever key it carries is published along with it. See
# `signing/README.md` for why that is inherent to client-side signing and
# what a trustworthy setup would look like instead.
- name: Build
run: npm run build
env:
C2PA_SIGNING_CERT: ${{ secrets.C2PA_SIGNING_CERT }}
C2PA_SIGNING_KEY: ${{ secrets.C2PA_SIGNING_KEY }}

# The property this whole architecture exists to preserve. Checked against
# the artefact that is about to be published, not against the source.
- name: Check the published module carries no key material
run: ./conformance/scripts/check-no-key-material.sh

# The C2PA Trust List and the TSA Trust List, if this deployment ships
# them. The editor fetches both at run time and falls back to reporting
# signer identity as unchecked when they are absent, so an unset variable
# degrades the interface rather than breaking it.
- name: Publish the trust lists
if: vars.C2PA_TRUST_LIST_URL != ''
run: |
mkdir -p dist/trust-lists
curl -fsSL "${{ vars.C2PA_TRUST_LIST_URL }}" -o dist/trust-lists/c2pa-trust-list.pem
if [ -n "${{ vars.C2PA_TSA_TRUST_LIST_URL }}" ]; then
curl -fsSL "${{ vars.C2PA_TSA_TRUST_LIST_URL }}" \
-o dist/trust-lists/c2pa-tsa-trust-list.pem
fi

# Where the claim-signer lives, for a deployment that has one. Absent on
# the plain GitHub Pages build: there is no application server there to
# mint a session credential, so the editor runs without signing and says
# so. Note what is *not* here any more — no signing key, no certificate,
# no secret of any kind reaches the published bundle.
- name: Publish the claim-signer configuration
if: vars.CLAIM_SIGNER_URL != ''
run: |
printf '{"url":"%s","credentialEndpoint":"%s"}\n' \
"${{ vars.CLAIM_SIGNER_URL }}" \
"${{ vars.EDGE_CREDENTIAL_ENDPOINT }}" \
> dist/claim-signer.json

- name: Setup Pages
uses: actions/configure-pages@v5
Expand Down
14 changes: 13 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@ dist
target

# wasm-pack output - rebuilt by `npm run build:wasm`
/src/wasm/
/apps/editor/src/wasm/

# Conformance evidence - reproducible with one command, and CI uploads it as a
# build artefact. See conformance/README.md.
/conformance/evidence/

# Stray cargo-cyclonedx output, when sbom.sh is interrupted before it
# collects the documents into conformance/evidence/.
*.cdx.json

# Python bytecode from the conformance scripts.
__pycache__/
*.pyc
Loading
Loading