Skip to content

Conversation

migmartri
Copy link
Member

@migmartri migmartri commented Jul 28, 2023

This patch is the first step towards #252, it allows the definition of key/val annotations in the contract for the different materials.

These annotations are then injected in the attestation automatically and shown in the output

For example, having this contract

{
  "schemaVersion":  "v1",
  "materials":  [
    {
      "type":  "SBOM_CYCLONEDX_JSON",
      "name":  "skynet-sbom",
      "annotations": [{ "name": "component", "value": "controlplane" }]
    },
    {
      "type":  "CONTAINER_IMAGE",
      "name":  "image",
      "annotations": [{ "name": "component", "value": "controlplane" }]
    },
    {
      "type":  "STRING",
      "name":  "string"
    }
  ]
}

A resulting attestation will look like

// $ chainloop wf run describe --id 61aba7ed-8430-401d-89a8-39a8ca12744e -o statement | jq .predicate.materials
[
  {
    "annotations": {
      "chainloop.material.name": "image",
      "chainloop.material.type": "CONTAINER_IMAGE",
      "component": "controlplane" // note this custom annotation!
    },
    "digest": {
      "sha256": "97deaf8ad2e31524d6e7eee65468a4330cb55f7dcf4911ebdf2a580a4261c006"
    },
    "name": "ghcr.io/chainloop-dev/chainloop/control-plane"
  },
  {
    "annotations": {
      "chainloop.material.cas": true,
      "chainloop.material.name": "skynet-sbom",
      "chainloop.material.type": "SBOM_CYCLONEDX_JSON",
      "component": "controlplane" 
    },
    "digest": {
      "sha256": "ebe2e6ffab93f4b2e2743d3557bd094427ea059adc78cfe2cd330a72f61731e8"
    },
    "name": "sbom.cp.cyclonedx.json"
  },
  {
    "annotations": {
      "chainloop.material.name": "string",
      "chainloop.material.type": "STRING"
    },
    "content": "Q29udHJhcnkgdG8gcG9wdWxhciBiZWxpZWYsIExvcmVtIElwc3VtIGlzIG5vdCBzaW1wbHkgcmFuZG9tIHRleHQuIEl0IGhhcyByb290cyBpbiBhIHBpZWNlIG9mIGNsYXNzaWNhbCBMYXRpbiBsaXRlcmF0dXJlIGZyb20gNDUgQkMsIG1ha2luZyBpdCBvdmVyIDIwMDAgeWVhcnMgb2xkLiBSaWNoYXJkIE1jQ2xpbnRvY2ssIGEgTGF0aW4gcHJvZmVzc29yIGF0IEhhbXBkZW4tU3lkbmV5IENvbGxlZ2UgaW4gVmlyZ2luaWEsIGxvb2tlZCB1cCBvbmUgb2YgdGhlIG1vcmUgb2JzY3VyZSBMYXRpbiB3b3Jkcyw="
  }
]

The summary output has also been improved to show the custom annotations but also handle better the horizontal viewport by

  • Decoupling digest and descriptive name, also improving UX while copying the digest
  • Wrap value to 100 chars
  • ...
┌───────────────────────────────────────────────────────┐
│ Workflow                                              │
├────────────────┬──────────────────────────────────────┤
│ ID             │ 3e4ef02c-0f33-4248-84be-8a55ea2e3cb0 │
│ Name           │ only-sbom                            │
....

┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Materials                                                                                                          │
├─────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ image                                                                                                │
│ Type        │ CONTAINER_IMAGE                                                                                      │
│ Value       │ ghcr.io/chainloop-dev/chainloop/control-plane                                                        │
│ Digest      │ sha256:97deaf8ad2e31524d6e7eee65468a4330cb55f7dcf4911ebdf2a580a4261c006                              │
│ Annotations │ ------                                                                                               │
│             │ component: controlplane                                                                              │
├─────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ skynet-sbom                                                                                          │
│ Type        │ SBOM_CYCLONEDX_JSON                                                                                  │
│ Value       │ sbom.cp.cyclonedx.json                                                                               │
│ Digest      │ sha256:ebe2e6ffab93f4b2e2743d3557bd094427ea059adc78cfe2cd330a72f61731e8                              │
│ Annotations │ ------                                                                                               │
│             │ component: controlplane                                                                              │
├─────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ string                                                                                               │
│ Type        │ STRING                                                                                               │
│ Value       │ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classi │
│             │ cal Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professo │
│             │ r at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words,              │
└─────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────┘

