Skip to content

Conversation

@jiparis
Copy link
Member

@jiparis jiparis commented Sep 30, 2024

This PR implements policy groups.

A policy group is a set of policies that can be applied to a contract as a whole. For instance, having this policy group:

apiVersion: workflowcontract.chainloop.dev/v1
kind: PolicyGroup
metadata:
  name: sbom-quality
  description: This policy group applies a number of SBOM-related policies
  annotations:
    category: SBOM
spec:
  policies:
    attestation:
      - ref: sbom-present
    materials:
      - ref: cyclonedx-banned-licenses
        with:
          licenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later
      - ref: cyclonedx-banned-components
        with:
          components: log4j@2.14.1
      - ref: cyclonedx-freshness
        with:
          freshness: "20"

It could be applied to a contract using the group reference, as it if was a "sub-contract":

schemaVersion: v1
materials: []
policyGroups:
  - ref: file://test/policy-group.yaml

The PR includes several refactors to extract common policy behavior and reuse code as much as possible.

Some features:

  • groups and multi-kind policies coexist seamlessly
  • policy evaluations are flattened, so attestation format doesn't change
  • Different PolicyGroup loaders are supported (file://, https://).
  • Providers not yet implemented (as it requires API changes)

Demo (see how policies are applied):

➜  cldev wf contract update --name myproject-mywf --contract test/contract-group.yaml
WRN API contacted in insecure mode
WRN Both user credentials and $CHAINLOOP_TOKEN set. Ignoring $CHAINLOOP_TOKEN.
INF Contract updated!
┌────────────────────────────────────────────┐
│ Contract                                   │
├──────────────────────┬─────────────────────┤
│ Name                 │ myproject-mywf      │
├──────────────────────┼─────────────────────┤
│ Description          │                     │
├──────────────────────┼─────────────────────┤
│ Associated Workflows │                     │
├──────────────────────┼─────────────────────┤
│ Revision number      │ 11                  │
├──────────────────────┼─────────────────────┤
│ Revision Created At  │ 02 Oct 24 17:16 UTC │
└──────────────────────┴─────────────────────┘
┌────────────────────────────────────────┐
│ schemaVersion: v1                      │
│ materials: []                          │
│ policyGroups:                          │
│   - ref: file://test/policy-group.yaml │
│                                        │
└────────────────────────────────────────┘

➜  cldev att add --value test/cyclonedx.json
WRN API contacted in insecure mode
INF evaluating policy cyclonedx-banned-licenses against material-1727889452453559000
INF evaluating policy cyclonedx-banned-components against material-1727889452453559000
INF evaluating policy cyclonedx-freshness against material-1727889452453559000
WRN found policy violations (cyclonedx-freshness) for material-1727889452453559000
WRN  - SBOM created at: 2024-07-23T15:58:37+00:00 which is too old (freshness limit set to 30 days)
INF material kind detected kind=SBOM_CYCLONEDX_JSON
INF material added to attestation

➜  cldev att push
WRN API contacted in insecure mode
INF evaluating policy sbom-present against attestation
INF push completed
┌───────────────────┬──────────────────────────────────────┐
│ Initialized At    │ 02 Oct 24 17:17 UTC                  │
├───────────────────┼──────────────────────────────────────┤
│ Attestation ID    │ 36ea565e-2158-4f12-bc48-abba667bd910 │
│ Name              │ mywf                                 │
│ Team              │                                      │
│ Project           │ myproject                            │
│ Contract Revision │ 11                                   │
└───────────────────┴──────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────────┐
│ Materials                                                                          │
├──────────┬─────────────────────────────────────────────────────────────────────────┤
│ Name     │ material-1727889452453559000                                            │
│ Type     │ SBOM_CYCLONEDX_JSON                                                     │
│ Set      │ Yes                                                                     │
│ Required │ No                                                                      │
│ Value    │ cyclonedx.json                                                          │
│ Digest   │ sha256:7502f43a5f4c312006d2cbbbd2d6b555121b7e21cc03ef6d86808db73725d930 │
└──────────┴─────────────────────────────────────────────────────────────────────────┘
Attestation Digest: sha256:d1a8ec3c05caf56790ad2bb06772cec3507f5dccb18b51beafd68ee59f561de6

➜  cldev wf run describe --digest sha256:d1a8ec3c05caf56790ad2bb06772cec3507f5dccb18b51beafd68ee59f561de6 --output statement
...
      "policy_evaluations": {
         "CHAINLOOP.ATTESTATION": [
            {
               "annotations": {
                  "category": "sbom"
               },
               "description": "Checks that either a SPDX or CycloneDX SBOM material is present in the attestation",
               "name": "sbom-present",
               "policy_reference": {
                  "digest": {
                     "sha256": "8db761db44d5d4b73c109133b21e917adb40ddbb77755c8aae1ddcca6fce7e2b"
                  },
                  "name": "chainloop://localhost:8002/sbom-present"
               },
               "type": "ATTESTATION"
            }
         ],
         "material-1727889452453559000": [
            {
               "annotations": {
                  "category": "sbom"
               },
               "description": "Checks CycloneDX 1.5+ report for components banned licenses. \nIt accepts a comma-separated list of licenses as argument:\n  with: \n    licenses: AGPL-10, AGPL-3.0\n",
               "material_name": "material-1727889452453559000",
               "name": "cyclonedx-banned-licenses",
               "policy_reference": {
                  "digest": {
                     "sha256": "546298ff30fc3c7cb37dbc0f1c6e805a475d1a18886206d3c1792330a3d0ef22"
                  },
                  "name": "chainloop://localhost:8002/cyclonedx-banned-licenses"
               },
               "type": "SBOM_CYCLONEDX_JSON",
               "with": {
                  "licenses": "AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later"
               }
            },
            {
               "annotations": {
                  "category": "sbom, security"
               },
               "description": "Checks that the CycloneDX SBOM doesn't have any banned components. \nIt accepts a list of comma-separated list of components. If a version is specified, it will fail for versions equal or lower.\n  with:\n    components: log4j@2.14.1, banned-component\n",
               "material_name": "material-1727889452453559000",
               "name": "cyclonedx-banned-components",
               "policy_reference": {
                  "digest": {
                     "sha256": "67ce678337c28ea7086036b500f44542e6f6900b9989eda60daaaabe2b55085d"
                  },
                  "name": "chainloop://localhost:8002/cyclonedx-banned-components"
               },
               "type": "SBOM_CYCLONEDX_JSON",
               "with": {
                  "components": "log4j@2.14.1"
               }
            },
            {
               "annotations": {
                  "category": "sbom"
               },
               "description": "Checks that the CycloneDX SBOM is not older than a specified threshold.\nIt accepts a limit argument denoting the number of days, 30 by default:\n  with:\n    limit: 20\n",
               "material_name": "material-1727889452453559000",
               "name": "cyclonedx-freshness",
               "policy_reference": {
                  "digest": {
                     "sha256": "be4893b08090ea9469c5f5672b449ae989702c9cfc8d49cbb0cf3664c5be8530"
                  },
                  "name": "chainloop://localhost:8002/cyclonedx-freshness"
               },
               "type": "SBOM_CYCLONEDX_JSON",
               "violations": [
                  {
                     "message": "SBOM created at: 2024-07-23T15:58:37+00:00 which is too old (freshness limit set to 30 days)",
                     "subject": "cyclonedx-freshness"
                  }
               ],
               "with": {
                  "freshness": "20"
               }
            }
         ]
      },
      "runnerType": "RUNNER_TYPE_UNSPECIFIED"
   }
}

Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
@jiparis jiparis marked this pull request as ready for review September 30, 2024 16:27
Copy link
Member

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jiparis. I still need to do a review, sorry for the delay.

But something that I have mixed feelings is the way we handle arguments (I explained my reasoning inline).

I'd love to know more about any evaluation you might have done on other approaches

Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
@jiparis
Copy link
Member Author

jiparis commented Oct 2, 2024

Thanks @jiparis. I still need to do a review, sorry for the delay.

But something that I have mixed feelings is the way we handle arguments (I explained my reasoning inline).

I'd love to know more about any evaluation you might have done on other approaches

I've removed the whole overriding logic. I think it makes sense to discuss it separately as part of how we handle policy arguments in general.

Copy link
Member

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what I am doing but lgtm :)

@jiparis jiparis merged commit ed8440e into chainloop-dev:main Oct 3, 2024
@jiparis jiparis deleted the pfm-837 branch October 3, 2024 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants