Skip to main content

Scribe Platforms Github Action

Scribe offers the use of GitHub Actions to enable the embedding of evidence collection and integrity validation into your pipeline as a way to help secure your software supply chain.

Further documentation Platforms integration.

Input arguments

  command:
description: Command to run
required: true
valint_args:
description: Valint args
sign:
description: Sign evidence
platform:
description: Select Platform
required: true
args:
description: "Additional arguments to pass to Platforms"
log-level:
description: Log verbosity level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
log-file:
description: Log file path
config:
description: Path to a configuration file
print-config:
description: Print the configuration after applying all other arguments and exit
db-local-path:
description: Local db path

Usage

- name: Platform usage example
uses: scribe-security/action-platforms@master
with:
command: [discover, evidence, bom, verify]
platform: [k8s, dockerhub, gitlab, github]
args: [FLAGS]

Setting Secret Flags

Platforms CLI supports passing secrets as environment variables:

  • ATTEST_KEY, ATTEST_CERT, ATTEST_CA: Set evidence signing.
  • VALINT_SCRIBE_AUTH_CLIENT_SECRET: Set Scribe Client Secret.
  • VALINT_SCRIBE_ENABLE: Enable Scribe service.
  • VALINT_OUTPUT_DIRECTORY: Set evidence local cache directory.
  • PLATFORMS_DB_PATH: Set platforms database path.
  • GITHUB_TOKEN: Set GitHub discovery access.
  • JFROG_TOKEN: Set Jfrog discovery access.
  • DOCKERHUB_USERNAME, DOCKERHUB_PASSWORD: Set DockerHub discovery access.
  • K8S_URL, K8S_TOKEN: Set Kubernetes discovery access.
  • GITLAB_TOKEN: Set GitLab discovery access.
Github Platform Example
on:
workflow_dispatch:

concurrency:
group: github-ci-${{ github.ref }}
cancel-in-progress: true

env:
PLATFORMS_VERSION: "latest"
K8S_URL: https://my_cluster.com # K8s discovery URL
K8S_TOKEN: ${{ secrets.INTEGRATION_K8S_TOKEN }}
LOG_LEVEL: "INFO"
VALINT_SCRIBE_ENABLE: true
DOCKER_DRIVER: overlay2
DOCKER_CONFIG: $HOME/.docker
DOCKERHUB_USERNAME: scribesecurity
SCRIBE_PRODUCT_VERSION: "v0.0.2-github"

jobs:
discovery_github:
runs-on: ubuntu-latest
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }}
VALINT_OUTPUT_DIRECTORY: evidence/github
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: github.platforms.db
steps:
- name: Cache Github DB
uses: actions/cache@v4
with:
path: github.platforms.db
key: github-platforms-db-${{ hashFiles('github.platforms.db') }}
restore-keys: |
github-platforms-db-
github-platforms-db

- name: Discovery Github
uses: scribe-security/action-platforms@master
with:
command: discover
platform: github
args:
--scope.organization=scribe-security
--scope.repository=*mongo*
--workflow.skip --commit.skip --scope.branch=main

- name: Evidence Github
uses: scribe-security/action-platforms@master
with:
command: evidence
sign: true
platform: github
args: --organization.mapping=scribe-security::scribe-training-vue-project::${{ env.SCRIBE_PRODUCT_VERSION }} --repository.mapping=Scribe-Security*scribe-training-vue-project::scribe-training-vue-project::${{ env.SCRIBE_PRODUCT_VERSION }}

- name: Upload DB artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}
path: ${{ env.PLATFORMS_DB_PATH }}
Dockerhub Platform Example
on:
workflow_dispatch:

concurrency:
group: github-ci-${{ github.ref }}
cancel-in-progress: true

env:
PLATFORMS_VERSION: "latest"
LOG_LEVEL: "INFO"
VALINT_SCRIBE_ENABLE: true
DOCKER_DRIVER: overlay2
DOCKER_CONFIG: $HOME/.docker
DOCKERHUB_USERNAME: scribesecurity
SCRIBE_PRODUCT_VERSION: "v0.0.2-github"

jobs:
discovery_dockerhub:
runs-on: ubuntu-latest
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
VALINT_OUTPUT_DIRECTORY: evidence/dockerhub
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: dockerhub.platforms.db
steps:

- name: Discovery Dockerhub
uses: scribe-security/action-platforms@master
with:
command: discover
platform: dockerhub
args: --scope.past_days=60

- name: Evidence Dockerhub
uses: scribe-security/action-platforms@master
with:
command: evidence
sign: true
platform: dockerhub
args: |
--namespace.mapping
*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
*::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION}}
--repository.mapping
*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
*dhs*::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION }}

- name: Upload DB artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}
path: ${{ env.PLATFORMS_DB_PATH }}


bom_sign_dockerhub:
runs-on: ubuntu-latest
needs: [discovery_dockerhub]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/dockerhub
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: dockerhub.platforms.db
steps:
- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache Dockerhub Evidence
uses: actions/cache@v4
with:
path: evidence/dockerhub
key: evidence-dockerhub-${{ hashFiles('evidence/dockerhub/cache.json') }}
restore-keys: |
evidence-dockerhub-
evidence-dockerhub

- name: BOM Dockerhub
uses: scribe-security/action-platforms@master
with:
command: bom
platform: dockerhub
valint_args: --allow-failures
sign: true
args: >-
--image.mapping
*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
*dhs*::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION }}


policy_dockerhub:
runs-on: ubuntu-latest
needs: [bom_sign_dockerhub]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/dockerhub
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: dockerhub.platforms.db
steps:

- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache Dockerhub Evidence
uses: actions/cache@v4
with:
path: evidence/dockerhub
key: evidence-dockerhub

- name: Policy Dockerhub
uses: scribe-security/action-platforms@master
with:
command: verify
platform: dockerhub
valint_args: --valint.git-branch main
sign: true
args: >-
--image.mapping
*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
*dhs*::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION }}
Jfrog Platform Example
on:
workflow_dispatch:

concurrency:
group: github-ci-${{ github.ref }}
cancel-in-progress: true

env:
PLATFORMS_VERSION: "latest"
LOG_LEVEL: "INFO"
VALINT_SCRIBE_ENABLE: true
DOCKER_DRIVER: overlay2
DOCKER_CONFIG: $HOME/.docker
DOCKERHUB_USERNAME: scribesecurity
SCRIBE_PRODUCT_VERSION: "v0.0.2-github"
JFROG_URL: https://mycompany.jfrog.io

jobs:
discovery_jfrog:
runs-on: ubuntu-latest
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
JFROG_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}
VALINT_OUTPUT_DIRECTORY: evidence/jfrog
SCRIBE_TOKEN: ${{ secrets.GH_CI_TEST_SCRIBE_SECRET }}
SCRIBE_CLIENT_SECRET: ${{ secrets.GH_CI_TEST_SCRIBE_SECRET }}
PLATFORMS_DB_PATH: jfrog.platforms.db
steps:

- name: Discovery Jfrog
uses: scribe-security/action-platforms@master
with:
command: discover
platform: jfrog
args: --scope.tag_limit 2

- name: Evidence Jfrog
uses: scribe-security/action-platforms@main
with:
command: evidence
sign: true
platform: jfrog
args: |
--jf-repository.mapping
*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
--repository.mapping
*stub*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}

- name: Upload DB artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}
path: ${{ env.PLATFORMS_DB_PATH }}


bom_sign_jfrog:
runs-on: ubuntu-latest
needs: [discovery_jfrog]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/jfrog
SCRIBE_TOKEN: ${{ secrets.GH_CI_TEST_SCRIBE_SECRET }}
PLATFORMS_DB_PATH: jfrog.platforms.db
steps:
- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache Jfrog Evidence
uses: actions/cache@v4
with:
path: evidence/jfrog
key: evidence-jfrog-${{ hashFiles('evidence/jfrog/cache.json') }}
restore-keys: |
evidence-jfrog-
evidence-jfrog