The next steps would be to 1) use such annotations in the dependency-track plugin to solve scenario "a" and 2) allow setting these annotation at runtime.

254818327-bb1d155a-b8ee-43c5-9fc5-a79c7e05d3fe

Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
@migmartri migmartri requested a review from danlishka July 28, 2023 10:30
@danlishka
Copy link
Member

What about the root-level annotations? For instance, in your example I would rather use:

{
  "schemaVersion":  "v1",
  "annotations": [{ "name": "component", "value": "controlplane" }],
  "materials":  [
    {
      "type":  "SBOM_CYCLONEDX_JSON",
      "name":  "skynet-sbom",
    },
    {
      "type":  "CONTAINER_IMAGE",
      "name":  "image",
      "annotations": [{ "name": "arch", "value": "linux/arm64" }],

    },
    {
      "type":  "STRING",
      "name":  "string"
    }
  ]
}
┌───────────────────────────────────────────────────────┐
│ Workflow                                              │
├────────────────┬──────────────────────────────────────┤
│ ID             │ 3e4ef02c-0f33-4248-84be-8a55ea2e3cb0 │
│ Name           │ only-sbom                            │
....
│ Annotations │ ------                                                                                               │
│             │ component: controlplane                                                                              │

┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Materials                                                                                                          │
├─────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ image                                                                                                │
│ Type        │ CONTAINER_IMAGE                                                                                      │
│ Value       │ ghcr.io/chainloop-dev/chainloop/control-plane                                                        │
│ Digest      │ sha256:97deaf8ad2e31524d6e7eee65468a4330cb55f7dcf4911ebdf2a580a4261c006                              │
│ Annotations │ ------                                                                                               │
│             │ arch: linux/arm64                                                                              │
├─────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ skynet-sbom                                                                                          │
│ Type        │ SBOM_CYCLONEDX_JSON                                                                                  │
│ Value       │ sbom.cp.cyclonedx.json                                                                               │
│ Digest      │ sha256:ebe2e6ffab93f4b2e2743d3557bd094427ea059adc78cfe2cd330a72f61731e8                              │
├─────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name        │ string                                                                                               │
│ Type        │ STRING                                                                                               │
│ Value       │ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classi │
│             │ cal Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professo │
│             │ r at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words,              │
└─────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────┘

Then I would display the root-level annotations at the top in the CLI output and in notifications.

What do you think?

@migmartri
Copy link
Member Author

Right, that example I put might not be the right one.

High level annotations will not work in the scenario a, which is for example what we use in our go-release release process https://github.com/chainloop-dev/chainloop/blob/main/.github/workflows/contracts/releases.cue

The single release process contains artifacts from different components, having only top level annotations will effectively force us to do more than one attestation in the same job.

I see top-level annotations complementary to this feature because of the reasons you laid of in your case (using custom materials to add context).

Does it make sense?

Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
@danlishka
Copy link
Member

Makes sense.

The single release process contains artifacts from different components, having only top level annotations will effectively force us to do more than one attestation in the same job.

I understand. That is why I think we need both: the top level and per-material annotations, as you can see in my example above.

The summary output has also been improved to show the custom annotations but also handle better the horizontal viewport by

Love it. We need to make sure to apply this across all different CLI commands. Today the "chainloop attestation status" output is difficult to read:

Screenshot 2023-07-28 at 15 43 33

Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
@migmartri migmartri self-assigned this Jul 28, 2023
@migmartri
Copy link
Member Author

cc/ @gr0 since you might be interested in this change.

Copy link
Member

@danlishka danlishka left a comment

Choose a reason for hiding this comment

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

LGTM

Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
@migmartri migmartri merged commit c5b6a1b into chainloop-dev:main Jul 28, 2023
@migmartri migmartri deleted the annotations branch July 28, 2023 14:49
@gr0
Copy link
Collaborator

gr0 commented Jul 30, 2023

Great stuff, thank you @migmartri 🙇

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.

3 participants