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/falsevalue 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_COMPLIANTwhose value is eithertrueorfalse. - Using the Kosli CLI to make our
genericattestation.
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--jqflag.
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--jqrule as the key. For example, a lint outcome oftruewill create a json file containing{"lint": true} - replace the
kosli attest genericwithkosli attest custom - add the
--attestation-dataflag to name the created json file - add the
--typeflag 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
genericattestations, 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.