- name: BOM Jfrog
uses: scribe-security/action-platforms@master
with:
command: bom
platform: jfrog
valint_args: --allow-failures
sign: true
args: >-
--image.mapping
*stub*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
--exclude.repository *stub_remote_empty*
policy_jfrog:
runs-on: ubuntu-latest
needs: [bom_sign_jfrog]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/jfrog
SCRIBE_TOKEN: ${{ secrets.GH_CI_TEST_SCRIBE_SECRET }}
PLATFORMS_DB_PATH: jfrog.platforms.db
steps:

- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache Jfrog Evidence
uses: actions/cache@v4
with:
path: evidence/jfrog
key: evidence-jfrog

- name: Policy Jfrog
uses: scribe-security/action-platforms@dev
with:
command: verify
platform: jfrog
valint_args: --valint.git-branch main
sign: true
args: >-
--image.mapping
*stub*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
--exclude.repository *stub_remote_empty*
Kubernetes Platform Example
on:
workflow_dispatch:

concurrency:
group: github-ci-${{ github.ref }}
cancel-in-progress: true

env:
PLATFORMS_VERSION: "latest"
K8S_URL: https://my_cluster.com # K8s discovery URL
K8S_TOKEN: ${{ secrets.INTEGRATION_K8S_TOKEN }}
LOG_LEVEL: "INFO"
VALINT_SCRIBE_ENABLE: true
DOCKER_DRIVER: overlay2
DOCKER_CONFIG: $HOME/.docker
SCRIBE_PRODUCT_VERSION: "v0.0.2-github"

jobs:
discovery_k8s:
runs-on: ubuntu-latest
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
K8S_TOKEN: ${{ secrets.INTEGRATION_K8S_TOKEN }}
VALINT_OUTPUT_DIRECTORY: evidence/k8s
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: k8s.platforms.db
steps:
- name: Discover K8S
uses: scribe-security/action-platforms@master
with:
command: discover
platform: k8s

- name: Evidence K8S
uses: scribe-security/action-platforms@master
with:
command: evidence
sign: true
platform: k8s
args:
--namespace.mapping=default::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }} default::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION }}
--pod.mapping='*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }} *dhs*::dhs-vue-sample-proj::${{ env.SCRIBE_PRODUCT_VERSION}}'
env:
VALINT_OUTPUT_DIRECTORY: ${{ env.VALINT_OUTPUT_DIRECTORY }}

- name: Upload DB artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}
path: ${{ env.PLATFORMS_DB_PATH }}



bom_sign_k8s:
runs-on: ubuntu-latest
needs: [discovery_k8s]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/k8s
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: k8s.platforms.db
steps:

- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache K8S Evidence
uses: actions/cache@v4
with:
path: evidence/k8s
key: evidence-k8s

- name: BOM K8s
uses: scribe-security/action-platforms@master
with:
command: bom
platform: k8s
valint_args: --allow-failures
sign: true
args: >-
--ignore-state
--image.mapping
default::*service-*::*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}


policy_k8s:
runs-on: ubuntu-latest
needs: [bom_sign_k8s]
env:
ATTEST_KEY: ${{ secrets.ATTEST_KEY }}
ATTEST_CERT: ${{ secrets.ATTEST_CERT }}
ATTEST_CA: ${{ secrets.ATTEST_CA }}
VALINT_OUTPUT_DIRECTORY: evidence/k8s
VALINT_SCRIBE_AUTH_CLIENT_SECRET: ${{ secrets.SCRIBE_SECRET }}
PLATFORMS_DB_PATH: k8s.platforms.db
steps:

- name: Download DB artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.PLATFORMS_DB_PATH }}

- name: Cache K8S Evidence
uses: actions/cache@v4
with:
path: evidence/k8s
key: evidence-k8s-${{ hashFiles('evidence/k8s/cache.json') }}
restore-keys: |
evidence-k8s-
evidence-k8s

- name: Policy K8s
uses: scribe-security/action-platforms@master
with:
command: verify
platform: k8s
valint_args: --allow-failures
sign: true
args: >-
--ignore-state
--image.mapping
default::*service-*::*service-*::flask-monorepo-project::${{ env.SCRIBE_PRODUCT_VERSION }}
ECR Platform Example
on:
workflow_dispatch:

concurrency:
group: github-ci-${{ github.ref }}
cancel-in-progress: true

