|
1 | 1 | # Chainloop Extensions |
2 | 2 |
|
3 | | -Chainloop extensions are a way to extend the functionality of the Chainloop. |
| 3 | +Chainloop extensions are a way to add functionality to Chainloop by integrating with third-parties. |
| 4 | + |
| 5 | +Currently we only support one type, fanOut extensions. A FanOut extension implements logic that will get executed when attestations or materials are received. This logic can be anything from sending a Slack message, uploading the attestation to a storage backend or sending a Software Bill Of Materials (SBOMs) to Dependency-Track for analysis, for example. |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +## Lifecycle |
| 10 | + |
| 11 | +An fanOut extension goes through 4 different stages. Loading, Registration, Attachment and Execution. |
| 12 | + |
| 13 | +### Loading Stage |
| 14 | + |
| 15 | +The loading stage is when the extension gets enabled in the Chainloop Control Plane. This is implemented via the extension constructor. It is when you, as a extension developer, will define: |
| 16 | + |
| 17 | +- The extension identifier, version and description. |
| 18 | +- What kind of input you want your extension to receive, materials, attestations or both. |
| 19 | +- Available input properties for the registration and attachment phases. These schemas will be shown to the user and will be used to validate the input. |
| 20 | + |
| 21 | +Once loaded, the extension will be available to be registered on any organization and will be shown in the list of available extensions. |
| 22 | + |
| 23 | +```console |
| 24 | +$ chainloop integration available list |
| 25 | +┌─────────────────┬─────────┬──────────────────────┬───────────────────────────────────────────────────────────┐ |
| 26 | +│ ID │ VERSION │ MATERIAL REQUIREMENT │ DESCRIPTION │ |
| 27 | +├─────────────────┼─────────┼──────────────────────┼───────────────────────────────────────────────────────────┤ |
| 28 | +│ dependencytrack │ 0.2 │ SBOM_CYCLONEDX_JSON │ Send CycloneDX SBOMs to your Dependency-Track instance │ |
| 29 | +├─────────────────┼─────────┼──────────────────────┼───────────────────────────────────────────────────────────┤ |
| 30 | +│ smtp │ 0.1 │ │ Send emails with information about a received attestation │ |
| 31 | +├─────────────────┼─────────┼──────────────────────┼───────────────────────────────────────────────────────────┤ |
| 32 | +│ oci-registry │ 0.1 │ │ Send attestations to a compatible OCI registry │ |
| 33 | +├─────────────────┼─────────┼──────────────────────┼───────────────────────────────────────────────────────────┤ |
| 34 | +│ discord-webhook │ 0.1 │ │ Send attestations to Discord │ |
| 35 | +└─────────────────┴─────────┴──────────────────────┴─────────────────────────────────────────────────────────── |
| 36 | +``` |
| 37 | + |
| 38 | +And the information of how to use it can be found in the describe command. |
| 39 | + |
| 40 | +```console |
| 41 | +$ chainloop integration available describe --id dependencytrack |
| 42 | +┌─────────────────┬─────────┬──────────────────────┬────────────────────────────────────────────────────────┐ |
| 43 | +│ ID │ VERSION │ MATERIAL REQUIREMENT │ DESCRIPTION │ |
| 44 | +├─────────────────┼─────────┼──────────────────────┼────────────────────────────────────────────────────────┤ |
| 45 | +│ dependencytrack │ 0.2 │ SBOM_CYCLONEDX_JSON │ Send CycloneDX SBOMs to your Dependency-Track instance │ |
| 46 | +└─────────────────┴─────────┴──────────────────────┴────────────────────────────────────────────────────────┘ |
| 47 | +┌──────────────────────────────────────────────────────────────────────────────────────┐ |
| 48 | +│ Registration inputs │ |
| 49 | +├─────────────────┬──────────────┬──────────┬──────────────────────────────────────────┤ |
| 50 | +│ FIELD │ TYPE │ REQUIRED │ DESCRIPTION │ |
| 51 | +├─────────────────┼──────────────┼──────────┼──────────────────────────────────────────┤ |
| 52 | +│ allowAutoCreate │ boolean │ no │ Support of creating projects on demand │ |
| 53 | +│ apiKey │ string │ yes │ The API key to use for authentication │ |
| 54 | +│ instanceURI │ string (uri) │ yes │ The URL of the Dependency-Track instance │ |
| 55 | +└─────────────────┴──────────────┴──────────┴──────────────────────────────────────────┘ |
| 56 | +┌───────────────────────────────────────────────────────────────────────────────────────────┐ |
| 57 | +│ Attachment inputs │ |
| 58 | +├─────────────┬────────┬──────────┬─────────────────────────────────────────────────────────┤ |
| 59 | +│ FIELD │ TYPE │ REQUIRED │ DESCRIPTION │ |
| 60 | +├─────────────┼────────┼──────────┼─────────────────────────────────────────────────────────┤ |
| 61 | +│ projectID │ string │ no │ The ID of the existing project to send the SBOMs to │ |
| 62 | +│ projectName │ string │ no │ The name of the project to create and send the SBOMs to │ |
| 63 | +└─────────────┴────────┴──────────┴─────────────────────────────────────────────────────────┘ |
| 64 | +``` |
| 65 | + |
| 66 | +In addition to the constructor 3 more handlers need to be implemented. |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | +### Registration Stage |
4 | 71 |
|
5 | | -Currently we only support one type, fan-out extensions. FanOut extensions implement logic that will get executed when attestations or materials are received, |
6 | | - |
7 | | -## Anatomy of a FanOut Extension |
8 | | - |
9 | | -### Lifecycle |
10 | | - |
11 | | -An fanOut extension goes through 4 different stages. Loading, Registration, Attachment and Execution |
12 | | - |
13 | | -#### Loading |
14 | | - |
15 | | -Loading is when the extension gets enabled in the Chainloop Control plane. This is implemented via the extension constructor. At this time is when you, as a developer, can configure the identity of the extension and what kind of input you are expecting to receive. Materials, attestations or both. |
16 | | - |
17 | | -Example: |
| 72 | +Registration is when a specific instance of the extension is configured on a Chainloop organization. A registered instance is then available to be attached to any workflow, more on that later. |
18 | 73 |
|
19 | | -- Load the dependency track instance extension |
| 74 | +This handler will receive the input from the user, will validate it against the defined schema and run any custom logic. The handler's returned value will be stored in the extension state, which will make it available to the other handlers. |
20 | 75 |
|
21 | | -#### Registration |
| 76 | +Examples: |
22 | 77 |
|
23 | | -Registration is when a specific instance of the extension is configured on a Chainloop organization. A registered instance is then available to be attached to any workflow, more on that later. |
| 78 | +- Register a Dependency-Track instance by receiving its URL and API key. At this stage, the extension will make sure that the provided information is valid and store it for later use. |
| 79 | +- Register a Discord instance by receiving its webhook URL. The handler will store the webhook URL securely for later use. |
24 | 80 |
|
25 | | -Example: |
| 81 | +### Attachment Stage |
26 | 82 |
|
27 | | -- Register a dependency track instance by receiving its URL and API key. At this stage, the extension will make sure that the provided information is valid and store it for later use. |
| 83 | +In order for an user to use a registered instance, it needs to be attached to a workflow. This stage can be also used to optionally customize the behavior of the extension for a specific workflow. |
28 | 84 |
|
29 | | -#### Attachment |
| 85 | +This handler **will receive not only the input from the user but also the output from the registration state**. Similarly to the registration handler, the handler returned output value will be stored in the state for later use. |
30 | 86 |
|
31 | | -Attachment happens when a registered instance is attached to a Workflow. This means that any attestations or materials that are received by the workflow will be sent to the attached extension for processing. |
| 87 | +Examples: |
32 | 88 |
|
33 | | -Example: |
| 89 | +- Tell the already registered Dependency Track instance to send the SBOMs **to a specific project**. |
| 90 | +- Tell the already registered Discord instance to send all attestations to the configured channel |
34 | 91 |
|
35 | | -- Tell the already registered dependency track instance to send the SBOMs to a specific project. |
| 92 | +### Execution Stage |
36 | 93 |
|
37 | | -#### Execution |
| 94 | +This is the actual execution of the extension. This is where the extension will do its work. i.e call a workflow or send a notification. |
38 | 95 |
|
39 | | -This is the actual execution of the extension. This is where the extension will do its work. i.e call a workflow, or send a notification. |
| 96 | +This handler **will also have access to the outputs from the registration and attachment phases**. |
40 | 97 |
|
41 | | -Example: |
| 98 | +Examples: |
42 | 99 |
|
43 | | -In the dependency track use-case we will |
| 100 | +A Dependency-Track SBOM extension will |
44 | 101 |
|
45 | 102 | - Get the instance URL and API key from the state stored during the registration phase |
46 | 103 | - Get the specific project where we want to post the SBOMs from the attachment phase |
47 | 104 | - Send the SBOMs to the dependency track instance |
48 | 105 |
|
49 | | -## How to create a new extension |
| 106 | +A Discord webhook extension will |
50 | 107 |
|
| 108 | +- Get the Webhook URL from the state stored during the registration phase |
| 109 | +- Craft message to send to the Discord webhook |
| 110 | + |
| 111 | +## How to create a new extension |
51 | 112 |
|
52 | | -We offer a starter template in `./core/template`. Just copy it to a new folder and follow the steps shown in its readme. |
| 113 | +We offer a [starter template](./core/template). Just copy it to a new folder and follow the steps shown in its readme file. |
0 commit comments