Skip to content

slsa-framework/slsa-policy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SLSA policies

Overview

What is SLSA?

Supply chain Levels for Software Artifacts, or SLSA (salsa), is a security framework, a check-list of standards and controls to prevent tampering, improve integrity, and secure packages and infrastructure in your projects, businesses or enterprises.

SLSA defines an incrementially adoptable set of levels which are defined in terms of increasing compliance and assurance. SLSA levels are like a common language to talk about how secure software, supply chains and their component parts really are.

What is provenance?

Provenance is information, or metadata, about how a software artifact was created. This could include information about what source code, build system, and build steps were used, as well as who and why the build was initiated. Provenance can be used to determine the authenticity and trustworthiness of software artifacts that you use.

As part of the framework, SLSA defines a provenance format which can be used hold this metadata.

What is slsa-policy?

slsa-policy is an example Go library, CLI and set of GitHub Actions to implement source-to-deployment policies across an organization. The policy provides the following guarantees:

  1. Containers (builds) are protected against tampering across the SDLC
  2. Containers (builds) are bounds to a set of privileges, the same way that OS processes are restricted to a set of running privilages. In cloud environments, permissions are defined via IAM and are associated with Service Accounts (SAs) by the policy. For more details on the design, see Technical design.

End-to-end tutorial

For an end-to-end tutorial, follow the SLSA workshop hosted at the 2024 Open Source Security Conference.

The setup below are subset of the tutorial above, so we highly encourage you to follow hands-on activities of the workshop, available in the link above.

Setup

Publish policy

Org setup

Policy setup
  1. Set up ACLs for your entire repository:
    1. Assign ownership via GitHub CODEOWNERS for entire repository. Set the ownership to the administrators of the policy repository. It's important the workflows are also protected by CODEOWNERS.
    2. Enable Repository Rules (formerly Branch Protection) for all branches. The following settings can be written as one rule, or split into multiple rules. They can be specified at the repository level, or the organization level.
      1. Require a pull request before merging. Under additional settings: Require approvals (select at least 1-2 as the required number of approvals before merging).
      2. Require status checks to pass before merging. Under additional settings: Require branches to be up to date before merging (may be problematic for busy repos).
      3. Block force pushes
      4. Restrict deletions
      5. Limit any bypass actors to those that are strictly necessary (i.e. break glass).
      6. Require review from CODEOWNERS.
  2. Add team maintainers as contributors to the repository. Give them write access. Do NOT give them admin access. Note that you can do that later when teams create their first policy, see Policy definition.
  3. Create a folder to store the publish policies. See an example here.
  4. Create a file with your trusted roots. See example org.json.
Pre-submit validation

To validate the policy files, run the binary as:

cd policies/publish
$ go run . publish validate org.json .

TODO: we need pre-submits when new files are created, to ensure the appropriate owners are added to CODEOWNERS.

Publish service

You need to define a workflow that your teams will call when they want to publish their container images. This workflow is responsible for evaluating the publish policy. See an example image-publisher.yml

In the workflow above, the CLI is called as follows:

cd policies/publish
# This is passed by the caller, e.g. dev or prod.
env="${{ inputs.environment }}"
go run . publish evaluate org.json . "${image}" "${env}"

Team setup

Policy definition

Teams create their policy files under the folder defined by their organization in Policy setup. See an example of a policy in echo-server.json.

When a team creates a new file or folder:

  1. If not already done in Org setup, org administrators should add team members as contributors and give them write access. Do NOT gives them admin access.
  2. Update the CODEOWNERS file to give permissions to the team members who own the package. This allows teams to edit their policies without requiring reviews by the organization admnistrators.
Call the publish service

When publishing containers, teams must call the publish policy service service image-publisher.yml defined in the org's Publish service section. See an example deploy-image.yml. This workflows would be called with environment set as "staging" first. One staging tests have passed, it may be called with "prod" environment. Note that the environment must match one the values defined in the policy definition echo-server.json.

After the workflow has successfully run, you may manually verify the publish attestation via:

