The kosli attest generic CLI command can attest anything, but unlike a “typed” attestation (such as kosli attest snyk), it does not calculate a true/false
compliance value for you. Customers have reported that while a generic
“escape hatch” is useful, it nevertheless has some drawbacks:
- It can take some effort to calculate a
true/false
value in some cases. - It would be nice to split generic attestations into different types.
- Most importantly, many customers would prefer it if Kosli calculated all compliance values, as part of a zero trust model.
Based on this feedback we’ve implemented a new attest command called kosli attest custom. In this blog post we’ll migrate an existing generic attestation into a very simple custom attestation. In a follow up blog post we’ll create a much richer custom attestation type.
Our existing generic attestation
Suppose we are running a lint tool and wish to attest its results. If the linter had an option to export its results in JUnit xml format we could use kosli attest junit
. But it doesn’t, so in our CI workflow job we are:
- Running the linter in its own step.
- Ensuring the outcome of this step is zero if the lint is clean, otherwise non-zero.
- In another step, capturing the lint step outcome and creating an environment variable called
KOSLI_COMPLIANT
whose value is eithertrue
orfalse
. - Using the Kosli CLI to make our
generic
attestation.
on:
...
env:
...
jobs:
...
lint:
runs-on: ubuntu-latest
...
steps:
...
- name: Run lint
id: lint
run:
make lint
...
- name: Attest lint evidence to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
run: |
KOSLI_COMPLIANT=$([ "${{ steps.lint.outcome }}" == 'success' ] && echo true || echo false)
kosli attest generic \
--name=differ.lint
...
The --name
in the attestation is differ.lint
and in our compliance template yaml file we’ve specified the type of this attestation as generic
.
version: 1
trail:
...
artifacts:
- name: differ
attestations:
...
- name: lint
type: generic
...
This is the generic
attestation we’ll migrate using a simple custom attestation.
Create a simple custom attestation type
To begin the migration we define a new custom attestation type with the kosli create attestation-type CLI command.
- The type is called
mylint
. - It has a single rule
.lint
, specified as a jq expression using the--jq
flag.
For example:
kosli create attestation-type mylint
--jq ".lint"
A custom attestation type can also have its own --schema
. This allows you to specify the types of the names in the --jq
expressions, whether they are required, possible default values, etc.
Migrate your generic attestation
Now, instead of converting the outcome of the lint step into a KOSLI_COMPLIANT environment variable, we:
- save it into a json file, using
"lint"
from the--jq
rule as the key. For example, a lint outcome oftrue
will create a json file containing{"lint": true}
- replace the
kosli attest generic
withkosli attest custom
- add the
--attestation-data
flag to name the created json file - add the
--type
flag to name the custom attestation type (mylint
)
on:
...
env:
...
jobs:
...
lint:
runs-on: ubuntu-latest
...
steps:
...
- name: Run lint
id: lint
run:
make lint
...
- name: Attest lint evidence to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
run: |
LINT=$([ "${{ steps.lint.outcome }}" == 'success' ] && echo true || echo false)
jq -n --argjson lint $LINT '{"lint": $lint}' > /tmp/lint.json
kosli attest custom --type=mylint \
--attestation-data=/tmp/lint.json \
--name=differ.lint
...
Migrate the attestation type in the template
The --name
in the attestation is still differ.lint
but in our compliance template yaml file we update the type of this attestation to custom:mylint
.
version: 1
trail:
...
artifacts:
- name: differ
attestations:
...
- name: lint
type: custom:mylint
...
Summary
Kosli’s new custom attestations improve on generic attestations:
- You can define your own custom attestation types. These can be
- very simple and replace existing
generic
attestations, or - arbitrarily rich, expressing rules with thresholds
- very simple and replace existing
- These custom types can be reused across all Flows in your Kosli Org.
- Kosli can ensure the calculation adheres to a provided schema.
- Most importantly, as part of a zero trust model, Kosli can now calculate the compliance values of all attestations in a Trail.