env:
PLATFORMS_VERSION: "latest"
LOG_LEVEL: "INFO"
VALINT_SCRIBE_ENABLE: true
DOCKER_DRIVER: overlay2
DOCKER_CONFIG: $HOME/.docker
SCRIBE_PRODUCT_VERSION: "v0.0.2-github"
AWS_ACCESS_KEY_ID: $AWS_TEST_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_TEST_ACCESS_KEY
AWS_REGION: "us-west-2"
ECR_API_BASE_URL: ****.dkr.ecr.$AWS_REGION.amazonaws.com
ECR_URL: https://$ECR_API_BASE_URL

jobs:
discovery-ecr:
stage: discovery
image:
name: scribesecurity/platforms:${PLATFORMS_VERSION}
entrypoint: [""]
pull_policy: always
cache:
- key: ecr.platforms.db
paths:
- ecr.platforms.db
- key: evidence-ecr-discovery
paths:
- evidence/ecr-discovery
before_script:
- *show_versions
- *init_signing_keys
- export PLATFORMS_DB_PATH=ecr.platforms.db
- export VALINT_OUTPUT_DIRECTORY=evidence/ecr-discovery
- export VALINT_SCRIBE_ENABLE=true
- export LOG_LEVEL=DEBUG
script:
- |
export ECR_LOGIN_TOKEN=$(aws ecr get-login-password --region $AWS_REGION)

- |
platforms discover ecr \
--scope.past_days 60

- |
platforms evidence \
--valint.sign \
ecr \
--repository.mapping \
*scribe-service*::scribe-service::${SCRIBE_PRODUCT_VERSION}


bom-sign-ecr:
stage: bom-sign
needs: ["discovery-ecr"]
timeout: 5 hours
image:
name: scribesecurity/platforms:${PLATFORMS_VERSION}
entrypoint: [""]
pull_policy: always
services:
- docker:dind
cache:
- key: ecr.platforms.db
paths:
- ecr.platforms.db
- key: evidence-ecr
paths:
- evidence/ecr
before_script:
- *show_versions
- *init_signing_keys
- *fs-info
- *cleanup-docker-cache
- *fs-info
- export PLATFORMS_DB_PATH=ecr.platforms.db
- export VALINT_OUTPUT_DIRECTORY=evidence/ecr
- export LOG_LEVEL=DEBUG
- export VALINT_LOG_LEVEL=debug
after_script:
- *cleanup-docker-cache
script:
- |
export ECR_LOGIN_TOKEN=$(aws ecr get-login-password --region $AWS_REGION)
echo $ECR_LOGIN_TOKEN | docker login --username AWS --password-stdin $ECR_API_BASE_URL

- |
platforms bom \
--valint.sign \
--allow-failures \
ecr \
--image.mapping \
*scribe-service*::scribe-service::${SCRIBE_PRODUCT_VERSION}


policy-ecr:
stage: policy
needs: ["bom-sign-ecr"] # "policy-gitlab" hack to win some time for the backend to process the SBOMs
timeout: 5 hours
image:
name: scribesecurity/platforms:${PLATFORMS_VERSION}
entrypoint: [""]
pull_policy: always
services:
- docker:dind
cache:
- key: ecr.platforms.db
paths:
- ecr.platforms.db
- key: evidence-ecr
paths:
- evidence/ecr
after_script:
- *cleanup-docker-cache
- *cleanup-evidence-cache
- *fs-info
before_script:
- *show_versions
- *init_signing_keys
- *fs-info
- export PLATFORMS_DB_PATH=ecr.platforms.db
- export VALINT_OUTPUT_DIRECTORY=evidence/ecr
- export VALINT_DISABLE_EVIDENCE_CACHE=true
- export LOG_LEVEL=DEBUG
script:
- |
platforms verify \
--valint.bundle-branch main \
--valint.sign \
ecr \
--image.mapping \
*scribe-service*::scribe-service::${SCRIBE_PRODUCT_VERSION}

artifacts:
paths:
- evidence/ecr/*sarif*
expire_in: 1 week

.gitignore

It's recommended to add output directory value to your .gitignore file. By default add **/scribe to your .gitignore.