{"id":44988280,"url":"https://github.com/kosli-dev/playground","last_synced_at":"2026-02-18T20:28:32.610Z","repository":{"id":244768803,"uuid":"816201617","full_name":"kosli-dev/playground","owner":"kosli-dev","description":"A playground for learning how to implement Kosli","archived":false,"fork":false,"pushed_at":"2025-03-04T08:38:17.000Z","size":440,"stargazers_count":0,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-04T09:33:23.555Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kosli-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-17T08:46:37.000Z","updated_at":"2025-03-04T08:38:19.000Z","dependencies_parsed_at":"2024-08-05T10:18:35.085Z","dependency_job_id":"54ce9719-faf3-4b42-86d7-5be244aa11c3","html_url":"https://github.com/kosli-dev/playground","commit_stats":null,"previous_names":["kosli-dev/playground"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kosli-dev/playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kosli-dev%2Fplayground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kosli-dev%2Fplayground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kosli-dev%2Fplayground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kosli-dev%2Fplayground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kosli-dev","download_url":"https://codeload.github.com/kosli-dev/playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kosli-dev%2Fplayground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29594256,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T18:54:29.675Z","status":"ssl_error","status_checked_at":"2026-02-18T18:50:50.517Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-18T20:28:28.242Z","updated_at":"2026-02-18T20:28:32.597Z","avatar_url":"https://github.com/kosli-dev.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Kosli Playground\n\nA playground for learning how to implement [Kosli](https://kosli.com)\n\n# Learning about Kosli\n\nFeel free to skip this section if you are already familiar with Kosli\nor want to get started straight away.\n\n### Understanding Kosli Core Concepts\n- [What are Kosli Environments and Snapshots?](docs/get_familiar.md#what-are-kosli-environments-and-snapshots)\n- [What are Kosli Flows and Trails?](docs/get_familiar.md#what-are-kosli-flows-and-trails)\n\n### Exploring real examples\n- [Explore Kosli Environments and Snapshots for cyber-dojo's AWS ECS Clusters](docs/get_familiar.md#explore-kosli-environments-and-snapshots-for-cyber-dojos-aws-ecs-clusters)\n- [Explore Kosli Flows and Trails for cyber-dojo's Git repos](docs/get_familiar.md#explore-kosli-flows-and-trails-for-cyber-dojos-git-repos)\n\n\n# Setting up\n\n## [Fork this repo](https://github.com/kosli-dev/playground/fork)\n\n- Click the `Actions` tab at the top of your forked repo.\n- You will see a message saying `Workflows aren’t being run on this forked repository`.\n- Click the green button to enable Workflows on your forked repo.\n- Please follow the remaining instructions from the README in your forked repo.\n  (This is so the links correctly take you to the files in *your* repo)\n\n\n## Log into Kosli at https://app.kosli.com using GitHub\n\nLogging in using GitHub creates a Personal Kosli Organization whose name is your GitHub username.\nYou cannot invite other people to your personal organization; it is intended only to try Kosli out\nas you are now doing. For real use you would create a Shared Kosli Organization (from the top-right \ndropdown next to your user-icon) and invite people to it.\n\n\n## At https://app.kosli.com create a Docker Environment\n\nIn this playground the CI pipelines fake their deployment step by doing a \"docker compose up\".\nCreate a Kosli Environment to record what is running in this fake deployment.\n- Select `Environments` from left hand side menu\n- Click the blue `[Add new environment]` button at the top\n- Fill in the Name field as `playground-prod`\n- Check the `Docker host` radio button for the Type\n- Fill in the `Description` field, eg `Learning about Kosli`\n- Leave `Exclude scaling events` checked\n- Leave `Compliance Calculation Require artifacts to have provenance` set to `Off`\n- Click the blue `[Create environment]` button\n- Open a tab in your browser for the `playground-prod` Kosli Environment as we will often review how it changes \n\n\n## Set the .env file variables\n\n- Edit (and save) the [.env](.env) file as follows:\n  - DOCKER_ORG_NAME to your GitHub username in lowercase\n  - REPO_NAME (if you changed it from `playground`)\n\n    \n## Create a KOSLI_API_TOKEN and save it as a GitHub Action secret\n\n(Note: In a Shared Organization you would do this under a Service account) \n- At https://app.kosli.com click your GitHub user icon at the top-right\n- In the dropdown select `Profile`\n- Click the blue `[+ Add API Key]` button\n- Choose a value for the `API key expires in` or leave it as Never\n- Fill in the `Description` field, eg `playground CI`\n- Click the blue `[Add]` button\n- You will see the api-key, something like `p1Qv8TggcjOG_UX-WImP3Y6LAf2VXPNN_p9-JtFuHr0`\n- Copy this api-key (Kosli stores a hashed version of this, so it will never be available from https://app.kosli.com again).\n  There is a small copy button to the right of the api-key.\n- [Create a GitHub Action secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) (at the repo level), called `KOSLI_API_TOKEN`, set to the copied value\n\n\n# Understand the fake deployment in the CI pipeline\n\n- There is a *fake* [deploy](.github/workflows/main.yml#L122) job which runs this command to bring up the container in the CI pipeline!\n  ```yml\n  docker compose up --wait\n  ```\n  After this command, the CI pipeline installs the Kosli CLI, and runs this command:\n  ```yml\n  kosli snapshot docker \"${KOSLI_ENVIRONMENT_NAME}\"\n  ```\n  The [kosli snapshot docker](https://docs.kosli.com/client_reference/kosli_snapshot_docker/) command takes a snapshot \n  of the Docker containers currently running (inside the CI pipeline!)\n  and sends their image names and digests/fingerprints to the named Kosli Environment (`playground-prod`).\n  This command does _not_ need to set the `--org`, or `--api-token` flags because\n  the `KOSLI_ORG` and `KOSLI_API_TOKEN` environment variables have been set at the top of the workflow yml file.\n\n\n# Make a change, run the CI workflow, review the Environment in Kosli\n\n- Edit the file [code/alpha.rb](code/alpha.rb) so the return string from the `'/'` route is a new string\n- Commit (add+commit+push if not editing in GitHub)\n- Wait for the GitHub Action Workflow to complete\n- Refresh your `playground-prod` Environment at https://app.kosli.com and verify it shows the `playground-alpha` \nimage running. The image tag should be the short-sha of your new HEAD commit \n- This playground-alpha Artifact currently has No [provenance](https://www.kosli.com/blog/how-to-secure-your-software-supply-chain-with-artifact-binary-provenance/\n) but is nevertheless showing as Compliant. This is because the Environment was set up with `Require artifacts to have provenance`=Off. \nWe will provide provenance shortly.\n\n\n# Make another change, rerun the CI workflow, review the Environment in Kosli\n\n- Re-edit the file [code/alpha.rb](code/alpha.rb) so the return string from the `'/'` route is a new string\n- Commit (add+commit+push if not editing in GitHub)\n- Wait for the GitHub Action Workflow to complete\n- Refresh your `playground-prod` Environment at https://app.kosli.com and in the [Log] view verify\n  - the previous playground-alpha Artifact has exited\n  - the new playground-alpha Artifact is running, and this Artifact still has No provenance\n\n\n# Name your Kosli Flow and Trail\n\n- Kosli attestations must be made against a Trail, living inside a Flow.\n  - A Kosli Flow represents a business or software process for which you want to track changes and monitor compliance.\n  - A Kosli Trail represents a single execution of a process represented by a Kosli Flow. \n    Each trail must have a unique identifier of your choice, based on your process and domain. \n    Example identifiers include git commits or pull request numbers.\n- At the top of the [.github/workflows/main.yml](.github/workflows/main.yml) file add two new `env:` variables for the\nKosli Flow (named after your repo) and Kosli Trail (named after each git-commit), as follows:\n```yml\nenv:\n  KOSLI_FLOW: playground-alpha-ci\n  KOSLI_TRAIL: ${{ github.sha }}\n```\n\n\n# Attest the provenance of the Artifact in the CI pipeline\n\n- Most attestations need the Docker image digest/fingerprint. We will start by making this available to all jobs.\n- In [.github/workflows/main.yml](.github/workflows/main.yml)...\n  - uncomment the following comments near the top of the `build-image:` job\n  ```yml\n  #    outputs:\n  #      artifact_digest: ${{ steps.variables.outputs.artifact_digest }}\n  ```\n  - uncomment the following comments at the bottom of the `build-image:` job\n  ```yml\n  #    - name: Make image digest available to all jobs\n  #      id: variables\n  #      run: |\n  #        DIGEST=$(echo ${{ steps.docker_build.outputs.digest }} | sed 's/.*://')\n  #        echo \"artifact_digest=${DIGEST}\" \u003e\u003e ${GITHUB_OUTPUT}\n  ```\n  - add the following to the end of the `build-image:` job\n  to install the Kosli CLI and attest the Artifact's digest/fingerprint.\n  ```yml\n      - name: Setup Kosli CLI\n        uses: kosli-dev/setup-cli-action@v2\n        with:\n          version: ${{ env.KOSLI_CLI_VERSION }}\n\n      - name: Attest image provenance to Kosli Trail\n        run: \n          kosli attest artifact \"${{ needs.setup.outputs.image_name }}\" \n            --artifact-type=docker\n            --name=alpha\n  ```\n- Note that `kosli attest` commands do not need to specify the `--org` or `--flow` or `--trail` flags because there are \nenvironment variables called `KOSLI_ORG`, `KOSLI_FLOW`, and `KOSLI_TRAIL`.\n  - In the [kosli attest artifact](https://docs.kosli.com/client_reference/kosli_attest_artifact/) command above, the \n  Kosli CLI calculates the fingerprint. To do this the CLI needs to be told\n  the name of the Docker image (`${{needs.setup.outputs.image_name}}`), and that this is a Docker image\n  (`--artifact-type=docker`), and that the image has previously been pushed to its registry (which it has)\n  - You can also provide the fingerprint directly using the `--fingerprint` flag or `KOSLI_FINGERPRINT` environment \n    variable. \n- Commit (add+commit+push if not editing in GitHub)\n- Wait for the GitHub Action Workflow to complete\n- Refresh your `playground-prod` Environment at https://app.kosli.com \n- You will see a new Snapshot\n- This time the Artifact will have Provenance. You can see the Flow and Trail, and also the git commit\n  short-sha, and git commit message.\n- In https://app.kosli.com, click `Flows` on the left hand side menu\n- Click the Flow named `playground-alpha-ci`\n- You should see a single Trail whose name is the repo's current HEAD commit\n- Click the Trail name to view it, and confirm this Trail has a single Artifact attestation\n\n\n# View a deployment diff\n\n- Re-edit the file [code/alpha.rb](code/alpha.rb) so the return string from the `'/'` route is a new string\n- Commit (add+commit+push if not editing in GitHub)\n- Wait for the GitHub Action Workflow to complete\n- Refresh your `playground-prod` Environment at https://app.kosli.com\n- You will see a new Snapshot\n- Its Artifact will have Provenance\n- Click the `\u003e` chevron to reveal more information in a drop-down\n- Click the link titled `View diff` in the entry called `Previous` to see the deployment-diff; this is a diff\n  (spanning potentially many commits) between the newly deployed alpha Artifact, and the previously running alpha Artifact.\n\n\n# Attest unit-test evidence to Kosli\n\n- [.github/workflows/main.yml](.github/workflows/main.yml) has a `unit-test:` job. You will attest its results to Kosli\n- Add the following to the end of the `unit-test:` job to install the Kosli CLI, and attest the unit-test results\n```yml\n    - name: Setup Kosli CLI\n      uses: kosli-dev/setup-cli-action@v2\n      with:\n        version: ${{ env.KOSLI_CLI_VERSION }}\n          \n    - name: Attest unit-test results to Kosli\n      run:\n        kosli attest junit --name=alpha.unit-test --results-dir=test/reports/junit\n```\n- Commit (add+commit+push if not editing in GitHub)\n- Wait for the GitHub Action Workflow to complete\n- The [kosli attest junit](https://docs.kosli.com/client_reference/kosli_attest_junit/) command\n  reports the JUnit XML results files in the `--results-dir`. The alpha Artifact's tests\n  are written using the Ruby MiniTest framework. Like most test frameworks, it is easy\n  to output the test results in the JUnit XML format. See line 7 of [test/test_base.rb](test/test_base.rb)\n- Refresh your `playground-prod` Environment at https://app.kosli.com and verify it shows the new `playground-alpha` \nimage running. The image tag should be the short-sha of your new HEAD commit\n- Open the latest Trail in the `playground-alpha-ci` Flow and verify\n  - Its commit-sha name matches the commit in the latest `playground-prod` Snapshot\n  - There is a Trail Event for the attestation called `alpha.unit-test`\n  - Click the `\u003e` chevron in this Trail Event to open its drop-down\n  - Browse the JUnit results in the JSON sent by the `kosli attest junit` command\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkosli-dev%2Fplayground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkosli-dev%2Fplayground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkosli-dev%2Fplayground/lists"}