Secure your Software Supply Chain and your Content Authenticity with immutable data trails. This GitHub Action uses DataTrails implementation of the IETF Supply Chain, Integrity and Trust (SCITT) APIs.
NOTE::
This SCITT GitHub Action is in Preview, pending adoption of the SCITT Reference APIs (SCRAPI).
To use a production supported implementation, please contact DataTrails for more info.
To create immutable data trails, an account with a Client_ID
and Secret
are required.
To get started, Sign Up here, then see Creating Access Tokens Using a Custom Integration.
Required The CLIENT_ID
used to access the DataTrails SCITT APIs
Required The SECRET
used to access the DataTrails SCITT APIs
Required Unique ID for the collection of statements about an artifact. For more info, see subject
in the IETF SCITT Terminology.
Required The payload file to be registered on the SCITT Service (eg: SBOM, Scan Result, Attestation)
Required The payload content type (iana mediaType) to be registered on the SCITT Service (eg: application/spdx+json
, application/vnd.cyclonedx+json
, Scan Result, Attestation, ...)
Optional A required file representing the signed SCITT Statement that will be registered on SCITT. The parameter is optional, as it provides a default file name.
See Signed Statement Issuance and Registration
Default 'signed-statement.cbor'
Optional The file name used to return a cbor receipt (NOT CURRENTLY IMPLEMENTED) Default 'receipt.cbor'
Required The .pem
file used to sign the statement. NOTE: This version requires a local private key. The key may be volume mapped, with future versions supporting remote signing services.
Required The name of the issuer, set to CTW_Claims:iss
.
See Signed Statement Envelope.
The following example shows a minimal implementation for registering SCITT Signed Statements.
Three GitHub Action Secrets are used:
secrets.DATATRAILS_CLIENT_ID
secrets.DATATRAILS_CLIENT_SECRET
secrets.SIGNING_KEY
Sample github action.yaml
name: Register SCITT Statement
on:
workflow_dispatch:
# push:
# branches: [ "main" ]
env:
DATATRAILS_CLIENT_ID: ${{ secrets.DATATRAILS_CLIENT_ID }}
DATATRAILS_CLIENT_SECRET: ${{ secrets.DATATRAILS_CLIENT_SECRET }}
SIGNING_KEY: ${{ secrets.SYNSATION_SIGNING_KEY }}
SUBJECT: "synsation.io/myproduct-v1.0"
ISSUER: "synsation.io"
jobs:
build-image-register-DataTrails-SCITT:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
steps:
- name: Create buildOutput Directory
run: |
mkdir -p ./buildOutput/
- name: save-keys
env:
SIGNING_KEY: ${{ env.SIGNING_KEY }}
shell: bash
run: |
echo "$SIGNING_KEY" >> ./signingkey.pem
- name: Create Compliance Statement
# A sample compliance file. Replace with an SBOM, in-toto statement, image for content authenticity, ...
run: |
echo '{"compliance.42":"true","software.eol":"2025-03-15"}' >> ./buildOutput/attestation.json
- name: Upload Attestation
id: upload-attestation
uses: actions/upload-artifact@v4
with:
name: attestation.json
path: ./buildOutput/attestation.json
- name: Register as a SCITT Signed Statement
# Register the Signed Statement wit DataTrails SCITT APIs
id: register-compliance-scitt-signed-statement
uses: datatrails/[email protected]
with:
content-type: "application/vnd.unknown.attestation+json"
payload-file: "./buildOutput/attestation.json"
payload-location: ${{ steps.upload-attestation.outputs.artifact-url }}
subject: ${{ env.SUBJECT }}
issuer: ${{ env.ISSUER}}
signing-key-file: "./signingkey.pem"
- name: upload-transparent-statement
uses: actions/upload-artifact@v4
with:
name: transparent-statement
path: transparent-statement.cbor
- name: cleanup-keys
shell: bash
run: |
rm ./signingkey.pem
Registered SCITT Statements are available as DataTrails Events.
NOTE: As the SCITT Reference API queries mature, additional DataTrails SCITT Query APIs will be made available.
Using the SUBJECT
from above, query all DataTrails Events (SCITT Registered Statements).
SUBJECT="synsation.io/myproduct-v1.0"
curl https://app.datatrails.ai/archivist/v2/publicassets/-/events?event_attributes.subject=$SUBJECT \
| jq