# NOTE: change image to your image.
$ image=docker.io/slsa-framework/slsa-project-echo-server@sha256:4378b3d11e11ede0f64946e588c590e460e44f90c8a7921ad2cb7b04aaf298d4
$ creator_id=https://github.com/slsa-framework/oss-na24-slsa-workshop-organization/.github/workflows/image-publisher.yml@refs/heads/main
$ type=https://slsa.dev/publish/v0.1
$ cosign verify-attestation "${image}" \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity "${creator_id}" 
    --type "${type}" | jq -r '.payload' | base64 -d | jq

Deployment policy

Org setup

Policy setup
  1. Set up ACLs for your entire repository:
    1. Assign ownership via GitHub CODEOWNERS for entire repository. Set the ownership to the administrators of the policy repository. It's important the workflows are also protected by CODEOWNERS.
    2. Enable Repository Rules (formerly Branch Protection) for all branches. The following settings can be written as one rule, or split into multiple rules. They can be specified at the repository level, or the organization level.
      1. Require a pull request before merging. Under additional settings: Require approvals (select at least 1-2 as the required number of approvals before merging).
      2. Require status checks to pass before merging. Under additional settings: Require branches to be up to date before merging (may be problematic for busy repos).
      3. Block force pushes
      4. Restrict deletions
      5. Limit any bypass actors to those that are strictly necessary (i.e. break glass).
      6. Require review from CODEOWNERS.
  2. Add team maintainers as contributors to the repository. Give them write access. Do NOT give them admin access. Note that you can do that later when teams create their first policy, see Policy definition.
  3. Create a folder to store the deployment policies. See an example here.
  4. Create a file with your trusted roots. See example org.json.
Pre-submit validation

To validate the policy files, run the binary as:

cd policies/deployment
$ go run . deployment validate org.json .

TODO: we need pre-submits when new files are created, to ensure the appropriate owners are added to CODEOWNERS.

Deployer workflow

You need to define a workflow that your teams will call when they want to deploy their container images. This workflow is responsible for evaluating the deployment policy. See an example image-deployer.yml

In the workflow above, the CLI is called as follows:

cd policies/deployment
# This expands to https://github.com/slsa-framework/oss-na24-slsa-workshop-organization/.github/workflows/image-deployer.yml@refs/heads/main
creator_id="https://github.com/${{ needs.detect-env.outputs.repository }}/.github/workflows/image-deployer.yml@${{ needs.detect-env.outputs.ref }}"
# This is provided by the caller. It is the unique path to the policy, e.g. servers-dev.json
policy_id="${{ inputs.policy-id }}"
go run . deployment evaluate org.json . "${image}" "${policy_id}" "${creator_id}"

Project setup

Policy definition

Teams create their policy files under the folder defined by their organization in Policy setup. See an example of a policy in servers-prod.json.

When a team creates a new file or folder:

  1. If not already done in Org setup, org administrators should add team members as contributors and give them write access. Do NOT gives them admin access.
  2. Update the CODEOWNERS file to give permissions to the team members who own the package. This allows teams to edit their policies without requiring reviews by the organization admnistrators.
Call the deployment service

Before submitting a request to deploy containers, teams must call the deployment policy service image-deployer.yml defined in the org's Deployment service section. See an example deploy-image.yml. This may be called with "staging" environment first to allow the container to run on the staging service account defined in servers-staging.json. Once all staging tests have passed, it may be called with "prod" environment. Note that the environment must match one the values defined in the publish policy file servers-prod.json and the deployment policy file echo-server.json.

After the workflow has successfully run, you may manually verify the publish attestation via:

# NOTE: change image to your image.
$ image=docker.io/slsa-framework/slsa-project-echo-server@sha256:4378b3d11e11ede0f64946e588c590e460e44f90c8a7921ad2cb7b04aaf298d4
$ creator_id=https://github.com/slsa-framework/oss-na24-slsa-workshop-organization/blob/main/.github/workflows/image-deployer.yml@refs/heads/main
$ type=https://slsa.dev/deployment/v0.1
$ cosign verify-attestation "{$image}" \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity "${creator_id}" 
    --type "${type}" | jq -r '.payload' | base64 -d | jq

This verification will be performed by the admission controller. See Admission controller.

Admission controller

The admisson controller is responsible for verifying the deployment attestation:

  1. Verify the signature
  2. Verify each scope google_service_account == google service account the pod run under

Kyverno

TODO

OPA

TODO

Technical design

Specifications

TODO

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages