# API authentication methods Source: https://docs.kosli.com/administration/authentication/api_authentication_methods How to authenticate to the Kosli API using bearer tokens or HTTP basic auth. The Kosli API supports two authentication methods: | Method | Status | When to use | | ----------------------------------- | --------------- | ---------------------------------------------------------------------- | | [Bearer token](#bearer-token) | **Recommended** | All new integrations. Works for service account and personal API keys. | | [HTTP basic auth](#http-basic-auth) | Legacy | Fallback for tools that cannot send an `Authorization: Bearer` header. | If you are integrating Kosli for the first time, use bearer tokens. Basic auth remains supported for backwards compatibility but is not the recommended path. ## Bearer token Bearer tokens work with both [service account](/administration/authentication/service_accounts) and [personal](/user/personal_api_keys) API keys. ### In the CLI Pass the token to any `kosli` command using one of: * The `--api-token` flag. * The `KOSLI_API_TOKEN` environment variable. * A config file passed via `--config-file` — see [Assigning flags via config files](/getting_started/install#assigning-flags-via-config-files). ### In API requests Send the token in the `Authorization` header: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -H "Authorization: Bearer <>" \ https://app.kosli.com/api/v2/environments/<> ``` ## HTTP basic auth HTTP basic auth is a legacy method kept for backwards compatibility with tools that cannot send an `Authorization: Bearer` header. For all new integrations, use bearer tokens instead. Kosli accepts HTTP basic auth as an alternative to bearer tokens. The API key is sent as the **username**; the password is ignored. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -u "<>:" \ https://app.kosli.com/api/v2/environments/<> ``` The trailing colon (`:`) is required. Without it, `curl` treats the whole string as a username with no password and **prompts interactively** for one — at which point the API key may already be visible in the prompt or shell history (especially when the key comes from an environment variable). The value after the colon can be anything, including empty; Kosli ignores it. Equivalently, set the `Authorization` header directly with the base64-encoded `<>:` string: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -H "Authorization: Basic $(printf '%s:' "<>" | base64)" \ https://app.kosli.com/api/v2/environments/<> ``` # API key rotation Source: https://docs.kosli.com/administration/authentication/api_key_rotation Reference for how Kosli API key rotation works, including grace periods and the rotation API. Rotating API keys regularly limits the blast radius of a leaked credential. Kosli supports **zero-downtime rotation** for service account API keys: a new key is issued immediately while the old key remains valid for a configurable grace period. ## How rotation works When you rotate a service account API key, Kosli: 1. Generates a new API key and returns its value once. 2. Keeps the old key valid for a configurable grace period (default: **24 hours**). 3. Automatically revokes the old key when the grace period expires. Choose a grace period that fits your deployment cadence — long enough to roll the new key out to every consumer, short enough to limit exposure. ## Where next * [Rotating API keys (tutorial)](/tutorials/rotating_api_keys) — step-by-step walkthrough in the web app and via the API. * [Service accounts](/administration/authentication/service_accounts) — service account lifecycle. * [Rotate an API key (API reference)](/api-reference/service-accounts/rotate-an-api-key-for-a-service-account) * [Revoke an API key (API reference)](/api-reference/service-accounts/revoke-an-api-key-for-a-service-account) * [List API keys (API reference)](/api-reference/service-accounts/list-api-keys-for-a-service-account) # Service accounts Source: https://docs.kosli.com/administration/authentication/service_accounts Create and manage service accounts and their API keys for machine-to-machine access to Kosli. A **service account** is a machine user. Use service accounts for any non-human caller — CI pipelines, runtime reporters, scripts, and other automation — so that credentials and audit trails are tied to a system rather than a person. Service accounts are only available in shared organizations. ## Create a service account Sign in to Kosli and select the organization where the service account should live. Navigate to **Settings → Service accounts**. Click **Add new service account**, give it a descriptive name (e.g. `ci-github-actions`), and click **Add**. On the new service account, click **Add API key**. Choose a Time-To-Live (TTL), add a label that identifies where the key will be used, and click **Add**. Kosli stores only a cryptographic hash of the token. The original value is shown once and cannot be retrieved later — paste it directly into your secret store. ## Assign a role Service accounts have the same role model as users: **Admin**, **Member**, **Snapshotter**, or **Reader**. The role determines what the service account can do in the organization. Pick the least-privileged role that fits the workload. See [Roles in Kosli](/administration/managing_users/roles_in_kosli) for the full permissions matrix. As a starting point: * **Member** — CI/CD systems that report attestations, manage flows, and create resources. * **Snapshotter** — runtime reporters that record environment snapshots and create environments (for example, CLI callers using `--auto-environment`). * **Reader** — read-only systems such as dashboards or query tooling. * **Admin** — rarely needed; reserve for automation that manages users, roles, or organization-wide settings (for example, Terraform-driven org bootstrap). ## Rotate or revoke keys For zero-downtime rotation and the API-driven flow, see: * [API key rotation (reference)](/administration/authentication/api_key_rotation) * [Rotating API keys (tutorial)](/tutorials/rotating_api_keys) # Managing Custom Attestation Types Source: https://docs.kosli.com/administration/managing_custom_attestation_types/overview Learn how to manage Kosli custom attestation types via Terraform, including creating and importing types with JSON Schema and jq evaluation rules. The preferred way to manage custom attestation types is via the Kosli Terraform provider, so your Kosli configuration is version-controlled alongside your infrastructure. You can also manage custom attestation types through the Kosli CLI. This page covers managing custom attestation types via Terraform. For an introduction to custom attestation types and creating them via the CLI, see [Getting started: Attestations](/getting_started/attestations). Custom attestation types define how Kosli validates evidence from tools that don't have a built-in Kosli attestation command. Each type can include: * A **JSON Schema** (optional) that defines the expected structure of attestation data * **jq rules** (optional) that evaluate the data to determine compliance At least one of the two must be provided. ## Create a custom attestation type ### With schema and jq rules ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_custom_attestation_type" "security_scan" { name = "security-scan" description = "Validates security scan results" schema = jsonencode({ type = "object" properties = { critical_vulnerabilities = { type = "integer" } high_vulnerabilities = { type = "integer" } scan_date = { type = "string" } } required = ["critical_vulnerabilities", "high_vulnerabilities", "scan_date"] }) jq_rules = [ ".critical_vulnerabilities == 0", ".high_vulnerabilities < 5" ] } ``` ### With jq rules only ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_custom_attestation_type" "code_coverage" { name = "code-coverage" description = "Requires at least 80% line coverage" jq_rules = [".line_coverage >= 80"] } ``` ### With schema only ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_custom_attestation_type" "deployment_record" { name = "deployment-record" description = "Validates deployment record structure" schema = jsonencode({ type = "object" properties = { deployed_by = { type = "string" } deployed_at = { type = "string" } environment = { type = "string" } } required = ["deployed_by", "deployed_at", "environment"] }) } ``` ## Import an existing custom attestation type If you have custom attestation types created via the CLI, you can bring them under Terraform management by importing them into your Terraform state. 1. Find the attestation type name in the Kosli UI or run: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list attestation-types ``` 2. Add a matching `kosli_custom_attestation_type` resource block to your configuration. 3. Run the import: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform import kosli_custom_attestation_type.security_scan security-scan ``` 4. Verify with `terraform plan` — no changes should be planned if the import succeeded. ## Reference * [`kosli_custom_attestation_type` resource](/terraform-reference/resources/custom_attestation_type) * [`kosli_custom_attestation_type` data source](/terraform-reference/data-sources/custom_attestation_type) * [Kosli Terraform provider on the Terraform Registry](https://registry.terraform.io/providers/kosli-dev/kosli/latest) # Managing Environments Source: https://docs.kosli.com/administration/managing_environments/overview Learn how to manage Kosli environments via Terraform, including creating and importing physical and logical environments. Archiving environments requires the Admin role. The preferred way to manage environments is via the Kosli Terraform provider, so your Kosli configuration is version-controlled alongside your infrastructure. You can also manage environments through the Kosli CLI or UI. This page covers managing environments via Terraform. For creating environments via the CLI or UI, see [Getting started: Environments](/getting_started/environments). Kosli has two environment types: * **Physical environments** — each maps to a single runtime (e.g. a Kubernetes cluster or ECS service). Managed with the `kosli_environment` resource. * **Logical environments** — aggregate one or more physical environments into a single view. Managed with the `kosli_logical_environment` resource. ## Managing physical environments ### Create a physical environment ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_environment" "production" { name = "production-k8s" description = "Production Kubernetes cluster" type = "K8S" } ``` Supported types: `K8S`, `ECS`, `S3`, `docker`, `server`, `lambda`. ### Import an existing physical environment If you have environments created via the UI or CLI, you can bring them under Terraform management by importing them into your Terraform state. 1. Find the environment name in the Kosli UI under **Environments**, or run: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments ``` 2. Add a matching `kosli_environment` resource block to your configuration: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_environment" "my_environment" { name = "production" description = "Production environment" type = "K8S" # must match the existing environment's type } ``` 3. Run the import: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform import kosli_environment.my_environment production ``` 4. Verify with `terraform plan` — no changes should be planned if the import succeeded. The `type` in your Terraform configuration must exactly match the type of the existing environment in Kosli. A mismatch will cause import errors or misconfiguration. ## Managing logical environments Logical environments group physical environments into a combined view — useful for representing a full production tier across multiple runtimes. ### Create a logical environment ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "production_all" { name = "production-all" description = "All production environments" included_environments = ["production-k8s", "production-ecs", "production-lambda"] } ``` `included_environments` must reference the names of existing physical environments. Logical environments cannot include other logical environments. ### Import an existing logical environment 1. Find the logical environment name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments ``` 2. Add a matching `kosli_logical_environment` resource block: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "production_all" { name = "production-all" included_environments = ["production-k8s", "production-ecs"] } ``` 3. Run the import: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform import kosli_logical_environment.production_all production-all ``` 4. Verify with `terraform plan` — no changes should be planned if the import succeeded. ## Reference * [`kosli_environment` resource](/terraform-reference/resources/environment) * [`kosli_environment` data source](/terraform-reference/data-sources/environment) * [`kosli_logical_environment` resource](/terraform-reference/resources/logical_environment) * [`kosli_logical_environment` data source](/terraform-reference/data-sources/logical_environment) # Managing Tags Source: https://docs.kosli.com/administration/managing_tags Use tags to label and organize Kosli resources with custom key-value pairs via Terraform, CLI, or API. Tags are custom key-value pairs you attach to Kosli resources. They let you categorize, filter, and add metadata to your flows and environments without changing the resources themselves. ## Why use tags * **Organize resources** — group related flows or environments by team, project, region, or any other dimension. * **Drive policy behavior** — reference tags in [Environment Policy](/getting_started/policies) expressions to make attestation requirements conditional. For example, require security scans only for flows tagged `risk-level=high`. * **Add operational metadata** — store context such as cost center, service tier, or owner directly on the resource. ## Supported resources You can tag the following Kosli resource types: | Resource type | Terraform resource | CLI identifier | | :------------ | :---------------------------------------------------------------- | :------------- | | Flow | [`kosli_flow`](/terraform-reference/resources/flow) | `flow` | | Environment | [`kosli_environment`](/terraform-reference/resources/environment) | `env` | ## Tag key and value rules * **Keys** must start with a letter or digit and can contain letters, digits, hyphens (`-`), underscores (`_`), dots (`.`), and tildes (`~`). * **Values** are strings. If a value is a valid URL (e.g. `https://example.com`), Kosli automatically renders it as a clickable link in the UI. * There is no fixed limit on the number of tags per resource, but keep them concise for readability. ## Add or update tags Add a `tags` map to any `kosli_environment` or `kosli_flow` resource. Tags are applied via a diff — only changed tags are sent to the API. Tag an environment: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_environment" "production" { name = "production-k8s" type = "K8S" description = "Production Kubernetes cluster" tags = { region = "eu-west-1" tier = "critical" managed-by = "platform-team" } } ``` Tag a flow: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_flow" "api_service" { name = "api-service" description = "API service pipeline" tags = { team = "platform" risk-level = "high" } } ``` See the [`kosli_environment` resource](/terraform-reference/resources/environment) and [`kosli_flow` resource](/terraform-reference/resources/flow) for the full schema. Pass one or more `--set` flags with `key=value` pairs. If a key already exists, its value is updated: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag flow my-flow \ --set team=platform \ --set risk-level=high ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env production \ --set region=eu-west-1 \ --set tier=critical ``` See [`kosli tag`](/client_reference/kosli_tag) for all flags and options. Use the tags endpoint with `set_tags`: ```shell EU theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -X PATCH "https://app.kosli.com/api/v2/tags/{org}/flow/my-flow" \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "set_tags": {"team": "platform", "risk-level": "high"} }' ``` ```shell US theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -X PATCH "https://app.us.kosli.com/api/v2/tags/{org}/flow/my-flow" \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "set_tags": {"team": "platform", "risk-level": "high"} }' ``` ## Remove tags Remove individual tags by deleting them from the `tags` map. Set `tags = {}` to remove all tags: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_environment" "production" { name = "production-k8s" type = "K8S" tags = {} } ``` Pass one or more `--unset` flags with the keys to remove: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env production \ --unset region ``` Use the tags endpoint with `remove_tags`: ```shell EU theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -X PATCH "https://app.kosli.com/api/v2/tags/{org}/env/production" \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "remove_tags": ["region"] }' ``` ```shell US theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -X PATCH "https://app.us.kosli.com/api/v2/tags/{org}/env/production" \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "remove_tags": ["region"] }' ``` ## Read tags Use data sources to read tags from existing resources: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} data "kosli_environment" "production" { name = "production-k8s" } output "production_tags" { value = data.kosli_environment.production.tags } output "managed_by" { value = try(data.kosli_environment.production.tags["managed-by"], "unknown") } ``` Tags are included in the resource response when you fetch an environment or flow via the API. ## Recommended tag patterns A consistent tagging strategy makes it easier to organize resources as your Kosli usage grows. Here are common patterns: | Tag key | Example values | Purpose | | :------------ | :------------------------------- | :-------------------------------- | | `tier` | `dev`, `staging`, `prod` | Distinguish environment stages | | `team` | `platform`, `payments`, `mobile` | Identify the owning team | | `region` | `eu-west-1`, `us-east-1` | Track geographic location | | `risk-level` | `high`, `medium`, `low` | Drive conditional policy behavior | | `cost-center` | `eng-1234`, `ops-5678` | Map to internal accounting | Pick a small set of tag keys and document them for your organization. Consistent keys across environments and flows make filtering and policy expressions predictable. ### Example: categorizing environments by stage Tag your environments to reflect their deployment stage. This lets you quickly identify which environments are production-critical and apply policies accordingly: ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_environment" "staging_k8s" { name = "staging-k8s" type = "K8S" description = "Staging Kubernetes cluster" tags = { tier = "staging" team = "platform" region = "eu-west-1" } } resource "kosli_environment" "production_k8s" { name = "production-k8s" type = "K8S" description = "Production Kubernetes cluster" tags = { tier = "prod" team = "platform" region = "eu-west-1" } } ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env staging-k8s \ --set tier=staging \ --set team=platform \ --set region=eu-west-1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env production-k8s \ --set tier=prod \ --set team=platform \ --set region=eu-west-1 ``` ## Using tags in policies Tags become powerful when combined with [Environment Policies](/getting_started/policies). You can reference flow tags in policy expressions to conditionally require attestations: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} attestations: - if: ${{ flow.tags.risk-level == "high" }} name: security-scan type: snyk ``` In this example, the `security-scan` attestation is only required when the flow is tagged with `risk-level=high`. This lets you enforce stricter compliance for high-risk services while keeping lighter requirements for lower-risk ones. For the full expression syntax, see the [Environment Policy reference](/policy-reference/environment_policy). # Mapping users to roles Source: https://docs.kosli.com/administration/managing_users/mapping_users_to_roles Recommended mappings from common organizational roles to Kosli roles. When implementing Kosli, you need to map organizational roles to [Kosli roles](/administration/managing_users/roles_in_kosli). This table provides recommended mappings based on typical responsibilities: | Organizational Role | Recommended Kosli Role | Alternative | Rationale | | -------------------------- | ---------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Platform Engineers** | Member | Admin (for leads) | Platform engineers need to set up flows, manage service accounts, configure integrations, and implement Kosli across teams. Member role provides these capabilities. Lead platform engineers managing the overall setup may need Admin access. | | **Application Developers** | Member | Reader (for view-only) | Developers typically need to report attestations and manage flows for their applications. Member role enables this. Some developers may only need visibility into deployments and compliance status, making Reader sufficient. | | **Security & Compliance** | Admin | N/A | Security and compliance teams need to manage policies, review audit data, control user access, and configure organization-wide settings. Admin role is required for these governance responsibilities. | | **Sponsors** | Reader | N/A | Sponsors need visibility into adoption progress, compliance status, and overall system health but don't need to make technical changes. Reader role provides necessary oversight without operational access. | ## Understanding the mapping This mapping is a starting point. Your organization's structure and responsibilities may require adjustments: * **Small teams**: Developers might need Admin access if they handle all aspects * **Large enterprises**: Strict separation may require more Readers, fewer Admins * **Regulated industries**: Security teams might need dedicated Admin accounts separate from operations The key principle: Assign the minimum role required for someone to fulfill their responsibilities effectively. ## Learn more about organizational roles For detailed guidance on each organizational role's responsibilities during Kosli implementation, see: * [Implementation Guide: Roles and Responsibilities](/implementation_guide/phase_1/roles_and_responsibilities/overview) * [Platform Engineers](/implementation_guide/phase_1/roles_and_responsibilities/platform_engineers) * [Application Developers](/implementation_guide/phase_1/roles_and_responsibilities/app_developers) * [Security & Compliance](/implementation_guide/phase_1/roles_and_responsibilities/security_compliance) * [Sponsors](/implementation_guide/phase_1/roles_and_responsibilities/sponsors) # Roles in Kosli Source: https://docs.kosli.com/administration/managing_users/roles_in_kosli Understand the roles in Kosli and their permissions to manage access for users and service accounts within your organization. Kosli uses a single role model that applies to both **users** and **[service accounts](/administration/authentication/service_accounts)**. Understanding these roles is essential for assigning the appropriate level of access to your team members and to the automated systems that talk to Kosli on their behalf. Roles apply to service accounts the same way they apply to users. Wherever this page mentions a "user", read it as "user or service account" unless explicitly stated otherwise. The only role-related capability that is user-only is being invited to or removed from the organization. ## Overview | Role | Description | Best for | | --------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------- | | **Admin** | Full control over the organization | Organization owners, security leads, platform engineering leads | | **Member** | Can create and modify resources | Developers, platform engineers, CI/CD systems | | **Snapshotter** | Can create snapshots, environments, and manage their own service accounts | Environment and operations teams | | **Reader** | Read-only access to view data | Auditors, compliance officers, stakeholders, reporting systems | ## Permissions Matrix | Capability | Admin | Member | Snapshotter | Reader | | -------------------------------------------------------------------- | :---: | :----: | :---------: | :----: | | **User Management** | | | | | | Invite and remove users | ✅ | ❌ | ❌ | ❌ | | Change user roles | ✅ | ❌ | ❌ | ❌ | | **Organization Settings** | | | | | | Modify organization settings | ✅ | ❌ | ❌ | ❌ | | Configure integrations (Slack, LaunchDarkly) | ✅ | ✅ | ❌ | ❌ | | **Service Accounts** | | | | | | Create and manage service accounts | ✅ | ✅ | ✅ | ❌ | | Generate service account API keys | ✅ | ✅ | ✅ | ❌ | | **Resource Management** | | | | | | Create flows | ✅ | ✅ | ❌ | ❌ | | Update/delete flows | ✅ | ✅ | ❌ | ❌ | | Create environments (and re-create) | ✅ | ✅ | ✅ | ❌ | | Update environments (PATCH, archive, rename, attach/detach policies) | ✅ | ✅ | ❌ | ❌ | | Delete environments | ✅ | ❌ | ❌ | ❌ | | Create/update policies | ✅ | ✅ | ❌ | ❌ | | Delete policies | ❌ | ❌ | ❌ | ❌ | | Create attestation types | ✅ | ✅ | ❌ | ❌ | | Update/delete attestation types | ✅ | ✅ | ❌ | ❌ | | **Attestations & Snapshots** | | | | | | Report attestations | ✅ | ✅ | ❌ | ❌ | | Report environment snapshots | ✅ | ✅ | ✅ | ❌ | | **Actions** | | | | | | Create, update, and delete actions | ✅ | ✅ | ❌ | ❌ | | View actions | ✅ | ✅ | ✅ | ✅ | | **Data Access** | | | | | | View trails and artifacts | ✅ | ✅ | ✅ | ✅ | | View attestations | ✅ | ✅ | ✅ | ✅ | | View snapshots | ✅ | ✅ | ✅ | ✅ | | Query and search data | ✅ | ✅ | ✅ | ✅ | | Export and generate reports | ✅ | ✅ | ✅ | ✅ | | View flow/policy configurations | ✅ | ✅ | ✅ | ✅ | *** ## Role details The following sections provide more details about each Kosli user role, including their permissions and when to assign them. Administrators have full control over the organization and its resources. ### Permissions Admins can perform all actions in Kosli, including: * **User Management**: Invite, remove, and change roles of organization members (Admin only) * **Organization Settings**: Modify organization-wide settings and configurations (Admin only) * **Service Accounts**: Create and manage service accounts and their API keys * **Integrations**: Configure integrations with external systems (Slack, LaunchDarkly, etc.) * **Resource Management**: Create, update, and delete flows, environments, policies, and attestation types * **Attestations & Snapshots**: Report attestations and environment snapshots * **Actions**: Create, update, and delete actions for automated workflows and notifications * **Data Access**: View all trails, artifacts, attestations, and snapshots ### When to assign Assign the Admin role to: * Organization owners or senior leaders responsible for overall Kosli implementation * Security engineers who need to manage user access and compliance processes * Platform engineering leads who need to configure integrations and manage organization settings Limit the number of Admins to maintain security and control over your organization. Most users should be Members or Readers. Members can create and modify resources, manage service accounts, and configure integrations, but cannot manage users or organization-wide settings. ### Permissions Members can: * **Service Accounts**: Create and manage service accounts and their API keys * **Integrations**: Configure integrations with external systems (Slack, LaunchDarkly, etc.) * **Resource Management**: Create, update, and delete flows, environments, policies, and attestation types * **Attestations & Snapshots**: Report attestations and environment snapshots * **Actions**: Create, update, and delete actions for automated workflows and notifications * **Data Access**: View all trails, artifacts, attestations, and snapshots Members cannot: * Manage users or change user roles * Modify organization-wide settings ### When to assign Assign the Member role to: * Platform engineers who need to implement Kosli across teams and manage service accounts * Application developers who need to report attestations and manage flows * Team leads who need to configure integrations and create service accounts for their teams * CI/CD systems that need to report attestations and snapshots (via service accounts) Snapshotters can create environments, report environment snapshots, and manage their own service accounts, but cannot modify other resources, manage users, configure integrations, or change organization-wide settings. ### Permissions Snapshotters can: * **Service Accounts**: Create service accounts. They can manage the API keys of service accounts they created themselves — API keys on other service accounts can only be managed by the account's creator or an org Admin. * **Environments**: Create new environments (needed so CLI flows like `--auto-environment` work with a snapshotter token). * **Snapshots**: Report environment snapshots. * **View Data**: Access trails, artifacts, attestations, and snapshots. * **Query Information**: Search and filter data across flows and environments. * **Generate Reports**: Export and analyze compliance data. * **View Configurations**: See flow definitions, policies, attestation types, and actions (but cannot modify them). Snapshotters cannot: * Use the dedicated update paths on an environment (PATCH, archive, rename, attach/detach policies). * Create, update, or delete flows, policies, attestation types, or other resources. * Report attestations. * Create or manage actions. * Configure integrations. * Invite users or change settings. Because the environment create endpoint (`PUT /api/v2/environments/{org}`) is idempotent — a re-PUT of an existing environment updates it — a snapshotter token can modify an existing environment's description, scaling, policies, and included environments by re-PUTting a full payload. Only the dedicated update paths (PATCH, archive, rename, policy attach/detach) are blocked. Keep this in mind when scoping snapshotter tokens for environments you don't want them to change. ### When to assign Assign the Snapshotter role to: * Environment teams who need to manage runtime environments and report snapshots * Systems that only need to report environment state without modifying build pipelines *** Readers have read-only access to view data in Kosli without the ability to create or modify resources. ### Permissions Readers can: * **View Data**: Access trails, artifacts, attestations, and snapshots * **Query Information**: Search and filter data across flows and environments * **Generate Reports**: Export and analyze compliance data * **View Configurations**: See flow definitions, policies, attestation types, and actions (but cannot modify them) Readers cannot: * Create, update, or delete any resources * Report attestations or snapshots * Create or manage actions * Create or manage service accounts * Configure integrations * Invite users or change settings ### When to assign Assign the Reader role to: * Auditors who need visibility into compliance data * Compliance officers reviewing attestation and deployment history * Stakeholders and executives who want to monitor software delivery * Reporting and monitoring systems that query Kosli data for dashboards ## Assigning roles To assign or change a user's role: 1. Log in to Kosli as an Admin 2. Navigate to your organization from the left navigation menu 3. Go to `Settings` > `Members` 4. Find the user you want to modify 5. Select their new role from the dropdown menu Role changes take effect immediately. Users will see their updated permissions the next time they interact with Kosli. *** ## Best practices ### Follow the principle of least privilege Assign users the minimum role required to perform their job functions. Start with Reader access and increase permissions as needed. ### Use service accounts for automation For CI/CD pipelines and automated systems, create service accounts with the Member role rather than using personal API keys. This provides better auditability and security. ### Regular access reviews Periodically review user roles and remove access for team members who no longer need it. This is especially important when people change roles or leave the organization. ### Separate concerns * **Admins**: Focus on governance, security, and organization-wide configuration * **Members**: Handle day-to-day operations and resource management * **Snapshotters**: Manage environments and policies without affecting build flows * **Readers**: Provide visibility without risk of accidental changes *** ## See also * [Mapping users to roles](/administration/managing_users/mapping_users_to_roles) — recommended Kosli roles for common organizational roles. * [Service accounts](/administration/authentication/service_accounts) — assigning roles to machine users. # Create or update environment action Source: https://docs.kosli.com/api-reference/actions/create-or-update-environment-action https://app.kosli.com/api/v2/openapi.json put /actions/{org}/environments Create or Update an environment action for an org. # Create or update flow action Source: https://docs.kosli.com/api-reference/actions/create-or-update-flow-action https://app.kosli.com/api/v2/openapi.json put /actions/{org}/flows Create or Update a flow action for an org. # Delete an action Source: https://docs.kosli.com/api-reference/actions/delete-an-action https://app.kosli.com/api/v2/openapi.json delete /actions/{org}/{action_number} Delete a specific action for an org. # Get action Source: https://docs.kosli.com/api-reference/actions/get-action https://app.kosli.com/api/v2/openapi.json get /actions/{org}/{action_number} Get a specific action for an org. # List actions Source: https://docs.kosli.com/api-reference/actions/list-actions https://app.kosli.com/api/v2/openapi.json get /actions/{org} List actions for an org. # Allow artifact for environment Source: https://docs.kosli.com/api-reference/allowlists/allow-artifact-for-environment https://app.kosli.com/api/v2/openapi.json put /allowlists/{org}/{env_name} Allow an artifact for an environment. # List allowlist Source: https://docs.kosli.com/api-reference/allowlists/list-allowlist https://app.kosli.com/api/v2/openapi.json get /allowlists/{org} List Allowlist records in an organization. # Get artifact audit package Source: https://docs.kosli.com/api-reference/artifacts/get-artifact-audit-package https://app.kosli.com/api/v2/openapi.json get /artifacts/{org}/{flow_name}/{fingerprint}/audit_package Get audit package for an artifact. # Get artifact by fingerprint Source: https://docs.kosli.com/api-reference/artifacts/get-artifact-by-fingerprint https://app.kosli.com/api/v2/openapi.json get /artifacts/{org}/{flow_name}/fingerprint/{fingerprint} Get artifact by fingerprint. # Get artifacts by commit SHA Source: https://docs.kosli.com/api-reference/artifacts/get-artifacts-by-commit-sha https://app.kosli.com/api/v2/openapi.json get /artifacts/{org}/{flow_name}/commit_sha/{commit_sha} Get artifact by commit sha. # Get latest artifact commit Source: https://docs.kosli.com/api-reference/artifacts/get-latest-artifact-commit https://app.kosli.com/api/v2/openapi.json get /artifacts/{org}/{flow_name}/{fingerprint}/latest_commit Get the latest git commit of the artifact. # List artifacts Source: https://docs.kosli.com/api-reference/artifacts/list-artifacts https://app.kosli.com/api/v2/openapi.json get /artifacts/{org} List artifacts in organization. Can be filtered by flow name or repo name. - The result is paginated. - The list of artifacts is sorted by creation time in descending order. # List artifacts in flow Source: https://docs.kosli.com/api-reference/artifacts/list-artifacts-in-flow https://app.kosli.com/api/v2/openapi.json get /artifacts/{org}/{flow_name} Get artifacts in flow. # Report artifact Source: https://docs.kosli.com/api-reference/artifacts/report-artifact https://app.kosli.com/api/v2/openapi.json post /artifacts/{org}/{flow_name} Create an artifact for organization. # Assert artifact Source: https://docs.kosli.com/api-reference/asserts/assert-artifact https://app.kosli.com/api/v2/openapi.json get /asserts/{org}/fingerprint/{fingerprint} Assert an artifact. # Attest custom Source: https://docs.kosli.com/api-reference/attestation/attest-custom https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/custom Add custom attestation to a trail with an optional attachment file. # Attest generic Source: https://docs.kosli.com/api-reference/attestation/attest-generic https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/generic Add Generic attestation to a trail with an optional attachment file. # Attest Jira issue Source: https://docs.kosli.com/api-reference/attestation/attest-jira-issue https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/jira Add Jira attestation to a trail with an optional attachment file. # Attest JUnit test results Source: https://docs.kosli.com/api-reference/attestation/attest-junit-test-results https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/junit Add JUnit attestation to a trail with an optional attachment file. # Attest pull request Source: https://docs.kosli.com/api-reference/attestation/attest-pull-request https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/pull_request Add Pull-Request attestation to a trail with an optional attachment file. # Attest Snyk scan Source: https://docs.kosli.com/api-reference/attestation/attest-snyk-scan https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/snyk Add Snyk attestation to a trail with an optional attachment file. # Attest Sonar scan Source: https://docs.kosli.com/api-reference/attestation/attest-sonar-scan https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/sonar Add Sonar attestation to a trail with an optional attachment file. # Attest system Source: https://docs.kosli.com/api-reference/attestation/attest-system https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/system Add a system attestation to a trail. # Get artifact attestation Source: https://docs.kosli.com/api-reference/attestation/get-artifact-attestation https://app.kosli.com/api/v2/openapi.json get /attestations/{org}/{flow_name}/artifact/{fingerprint}/{attestation_name} # Get attestation evidence file Source: https://docs.kosli.com/api-reference/attestation/get-attestation-evidence-file https://app.kosli.com/api/v2/openapi.json get /attestations/{org}/{flow_name}/trail/{trail_name}/attestation/{attestation_id}/evidence Download the evidence file attached to an attestation. # Get trail attestation Source: https://docs.kosli.com/api-reference/attestation/get-trail-attestation https://app.kosli.com/api/v2/openapi.json get /attestations/{org}/{flow_name}/trail/{trail_name}/{attestation_name} # List attestations Source: https://docs.kosli.com/api-reference/attestation/list-attestations https://app.kosli.com/api/v2/openapi.json get /attestations/{org} Get a paginated list of attestations for an organization based on filters provided as query parameters. # List attestations for criteria Source: https://docs.kosli.com/api-reference/attestation/list-attestations-for-criteria https://app.kosli.com/api/v2/openapi.json get /attestations/{org}/list_attestations_for_criteria List attestations matching a search criteria within an organization. This endpoint returns a dictionary mapping commit SHAs to lists of attestations. Each attestation contains metadata about compliance, timing, and type-specific data. `commit_list` is required; it scopes the search to a specific set of commits. `attestation_type`, `attestation_name`, and `flow_name` further narrow results within that commit set but cannot be used on their own. ## Usage Examples ### Get all attestations for a list of commits ``` GET /attestations/my-org/list_attestations_for_criteria?commit_list=ae08fc6a5c963ae8dfaa0c27d8e5de9980d433b6 ``` ### Narrow by flow and attestation type ``` GET /attestations/my-org/list_attestations_for_criteria?commit_list=ae08fc6a5c963ae8dfaa0c27d8e5de9980d433b6&flow_name=production-flow&attestation_type=snyk ``` ### Narrow by attestation name ``` GET /attestations/my-org/list_attestations_for_criteria?commit_list=ae08fc6a5c963ae8dfaa0c27d8e5de9980d433b6&attestation_name=manual-test ``` ### Narrow by custom attestation type ``` GET /attestations/my-org/list_attestations_for_criteria?commit_list=ae08fc6a5c963ae8dfaa0c27d8e5de9980d433b6&attestation_type=custom:security-scan ``` # List flow attestations Source: https://docs.kosli.com/api-reference/attestation/list-flow-attestations https://app.kosli.com/api/v2/openapi.json get /attestations/{org}/{flow_name} Get all attestations for a flow for a given time span. # List system attestation types Source: https://docs.kosli.com/api-reference/attestation/list-system-attestation-types https://app.kosli.com/api/v2/openapi.json get /attestations/system-attestation-types List all registered system attestation types with their per-version attestation_data schemas. # Override attestation Source: https://docs.kosli.com/api-reference/attestation/override-attestation https://app.kosli.com/api/v2/openapi.json post /attestations/{org}/{flow_name}/trail/{trail_name}/override Override an attestation in a trail. # List membership/role change history for an org Source: https://docs.kosli.com/api-reference/audit-log/list-membershiprole-change-history-for-an-org https://app.kosli.com/api/v2/openapi.json get /membership-audit-log/{org} # Build frequency statistics Source: https://docs.kosli.com/api-reference/builds/build-frequency-statistics https://app.kosli.com/api/v2/openapi.json get /builds/{org}/statistics Build-frequency series for a repo within a time window. Returns one timestamp per build (deduplicated by fingerprint) plus the resolved window bounds and a count. Daily bucketing and the median are computed client-side. - end_ts defaults to now. - start_ts defaults to 28 days before end_ts. # List Builds Source: https://docs.kosli.com/api-reference/builds/list-builds https://app.kosli.com/api/v2/openapi.json get /builds/{org} List builds for an organization. - end_ts defaults to now. - start_ts defaults to 28 days before end_ts. # Archive a control Source: https://docs.kosli.com/api-reference/controls/archive-a-control https://app.kosli.com/api/v2/openapi.json post /controls/{org}/{identifier}/archive **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Create a control Source: https://docs.kosli.com/api-reference/controls/create-a-control https://app.kosli.com/api/v2/openapi.json post /controls/{org} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Environment coverage for a control Source: https://docs.kosli.com/api-reference/controls/environment-coverage-for-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier}/coverage **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Get a control Source: https://docs.kosli.com/api-reference/controls/get-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Get a single decision for a control Source: https://docs.kosli.com/api-reference/controls/get-a-single-decision-for-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier}/decisions/{decision_id} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Get a specific version of a control Source: https://docs.kosli.com/api-reference/controls/get-a-specific-version-of-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier}/versions/{version_number} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List controls Source: https://docs.kosli.com/api-reference/controls/list-controls https://app.kosli.com/api/v2/openapi.json get /controls/{org} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List decisions for a control Source: https://docs.kosli.com/api-reference/controls/list-decisions-for-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier}/decisions **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List distinct tag key/value pairs for an org's controls Source: https://docs.kosli.com/api-reference/controls/list-distinct-tag-keyvalue-pairs-for-an-orgs-controls https://app.kosli.com/api/v2/openapi.json get /controls/{org}/tags **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List versions of a control Source: https://docs.kosli.com/api-reference/controls/list-versions-of-a-control https://app.kosli.com/api/v2/openapi.json get /controls/{org}/{identifier}/versions **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Unarchive a control Source: https://docs.kosli.com/api-reference/controls/unarchive-a-control https://app.kosli.com/api/v2/openapi.json post /controls/{org}/{identifier}/unarchive **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Update a control Source: https://docs.kosli.com/api-reference/controls/update-a-control https://app.kosli.com/api/v2/openapi.json put /controls/{org}/{identifier} **Beta** — the Controls feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Archive custom attestation type Source: https://docs.kosli.com/api-reference/custom-attestation-types/archive-custom-attestation-type https://app.kosli.com/api/v2/openapi.json put /custom-attestation-types/{org}/{custom_attestation_type_name}/archive Archive a custom attestation type. # Create or update custom attestation type Source: https://docs.kosli.com/api-reference/custom-attestation-types/create-or-update-custom-attestation-type https://app.kosli.com/api/v2/openapi.json post /custom-attestation-types/{org} Create or update a custom attestation type for an org. # Get custom attestation type Source: https://docs.kosli.com/api-reference/custom-attestation-types/get-custom-attestation-type https://app.kosli.com/api/v2/openapi.json get /custom-attestation-types/{org}/{custom_attestation_type_name} Get a custom attestation type. # List custom attestation types Source: https://docs.kosli.com/api-reference/custom-attestation-types/list-custom-attestation-types https://app.kosli.com/api/v2/openapi.json get /custom-attestation-types/{org} List all custom attestation types for an org. # Get Deployment Source: https://docs.kosli.com/api-reference/deployments/get-deployment https://app.kosli.com/api/v2/openapi.json get /deployments/{org}/{env_name}/{fingerprint} Get a single deployment by environment and fingerprint. # List Deployments Source: https://docs.kosli.com/api-reference/deployments/list-deployments https://app.kosli.com/api/v2/openapi.json get /deployments/{org} List deployments for an organization. - end_ts defaults to now. - start_ts defaults to 28 days before end_ts. # Get environment diff Source: https://docs.kosli.com/api-reference/envdiff/get-environment-diff https://app.kosli.com/api/v2/openapi.json get /env-diff/{org} Get diff between to snapshots # Add environment to logical environment Source: https://docs.kosli.com/api-reference/environments/add-environment-to-logical-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/join Join the given physical environment to this Logical environment # Archive environment Source: https://docs.kosli.com/api-reference/environments/archive-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/archive Archive an environment. # Attach policy to environment Source: https://docs.kosli.com/api-reference/environments/attach-policy-to-environment https://app.kosli.com/api/v2/openapi.json post /environments/{org}/{env_name}/policies Attach a Policy to an environment. # Create or update environment Source: https://docs.kosli.com/api-reference/environments/create-or-update-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org} Create or update an Environment for an organization. # Detach policy from environment Source: https://docs.kosli.com/api-reference/environments/detach-policy-from-environment https://app.kosli.com/api/v2/openapi.json delete /environments/{org}/{env_name}/policies Detach a Policy from an environment. # Get deployment frequency Source: https://docs.kosli.com/api-reference/environments/get-deployment-frequency https://app.kosli.com/api/v2/openapi.json get /environments/{org}/{env_name}/deployment_frequency Get deployment frequency for a specific flow in an environment. # Get environment Source: https://docs.kosli.com/api-reference/environments/get-environment https://app.kosli.com/api/v2/openapi.json get /environments/{org}/{env_name} Get an environment for an organization. # Get environment audit log Source: https://docs.kosli.com/api-reference/environments/get-environment-audit-log https://app.kosli.com/api/v2/openapi.json get /environments/{org}/{env_name}/auditlog Get audit log (as a CSV file) for an environment. # List deployments for an environment Source: https://docs.kosli.com/api-reference/environments/list-deployments-for-an-environment https://app.kosli.com/api/v2/openapi.json get /environments/{org}/{env_name}/deployments List deployments for a single environment within a time range, newest first. # List environment events Source: https://docs.kosli.com/api-reference/environments/list-environment-events https://app.kosli.com/api/v2/openapi.json get /environments/{org}/{env_name}/events Get events log for an environment. **Response Headers:** * `X-Total-Count`: Total number of events available * `X-Per-Page`: Number of events per page * `X-Current-Page`: Current page number * `X-Total-Pages`: Total number of pages * `Link`: Pagination links (first, prev, next, last) when applicable **Pagination Links Format:** ``` ; rel="first", ; rel="prev", ; rel="next", ; rel="last" ``` **Note:** The Link header is only included when there are multiple pages. # List environments Source: https://docs.kosli.com/api-reference/environments/list-environments https://app.kosli.com/api/v2/openapi.json get /environments/{org} List environments of an organization. # Rename environment Source: https://docs.kosli.com/api-reference/environments/rename-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/rename Rename an environment # Report Azure Web and Function Apps environment Source: https://docs.kosli.com/api-reference/environments/report-azure-web-and-function-apps-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/azure-apps Process a report for an Azure Web and Function Apps environment. # Report Cloud Run environment Source: https://docs.kosli.com/api-reference/environments/report-cloud-run-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/cloud-run Process a report for a Google Cloud Run environment. # Report Docker environment Source: https://docs.kosli.com/api-reference/environments/report-docker-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/docker Process a report for a Docker environment. # Report ECS environment Source: https://docs.kosli.com/api-reference/environments/report-ecs-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/ECS Process a report for an ECS environment. # Report K8S environment Source: https://docs.kosli.com/api-reference/environments/report-k8s-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/K8S Process a report for a K8S environment. # Report Lambda environment Source: https://docs.kosli.com/api-reference/environments/report-lambda-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/lambda Process a report for a Lambda environment. # Report S3 environment Source: https://docs.kosli.com/api-reference/environments/report-s3-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/S3 Process a report for an S3 environment. # Report server environment Source: https://docs.kosli.com/api-reference/environments/report-server-environment https://app.kosli.com/api/v2/openapi.json put /environments/{org}/{env_name}/report/server Process a report for a server environment. # Update environment Source: https://docs.kosli.com/api-reference/environments/update-environment https://app.kosli.com/api/v2/openapi.json patch /environments/{org}/{env_name} Update an existing Environment for an organization. Only fields present in the request body are updated; omitted fields are left unchanged. Unlike the PUT endpoint, an empty string for description will clear the description. # Create an evaluation Source: https://docs.kosli.com/api-reference/evaluations/create-an-evaluation https://app.kosli.com/api/v2/openapi.json post /evaluations/{org} **Beta** — the Server-side evaluation feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Get an evaluation Source: https://docs.kosli.com/api-reference/evaluations/get-an-evaluation https://app.kosli.com/api/v2/openapi.json get /evaluations/{org}/{evaluation_id} **Beta** — the Server-side evaluation feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List evaluations Source: https://docs.kosli.com/api-reference/evaluations/list-evaluations https://app.kosli.com/api/v2/openapi.json get /evaluations/{org} **Beta** — the Server-side evaluation feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # Archive flow Source: https://docs.kosli.com/api-reference/flows/archive-flow https://app.kosli.com/api/v2/openapi.json put /flows/{org}/{flow_name}/archive Archive a flow. # Create or update flow Source: https://docs.kosli.com/api-reference/flows/create-or-update-flow https://app.kosli.com/api/v2/openapi.json put /flows/{org} Create or update a flow for an organization. # Create or update flow with template Source: https://docs.kosli.com/api-reference/flows/create-or-update-flow-with-template https://app.kosli.com/api/v2/openapi.json put /flows/{org}/template_file Create or update a flow for an organization. # Get flow Source: https://docs.kosli.com/api-reference/flows/get-flow https://app.kosli.com/api/v2/openapi.json get /flows/{org}/{flow_name} Get a flow for an organization. # List flows Source: https://docs.kosli.com/api-reference/flows/list-flows https://app.kosli.com/api/v2/openapi.json get /flows/{org} List flows for an organization. # Rename flow Source: https://docs.kosli.com/api-reference/flows/rename-flow https://app.kosli.com/api/v2/openapi.json put /flows/{org}/{flow_name}/rename Rename a flow. The flow will remain available under its old name until that name is taken by another flow. # Create or update environment notification Source: https://docs.kosli.com/api-reference/organizations/create-or-update-environment-notification https://app.kosli.com/api/v2/openapi.json put /organizations/{org}/environments_notifications Create or Update an environments-notification for an org. # Delete environment notification Source: https://docs.kosli.com/api-reference/organizations/delete-environment-notification https://app.kosli.com/api/v2/openapi.json delete /organizations/{org}/environments_notifications/{notification_number} Delete a specific environments-notification for an org. # Get environment notification Source: https://docs.kosli.com/api-reference/organizations/get-environment-notification https://app.kosli.com/api/v2/openapi.json get /organizations/{org}/environments_notifications/{notification_number} Get a specific environments-notification for an org. # Get organization Source: https://docs.kosli.com/api-reference/organizations/get-organization https://app.kosli.com/api/v2/openapi.json get /organizations/{org} Get a specific org. # List environment notifications Source: https://docs.kosli.com/api-reference/organizations/list-environment-notifications https://app.kosli.com/api/v2/openapi.json get /organizations/{org}/environments_notifications List environments-notifications for an org. # Update environment notification Source: https://docs.kosli.com/api-reference/organizations/update-environment-notification https://app.kosli.com/api/v2/openapi.json put /organizations/{org}/environments_notifications/{notification_number} Update a specific environments-notification for an org. # Create or update policy Source: https://docs.kosli.com/api-reference/policies/create-or-update-policy https://app.kosli.com/api/v2/openapi.json put /policies/{org} Create or update a Policy in an organization. # Get policy Source: https://docs.kosli.com/api-reference/policies/get-policy https://app.kosli.com/api/v2/openapi.json get /policies/{org}/{policy_name} Get a Policy in an organization. # List policies Source: https://docs.kosli.com/api-reference/policies/list-policies https://app.kosli.com/api/v2/openapi.json get /policies/{org} List Policies in an organization. # Deployment frequency and lead-time statistics for a repo Source: https://docs.kosli.com/api-reference/repos/deployment-frequency-and-lead-time-statistics-for-a-repo https://app.kosli.com/api/v2/openapi.json get /repos/{org}/{repo}/deployment-statistics Per-environment deployment-frequency and lead-time series for a repo, identified by its internal `id` (the `{repo}` path segment). Returns one entry per non-logical environment the repo has been deployed to (respecting the env filter), each with its raw `deployed_at` and `lead_time_seconds` series plus the shared window bounds. Daily bucketing, median and percentiles are computed client-side. - end_ts defaults to now. - start_ts defaults to 28 days before end_ts. # Get a repo Source: https://docs.kosli.com/api-reference/repos/get-a-repo https://app.kosli.com/api/v2/openapi.json get /repos/{org}/{repo_name} Get a repo by name, or unambiguously by its internal `id`. Returns the repo's details, including its internal `id`, which is required to tag the repo via the generic tags endpoint (PATCH /tags/{org}/repo/{id}). If multiple repos share the same name across different VCS providers and neither `id` nor `provider` is given, returns a 400 listing the providers to choose from. # Get live artifacts for a repo Source: https://docs.kosli.com/api-reference/repos/get-live-artifacts-for-a-repo https://app.kosli.com/api/v2/openapi.json get /repos/{org}/live-artifacts/{repo_name} Get the live status of artifacts from a repository across all environments. Returns a `RepoLiveStatusResponse` object that includes: - `_embedded.environments`: environments that currently have running artifacts from this repo - `_embedded.artifacts`: the corresponding artifacts for those environments - `live_artifacts`: a flattened view of currently running artifacts, including each artifact's compliance status, fingerprint, commit SHA, and start timestamp. Repo names are not unique within an org, so pass `id` to resolve an exact repo. Otherwise, if multiple repos share the same name across different VCS providers, use the `provider` parameter to disambiguate; without either, the most recently created match is used. # List deployments for a repo Source: https://docs.kosli.com/api-reference/repos/list-deployments-for-a-repo https://app.kosli.com/api/v2/openapi.json get /repos/{org}/{repo}/deployments List deployments for a repo, identified by its internal `id` (the `{repo}` path segment), newest first. - end_ts defaults to now. - start_ts defaults to 28 days before end_ts. # List repo filter options Source: https://docs.kosli.com/api-reference/repos/list-repo-filter-options https://app.kosli.com/api/v2/openapi.json get /repos/{org}/filter-options List the distinct facet values (providers, VCS instances, and namespace values) across the organization's repos, scoped by the given filters. Used to populate the repos faceted filters. Each facet reflects every filter except its own dimension, so alternative values stay visible (e.g. the returned `providers` list isn't narrowed by the `provider` filter itself). `namespace_values` cascades: it returns the values one level below `namespace`, so drilling into a namespace reveals the next level. Declared before the "/{org}/{repo_name}" route so the literal "filter-options" segment is not captured as a repo name. # List repo tag choices Source: https://docs.kosli.com/api-reference/repos/list-repo-tag-choices https://app.kosli.com/api/v2/openapi.json get /repos/{org}/tags List the distinct tag key/value pairs across the organization's repos. Used to populate the repos tag filter. Declared before the "/{org}/{repo_name}" route so the literal "tags" segment is not captured as a repo name. # List repos Source: https://docs.kosli.com/api-reference/repos/list-repos https://app.kosli.com/api/v2/openapi.json get /repos/{org} List repos for an organization. Repos are paginated. - The response includes pagination information and the list of repos. - The list of repos is sorted by the repo name; sort_direction selects the direction (asc = A–Z, the default; desc = Z–A). - Optional filters: name (exact match), search (case-insensitive substring match on the name), provider (VCS provider), repo_id (external repo ID), vcs_instance (VCS host, exact match), namespace (namespace prefix), and tag (key or key:value, repeatable). - name and search are mutually exclusive; providing both returns a 400. - repo_id is the stronger identifier as names of repos can change. So if repo_id is provided, name is ignored. Repos are captured when attestations include a reference to a repo. This happens automatically when using Kosli CLI v2.11.35 or higher. # Environment policy schema v1 Source: https://docs.kosli.com/api-reference/schemas/environment-policy-schema-v1 https://app.kosli.com/api/v2/openapi.json get /schemas/environment-policy/v1 Return the JSON Schema for the environment policy YAML format (v1). # Flow template schema v1 Source: https://docs.kosli.com/api-reference/schemas/flow-template-schema-v1 https://app.kosli.com/api/v2/openapi.json get /schemas/flow-template/v1 Return the JSON Schema for the flow template YAML format (v1). # Search artifacts by SHA or fingerprint Source: https://docs.kosli.com/api-reference/search/search-artifacts-by-sha-or-fingerprint https://app.kosli.com/api/v2/openapi.json get /search/{org}/sha/{search_value} Get artifacts that match fingerprint or commit-sha. # Create a service account Source: https://docs.kosli.com/api-reference/service-accounts/create-a-service-account https://app.kosli.com/api/v2/openapi.json post /service-accounts/{org} Create a new service account in the organization. API keys are minted separately via the `/{name}/api-keys` endpoint. # Create an API key for a service account Source: https://docs.kosli.com/api-reference/service-accounts/create-an-api-key-for-a-service-account https://app.kosli.com/api/v2/openapi.json post /service-accounts/{org}/{name}/api-keys Create a new API key for a service account. The key value is only returned once. # Delete a service account Source: https://docs.kosli.com/api-reference/service-accounts/delete-a-service-account https://app.kosli.com/api/v2/openapi.json delete /service-accounts/{org}/{name} Remove a service account from the organization. # Get a service account Source: https://docs.kosli.com/api-reference/service-accounts/get-a-service-account https://app.kosli.com/api/v2/openapi.json get /service-accounts/{org}/{name} Get a single service account by name. # Get an API key for a service account Source: https://docs.kosli.com/api-reference/service-accounts/get-an-api-key-for-a-service-account https://app.kosli.com/api/v2/openapi.json get /service-accounts/{org}/{name}/api-keys/{key_id} Get a single active API key for a service account. # List API keys for a service account Source: https://docs.kosli.com/api-reference/service-accounts/list-api-keys-for-a-service-account https://app.kosli.com/api/v2/openapi.json get /service-accounts/{org}/{name}/api-keys List all active API keys for a service account. # List service accounts in an organization Source: https://docs.kosli.com/api-reference/service-accounts/list-service-accounts-in-an-organization https://app.kosli.com/api/v2/openapi.json get /service-accounts/{org} List all service accounts in the organization. # Revoke an API key for a service account Source: https://docs.kosli.com/api-reference/service-accounts/revoke-an-api-key-for-a-service-account https://app.kosli.com/api/v2/openapi.json delete /service-accounts/{org}/{name}/api-keys/{key_id} Revoke an API key for a service account. # Rotate an API key for a service account Source: https://docs.kosli.com/api-reference/service-accounts/rotate-an-api-key-for-a-service-account https://app.kosli.com/api/v2/openapi.json post /service-accounts/{org}/{name}/api-keys/{key_id}/rotate Rotate an API key for a service account. A new key is generated immediately. The old key remains valid for `grace_period_hours` (default 24) to allow time to update dependent systems. The new key value is only returned once. # Update a service account Source: https://docs.kosli.com/api-reference/service-accounts/update-a-service-account https://app.kosli.com/api/v2/openapi.json patch /service-accounts/{org}/{name} Update a service account's description and/or privilege. Sending `description: null` clears the description; omitting the field leaves it unchanged. # Get snapshot Source: https://docs.kosli.com/api-reference/snapshots/get-snapshot https://app.kosli.com/api/v2/openapi.json get /snapshots/{org}/{env_name}/{snapshot_expression} Get a snapshot for an environment. `snapshot_expression` can be specified as follows: - `N`: the Nth snapshot, counting from 1. Negative values count from the latest snapshot i.e. -1 is the latest snapshot. example: 42 - `~N`: the Nth snapshot behind the latest, at the time of the request example: ~5 - `@{YYYY-MM-DDTHH:MM:SS}`: the snapshot at specific moment in time in UTC example: @{2023-10-02T12:00:00} - `@{N..ago}`: the snapshot at a time relative to the time of the request. N is a positive integer. example: @{2.hours.ago} - `@{now}`: the snapshot at the time of the request example: @{now} # List snapshots Source: https://docs.kosli.com/api-reference/snapshots/list-snapshots https://app.kosli.com/api/v2/openapi.json get /snapshots/{org}/{env_name} Get list of snapshots for an environment. # Update tags Source: https://docs.kosli.com/api-reference/tags/update-tags https://app.kosli.com/api/v2/openapi.json patch /tags/{org}/{resource_type}/{resource_id} Patch tags for resource. # Begin trail Source: https://docs.kosli.com/api-reference/trails/begin-trail https://app.kosli.com/api/v2/openapi.json put /trails/{org}/{flow_name} Add a Trail to a Flow. # Download trail audit package Source: https://docs.kosli.com/api-reference/trails/download-trail-audit-package https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name}/{trail_name}/audit_package Download the full trail audit package (same content as the app “Download Full Audit Package”). # Download trail audit PDF Source: https://docs.kosli.com/api-reference/trails/download-trail-audit-pdf https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name}/{trail_name}/audit_pdf Download only the trail PDF report (same as `trail-page.pdf` inside the full audit package). # Get trail Source: https://docs.kosli.com/api-reference/trails/get-trail https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name}/{trail_name} Get a Trail for a Flow in an organization. # Get trail moment Source: https://docs.kosli.com/api-reference/trails/get-trail-moment https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name}/{trail_name}/moments/{moment_expression} **Beta** — the Server-side evaluation feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List trail moments Source: https://docs.kosli.com/api-reference/trails/list-trail-moments https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name}/{trail_name}/moments **Beta** — the Server-side evaluation feature is in beta. Requests from organizations without it enabled receive `403 Forbidden`. # List trails Source: https://docs.kosli.com/api-reference/trails/list-trails https://app.kosli.com/api/v2/openapi.json get /trails/{org}/{flow_name} List Trails of a Flow. # List trails for organization Source: https://docs.kosli.com/api-reference/trails/list-trails-for-organization https://app.kosli.com/api/v2/openapi.json get /trails/{org} Get a paginated list of trails for an organization based on filters provided as query parameters. # Get default organization Source: https://docs.kosli.com/api-reference/user/get-default-organization https://app.kosli.com/api/v2/openapi.json get /user/default-org Get the default org for the current user. # Set default organization Source: https://docs.kosli.com/api-reference/user/set-default-organization https://app.kosli.com/api/v2/openapi.json put /user/{org} Set a default org for the current user. # Changelog Source: https://docs.kosli.com/changelog/index Release notes for Kosli products. ## Updates * **Help text fixes** — corrected typos in the help text for [`kosli attest sonar`](/client_reference/kosli_attest_sonar) and its `--sonar-working-dir` flag description. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.39.2) ## Bug fixes * **Attestations filter no longer breaks infinite scroll** — applying a filter on the org attestations list while a page request was still in flight could stop pagination for the rest of the session: the first page of filtered results rendered and nothing more, with no error. Filter and page requests are now serialized. ## Updates * **Clearer help text** — reworded the help for [`kosli attest jira`](/client_reference/kosli_attest_jira), [`kosli attest sonar`](/client_reference/kosli_attest_sonar), and [`kosli snapshot azure`](/client_reference/kosli_snapshot_azure), and fixed formatting glitches in the generated CLI reference. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.39.1) ## New features * **`--sonar-branch` on `kosli attest sonar`** — attest a SonarQube scan that ran on a branch other than the project's main branch by naming the branch. The flag cannot be combined with `--pull-request`. When a scan revision is not found, the error now says that only the main branch was searched and suggests passing `--sonar-branch`. See the [`kosli attest sonar` reference](/client_reference/kosli_attest_sonar). ## Updates * **`kosli attest jira` reports rejected credentials as such** — when Jira does not accept the credentials (for example an expired API token), the CLI prints a warning naming the username and reports the affected issues as "not confirmed" instead of silently as missing. The `--assert` failure message distinguishes missing, unconfirmed, and mixed cases. See the [`kosli attest jira` reference](/client_reference/kosli_attest_jira). * **`--jira-project-key` tolerates whitespace** — comma-separated lists like `"ABC, DEF"` are now accepted; each key is trimmed before validation, and invalid keys are quoted in the error message. * **`.kosli_ignore` documented in command help** — the help for `kosli allow artifact`, `kosli assert artifact`, and every `kosli attest` command now describes `.kosli_ignore` support when fingerprinting directories. ## Bug fixes * **`kosli version` reports the real release inside published Docker images** — published images identified themselves as `dev+` instead of the release tag they were built from, so `kosli version` in a container could not tell you which release was running. Any image published before v2.39.0 is affected; images from v2.39.0 onward report their release tag. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.39.0) ## New features * **Spaces enabled for every org** — Spaces, the hierarchical tree for organizing flows and environments, is now available to every organization by default. The Manage Spaces page and the Space filter on the Flows and Environments lists no longer require a feature flag or an org-level opt-in setting, both of which are gone. See [organizing flows and environments with Spaces](/tutorials/organizing_with_spaces). ## Bug fixes * **Policy expressions treat a missing value as never matching** — `matches()` and the ordering comparisons (`<`, `>`, `<=`, `>=`) now evaluate to `false` when either side is missing, consistent with how `==`, `!=`, `in`, and `exists()` already behaved. Missing values are common: `flow` is empty for any artifact without provenance, and `flow.tags.` is empty for a tag a flow doesn't have. Previously an expression like `not matches(flow.name, "^snyk-.*")` crashed snapshot compliance evaluation, and could return a 500 from the assert-artifact endpoint. See [policy expressions](/policy-reference/environment_policy#policy-expressions). ## Updates * **Environments tag filter drills into values** — the tag filter on the Environments list now offers both key-existence and key:value filtering, matching the Flows, Repos, and Controls pages. Previously it only listed keys, which made it useless when environments share keys but differ on values. ## Bug fixes * **Environment policies see override attestations** — `attestation` rules in [environment policies](/policy-reference/environment_policy) (and the assert-artifact API) now evaluate the newest attestation including overrides. Previously an override never matched the rule's attestation type, so overriding a non-compliant attestation could not bring an environment back to compliant, and overriding a compliant one down to non-compliant left the environment falsely reporting compliant. * **Archived resources disappear from the Spaces tree** — archiving two or more environments or flows could leave some of them still showing on the Spaces page. All archived resources are now filtered out. * **Attestation reads tolerate retargeted artifact names** — reading attestations no longer fails with a 500 when the same fingerprint was later reported under a different artifact name in the same trail. The artifact-name consistency check now runs when an attestation is written, not on every read. ## Updates * **Cleaner timestamps on the flows list** — the flows list now shows a plain date and time, matching the environments list, instead of a stacked icon, caption, and timestamp. The frequency-chart tooltip on the repo page also switches from DD/MM/YYYY to the app-standard YYYY-MM-DD. ## Bug fixes * **Empty attestation names refused in flow templates** — a flow template with an attestation named `""` could be saved but never satisfied, since no attestation can be reported under that name. Creating or updating a template with an empty attestation name is now rejected with a clear error. Existing records with the empty value still load. * **Empty filenames refused when reporting artifacts** — `POST` to the artifact create endpoint with `filename: ""` is now rejected instead of storing a blank filename against the artifact's fingerprint. * **A single malformed record no longer breaks list endpoints** — on environments, flows, artifacts, and other list endpoints, an exception rendering one record used to fail the whole response for every caller. The listing now returns successfully with a clearly-marked placeholder in place of the bad record. ## New features * **Custom attestation type summaries** — `kosli create attestation-type` now accepts `--summary`, a repeatable `'NAME=EXPRESSION'` entry (for example `--summary "Critical=.critical_count"`), and `--summary-json`, the same list given as a JSON array of `{name, expression}` entries. Each expression is a jq expression evaluated against the attestation payload, and Kosli renders the results as labeled rows on the attestation detail page, in the order given. The two flags cannot be combined. See [custom attestation types](/getting_started/attestations) and the [`kosli create attestation-type` reference](/client_reference/kosli_create_attestation-type). ## Bug fixes * **`kosli begin trail` no longer wipes description and user\_data on re-run** — running `kosli begin trail` without `--description` or `--user-data` used to send empty values and overwrite whatever was stored. The CLI now omits those fields when they aren't set, matching how the API behaves. * **Docker image has a writable `/tmp`** — the scratch-based image now ships an empty `/tmp`, so operations that rely on a temp directory (directory fingerprinting, evidence tarballing) work inside the container. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.38.0) ## Updates * **Scaling removed from environments** — capture of scale-only changes has been retired. An instance-count-only difference no longer creates a new snapshot or annotates an artifact as scaled, and the `include_scaling` environment setting is gone. Instance counts are still recorded on snapshots saved for another reason. Scaling had no compliance value: when a workload scales up or down, the artifact, its digest, and its provenance are unchanged. ## Bug fixes * **`attest override --commit` no longer 500s without prior git provenance** — overriding an attestation that was reported without a commit failed with a 500 when the override supplied `--commit`. Overrides now work whether or not the original attestation had git provenance. * **Environment listing tolerates logical environments without included environments** — a logical environment created with no `--included-environments` could 500 the org's whole environment listing. The listing now returns normally, and newly created logical environments always record an explicit (possibly empty) included-environments list. ## Breaking changes * **An empty flag value is refused** — `--flag ""` is now an error on every flag of every command, wherever the value comes from: the command line, a `KOSLI_` environment variable, or `~/.kosli.yml`. Accepting it was a bug. An empty value never did what the command was asked to do, and usually reported success anyway, so a pipeline that starts failing here was already producing a result nobody asked for. The usual cause is a shell variable that is unset. The error names the flag: give it a real value, or remove the flag, since in almost every case an empty value did what leaving the flag out does. Leaving a flag out is unchanged, including defaults filled in from your CI environment. See [empty flag values](/faq/faq#empty-flag-values). * **`--description ""` no longer clears a description** — on `kosli update control` and `kosli update service-account`, an empty value was the only way to empty a description. That is no longer possible: a description can be changed but not emptied. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.37.0) ## New features * **`summary` attribute on `kosli_custom_attestation_type`** — the resource and data source now accept an optional `summary`: a JSON list of ordered, labeled jq expressions that Kosli renders as rows on the attestation detail page. URL values render as links. ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_custom_attestation_type" "security_scan" { name = "security-scan" schema = file("${path.module}/schemas/security-scan.json") jq_rules = [".critical_count == 0"] summary = jsonencode([ { name = "Critical", expression = ".critical_count" }, { name = "Report", expression = ".report_url" }, ]) } ``` See [custom attestation types](/getting_started/attestations). [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.9.3) ## Updates * **Faster snapshot responses** — `GET /api/v2/snapshots*` used to fetch each artifact's provenance one at a time and read every attestation on the artifact. Provenance lookups are now batched across a snapshot's artifacts, and only the newest attestation is read per artifact. On snapshots with a single running artifact this cuts multi-second waits down to well under a second. ## Bug fixes * **Flows list no longer breaks on legacy `repo_url` values** — flows created before the artifact endpoint moved to strict URL validation could store a non-URL `repo_url`, which caused the flows page to return an error instead of the list. Invalid values are now repaired (scp-style Azure remotes converted to browse URLs, scheme-less hosts prefixed with `https://`, known placeholders removed) so the page loads. ## Bug fixes * **Empty multi-value flag elements rejected** — `--attachments` or `--template` values that expand to an empty element (for example from an unset shell variable) now fail with a clear error naming the flag instead of being silently dropped. * **Empty boolean flag values rejected** — passing an empty value to a boolean flag (for example `--compliant ""` or `--new-compliance-status ""`) now fails with a clear error instead of recording the opposite compliance verdict. * **`KOSLI_*` env vars set to empty treated as unset** — `KOSLI_CONFIG_FILE=""` no longer suppresses config file loading, and `KOSLI_API_TOKEN=""` no longer skips decryption of a config-file token. Both fall back to the default. * **Bad config values surface errors** — config file or environment values that cannot be applied to a flag now produce an error naming the flag and its source, instead of silently failing. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.6) ## New features * **Custom attestation summaries** — [custom attestation types](/getting_started/attestations) can now define a `summary` list of JQ expressions that extract key values (for example `Critical`, `Tool`) from the payload. The attestation drawer renders these as labeled rows instead of only raw JSON, matching the built-in Sonar, Snyk, and JUnit types. Summaries are versioned with the type, so schema changes create a new version. Array payloads render one summary group per element. ## Updates * **Flows list rebuilt as a React page** — `//flows/` now runs as a React island. Search, space filter, sort (by name or latest activity), and paging update in place instead of triggering a full page reload. The `GET /api/v2/flows/{org}` endpoint gained `latest_activity_at` and `latest_state` fields and a `sort` (`name` | `latest_activity`) parameter with `sort_direction` to power the new UI. ## Bug fixes * **Faster webhook saves** — the SSRF guard on webhook URLs no longer performs a blocking DNS lookup while saving an action. A slow resolver can no longer stall the save (or time out the request). * **Notification emails and trail events hardened against injected HTML** — user-controlled names and descriptions in notification emails and trail event descriptions are now HTML-escaped when rendered, closing a defense-in-depth gap on top of existing input validation. ## Bug fixes * **React pages redirect to login on session timeout** — Controls, Repos, Environments, and Audit Log now send you to the login page (with `next` set to where you were) when the session expires, instead of leaving the page with a generic error. * **Unmatched `/api/*` returns JSON 404** — a request to a non-existent `/api/*` path now returns a JSON `404` instead of redirecting to the HTML login page, so API clients see a proper error. ## Bug fixes * **Login email field focused on load** — the email input on the login and sign-in pages now receives focus automatically, so you can start typing straight away. * **No more double-login inside off-canvas panels** — when a session expired while an off-canvas panel was open, the login page could get swapped into the panel instead of taking over the tab. Auth redirects from htmx requests now navigate the whole tab. ## Updates * **Readable summary for override attestations** — an override attestation now opens on a summary showing the reason, the original attestation's type and status, and a link to the attestation it overrides. The raw JSON payload is still available in the raw view. ## Bug fixes * **Trail-by-artifact lookups no longer fail with tag filters** — `GET /api/v2/trails/{org}` filtered by fingerprint and `flow_tag` could return a 500 on large orgs because the database ran out of memory ordering the query. The fingerprint is now matched before flow filters, so these lookups return normally. ## Bug fixes * **`kosli attest` no longer fails on container-produced attachments** — passing two or more `--attachments` paths could abort with `chown ...: operation not permitted` when an attachment (for example lint, test, or coverage output) had been written by a Docker container running as a different user. The CLI no longer tries to preserve file ownership when staging attachments for upload. A genuine copy error now also names the evidence path you passed rather than an internal temp directory. See the [`kosli attest artifact` reference](/client_reference/kosli_attest_artifact) for usage. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.4) ## Updates * **Deprecated flags visible in reference docs** — deprecated flags (for example `--registry-provider`) are now listed in the [CLI reference](/client_reference) with their migration message, instead of being silently hidden. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.3) ## Updates * **Cleaner snapshot change summaries** — an artifact is no longer marked as `changed` when only its timestamp differs from the previous snapshot (for example a touched file or a restarted pod). Only differences that carry compliance meaning now produce a change event, so real changes stand out on the snapshot page. * **Snapshot event counts add up** — the started/changed/exited breakdown next to a snapshot's total event count now includes legacy `changed` events, so the totals match. * **Accurate compliance evaluation timestamps** — `compliance_status.evaluated_at` on the v2 API now reflects the event that triggered the evaluation, instead of the previous one. Verdicts no longer appear to predate the attestation inside them. ## Bug fixes * **Instance count hidden without scaling capture** — environments that don't capture scaling no longer display a stale instance count on artifact and event views. ## New features * **Non-interactive delete safety** — `kosli delete api-key` and `kosli delete service-account` now fail with a clear error when stdin is not a TTY (for example in CI) instead of silently exiting without deleting. Pass `--assume-yes` to delete non-interactively. ## Updates * **`--include-scaling` / `--exclude-scaling` deprecated** — these flags on `kosli create environment` and `kosli snapshot` now print a deprecation warning. Scaling events no longer trigger new snapshots. ## Bug fixes * **Payload logging failures no longer abort requests** — a failure to log an outgoing request payload now warns instead of exiting, so the request itself is no longer canceled. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.2) ## Breaking changes * **`include_scaling` removed from `kosli_environment`** — the `include_scaling` attribute has been removed from both the `kosli_environment` resource and data source. The Kosli API no longer honors it (it always reports `false`), and setting it to `true` caused apply failures. Remove any `include_scaling` values from your configuration before upgrading. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.9.2) ## Bug fixes * **FAQ URL typo** — fixed a double slash in the FAQ link shown when boolean flag arguments are misused (`https://docs.kosli.com//faq/` → `https://docs.kosli.com/faq/`). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.1) ## Updates * **Cleaner errors for unknown commands** — unrecognized command tokens (for example `kosli list garbage`) now report an error and exit non-zero instead of silently exiting `0`. * **Boolean flag help cleanup** — the boolean-flag FAQ link has been removed from the `--compliant` and `--compliance-status` flag descriptions now that space-form booleans are handled correctly. ## Bug fixes * **Space-form boolean flags** — boolean flags written in the space form (for example `--compliant false`) were being misread as positional arguments, causing spurious errors or silently wrong behavior. They now parse correctly. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.36.0) ## Breaking changes * **Approval commands removed** — `kosli assert approval`, `kosli get approval`, `kosli list approvals`, `kosli report approval`, and `kosli request approval` are gone, along with the `kosli request` parent command, since `request approval` was its only subcommand. They were deprecated in v2.20.0. Use [attestations](/getting_started/attestations) to record approval evidence instead. ## Updates * **k8s-reporter Helm chart (2.6.0)** — the `--auto-environment` flag and its companions (`--environment-description`, `--include-scaling`, `--exclude-scaling`) are now exposed as `reporterConfig.*` values, so the reporter CronJob can auto-create a K8S environment on first run without editing the chart. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.35.0) ## Breaking changes * **Approval API removed** — the deprecated approval endpoints under `/api/v2/approvals/` no longer exist. Approvals are also gone from custom webhook notification payloads and from artifact responses. Use [attestations](/getting_started/attestations) to record approval evidence instead. ## New features * **Auto-create environments from `kosli snapshot`** — new `--auto-environment` flag (alias `--auto-env`, shorthand `-A`) on all `kosli snapshot` subcommands creates the target environment (with the type inferred from the subcommand) if it doesn't already exist. Pair with `--environment-description` to set a description, and `--include-scaling` / `--exclude-scaling` (mutually exclusive) to control scaling-event behaviour on auto-created environments. ## Updates * **More informative error messages** — command errors now include the command path, and the `--flow` / `--trail` values when set, making it easier to spot which invocation failed when running multiple similar commands in a script. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.34.0) ## Bug fixes * **PR evidence for deleted GitHub accounts** — PR evidence reports now always include the `author` field (as an empty string when unknown), so pull requests whose creator's GitHub account has been deleted no longer fail server-side validation. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.33.3) ## Updates * **Bitbucket API tokens in help text** — Bitbucket Cloud is removing app password authentication on 28 July 2026. CLI help and generated command reference now point to Atlassian API tokens instead: pass your Atlassian account email to `--bitbucket-username` and the API token to `--bitbucket-password`. `--bitbucket-access-token` is unaffected. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.33.2) ## New features * **Per-domain MagicLink login** — MagicLink login can now be enabled for individual customer email domains on shared multi-tenant instances, instead of only per-deployment. ## Bug fixes * **MagicLink double email** — fixed a form-submission race where password-manager extensions could trigger two MagicLink emails for a single login attempt. * **Concurrent create races** — concurrent duplicate creates on flows and other unique-indexed resources now return a retryable `409` instead of surfacing as a `500`. ## Bug fixes * **`--repository` no longer overrides CI-detected repo names** — the flag's default value could overwrite a fuller CI-detected repository name (for example GitLab's `CI_PROJECT_PATH`) in the reported repo info. It now only overrides the CI-detected name when set explicitly. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.33.1) ## New features * **`kosli_control` list resource** — the provider now ships a list resource for `kosli_control`, so you can discover existing (unmanaged) controls with `terraform query` and generate import and configuration blocks for them. Supports the API's `search` and `archived` filters. Requires Terraform 1.14+ (the managed resource still works on Terraform 1.10+). [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.8.1) ## New features * **`kosli list repos` filtering and sorting** — new `--search` flag filters repos by case-insensitive name substring (mutually exclusive with `--name`), `--tag` filters by tag key or `key:value`, and `--sort-direction` sorts results ascending or descending by name. * **`kosli list controls` sorting** — new `--sort-direction` flag sorts results ascending or descending by name. ## Updates * **Clearer registry credential help** — `--registry-username` and `--registry-password` descriptions and root help now document that these are only needed when credentials aren't already available via Docker/Podman auth files or a credential helper, and spell out the automatic credential resolution order for `--artifact-type=oci` and `--artifact-type=docker`. * **`kosli list environments --tag`** — the `--tag` flag now accepts repeated values consistently with other list commands. * **Clarified `--tag` help for controls** — the flag description now states that repeating it matches more than one tag. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.33.0) ## Updates * **Refreshed repo pages** — repo pages now share a single header (name, provider badge, VCS id, repo URL) above the Build, Release, and Run tabs, and switching between tabs happens client-side without a full page reload. Deep links and Release sub-tabs continue to work. * **Repo tag management from the header** — manage repo tags directly from the new repo header via the kebab menu. ## Updates * `kosli list repos` table output now shows a pagination footer (`Showing page 1 of N, total N repos`) and includes expanded help and usage examples. * `kosli list repos` `--name` flag description now clarifies that it performs an exact match. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.32.1) ## New features * **Repo commands are GA** — `kosli get repo` and `kosli list repos` are no longer hidden and are now generally available. * **Fetch a repo by internal ID** — `kosli get repo` now supports `--repo-id` (mutually exclusive with the `REPO-NAME` argument). * **Repo tagging** — `kosli tag` now supports tagging repos (`repo`/`repos` resource types), with disambiguation via `--provider` or `--repo-id`. `--set` and `--unset` gain short aliases `-s` and `-u`. ## Updates * `kosli get repo` and `kosli list repos` table output now include a `Tags` column showing key=value pairs. * `kosli get repo` now returns an error (instead of a "not found" message) when a repo does not exist or when multiple repos match the given name, and suggests using `--provider` to disambiguate. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.32.0) ## New features * **`kosli_control` resource and data source (beta)** — manage Kosli controls as Terraform resources. The resource supports `identifier` (immutable), `name`, `description`, and `links`, plus computed `version`, `created_at`, `created_by`, `tags`, and `policies_referencing`, and can be imported by `identifier`. Archived controls are treated as deleted for drift detection. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.8.0) ## New features * **Repo tags** — repos can now be tagged, and tags appear in repo listings. ## Updates * **Faster customer usage metrics** — internal usage metrics are computed with chunked org counts, avoiding timeouts on large tenants. * **Cleaner environment deployments table** — artifact names are simplified and column widths are adjusted for readability. ## New features * **Service account resources** — new `kosli_service_account` and `kosli_service_account_api_key` resources let you manage service accounts and their API keys in Terraform. Service accounts support `name`, `description`, and `privilege` with import by `name`. API keys are minted as write-once sensitive values; all arguments force replacement since keys are immutable. * **`kosli_service_account` data source** — look up existing service accounts by `name`. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.7.0) ## New features * **Environment deployments report** — new deployments report for environments, gated behind a feature flag during rollout. ## Updates * **Space resources link to their pages** — flow and environment names in space views now link directly to their flow/environment pages. ## Bug fixes * **Duplicate environment create** — fixed an unhandled error when two clients concurrently created the same environment. ## New features * **`kosli get api-key`** — new command (alias: `ak`) to retrieve metadata for a specific API key belonging to a service account. Supports `--output table` (default) and `--output json`. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.31.0) ## Updates * **Faster logical environment pages** — logical environment page loads are noticeably quicker. * **More reliable org deletion** — org deletion now waits longer for HubSpot opt-out and resumes from the first unfinished step on retry. * **Automatic Descope role provisioning** — Descope roles are now created for orgs and assigned automatically during SCIM sync. ## Bug fixes * **Login form Enter key** — pressing Enter now submits the login form even when a password-manager browser extension is active. * **Logical environment description** — clearing or updating a logical environment description from the settings form now saves correctly. ## Updates * Dependency updates (AWS SDK, OPA, gRPC, Google API, and others). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.30.1) ## New features * **Attestation filters** — the org attestations list now supports filters, including a new **decision** entry in the Types filter for control decision attestations. * **Single service-account API key endpoint** — new `GET` endpoint to retrieve a specific service-account API key by identifier. ## Updates * **Faster org trail listings** — flows are now batch-loaded when listing org trails, removing an N+1 query. * **Cleaner control decision display** — the internal `system:` prefix is hidden from control decision attestations in the UI. * **Org deletion moved to a dedicated task** — long-running org deletion now runs in its own ECS task triggered via EventBridge, improving reliability. ## New features * **Controls management (beta)** — new commands to `get`, `list`, `create`, `update`, and `archive` Kosli controls. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.30.0) ## Updates * **Filtering and pagination on org attestations API** — the `list_org_attestations` endpoint now accepts filters and paginates results. ## Updates * **Approval API endpoints deprecated** — the approval endpoints are now marked deprecated in the API and OpenAPI schema. Existing integrations continue to work, but new work should move off them. * **Remembered space selection** — the UI now remembers your selected space(s) between pages using local storage. ## New features * **Service account management** — new commands to `create`, `get`, `list`, `update`, and `delete` service accounts: `kosli create service-account`, `kosli get service-account`, `kosli list service-accounts`, `kosli update service-account`, and `kosli delete service-account` (with a confirmation prompt, skippable via `--assume-yes`/`-y`). * **Default organization commands** — `kosli update default-org` sets the default organization for the current user, and `kosli get default-org` retrieves it. * **New top-level `kosli update` command group** (aliases: `u`, `up`). ## Updates * `kosli assert snapshot` and `kosli get environment` now report non-compliant environments as `NON-COMPLIANT` (previously `INCOMPLIANT`). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.29.0) ## Updates * **Resume stalled org deletion** — the UI now offers a **Resume** action on a stalled org deletion, so operators can pick up where the previous run left off. ## Updates * **Lifecycle status on control version list** — each entry in a control's Version List now shows whether it represents a **Created**, **Edited**, **Archived**, or **Unarchived** event, making history easier to scan. * **Consistent Controls list UI** — the Controls Decision List and Version List now use the same card-list layout as the main Controls listing. ## New features * **Deployment lead time** — `list` and `get` deployment endpoints now expose `lead_time_seconds`. ## Updates * Dependency updates (AWS SDK, Moby Docker client/API, Google API). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.28.2) ## New features * **Archive and unarchive controls** — retired controls can now be archived (and later unarchived) instead of deleted, preserving history while removing them from the active catalog. New `POST /api/v2/controls/{org}/{identifier}/archive` and `unarchive` endpoints, plus UI support. * **Controls coverage report** — a new Coverage tab and API show which environments enforce a given control (via a policy whose latest version references it through `for_control`) and which don't. * **Filter control decisions by flow** — a control's decisions list can now be filtered by one or more flows. * **Controls API in OpenAPI schema (beta)** — the `/api/v2/controls/...` endpoints are now published in the OpenAPI schema, marked beta and gated per-request by the `is-controls-enabled` flag. This unblocks downstream tooling like the Terraform provider. ## Updates * **Swagger docs can call mutating endpoints again** — requests carrying an `Authorization` header now skip session-CSRF enforcement, so authorized API-key calls from `/api/v2/doc/` no longer fail with `403 CSRF token missing`. * **Better flow-template error handling** — invalid flow template YAML now catches a wider range of parser errors instead of returning a 500. * **Experimental features opt-in removed** — the unused per-org "experimental features" setting and its API endpoint have been removed. ## Bug fixes * **Security: SSRF in environment-action webhooks** — webhook and Slack action targets are now validated and re-resolved immediately before each outbound POST, blocking requests to internal infrastructure (loopback, RFC 1918, cloud metadata endpoints, internal Kubernetes services). * **Control links with dots in names** — control link names containing `.` are now sanitized for MongoDB storage instead of being rejected. ## New features * **`decision` attestation in flow templates** — the `decision` attestation type introduced by Controls is now a first-class option in the flow template system and UI. ## Updates * **"+ Add tag" affordance on controls with no tags** — the view-control page now shows a clear add-tag button when a control has no tags, instead of a lone kebab menu. ## Updates * **Beta status moved to annotations** — `evaluate`, `attest decision`, and related subcommands no longer prefix their short description with `[BETA]`; beta status is now conveyed via annotations and sidebar tags. ## Bug fixes * **`kosli snapshot ecs` with empty clusters** — fixed a failure (`InvalidParameterException: Services cannot be empty`) when a scanned ECS cluster had no services. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.28.1) ## New features * **Membership audit log page** — the membership/role-change history now has a dedicated **Audit Log** page under Settings → User Management, with search, filters (event type, role, source), date range, and sortable columns. * **`pull_request` attestation fields** — V2 `pull_request` attestations now carry per-commit `verified` / `signature_state` and a PR `base_ref` (populated by CLI v2.27.0+), enabling Rego policies for signed commits and "merged into main". * **Service account CRUD API** — new JSON endpoints under `/service-accounts/{org}` to create, list, get, update, and delete service accounts, complementing the existing API-key endpoints. ## Updates * **Artifact name on control decisions** — the decisions list and decision tray now show a human-readable artifact name alongside the fingerprint. * **Decision list columns** — added **control version** and **attestation name** columns to the decisions list. * **Auto-run deletability check** — initiating an org-deletion plan now runs the deletability check automatically, with an approval-blocker warning banner on each plan card when checks fail; the manual button is renamed **Re-check deletability**. * **Controls UI refresh** — the controls list, control detail, control edit/new form, and version list pages have been restyled with new layouts, filtering, and interaction improvements. * **Faster environment snapshot listing** — `GET /api/v2/snapshots/{org}/{env_name}` (and `kosli list snapshots`) is significantly faster on large/long-lived environments by eliminating per-snapshot ordinal seeks and discarded counts. * **Display name fallback** — audit log, controls, and trail views now fall back to `login_name` when a user has no display name set. * **Signup form** — the welcome signup form now shows field labels. * **Wording** — "Logout" is now "Sign out" across the app. * **`base_ref` field placement** — in serialized `pull_request` attestation JSON, `base_ref` now sits next to `head_ref` (cosmetic; key order is not significant). ## Bug fixes * **Concurrent create 500s** — fixed 500 errors on concurrent `PUT /api/v2/trails/{org}/{flow}` (begin trail) and `PUT /api/v2/policies/{org}/{name}` requests by retrying on duplicate-key races. * **"Added" date reset on role change** — fixed a regression where changing a user's role reset their **Added** date (and the service account **Created** date) to today; both now read the original `created_at`. ## New features * **`kosli get trail --output markdown`** — `get trail` now supports GitHub-Flavored Markdown output, suitable for piping into CI job summaries (e.g. `$GITHUB_STEP_SUMMARY`). The output includes trail metadata, git commit info, attestation statuses with compliance indicators and links to the Kosli app, and an events table with linked commit SHAs, environment snapshots, and attestation references. See the [get trail reference](/client_reference/kosli_get_trail). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.28.0) ## New features * **`pull_request` attestations capture commit signatures and PR base branch** — each commit now records `verified` and `signature_state` (GitHub and GitLab), and every PR records `base_ref` (GitHub, GitLab, Bitbucket, Azure DevOps), enabling Rego policies for signed commits and "merged into main". Bitbucket and Azure DevOps don't expose per-commit signature verification, so those fields are omitted for them. ## Updates * **`pull_request` attestation commits** — record the git **author** identity and authored timestamp (not the committer) across all providers. * **API key rotation** — failures now clean up the duplicate key ID and include details in the error response. The new `base_ref` field is rejected by Kosli servers older than the matching server change. **Self-hosted users must upgrade their Kosli server before upgrading this CLI**, otherwise `pull_request` attestations will fail validation. Kosli SaaS (app.kosli.com / app.us.kosli.com) is already updated. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.27.0) ## New features * **Sign in with SSO** — a redesigned sign-in page makes SSO a first-class option alongside other providers. * **Membership history audit log** — organization membership and role changes are now appended to an audit history, capturing who changed what and when. * **Short fingerprints on artifact GETs** — artifact GET endpoints once again accept short fingerprint prefixes (5–64 chars), restoring documented CLI behavior like `kosli get artifact flow@`. ## Updates * **Faster org-scoped queries** — trail moments and recently-modified artifact queries now use org-scoped indexes for better performance on large organizations. ## Bug fixes * Fixed revoking an already-archived service account API key returning `200 OK` instead of `404 Not Found`. * Fixed an order-dependent waiver leak in trail and provenance compliance evaluation where one waived exception could incorrectly carry over to later artifacts. ## New features * **`kosli list environments` filtering and pagination** — new `--name`, `--type`, `--space-id`, `--tag`, `--page`, and `--page-limit` flags filter and paginate environment listings. See the [list environments reference](/client_reference/kosli_list_environments). * **`kosli list flows` name search** — new `--name` and `--ignore-case` flags search flows by name. See the [list flows reference](/client_reference/kosli_list_flows). ## Updates * **`kosli attest jira`** — clearer help text for CVE and multi-segment identifier filtering behavior. See the [attest jira reference](/client_reference/kosli_attest_jira). ## Bug fixes * **Service account API key prompts** — the revoke confirmation prompt now reads inline, and cancellation messaging and key ID styling are consistent with other commands. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.26.0) ## New features * **`kosli service-account api-keys`** — new command group (alias `sa ak`) to manage service account API keys from the CLI, with `create`, `revoke`, `rotate`, and `list` subcommands. * **Short aliases for top-level verbs** — `get` (`g`), `rename` (`re`), `disable` (`dis`), `enable` (`en`), `log` (`lo`), and `status` (`s`, `st`) now have shorter aliases. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.25.0) ## Updates * **Consistent "organization" wording** — standardized spelling across user-facing strings in the app. * **Simpler invite acceptance** — accepting an invite now requires OTP verification only when the logged-in user's email doesn't match the invitation; matching emails are accepted directly regardless of auth provider. ## Bug fixes * **Security: service account API keys on public orgs** — fixed a path that could return an arbitrary membership document for unauthenticated callers on public orgs, potentially exposing service account API keys. `is_admin(None)` now always returns `False`. * **Flows page** — guarded against a null `space_id` element that could break the flows listing. * **Redirects** — all query parameters are now preserved through redirects. ## New features * **`for_control` policy compliance** — snapshot compliance now evaluates `for_control` policy requirements. When a policy requires a passing decision attestation for a specific control, the snapshot is checked against a matching decision for that control. ## Updates * **Assert artifact response includes `for_control`** — the assert artifact API now returns the control identifier in the resolution context for `for_control` rule failures, so clients can show which specific control is unsatisfied. ## New features * **`linux/s390x` builds** — the CLI is now published for `linux/s390x` so it can be installed natively on IBM Z hosts. ## Bug fixes * Bumped Go to 1.26.4 to address standard-library CVEs. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.24.2) ## Updates * **`kosli assert artifact`** — when a `for_control` policy rule fails, the failure output now names the specific control identifier that is unsatisfied, making it easier to act on policy failures in CI. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.24.1) ## Updates * **SonarQube authentication** — `kosli attest sonar` now falls back to HTTP Basic auth (token as username) on self-hosted SonarQube Server versions earlier than 10.0, which reject `Authorization: Bearer`. The fallback is transparent for self-hosted servers and never applied to SonarCloud. Authentication errors now distinguish 401/403 token or permission problems from 5xx server-availability issues instead of the previous generic "please check your API token" message. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.24.0) ## New features * **Default organization on user profile** — pick a default organization from a dropdown on your [profile settings page](https://app.kosli.com/settings/profile) so the Kosli app opens to it on sign-in. ## Updates * **`visibility` optional when creating flows** — the create-flow API no longer requires a `visibility` field. New flows default to `private`. ## Bug fixes * Upgraded `libxml2` in the Kosli app image to address CVE-2026-6732 (high-severity denial-of-service in XSD validation). * Fixed orphaned tooltips lingering on the page after HTMX-driven updates. ## Bug fixes * **`kosli create flow`** — restored the `--visibility` flag as a deprecated (rather than removed) option, so existing scripts that pass it keep working. The flag has no effect on newer Kosli servers and will be removed in a future release. See the [create flow reference](/client_reference/kosli_create_flow). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.23.2) ## Updates * **`kosli create flow`** — the `--visibility` flag is deprecated. Flow visibility now defaults to `private` server-side and the flag is no longer needed. * **Deprecation warning for legacy flow creation** — `kosli create flow` now prints a warning when neither `--template-file` nor `--use-empty-template` is supplied. The legacy code path will stop working in a future release; pass a template file or use the empty template instead. See the [create flow reference](/client_reference/kosli_create_flow). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.23.0) ## Bug fixes * Fixed malformed URLs in `kosli list` and `kosli diff` commands when host or path segments contained extra slashes. Requests are now built with proper URL joining. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.22.1) ## New features * **Redesigned environments listing page** — the environments page in the Kosli app is now a paginated view with filtering by name, type, and tag, and sorting by last-changed time. * **Timestamp filtering on environment events** — the env events API accepts `from` and `to` timestamp query parameters. * **Service account privilege management** — admins can change the privilege level of existing service accounts. * **API key rotation** — rotate API keys without invalidating existing integrations. ## Updates * **Faster environments listing** — large environments now load and filter noticeably faster. * **Faster trail and snapshot operations** — listing trails and processing snapshots is quicker on large orgs. * **OpenAPI improvements** — the API spec has been refined for cleaner SDK generation. * **Magic Link login hardening** — added additional protections to the Magic Link sign-in flow. ## Bug fixes * Fixed empty-digest reports always creating a new snapshot instead of reusing the existing one. * Fixed the environments listing not falling back to a user's login name when no display name was set. * Fixed an authentication flow issue caused by a trailing slash in default Descope URLs. ## Bug fixes * **`kosli attest jira`** — fixed false-positive Jira issue key matches from multi-segment identifiers such as CVE numbers (`CVE-2026-41284` no longer matches as a Jira key). See the [attest jira reference](/client_reference/kosli_attest_jira). * **`kosli attest junit`** — JUnit XML ingestion now walks directories recursively, deduplicates file scans, and returns a clearer error message for non-UTF-8 encoded XML files. See the [attest junit reference](/client_reference/kosli_attest_junit). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.21.0) ## Bug fixes * Fixed CLI flags rendering as em dashes in the generated [CLI reference](/client_reference) pages. Flag names (`--flag`, `-x`) are now wrapped in backticks so Mintlify's smart-typography renderer leaves them intact. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.20.1) ## Updates * **`kosli approval` commands deprecated** — the `kosli approval` command tree is now marked as deprecated. Use [attestations](/getting_started/attestations) going forward. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.20.0) ## Updates * Migrated the Docker client dependency from `github.com/docker/docker` to `github.com/moby/moby` and related modular packages (`moby/moby/api`, `moby/moby/client`). * Updated `github.com/open-policy-agent/opa` to v1.16.2. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.19.0) ## New features * **`kosli snapshot cloud-run` is now generally available** — the [Cloud Run snapshotter](/client_reference/kosli_snapshot_cloud-run) is no longer hidden and now reports its coverage table alongside the snapshot. * **Path filters for `kosli snapshot s3`** — added `--include-regex` and `--exclude-regex` flags to [`kosli snapshot s3`](/client_reference/kosli_snapshot_s3) so you can scope a snapshot to a subset of objects in a bucket. ## Bug fixes * Fixed `kosli attest snyk` and other SonarQube-backed attestations not forwarding the branch name to SonarQube's `project_analyses/search` endpoint, which previously returned results from the wrong branch. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.18.0) ## New features * **Remote policies for `kosli evaluate`** — `--policy` on [`kosli evaluate`](/client_reference/kosli_evaluate_trail) now accepts remote `http(s)` URLs in addition to local file paths, so you can evaluate against centrally-hosted policy files. * **`--quiet` flag** — a new global `--quiet` flag suppresses non-essential output from the CLI, useful for scripting and CI pipelines that only care about exit codes. * **Expanded Cloud Run support** — [`kosli snapshot cloud-run`](/client_reference/kosli_snapshot_cloud-run) now reports Cloud Run Jobs in addition to services, and recovers missing image digests via a registry lookup when the runtime does not expose them directly. ## Bug fixes * Fixed bare URLs in CLI flag descriptions producing broken links in the generated reference docs. * Fixed the Helm chart docs templates so they render correctly in [Mintlify](/helm). [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.8) ## Updates * **Toolchain update** — the [Terraform provider](/terraform-reference) is now built with Go 1.26. No user-facing behavior changes. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.6.4) ## New features * **Cloud Run Jobs support in `kosli snapshot cloud-run`** — the [Cloud Run snapshotter](/client_reference/kosli_snapshot_cloud-run) can now report Cloud Run Jobs alongside services, and its wire format has been cleaned up. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.7) ## Bug fixes * Fixed [`kosli snapshot docker`](/client_reference/kosli_snapshot_docker) crashing when it encountered a container that the Docker daemon could not inspect. Such containers are now skipped with a warning and the snapshot continues. * Fixed a broken `http-proxy` example link in the CLI reference docs. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.6) ## New features * **PATCH endpoint for environment updates** — a new `PATCH /environments/{org}/{env_name}` endpoint allows updating individual environment fields without replacing the entire resource. This fixes the issue where setting a description to an empty string was silently ignored, and enables proper support in the [Terraform provider](/terraform-reference/resources/environment). ## Updates * **Significantly faster environment and snapshot pages** — eliminated thousands of redundant database queries during snapshot reporting and page rendering. For large environments (\~800 artifacts), this removes approximately 5,600 unnecessary database round-trips per snapshot report. The environment events page, which previously took \~60 seconds to load for large environments, now loads normally. * **Infinite scroll on snapshot events tab** — the snapshot events tab now loads events incrementally via infinite scroll instead of all at once, improving responsiveness for environments with many events. * **Improved environment page search** — search and filter on the environment page now returns all matching artifacts in a single request with loading indicators, fixing broken behavior for large environments. * **Faster flow filter lookups** — environment pages that filter by flow now use a pre-materialized collection instead of scanning all artifacts, speeding up load times. * **Case-insensitive email lookups** — user and invitation email lookups no longer require exact case matching. * **Redirect preserved through login** — when a session expires, the original destination URL (e.g., an org invite page) is now preserved through the logout/login cycle. * **API documentation improvements** — the OpenAPI spec title is now "Kosli API", endpoints are sorted alphabetically, and server URLs are absolute for [API playground](/api-reference/actions/list-actions) compatibility. ## Bug fixes * Fixed the flows filter incorrectly rejecting substring searches starting with hyphens, underscores, dots, or tildes. * Fixed the logical environment snapshot events tab raising an error, and the "Running" badge incorrectly counting exited artifacts. * Fixed a 500 error when listing API keys with legacy expiration timestamps. * Fixed unhandled exceptions during OAuth and SSO sign-in flows. * Security: upgraded xz/xz-libs packages to patch CVE-2026-34743. ## Updates * **More diagnostic `--debug` output for GitHub calls** — `kosli attest pullrequest github` and other GitHub-backed commands now include the (redacted) `Authorization` header, the resolved proxy URL, and any response body returned alongside transport errors when run with `--debug`. This makes it possible to diagnose corporate proxy and edge filter rejections that previously surfaced only as opaque transport errors. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.5) ## Updates * **Removed automatic update notifications** — the CLI no longer checks for new versions on every command. The update notice introduced in v2.17.0 occasionally polluted captured output (for example `FP=$(kosli fingerprint ...)`), so version checks now run only for the `version` subcommand and the `--version` flag. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.4) ## Updates * **Debug logging for GitHub PR attestations** — running `kosli attest pullrequest github` with `--debug` now prints every GitHub REST and GraphQL request and response (method, URL, headers, body) to stderr, with the `Authorization` header redacted. Useful for diagnosing 4xx/5xx responses and eventual-consistency issues in CI. See the [attest pullrequest github](/client_reference/kosli_attest_pullrequest_github) reference. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.3) ## Bug fixes * **Race condition on environment rename** — renaming a `kosli_environment` or `kosli_logical_environment` resource label while keeping the same `name` no longer fails with a 404 ("Environment has been archived"). The provider now retries the post-create read with bounded backoff and re-asserts desired state when it observes the parallel destroy + create race. If you are intentionally renaming an environment, use `terraform state mv` as documented in the [`kosli_environment`](/terraform-reference/resources/environment) reference. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.6.3) ## Bug fixes * **Clearing environment descriptions** — `kosli_environment` and `kosli_logical_environment` updates now use the `PATCH` endpoint, so setting `description = ""` correctly clears the environment's description. The previous `PUT`-based flow silently ignored empty descriptions. See the [`kosli_environment`](/terraform-reference/resources/environment) and [`kosli_logical_environment`](/terraform-reference/resources/logical_environment) references. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.6.2) ## New features * **`--assert` / `--no-assert` for evaluate commands** — `kosli evaluate trail`, `kosli evaluate trails`, and `kosli evaluate input` now accept a mutually-exclusive `--assert` / `--no-assert` flag pair. Pass `--no-assert` to use these commands as a policy decision point: the verdict is printed and the command exits 0, leaving any assertion to a downstream step. Default behavior is unchanged — a policy deny still exits non-zero. These commands are now marked `[BETA]`. See the [evaluate trail](/client_reference/kosli_evaluate_trail), [evaluate trails](/client_reference/kosli_evaluate_trails), and [evaluate input](/client_reference/kosli_evaluate_input) references. ## Updates * Help text for `kosli attest artifact` and `kosli fingerprint` now clarifies that `--artifact-type=docker` requires the image to have been pushed to or pulled from a registry, and points to `--artifact-type=oci` as the preferred alternative for registry-resident images. See the [attest artifact](/client_reference/kosli_attest_artifact) reference. ## Bug fixes * Reduced API request payload sizes by switching to compact JSON marshalling for both multipart (`--attestation-data`, `--user-data`) and non-multipart request bodies. Multipart payloads no longer hit the server's per-part size limit at \~400-500 KB on disk, and non-multipart bodies are 30-55% smaller on the wire. Debug and dry-run output remains pretty-printed. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.2) ## Bug fixes * **GitHub PR attestation reliability** — `kosli attest pullrequest github` and `kosli assert pullrequest github` now correctly detect pull requests merged seconds before CI runs. The CLI falls back to a REST + per-PR GraphQL lookup when GitHub's GraphQL `associatedPullRequests` returns no results due to eventual consistency, with retries up to 60 seconds. ## Updates * Improved help text for `kosli attest artifact` to clarify that `--repo-id`, `--repo-url`, and `--repository` must be set together, and which CI systems set them automatically. See the [attest artifact](/client_reference/kosli_attest_artifact) reference. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.1) ## Bug fixes * Bumped `hc-install` to v0.9.4 to use the renewed HashiCorp GPG key, restoring provider installation in environments that verify the key. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.6.1) ## New features * **Automatic update notifications** — the CLI now checks for available updates after each command and prints a notice to stderr when a newer version is released. Notices are suppressed in debug mode and for commands with programmatic output (e.g. `--output json`). * **`kosli --version` enhancements** — `kosli --version` now prints the full version struct and shows an update notice when a newer version is available. ## Bug fixes * Attestation `--name` validation now rejects names with a leading dot (e.g. `.foo`), trailing dot, or more than one dot (e.g. `foo.bar.baz`) with a clear error message instead of silently mishandling them. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.17.0) ## New features * **API key management for service accounts** — programmatically create and manage API keys for service accounts, making it easier to automate integrations. * **Filter repositories by name** — the repositories list now supports filtering by name for faster navigation. ## Updates * Significantly improved environment snapshot page performance, including faster artifact loading, lazy loading, and optimized search. ## Bug fixes * Fixed a 500 error when listing API keys for keys that had never been used. * Fixed YAML syntax errors in policies returning a 500 instead of a 400 error. * Fixed snapshot rejection when a repository has no provider set. ## New features * **Custom CA bundle support for k8s-reporter** — the [k8s-reporter Helm chart](/helm/k8s_reporter) now supports `extraVolumes`, `extraVolumeMounts`, `extraEnvVars`, and a `customCA` convenience wrapper for environments behind a TLS-inspecting proxy. See the [Helm chart reference](/helm/k8s_reporter) for details. * **SonarQube pull request scan support** — `kosli attest sonar` now retrieves scan results for pull request analyses. Pass `--pull-request` to specify the PR number, or let the CLI detect it automatically from the SonarQube metadata file. See the [attest sonar](/client_reference/kosli_attest_sonar) reference. * **`--sonar-ce-task-url` flag** — pass the SonarQube CE task URL directly to `kosli attest sonar`, bypassing the need for the `.scannerwork/report-task.txt` file. Useful in CI environments where the scanner and CLI run in separate containers. ## Updates * The Helm chart now uses `appVersion` as the default CLI version. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.16.0) ## New features * **Tags support for environments, logical environments, and flows** — you can now manage tags directly on [`kosli_environment`](/terraform-reference/resources/environment), [`kosli_logical_environment`](/terraform-reference/resources/logical_environment), and [`kosli_flow`](/terraform-reference/resources/flow) resources and their corresponding data sources. Tags are applied as diffs, so only changed tags are sent to the API. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.6.0) ## Updates * Updated dependencies across Go libraries, OpenTelemetry SDK, and CI tooling to incorporate the latest security patches and stability improvements. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.15.3) ## Updates * **`kosli assert artifact` flag validation** — the `--environment` and `--policy` flags are now validated as mutually exclusive client-side, giving you a faster error message without a server round-trip. The `--flow` flag can be combined with either mode to narrow the artifact lookup scope. See the [assert artifact](/client_reference/kosli_assert_artifact) reference. ## Bug fixes * Fixed `kosli list repos` and `kosli get repo` displaying garbled text when the latest activity field was empty. * Updated dependencies to resolve security vulnerabilities in Go standard library and OpenTelemetry packages. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.15.2) ## New features * **`kosli_flow` resource and data source** — manage Kosli [flows](/getting_started/flows) as Terraform resources. Define name, description, and YAML template inline or via `file()`. The data source lets you query existing flows and reuse their templates. See the [resource](/terraform-reference/resources/flow) and [data source](/terraform-reference/data-sources/flow) reference. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.5.0) ## New features * **`kosli evaluate input`** — evaluate a local JSON file (or stdin) against a Rego policy with no API dependency. Enables local policy development and fast iteration without a running Kosli server. See the [evaluate input](/client_reference/kosli_evaluate_input) reference. * **`--params` flag for policy evaluation** — pass configuration data (thresholds, expected counts, etc.) to Rego policies via `--params` on [`kosli evaluate trail`](/client_reference/kosli_evaluate_trail), [`kosli evaluate trails`](/client_reference/kosli_evaluate_trails), and [`kosli evaluate input`](/client_reference/kosli_evaluate_input). Accepts inline JSON or a file reference. Parameters are available as `data.params` in the policy. * **npm installation** — the Kosli CLI is now available as an npm package (`@kosli/cli`), making it easy to install in JavaScript/Node.js toolchains. ## Bug fixes * Fixed Docker API version negotiation — the CLI now automatically negotiates the Docker API version with the host daemon, preventing compatibility errors after SDK upgrades. * Fixed AWS API rate limiting — snapshot commands for ECS, S3, and Lambda environments now use adaptive retry with up to 10 attempts, preventing failures under heavy API load. * Fixed git HEAD resolution in linked worktrees. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.15.1) ## New features * **Deployment list** — the repository releases page now includes a deployments tab showing a paginated list of deployments with artifact details, commit links, replaced artifacts, and compliance status. * **Filter deployments by environment** — filter the deployment list and metrics by specific environments on the repository releases page. ## Updates * Redesigned the repository run page with improved layout, hover states, and rich tooltips showing artifact fingerprints, snapshot references, and commit details. ## Bug fixes * Fixed an error when viewing deployment details for artifacts with a missing replaced snapshot index. ## Updates * **Removed deprecated `kosli expect deployment` command** — deployment expectation is no longer required for compliance. If your pipelines still reference this command, remove or replace it. * **CI-ready Docker image** — a new Alpine-based Dockerfile is available for use as a CI runner image (e.g., GitLab CI), providing the Kosli CLI alongside common CI tooling. ## Bug fixes * Fixed `kosli get attestation-type` displaying `type_schema` as a Go map instead of formatted JSON. * The `--debug` flag now shows the HTML response body when a server error occurs, improving troubleshooting. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.13.2) ## Bug fixes * Fixed `type_schema` handling — the provider now correctly reads JSON objects returned by the API, replacing the previous Python repr string workaround. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.4.2) ## New features * **Deployment frequency statistics** — the repository releases page now shows a deployment frequency bar chart with daily counts, a median line, and summary statistics for each environment. ## Updates * Removed the deprecated deployments API. This aligns with the CLI removal of `kosli expect deployment`. ## New features * **`kosli_action` resource and data source** — manage webhook notification actions as Terraform resources. Create, update, and import actions by name, and read existing actions to reference in your configurations. * **`kosli_policy` resource and data source** — manage Kosli policies as Infrastructure-as-Code. The data source exposes the policy name, description, content, and latest version. * **`kosli_policy_attachment` resource** — manage the relationship between policies and environments, letting you attach and detach policies declaratively. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.4.0) ## New features * **Repository metadata on attestations** — all `kosli attest` commands and `kosli begin trail` now accept `--repo-id`, `--repository`, `--repo-url`, and `--repo-provider` flags to associate attestations and trails with their source repository. These flags are automatically populated from CI environment variables in GitHub Actions, GitLab CI, Bitbucket Pipelines, Azure DevOps, and CircleCI — no manual configuration needed. See the [CI defaults](/integrations/ci_cd) reference. * **Helm chart CronJob configuration** — the [k8s-reporter Helm chart](/helm/k8s_reporter) now lets you configure `concurrencyPolicy`, `failedJobsHistoryLimit`, and `successfulJobsHistoryLimit` for the reporter CronJob. ## Updates * `--repo-url` is now validated as a well-formed URL when explicitly provided. * `--repo-provider` is validated against the allowed values: `github`, `gitlab`, `bitbucket`, `azure-devops`. * For `kosli attest pullrequest github` and `kosli attest pullrequest azure`, the `--repository` flag now also controls which repository is queried for pull requests. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.13.0) ## Bug fixes * Fixed an issue where artifact names with leading periods were rejected. Leading periods are now trimmed automatically. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.13.1) ## New features * **Attestation evidence download** — a new API endpoint lets you download evidence files attached to attestations, making it easier to retrieve and audit attestation data programmatically. * **Snapshotter role** — a new [Snapshotter role](/administration/managing_users/roles_in_kosli) is available for users who need to create environment snapshots and manage service accounts without full member permissions. Ideal for environment and operations teams. ## Bug fixes * Fixed `kosli attest artifact` sending empty repository information when no repo data is available. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.12.1) ## New features * **`kosli evaluate trail` and `kosli evaluate trails`** — evaluate one or more trails against a [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) policy and get a structured pass/fail decision. Use `--attestations` to filter which attestations are checked, and `--output json` for machine-readable results. Exit code reflects the policy decision, making it ideal for CI/CD gates. See the [evaluate trail](/client_reference/kosli_evaluate_trail) and [evaluate trails](/client_reference/kosli_evaluate_trails) reference for details. * **Multi-environment K8s reporting** — `kosli snapshot k8s` now accepts a `--config-file` flag to report multiple Kosli environments in a single command. Define environment-to-namespace mappings in a YAML file instead of running the command once per environment. See the [snapshot k8s](/client_reference/kosli_snapshot_k8s) reference. * **Helm chart v2.0.0** — the [k8s-reporter Helm chart](/helm/k8s_reporter) now uses a `reporterConfig.environments` list, enabling multi-environment reporting from a single chart installation. This is a breaking change from v1.x — see the chart README for migration steps. [View on GitHub](https://github.com/kosli-dev/cli/releases/tag/v2.12.0) ## Bug fixes * Fixed handling of Python boolean (`true`/`false`) and null values in custom attestation type schemas. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.3.1) ## New features * **`kosli_logical_environment` resource** — create and manage logical environments that aggregate multiple physical environments into a single view. * **`kosli_logical_environment` data source** — query details of existing logical environments. * **Drift detection for logical environments** — Kosli now detects when the `included_environments` of a logical environment change outside of Terraform. * **User agent header** — the provider now sends a versioned user agent on every API request, improving diagnostics. ## Bug fixes * Fixed a missing `flow` field in pull request attestation resources. * Fixed `terraform plan` showing `(known after apply)` for the `type` attribute of logical environments instead of `"logical"`. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.3.0) ## New features * **`kosli_environment` resource** — create and manage physical Kosli environments (K8S, ECS, S3, docker, server, lambda) as Terraform resources. * **`kosli_environment` data source** — query details of existing physical environments. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.2.0) ## Changes * `schema` and `jq_rules` are now optional fields on `kosli_attestation_type`, allowing you to create attestation types without a validation schema. [View on GitHub](https://github.com/kosli-dev/terraform-provider-kosli/releases/tag/v0.1.0) # kosli Source: https://docs.kosli.com/client_reference/kosli The Kosli CLI. ## Synopsis The Kosli CLI. Environment variables: You can set any flag from an environment variable by capitalizing it in snake case and adding the KOSLI\_ prefix. For example, to set --api-token from an environment variable, you can export KOSLI\_API\_TOKEN=YOUR\_API\_TOKEN. Setting the API token to DRY\_RUN sets the --dry-run flag. ## Flags | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-h`, `--help` | bool | help for kosli | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli allow artifact Source: https://docs.kosli.com/client_reference/kosli_allow_artifact Add an artifact to an environment's allowlist. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli allow artifact [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Add an artifact to an environment's allowlist. The artifact fingerprint can be provided directly with the `--fingerprint` flag, or calculated based on `--artifact-type` flag. Artifact type can be one of: "file" for files, "dir" for directories, "oci" for container images in registries or "docker" for local docker images. Note: `--artifact-type=docker` reads the image's repo digest via the local Docker daemon. The image must have been pushed to or pulled from a registry for a repo digest to exist; a freshly built image (just `docker build`) will not have one. If the image is already in a registry, prefer `--artifact-type=oci`, which fetches the digest directly from the registry without needing a local Docker daemon. For `--artifact-type=oci` (and for `--artifact-type=docker` when `--registry-username` is set), registry credentials are resolved as follows: 1. If `--registry-username` (and optionally `--registry-password`) is set, it is used directly. 2. Otherwise, credentials are discovered automatically from: * the Docker config file (`~/.docker/config.json`, populated by `docker login`) * the Podman/containers auth file (`~/.config/containers/auth.json`, or `$REGISTRY_AUTH_FILE`) * any Docker credential helper configured in that config (e.g. `docker-credential-ecr-login` for AWS ECR, `docker-credential-gcloud` for GCR/Artifact Registry, an ACR helper for Azure, or a local keychain helper), invoked as an external binary on `$PATH` * if none of the above yield credentials, the registry is accessed anonymously, which works for public images `--registry-provider` is deprecated and no longer used. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--environment` | string | The environment name for which the artifact is allowlisted. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact. Only required if you don't specify '`--artifact-type`'. | | `-h`, `--help` | bool | help for artifact | | `--reason` | string | The reason why this artifact is allowlisted. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli archive attestation-type Source: https://docs.kosli.com/client_reference/kosli_archive_attestation-type Archive a custom Kosli attestation type. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive attestation-type TYPE-NAME [flags] ``` Archive a custom Kosli attestation type. New custom attestations using this type cannot be made, but existing attestations will still be visible. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for attestation-type | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive attestation-type yourAttestationTypeName ``` # kosli archive control Source: https://docs.kosli.com/client_reference/kosli_archive_control Archive a Kosli control. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive control CONTROL-IDENTIFIER [flags] ``` Archive a Kosli control. An archived control is no longer active. It remains visible via `kosli get control` and via `kosli list controls --archived`, and can be restored with `kosli unarchive control`. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for control | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive control yourControlIdentifier ``` # kosli archive environment Source: https://docs.kosli.com/client_reference/kosli_archive_environment Archive a Kosli environment. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive environment ENVIRONMENT-NAME [flags] ``` Archive a Kosli environment. The environment will no longer be visible in list of environments, data is still stored in the database. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for environment | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive environment yourEnvironmentName ``` # kosli archive flow Source: https://docs.kosli.com/client_reference/kosli_archive_flow Archive a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive flow FLOW-NAME [flags] ``` Archive a Kosli flow. The flow will no longer be visible in list of flows, data is still stored in the database. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for flow | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli archive flow yourFlowName ``` # kosli assert artifact Source: https://docs.kosli.com/client_reference/kosli_assert_artifact Assert the compliance status of an artifact in Kosli. There are three ways to choose what to assert against: 1. Against an environment. When `--environment` is specified, asserts against all poli... ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert artifact [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Assert the compliance status of an artifact in Kosli. There are three ways to choose what to assert against: 1. Against an environment. When `--environment` is specified, asserts against all policies currently attached to the given environment. 2. Against one or more policies. When `--policy` is specified, asserts against all the given policies. 3. Against flow templates. When neither `--environment` nor `--policy` is specified, asserts against the template files of the flows the artifact is found in. `--environment` and `--policy` are mutually exclusive. `--flow` can be combined with any of the above to narrow the lookup to a specific flow. Without `--flow`, all flows containing the artifact (by fingerprint) are considered. Exits with zero code if the artifact has compliant status, non-zero code if non-compliant status. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--environment` | string | The Kosli environment name to assert the artifact against. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact. Only required if you don't specify '`--artifact-type`'. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for artifact | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--policy` | strings | \[optional] policy name (can be specified multiple times) | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli assert artifact` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/differ/blob/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de/.github/workflows/main.yml#L271) View an example of the `kosli assert artifact` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/42876c4da26ee74e4bbfe14c2949cc7cb2d3345e/.gitlab/workflows/main.yml#L158) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert artifact --fingerprint 184c799cd551dd1d8d5c5f9a5d593b2e931f5e36122ee5c793c1d08a19839cc0 --environment prod ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert artifact --fingerprint 184c799cd551dd1d8d5c5f9a5d593b2e931f5e36122ee5c793c1d08a19839cc0 --policy has-approval,has-been-integration-tested ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_FLOW=yourFlowName kosli assert artifact --fingerprint 184c799cd551dd1d8d5c5f9a5d593b2e931f5e36122ee5c793c1d08a19839cc0 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} unset KOSLI_FLOW kosli assert artifact library/nginx:1.21 --artifact-type docker ``` # kosli assert pullrequest azure Source: https://docs.kosli.com/client_reference/kosli_assert_pullrequest_azure Assert an Azure DevOps pull request for a git commit exists. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest azure [flags] ``` Assert an Azure DevOps pull request for a git commit exists.\ The command exits with non-zero exit code if no pull requests were found for the commit. ## Flags | Flag | Type | Description | | :---------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `--azure-org-url` | string | Azure organization url. E.g. `https://dev.azure.com/myOrg` (defaulted if you are running in Azure Devops pipelines: [docs](/integrations/ci_cd) ). | | `--azure-token` | string | Azure Personal Access token. | | `--commit` | string | Git commit for which to find pull request evidence. (defaulted in some CIs: [docs](/integrations/ci_cd) ). (default "HEAD") | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for azure | | `--project` | string | Azure project.(defaulted if you are running in Azure Devops pipelines: [docs](/integrations/ci_cd) ). | | `--repository` | string | Git repository. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest azure \ --azure-token yourAzureToken \ --azure-org-url yourAzureOrgUrl \ --commit yourGitCommit \ --project yourAzureDevopsProject \ --repository yourAzureDevOpsGitRepository ``` # kosli assert pullrequest bitbucket Source: https://docs.kosli.com/client_reference/kosli_assert_pullrequest_bitbucket Assert a Bitbucket pull request for a git commit exists. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest bitbucket [flags] ``` Assert a Bitbucket pull request for a git commit exists.\ The command exits with non-zero exit code if no pull requests were found for the commit. Authentication to Bitbucket can be done with an access token (recommended) or an Atlassian API token, passed via --bitbucket-username (your Atlassian account email) and --bitbucket-password. Bitbucket app passwords are no longer supported as of 28 July 2026; replace any app passwords with API tokens. Credentials need to have read access for both repos and pull requests. ## Flags | Flag | Type | Description | | :------------------------- | :----- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--bitbucket-access-token` | string | Bitbucket repo/project/workspace access token. See [Bitbucket access tokens](https://developer.atlassian.com/cloud/bitbucket/rest/intro/#access-tokens) for more details. | | `--bitbucket-password` | string | Bitbucket API token. Bitbucket app passwords are no longer supported as of 28 July 2026. See [Bitbucket authentication](https://developer.atlassian.com/cloud/bitbucket/rest/intro/#authentication) for more details. | | `--bitbucket-username` | string | Bitbucket username (your Atlassian account email when using an API token). Only needed if you use `--bitbucket-password` | | `--bitbucket-workspace` | string | Bitbucket workspace ID. | | `--commit` | string | Git commit for which to find pull request evidence. (defaulted in some CIs: [docs](/integrations/ci_cd) ). (default "HEAD") | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for bitbucket | | `--repository` | string | Git repository. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest bitbucket \ --bitbucket-access-token yourBitbucketAccessToken \ --bitbucket-workspace yourBitbucketWorkspace \ --commit yourGitCommit \ --repository yourBitbucketGitRepository ``` # kosli assert pullrequest github Source: https://docs.kosli.com/client_reference/kosli_assert_pullrequest_github Assert a Github pull request for a git commit exists. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest github [flags] ``` Assert a Github pull request for a git commit exists.\ The command exits with non-zero exit code if no pull requests were found for the commit. ## Flags | Flag | Type | Description | | :------------------ | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `--commit` | string | Git commit for which to find pull request evidence. (defaulted in some CIs: [docs](/integrations/ci_cd) ). (default "HEAD") | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--github-base-url` | string | \[optional] GitHub base URL (only needed for GitHub Enterprise installations). | | `--github-org` | string | Github organization. (defaulted if you are running in GitHub Actions: [docs](/integrations/ci_cd) ). | | `--github-token` | string | Github token. | | `-h`, `--help` | bool | help for github | | `--repository` | string | Git repository. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest github \ --github-token yourGithubToken \ --github-org yourGithubOrg \ --commit yourGitCommit \ --repository yourGithubGitRepository ``` # kosli assert pullrequest gitlab Source: https://docs.kosli.com/client_reference/kosli_assert_pullrequest_gitlab Assert a Gitlab merge request for a git commit exists. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert pullrequest gitlab [flags] ``` Assert a Gitlab merge request for a git commit exists.\ The command exits with non-zero exit code if no merge requests were found for the commit. ## Flags | Flag | Type | Description | | :------------------ | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `--commit` | string | Git commit for which to find pull request evidence. (defaulted in some CIs: [docs](/integrations/ci_cd) ). (default "HEAD") | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--gitlab-base-url` | string | \[optional] Gitlab base URL (only needed for on-prem Gitlab installations). | | `--gitlab-org` | string | Gitlab organization. (defaulted if you are running in Gitlab Pipelines: [docs](/integrations/ci_cd) ). | | `--gitlab-token` | string | Gitlab token. | | `-h`, `--help` | bool | help for gitlab | | `--repository` | string | Git repository. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert mergerequest gitlab \ --github-token yourGithubToken \ --github-org yourGithubOrg \ --commit yourGitCommit \ --repository yourGithubGitRepository ``` # kosli assert snapshot Source: https://docs.kosli.com/client_reference/kosli_assert_snapshot Assert the compliance status of an environment in Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert snapshot ENVIRONMENT-NAME-OR-EXPRESSION [flags] ``` Assert the compliance status of an environment in Kosli. Exits with non-zero code if the environment has a non-compliant status. The expected argument is an expression to specify the specific environment snapshot to assert. It has the format `ENVIRONMENT_NAME`\[SEPARATOR]\[SNAPSHOT\_REFERENCE] Separators can be: * '#' to specify a specific snapshot number for the environment that is being asserted. * '\~' to get N-th behind the latest snapshot. Examples of valid expressions are: * prod (latest snapshot of prod) * prod#10 (snapshot number 10 of prod) * prod\~2 (third latest snapshot of prod) ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for snapshot | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert snapshot prod#5 \ --api-token yourAPIToken \ --org yourOrgName ``` # kosli assert status Source: https://docs.kosli.com/client_reference/kosli_assert_status Assert the status of a Kosli server. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert status [flags] ``` Assert the status of a Kosli server. Exits with non-zero code if the Kosli server down. ## Flags | Flag | Type | Description | | :------------- | :--- | :-------------- | | `-h`, `--help` | bool | help for status | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli attach-policy Source: https://docs.kosli.com/client_reference/kosli_attach-policy Attach a policy to one or more Kosli environments. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attach-policy POLICY-NAME [flags] ``` Attach a policy to one or more Kosli environments. ## Flags | Flag | Type | Description | | :-------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--environment` | strings | the list of environment names to attach the policy to | | `-h`, `--help` | bool | help for attach-policy | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attach-policy yourPolicyName --environment yourFirstEnvironmentName --environment yourSecondEnvironmentName ``` # kosli attest artifact Source: https://docs.kosli.com/client_reference/kosli_attest_artifact Attest an artifact creation to a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact {IMAGE-NAME | FILE-PATH | DIR-PATH} [flags] ``` Attest an artifact creation to a Kosli flow. The artifact fingerprint can be provided directly with the `--fingerprint` flag, or calculated based on `--artifact-type` flag. Artifact type can be one of: "file" for files, "dir" for directories, "oci" for container images in registries or "docker" for local docker images. Note: `--artifact-type=docker` reads the image's repo digest via the local Docker daemon. The image must have been pushed to or pulled from a registry for a repo digest to exist; a freshly built image (just `docker build`) will not have one. If the image is already in a registry, prefer `--artifact-type=oci`, which fetches the digest directly from the registry without needing a local Docker daemon. For `--artifact-type=oci` (and for `--artifact-type=docker` when `--registry-username` is set), registry credentials are resolved as follows: 1. If `--registry-username` (and optionally `--registry-password`) is set, it is used directly. 2. Otherwise, credentials are discovered automatically from: * the Docker config file (`~/.docker/config.json`, populated by `docker login`) * the Podman/containers auth file (`~/.config/containers/auth.json`, or `$REGISTRY_AUTH_FILE`) * any Docker credential helper configured in that config (e.g. `docker-credential-ecr-login` for AWS ECR, `docker-credential-gcloud` for GCR/Artifact Registry, an ACR helper for Azure, or a local keychain helper), invoked as an external binary on `$PATH` * if none of the above yield credentials, the registry is accessed anonymously, which works for public images `--registry-provider` is deprecated and no longer used. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. This command requires access to a git repo to associate the artifact to the git commit it is originating from. You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `-b`, `--build-url` | string | The url of CI pipeline that built the artifact. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-g`, `--commit` | string | \[defaulted] The git commit from which the artifact was created. (defaulted in some CIs: [docs](/integrations/ci_cd), otherwise defaults to HEAD ). (default "HEAD") | | `-u`, `--commit-url` | string | The url for the git commit that created the artifact. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-N`, `--display-name` | string | \[optional] Artifact display name, if different from file, image or directory name. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact. Only required if you don't specify '`--artifact-type`'. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for artifact | | `-n`, `--name` | string | The name of the artifact in the yml template file. | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest artifact` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/reusable-actions-workflows/blob/25f0b797c18403de1c8490a9a71bbe9789c809a9/.github/workflows/secure-docker-build.yml#L210), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de?attestation_id=11345222-f37a-4f8d-8051-ec26a321). View an example of the `kosli attest artifact` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L111), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/d64d2b11879179255f11dc991e81fbaf4a040264?attestation_id=61384b36-4d32-43f2-8d5d-a72e2e7e). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact FILE.tgz --artifact-type file --build-url https://exampleci.com --commit-url https://github.com/YourOrg/YourProject/commit/yourCommitShaThatThisArtifactWasBuiltFrom --commit yourCommitShaThatThisArtifactWasBuiltFrom --name yourTemplateArtifactName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact ANOTHER_FILE.txt --build-url https://exampleci.com --commit-url https://github.com/YourOrg/YourProject/commit/yourCommitShaThatThisArtifactWasBuiltFrom --commit yourCommitShaThatThisArtifactWasBuiltFrom --fingerprint yourArtifactFingerprint --name yourTemplateArtifactName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact ANOTHER_FILE.txt --build-url https://exampleci.com --commit-url https://github.com/YourOrg/YourProject/commit/yourCommitShaThatThisArtifactWasBuiltFrom --commit yourCommitShaThatThisArtifactWasBuiltFrom --fingerprint yourArtifactFingerprint --external-url label=https://example.com/attachment --external-fingerprint label=yourExternalAttachmentFingerprint --name yourTemplateArtifactName ``` # kosli attest custom Source: https://docs.kosli.com/client_reference/kosli_attest_custom Report a custom attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a custom attestation to an artifact or a trail in a Kosli flow. The name of the custom attestation type is specified using the `--type` flag. The path to the JSON file the custom type will evaluate is specified using the `--attestation-data` flag. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `--attestation-data` | string | The filepath of a json file containing the custom attestation data. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for custom | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `--type` | string | The name of the custom attestation type. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest custom` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/differ/blob/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de/.github/workflows/main.yml#L168), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de?attestation_id=8dfb2b55-0e6d-4d76-8396-4c85e9aa). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom yourDockerImageName --artifact-type oci --type customTypeName --name yourAttestationName --attestation-data yourJsonFilePath ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom --fingerprint yourDockerImageFingerprint --type customTypeName --name yourAttestationName --attestation-data yourJsonFilePath ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom --type customTypeName --name yourAttestationName --attestation-data yourJsonFilePath ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom --type customTypeName --name yourTemplateArtifactName.yourAttestationName --attestation-data yourJsonFilePath --commit yourArtifactGitCommit ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom --type customTypeName --name yourAttestationName --attestation-data yourJsonFilePath --attachments yourAttachmentPathName ``` # kosli attest decision Source: https://docs.kosli.com/client_reference/kosli_attest_decision Record a compliance decision against a control in a Kosli trail. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest decision [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Record a compliance decision against a control in a Kosli trail.\ Use this command to record the outcome of evaluating a control as part of your delivery pipeline — whether it was satisfied or not — attached to a specific trail with an optional artifact. This decision is the evidence that a governance requirement was assessed. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-C`, `--compliant` | bool | \[defaulted] Whether the attestation is compliant or not. | | `--control` | string | The control identifier being evaluated (e.g. RCTL-043). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for decision | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest decision --name yourAttestationName --control RCTL-043 --compliant=true ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest decision --name yourAttestationName --control RCTL-043 --compliant=false ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest decision --name yourAttestationName --control RCTL-043 --compliant=true --fingerprint yourArtifactFingerprint ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest decision --name yourAttestationName --control RCTL-043 --compliant=true --attachments eval-report.json ``` # kosli attest generic Source: https://docs.kosli.com/client_reference/kosli_attest_generic Report a generic attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a generic attestation to an artifact or a trail in a Kosli flow. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-C`, `--compliant` | bool | \[defaulted] Whether the attestation is compliant or not. (default true) | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for generic | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest generic` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/dashboard/blob/ff9f292e809801d35246183988b7812826bc2760/.github/workflows/main.yml#L198), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/dashboard-ci/trails/ff9f292e809801d35246183988b7812826bc2760?attestation_id=dcf20aee-975c-4b20-9d25-02c789f8). View an example of the `kosli attest generic` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L131), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/d64d2b11879179255f11dc991e81fbaf4a040264?attestation_id=b72fe1fe-90da-4738-a506-d803f5a6). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic yourDockerImageName --artifact-type docker --name yourAttestationName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --fingerprint yourDockerImageFingerprint --name yourAttestationName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --name yourAttestationName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --name yourTemplateArtifactName.yourAttestationName --commit yourArtifactGitCommit ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --name yourAttestationName --attachments yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --name yourAttestationName --compliant=false ``` # kosli attest jira Source: https://docs.kosli.com/client_reference/kosli_attest_jira Report a jira attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a jira attestation to an artifact or a trail in a Kosli flow.\ Parses the given commit's message, current branch name or the content of the `--jira-secondary-source` argument for Jira issue references of the form: 'at least 2 characters long, starting with an uppercase letter project key followed by dash and one or more digits'. Matching is case-insensitive: `proj-42` and `PROJ-42` in a commit message are both recognised and returned as `PROJ-42`. Any token that matches the Jira key format (a word boundary, two or more letters/digits starting with a letter, a dash, and one or more digits) is treated as a candidate, regardless of whether it is an intentional Jira reference. For example, a commit message `see note-1 for context, fixes PROJ-42` will look up both `NOTE-1` and `PROJ-42` in Jira. If `NOTE-1` does not exist, the attestation will be non-compliant even though `PROJ-42` is valid. Use `--jira-project-key` to restrict matching to one or more known project keys and avoid unintended candidates. Any candidate match is automatically excluded if every occurrence in the parsed text is immediately followed by a hyphen and a digit — for example, `CVE-2026-41284` is excluded because `CVE-2026` would be followed by `-4`. This applies across all parsed sources (commit message, branch name, and secondary source). Note: if your Jira project key collides with this pattern (e.g. a project key of `CVE`), an issue reference that happens to be the prefix of a longer hyphenated number (such as a CVE identifier) will be filtered out. Use `--jira-secondary-source` with a different identifier format as a workaround. If you want to restrict the Jira issue matching to a specific project, use the `--jira-project-key` flag to specify your own project key. You can specify multiple project keys if needed. If the `--ignore-branch-match` is set, the branch name is not parsed for a match. The found issue references will be checked against Jira to confirm their existence. The attestation is reported in all cases, and its compliance status depends on referencing existing Jira issues. A reachable but wrong base URL still surfaces as a non-existent issue, because Jira answers 404 both for an issue that does not exist and for one you may not view. A base URL that cannot be reached is reported as not confirmed, with the transport error as the reason. A credential rejection is likewise detected and reported as not confirmed, with a warning identifying the credentials. Use `--debug` to see the status Jira returned per issue. The `--jira-issue-fields` can be used to include fields from the jira issue. By default no fields are included. `*all` will give all fields. Using `--jira-issue-fields "*all" --dry-run` will give you the complete list so you can select the once you need. The issue fields uses the jira API that is documented here: [https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get-request](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get-request) The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :------------------------ | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--assert` | bool | \[optional] Exit with non-zero code if the attestation is non-compliant | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for jira | | `--ignore-branch-match` | bool | Ignore branch name when searching for Jira ticket reference. | | `--jira-api-token` | string | Jira API token (for Jira Cloud) | | `--jira-base-url` | string | The base url for the jira project, e.g. `https://kosli.atlassian.net` | | `--jira-issue-fields` | string | \[optional] The comma separated list of fields to include from the Jira issue. Default no fields are included. '\*all' will give all fields. | | `--jira-pat` | string | Jira personal access token (for self-hosted Jira) | | `--jira-project-key` | strings | \[optional] Jira project key to match against. Can be repeated, or given as a comma-separated list. Defaults to matching any jira project key. | | `--jira-secondary-source` | string | \[optional] An optional string to search for Jira ticket reference, e.g. '`--jira-secondary-source` \$\{\{ github.head\_ref }}' | | `--jira-username` | string | Jira username (for Jira Cloud) | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira yourDockerImageName --artifact-type docker --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --fingerprint yourDockerImageFingerprint --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken --jira-project-key ABC ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken --jira-issue-fields "summary,description,creator" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourTemplateArtifactName.yourAttestationName --commit yourArtifactGitCommit --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken --attachments yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken --assert ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira --name yourAttestationName --jira-secondary-source ${{ github.head_ref }} --jira-base-url https://kosli.atlassian.net --jira-username user@domain.com --jira-api-token yourJiraAPIToken ``` # kosli attest junit Source: https://docs.kosli.com/client_reference/kosli_attest_junit Report a junit attestation to an artifact or a trail in a Kosli flow. JUnit xml files are read from the `--results-dir` directory which defaults to the current directory. The xml files are automati... ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a junit attestation to an artifact or a trail in a Kosli flow. JUnit xml files are read from the `--results-dir` directory which defaults to the current directory. The xml files are automatically uploaded as `--attachments` via the `--upload-results` flag which defaults to `true`. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for junit | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-R`, `--results-dir` | string | \[defaulted] The path to a directory with JUnit test results. By default, the directory will be uploaded to Kosli's evidence vault. (default ".") | | `-T`, `--trail` | string | The Kosli trail name. | | `--upload-results` | bool | \[defaulted] Whether to upload the provided Junit results directory as an attachment to Kosli or not. (default true) | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest junit` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/differ/blob/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de/.github/workflows/main.yml#L101), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de?attestation_id=1143f5cc-9e0e-4bbc-a6bd-be16b348). View an example of the `kosli attest junit` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L126), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/d64d2b11879179255f11dc991e81fbaf4a040264?attestation_id=bea54670-c4f5-4e14-93b1-e234c111). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit yourDockerImageName --artifact-type docker --name yourAttestationName --results-dir yourFolderWithJUnitResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit --fingerprint yourDockerImageFingerprint --name yourAttestationName --results-dir yourFolderWithJUnitResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit --name yourAttestationName --results-dir yourFolderWithJUnitResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit --name yourTemplateArtifactName.yourAttestationName --commit yourArtifactGitCommit --results-dir yourFolderWithJUnitResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit --name yourAttestationName --results-dir yourFolderWithJUnitResults --attachments yourAttachmentPathName ``` # kosli attest pullrequest azure Source: https://docs.kosli.com/client_reference/kosli_attest_pullrequest_azure Report an Azure Devops pull request attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report an Azure Devops pull request attestation to an artifact or a trail in a Kosli flow.\ It checks if a pull request exists for the artifact (based on its git commit) and reports the pull-request attestation to the artifact in Kosli. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--assert` | bool | \[optional] Exit with non-zero code if no pull requests found for the given commit. | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `--azure-org-url` | string | Azure organization url. E.g. `https://dev.azure.com/myOrg` (defaulted if you are running in Azure Devops pipelines: [docs](/integrations/ci_cd) ). | | `--azure-token` | string | Azure Personal Access token. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for azure | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--project` | string | Azure project.(defaulted if you are running in Azure Devops pipelines: [docs](/integrations/ci_cd) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure yourDockerImageName --artifact-type docker --name yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure --fingerprint yourDockerImageFingerprint --name yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure --name yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure --name yourTemplateArtifactName.yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure --name yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository --attachments=yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest azure --name yourTemplateArtifactName.yourAttestationName --azure-org-url https://dev.azure.com/myOrg --project yourAzureDevOpsProject --azure-token yourAzureToken --commit yourGitCommitSha1 --repository yourAzureGitRepository --assert ``` # kosli attest pullrequest bitbucket Source: https://docs.kosli.com/client_reference/kosli_attest_pullrequest_bitbucket Report a Bitbucket pull request attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a Bitbucket pull request attestation to an artifact or a trail in a Kosli flow.\ It checks if a pull request exists for a given merge commit and reports the pull-request attestation to Kosli. Authentication to Bitbucket can be done with an access token (recommended) or an Atlassian API token, passed via --bitbucket-username (your Atlassian account email) and --bitbucket-password. Bitbucket app passwords are no longer supported as of 28 July 2026; replace any app passwords with API tokens. Credentials need to have read access for both repos and pull requests. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :------------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--assert` | bool | \[optional] Exit with non-zero code if no pull requests found for the given commit. | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `--bitbucket-access-token` | string | Bitbucket repo/project/workspace access token. See [Bitbucket access tokens](https://developer.atlassian.com/cloud/bitbucket/rest/intro/#access-tokens) for more details. | | `--bitbucket-password` | string | Bitbucket API token. Bitbucket app passwords are no longer supported as of 28 July 2026. See [Bitbucket authentication](https://developer.atlassian.com/cloud/bitbucket/rest/intro/#authentication) for more details. | | `--bitbucket-username` | string | Bitbucket username (your Atlassian account email when using an API token). Only needed if you use `--bitbucket-password` | | `--bitbucket-workspace` | string | Bitbucket workspace ID. | | `-g`, `--commit` | string | the git merge commit to be checked for associated pull requests. | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for bitbucket | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket yourDockerImageName --artifact-type docker --name yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket --fingerprint yourDockerImageFingerprint --name yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket --name yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket --name yourTemplateArtifactName.yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket --name yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository --attachments=yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest bitbucket --name yourTemplateArtifactName.yourAttestationName --bitbucket-access-token yourBitbucketAccessToken --bitbucket-workspace yourBitbucketWorkspace --commit yourArtifactGitCommit --repository yourBitbucketGitRepository --assert ``` # kosli attest pullrequest github Source: https://docs.kosli.com/client_reference/kosli_attest_pullrequest_github Report a Github pull request attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a Github pull request attestation to an artifact or a trail in a Kosli flow.\ It checks if a pull request exists for a given merge commit and reports the pull-request attestation to Kosli. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--assert` | bool | \[optional] Exit with non-zero code if no pull requests found for the given commit. | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | the git merge commit to be checked for associated pull requests. | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `--github-base-url` | string | \[optional] GitHub base URL (only needed for GitHub Enterprise installations). | | `--github-org` | string | Github organization. (defaulted if you are running in GitHub Actions: [docs](/integrations/ci_cd) ). | | `--github-token` | string | Github token. | | `-h`, `--help` | bool | help for github | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest pullrequest github` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/differ/blob/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de/.github/workflows/main.yml#L81), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de?attestation_id=7cf44301-0ca2-4b1f-9ce2-6f17ee0d). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github yourDockerImageName --artifact-type docker --name yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github --fingerprint yourDockerImageFingerprint --name yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github --name yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github --name yourTemplateArtifactName.yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github --name yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository --attachments=yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest github --name yourTemplateArtifactName.yourAttestationName --github-token yourGithubToken --github-org yourGithubOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository --assert ``` # kosli attest pullrequest gitlab Source: https://docs.kosli.com/client_reference/kosli_attest_pullrequest_gitlab Report a Gitlab merge request attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a Gitlab merge request attestation to an artifact or a trail in a Kosli flow.\ It checks if a merge request exists for a given merge commit and reports the merge request attestation to Kosli. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--assert` | bool | \[optional] Exit with non-zero code if no pull requests found for the given commit. | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | the git merge commit to be checked for associated pull requests. | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `--gitlab-base-url` | string | \[optional] Gitlab base URL (only needed for on-prem Gitlab installations). | | `--gitlab-org` | string | Gitlab organization. (defaulted if you are running in Gitlab Pipelines: [docs](/integrations/ci_cd) ). | | `--gitlab-token` | string | Gitlab token. | | `-h`, `--help` | bool | help for gitlab | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest pullrequest gitlab` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L75), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/d64d2b11879179255f11dc991e81fbaf4a040264?attestation_id=c02a9fb9-70fd-44e8-80f0-ec85ea83). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab yourDockerImageName --artifact-type docker --name yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab --fingerprint yourDockerImageFingerprint --name yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab --name yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab --name yourTemplateArtifactName.yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab --name yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository --attachments=yourAttachmentPathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest pullrequest gitlab --name yourTemplateArtifactName.yourAttestationName --gitlab-token yourGitlabToken --gitlab-org yourGitlabOrg --commit yourArtifactGitCommit --repository yourGithubGitRepository --assert ``` # kosli attest snyk Source: https://docs.kosli.com/client_reference/kosli_attest_snyk Report a snyk attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a snyk attestation to an artifact or a trail in a Kosli flow.\ Only SARIF snyk output is accepted. Snyk output can be for "snyk code test", "snyk container test", or "snyk iac test". The `--scan-results` .json file is analyzed and a summary of the scan results are reported to Kosli. By default, the `--scan-results` .json file is also uploaded to Kosli's evidence vault. You can disable that by setting `--upload-results=false` The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. You can optionally associate the attestation to a git commit using `--commit` (requires access to a git repo). You can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. Note that when the attestation is reported for an artifact that does not yet exist in Kosli, `--commit` is required to facilitate binding the attestation to the right artifact. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for snyk | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-R`, `--scan-results` | string | The path to Snyk scan SARIF results file from 'snyk test' and 'snyk container test'. By default, the Snyk results will be uploaded to Kosli's evidence vault. | | `-T`, `--trail` | string | The Kosli trail name. | | `--upload-results` | bool | \[defaulted] Whether to upload the provided Snyk results file as an attachment to Kosli or not. (default true) | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest snyk` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/snyk-container-test/blob/43373102aa2abee72027e2aba050adea9fdb0173/action.yml#L70), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/2e482ef95263c81570a82f0456b026e29203d550?attestation_id=c4d17fb4-05d2-4894-bca7-f21e56ab). View an example of the `kosli attest snyk` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/a184b5b7d2053ce2b2f7064bf46f0b6f72f9f393/.gitlab/workflows/main.yml#L146), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/a184b5b7d2053ce2b2f7064bf46f0b6f72f9f393?attestation_id=3e9cd5ee-4fd3-403f-ba59-6d431dec). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk yourDockerImageName --artifact-type docker --name yourAttestationName --scan-results yourSnykSARIFScanResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk --fingerprint yourDockerImageFingerprint --name yourAttestationName --scan-results yourSnykSARIFScanResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk --name yourAttestationName --scan-results yourSnykSARIFScanResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk --name yourTemplateArtifactName.yourAttestationName --commit yourArtifactGitCommit --scan-results yourSnykSARIFScanResults ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk --name yourAttestationName --scan-results yourSnykSARIFScanResults --attachments yourEvidencePathName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk --name yourAttestationName --scan-results yourSnykSARIFScanResults --upload-results=false ``` # kosli attest sonar Source: https://docs.kosli.com/client_reference/kosli_attest_sonar Report a SonarQube attestation to an artifact or a trail in a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] ``` Report a SonarQube attestation to an artifact or a trail in a Kosli flow.\ Retrieves results for the specified scan from SonarQube Cloud or SonarQube Server and attests them to Kosli. The results are parsed to find the status of the project's quality gate which is used to determine the attestation's compliance status. Both branch scans and pull request scans are supported. The scan to be retrieved can be specified in three ways: 1. (Default) Using metadata created by the Sonar scanner. By default this is located within a temporary `.scannerwork` folder in the repo base directory. If you have overridden the location of this folder by passing parameters to the Sonar scanner, or are running Kosli's CLI locally outside the repo's base directory, you can provide the correct path using the `--sonar-working-dir` flag. This metadata is generated by a specific scan, allowing Kosli to retrieve the results of that scan. If there are delays in the scan processing (either because the scanned project is very large, or because SonarQube is experiencing processing delays), it may happen that the scan results are not available by the time the attest sonar command is executed. In this case you can use the `--max-wait` flag to retry the command while waiting for the scan to be processed. This flag takes the maximum number of seconds to wait for the results to be available. The Kosli CLI will then attempt to retrieve the scan results until the maximum wait time is reached, with exponential backoff between retries. Once the results are available they are attested to Kosli as usual. 2. Providing the Sonar project key and either the revision or the pull-request ID of the scan (plus the SonarQube server URL if relevant). For branch scans: if running the Kosli CLI in some CI/CD pipeline, the revision is defaulted to the commit SHA. If you are running the command locally, or have overridden the revision in SonarQube via parameters to the Sonar scanner, you can provide the correct revision using the `--sonar-revision` flag. If the scan ran on a branch other than the project's main branch in SonarQube, also provide the branch name using the `--sonar-branch` flag. SonarQube only searches the project's main branch unless told otherwise, so without this flag the scan cannot be found. For pull request scans: provide the pull-request ID using the `--pull-request` flag instead of the revision. Kosli then finds the scan results for the specified project key and revision or pull-request ID. 3. Providing the CE task URL directly via `--sonar-ce-task-url`. The CE task URL can be found in the `report-task.txt` file generated by the Sonar scanner (the `ceTaskUrl` field). This is useful in CI/CD environments where the Sonar scanner and the Kosli CLI run in different containers that do not share a filesystem, making the `report-task.txt` file inaccessible to the CLI. Note that if your project is very large and you are using SonarQube Cloud's automatic analysis, it is possible for the attest sonar command to run before the SonarQube Cloud scan is completed. In this case, we recommend using Kosli's Sonar webhook integration ( [docs](/integrations/sonar/) ) rather than the CLI to attest the scan results. The attestation can be bound to a *trail* using the trail name. The attestation can be bound to an *artifact* in two ways: * using the artifact's SHA256 fingerprint which is calculated (based on the `--artifact-type` flag and the artifact name/path argument) or can be provided directly (with the `--fingerprint` flag). * using the artifact's name in the flow yaml template and the git commit from which the artifact is/will be created. Useful when reporting an attestation before creating/reporting the artifact. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--annotate` | stringToString | \[optional] Annotate the attestation with data using key=value. | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `--attachments` | strings | \[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault. | | `-g`, `--commit` | string | \[conditional] The git commit for which the attestation is associated to. Becomes required when reporting an attestation for an artifact before reporting it to Kosli. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--description` | string | \[optional] attestation description | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact to attach the attestation to. Only required if the attestation is for an artifact and `--artifact-type` and artifact name/path are not used. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for sonar | | `--max-wait` | int | \[optional] Allow the command to wait and retry fetching the scan results from SonarQube, up to the maximum number of seconds provided, with exponential backoff. Useful when using SonarQube's metadata file to retrieve and attest scans that take a long time to process . Defaults to 30 seconds. (default 30) | | `-n`, `--name` | string | The name of the attestation as declared in the flow or trail yaml template. | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--pull-request` | string | \[conditional] The ID of the pull-request. Only required if you want to use the project key/pull-request to get the scan results rather than using Sonar's metadata file. Cannot be used with `--sonar-revision` or `--sonar-branch`. | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--sonar-api-token` | string | \[required] SonarQube API token. | | `--sonar-branch` | string | \[conditional] The name of the branch the SonarQube scan ran on. Only required if you are using the project key/revision to get the scan results and the scan ran on a branch other than the project's main branch in SonarQube. Cannot be used with `--pull-request`. | | `--sonar-ce-task-url` | string | \[conditional] The URL of the SonarQube CE task. Can be used instead of `--sonar-working-dir` when the report-task.txt file is not accessible, e.g. due to container isolation in CI/CD pipelines. | | `--sonar-project-key` | string | \[conditional] The project key of the SonarQube project. Only required if you want to use the project key/revision/pull-request to get the scan results rather than using Sonar's metadata file. | | `--sonar-revision` | string | \[conditional] The revision of the SonarQube project. Only required if you want to use the project key/revision to get the scan results rather than using Sonar's metadata file and you have overridden the default revision, or you aren't using a CI. Defaults to the value of the git commit flag. Cannot be used with `--pull-request`. | | `--sonar-server-url` | string | \[conditional] The URL of your SonarQube server. Only required if you are using SonarQube Server and not using SonarQube's metadata file to get scan results. (default "[https://sonarcloud.io](https://sonarcloud.io)") | | `--sonar-working-dir` | string | \[conditional] The base directory of the repo scanned by SonarQube. Only required if you have overridden the default in the Sonar scanner or you are running the CLI locally in a separate folder from the repo. (default ".scannerwork") | | `-T`, `--trail` | string | The Kosli trail name. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the attestation. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli attest sonar` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/dashboard/blob/ff9f292e809801d35246183988b7812826bc2760/.github/workflows/main.yml#L123), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/dashboard-ci/trails/ff9f292e809801d35246183988b7812826bc2760?attestation_id=6d693383-c6de-4551-8a29-1025803a). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-working-dir yourSonarWorkingDirPath ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-working-dir yourSonarWorkingDirPath --max-wait 60 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-project-key yourSonarProjectKey --sonar-revision yourSonarRevision ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-server-url yourSonarServerURL --sonar-project-key yourSonarProjectKey --sonar-revision yourSonarRevision ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-project-key yourSonarProjectKey --sonar-revision yourSonarRevision --sonar-branch yourSonarBranchName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-project-key yourSonarProjectKey --pull-request yourPullRequestID ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-working-dir yourSonarWorkingDirPath --attachment yourAttachmentPath --max-wait 300 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest sonar --name yourAttestationName --sonar-api-token yourSonarAPIToken --sonar-ce-task-url yourCETaskURL ``` # kosli begin trail Source: https://docs.kosli.com/client_reference/kosli_begin_trail Begin or update a Kosli flow trail. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli begin trail TRAIL-NAME [flags] ``` Begin or update a Kosli flow trail. You can optionally associate the trail to a git commit using `--commit` (requires access to a git repo). And you can optionally redact some of the git commit data sent to Kosli using `--redact-commit-info`. To record repository information, all three of `--repo-id`, `--repo-url`, and `--repository` must be set together. These are automatically set in GitHub Actions, GitLab CI, Bitbucket Pipelines, and Azure DevOps. In other CI systems, set them explicitly to capture repository metadata. `TRAIL-NAME`s must start with a letter or number, and only contain letters, numbers, `.`, `-`, `_`, and `~`. ## Flags | Flag | Type | Description | | :----------------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-g`, `--commit` | string | \[defaulted] The git commit from which the trail is begun. (defaulted in some CIs: [docs](/integrations/ci_cd), otherwise defaults to HEAD ). | | `--description` | string | \[optional] The Kosli trail description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--external-fingerprint` | stringToString | \[optional] A SHA256 fingerprint of an external attachment represented by `--external-url`. The format is label=fingerprint (labels cannot contain '.' or '='). This flag can be set multiple times. There must be an external url with a matching label for each external fingerprint. | | `--external-url` | stringToString | \[optional] Add labeled reference URL for an external resource. The format is label=url (labels cannot contain '.' or '='). This flag can be set multiple times. If the resource is a file or dir, you can optionally add its fingerprint via `--external-fingerprint` | | `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for trail | | `-o`, `--origin-url` | string | \[optional] The url pointing to where the attestation came from or is related. (defaulted to the CI url in some CIs: [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) ). | | `--redact-commit-info` | strings | \[optional] The list of commit info to be redacted before sending to Kosli. Allowed values are one or more of \[author, message, branch]. | | `--repo-id` | string | \[conditional] The stable, unique identifier for the repository in your VCS provider (e.g. a numeric ID). Do not use the repository name as it can change if the repo is renamed. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-provider` | string | \[optional] The source code hosting provider. One of: github, gitlab, bitbucket, bitbucket\_cloud, bitbucket\_dc, azure-devops, azure\_devops\_services, azure\_devops\_server, git, subversion (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. Only used if `--commit` is used or defaulted in CI, see [docs](/integrations/ci_cd/#defaulted-kosli-command-flags-from-ci-variables) . (default ".") | | `--repo-url` | string | \[conditional] The URL of the repository. Must be a valid URL. All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `--repository` | string | \[conditional] The name of the repository (e.g. owner/repo-name). All three of `--repo-id`, `--repo-url` and `--repository` must be set to record repository information (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-f`, `--template-file` | string | \[optional] The path to a yaml template file. | | `-u`, `--user-data` | string | \[optional] The path to a JSON file containing additional data you would like to attach to the flow trail. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli begin trail` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/runner/blob/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9/.github/workflows/main.yml#L78), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/runner-ci/trails/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9?attestation_id=1). View an example of the `kosli begin trail` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L55), which created [this Kosli Event](https://app.kosli.com/cyber-dojo/flows/creator-ci/trails/d64d2b11879179255f11dc991e81fbaf4a040264?attestation_id=1). ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli begin trail yourTrailName --description yourTrailDescription --template-file /path/to/your/template/file.yml --user-data /path/to/your/user-data/file.json ``` # kosli completion Source: https://docs.kosli.com/client_reference/kosli_completion Generate completion script ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli completion [bash|zsh|fish|powershell] ``` To load completions: ### Bash ``` $ source <(kosli completion bash) ``` To load completions for each session, execute once: On Linux: ``` $ kosli completion bash > /etc/bash_completion.d/kosli ``` On macOS: ``` $ kosli completion bash > $(brew --prefix)/etc/bash_completion.d/kosli ``` ### Zsh If shell completion is not already enabled in your environment,\ you will need to enable it. You can execute the following once: ``` $ echo "autoload -U compinit; compinit" >> ~/.zshrc ``` To load completions for each session, execute once: ``` $ kosli completion zsh > "${fpath[1]}/_kosli" ``` You will need to start a new shell for this setup to take effect. ### fish ``` $ kosli completion fish | source ``` To load completions for each session, execute once: ``` $ kosli completion fish > ~/.config/fish/completions/kosli.fish ``` ### PowerShell ``` PS> kosli completion powershell | Out-String | Invoke-Expression ``` To load completions for every new session, run: ``` PS> kosli completion powershell > kosli.ps1 ``` and source this file from your PowerShell profile. ## Flags | Flag | Type | Description | | :------------- | :--- | :------------------ | | `-h`, `--help` | bool | help for completion | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli config Source: https://docs.kosli.com/client_reference/kosli_config Config global Kosli flags values and store them in $HOME/.kosli . ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli config [flags] ``` Config global Kosli flags values and store them in \$HOME/.kosli . Flag values are determined in the following order (highest precedence first): * command line flags on each executed command. * environment variables. * custom config file provided with --config-file flag. * default config file in \$HOME/.kosli You can configure global Kosli flags (the ones that apply to all/most commands) using their dedicated convenience flags (e.g. --org). API tokens are stored in the suitable credentials manager on your machine. Other Kosli flags can be configured using the --set flag which takes a comma-separated list of key=value pairs. Keys correspond to the specific flag name, capitalized. For instance: --flow would be set using --set FLOW=value ## Flags | Flag | Type | Description | | :------------- | :------------- | :--------------------------------------------------------------------------------- | | `-h`, `--help` | bool | help for config | | `--set` | stringToString | \[optional] The key-value pairs to tag the resource with. The format is: key=value | | `--unset` | strings | \[optional] The list of tag keys to remove from the resource. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli config --org=yourOrg --api-token=yourAPIToken --host=https://app.kosli.com --debug=false --max-api-retries=3 --http-proxy=http://192.0.0.1:8080 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli config --set FLOW=yourFlowName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli config --unset FLOW ``` # kosli create api-key Source: https://docs.kosli.com/client_reference/kosli_create_api-key Create an API key for a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create api-key [flags] ``` Create an API key for a service account. The key value is only returned once, at creation time, so make sure to store it securely. ## Flags | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | A description for the API key. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--expires-at` | string | \[optional] When the API key expires. Accepts an epoch timestamp or a date like '2026-06-04', '2026-06-04 15:04:05', or an RFC3339 timestamp. Defaults to no expiry. | | `-h`, `--help` | bool | help for api-key | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-s`, `--service-account` | string | The name of the service account whose API keys are managed. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create api-key --service-account yourServiceAccountName --description "key for CI" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create api-key --service-account yourServiceAccountName --description "key for CI" --expires-at 2026-12-31 ``` # kosli create attestation-type Source: https://docs.kosli.com/client_reference/kosli_create_attestation-type Create or update a Kosli custom attestation type. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type TYPE-NAME [flags] ``` Create or update a Kosli custom attestation type. You can specify attestation type parameters in flags. `TYPE-NAME` must start with a letter or number, and only contain letters, numbers, `.`, `-`, `_`, and `~`. `--schema` is a path to a file containing a JSON schema which will be used to validate attestations made using this type. The schema is used to specify the structure of the attestation data, e.g. any fields that are required or the expected type of the data. See an example schema file [here](https://github.com/cyber-dojo/kosli-attestation-types/blob/f9130c58d3a8151b0b0e7c5db284e4380eb2d2cf/metrics-coverage.schema.json). `--jq` defines an evaluation rule, given in `jq`-format, for this attestation type. The flag can be repeated in order to add additional rules. These rules specify acceptable values for attestation data, e.g. `.age >= 21` or `.failing_tests == 0`. When a custom attestation is reported, the provided data is evaluated according to the rules defined in its attestation-type. All rules must return `true` for the evaluation to pass and the attestation to be determined compliant. `--summary` defines one entry of the summary shown for attestations of this type, given as `'NAME=EXPRESSION'` where the expression is a `jq` expression evaluated against the attestation data. The flag can be repeated to add further entries, which are displayed in the order given, e.g. `--summary "Critical=.critical_count" --summary "Tool=.scanner.name"`. Each value is split on its first `=` only, so `jq` expressions containing `==` are unaffected. `--summary-json` is an alternative to `--summary` for summaries that are easier to express as JSON, given as a JSON array of `\{"name": ..., "expression": ...\}` entries, e.g. `'[\{"name":"Critical","expression":".critical_count"\}]'`. The two summary flags cannot be combined. Attestation types created without a summary fall back to the `jq` evaluation rules checklist. ## Flags | Flag | Type | Description | | :-------------------- | :---------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] The attestation type description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for attestation-type | | `--jq` | stringArray | \[optional] The attestation type evaluation JQ rules. | | `-s`, `--schema` | string | \[optional] Path to the attestation type schema in JSON Schema format. | | `--summary` | stringArray | \[optional] An attestation type summary entry, given as 'NAME=EXPRESSION'. Can be repeated. Cannot be used with `--summary-json`. | | `--summary-json` | string | \[optional] The attestation type summary, given as a JSON array of \{name, expression} entries, e.g. '\[\{"name":"Critical","expression":".critical\_count"}]'. Cannot be used with `--summary`. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli create attestation-type` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/kosli-attestation-types/blob/e115b88d482df7563cb10ac4fe80bdc34aad1209/.github/workflows/main.yml#L50) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type customTypeName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type customTypeName --description "Attest that a person meets the age requirements." --schema person-schema.json --jq ".age >= 18" --jq ".age < 65" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type customTypeName --schema scan-schema.json --summary "Critical=.critical_count" --summary "Tool=.scanner.name" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type customTypeName --schema scan-schema.json --summary-json '[{"name":"Critical","expression":".critical_count"},{"name":"Tool","expression":".scanner.name"}]' ``` # kosli create control Source: https://docs.kosli.com/client_reference/kosli_create_control Create a Kosli control. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create control CONTROL-IDENTIFIER [flags] ``` Create a Kosli control. `CONTROL-IDENTIFIER` must start with a letter or number, and only contain letters, numbers, `.`, `-`, `_`, and `~`. ## Flags | Flag | Type | Description | | :-------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] The control description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for control | | `-n`, `--name` | string | \[required] The control name. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create control yourControlIdentifier --name "Your control name" --description "what this control checks" ``` # kosli create environment Source: https://docs.kosli.com/client_reference/kosli_create_environment Create or update a Kosli environment. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create environment ENVIRONMENT-NAME [flags] ``` Create or update a Kosli environment. `--type` must match the type of environment you wish to record snapshots from. The following types are supported: * k8s - Kubernetes * ecs - Amazon Elastic Container Service * s3 - Amazon S3 object storage * lambda - AWS Lambda serverless * docker - Docker images * azure-apps - Azure app services * server - Generic type * logical - Logical grouping of real environments Logical environments are used for grouping of physical environments. For instance **prod-aws** and **prod-s3** can be grouped into logical environment **prod**. Logical environments are view-only, you can not report snapshots to them. `ENVIRONMENT-NAME`s must start with a letter or number, and only contain letters, numbers, `.`, `-` and `_`. ## Flags | Flag | Type | Description | | :------------------------ | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] The environment description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-h`, `--help` | bool | help for environment | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `--included-environments` | strings | \[optional] Comma separated list of environments to include in logical environment | | `--require-provenance` | bool | \[defaulted] Require provenance for all artifacts running in environment snapshots. (DEPRECATED: this flag is deprecated and will be removed in a future version. Use policies instead.) | | `-t`, `--type` | string | The type of environment. Valid types are: \[K8S, ECS, S3, lambda, server, docker, azure-apps, cloud-run, logical]. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create environment yourEnvironmentName --type K8S --description "my new env" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create environment yourLogicalEnvironmentName --type logical --included-environments realEnv1,realEnv2,realEnv3 --description "my full prod" ``` # kosli create flow Source: https://docs.kosli.com/client_reference/kosli_create_flow Create or update a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow FLOW-NAME [flags] ``` Create or update a Kosli flow. You can specify flow parameters in flags. `FLOW-NAME`s must start with a letter or number, and only contain letters, numbers, `.`, `-`, `_`, and `~`. ## Flags | Flag | Type | Description | | :---------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--description` | string | \[optional] The Kosli flow description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for flow | | `-t`, `--template` | strings | \[defaulted] The comma-separated list of required compliance controls names. | | `-f`, `--template-file` | string | \[optional] The path to a yaml template file. Cannot be used together with `--use-empty-template` | | `--use-empty-template` | bool | Use an empty template for the flow creation without specifying a file. Cannot be used together with `--template` or `--template-file` | | `--visibility` | string | \[deprecated] The visibility of the Kosli flow. This flag is deprecated and will be removed in a future version. (DEPRECATED: this flag is deprecated and will be removed in a future version.) | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli create flow` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/runner/blob/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9/.github/workflows/main.yml#L62) View an example of the `kosli create flow` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/65fd2bfa2478534ea4bc5ccf30f6bfc6aab7550c/.gitlab/workflows/main.yml#L53) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow yourFlowName --description yourFlowDescription --use-empty-template ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow yourFlowName --description yourFlowDescription --template-file /path/to/your/template/file.yml ``` # kosli create policy Source: https://docs.kosli.com/client_reference/kosli_create_policy Create or update a Kosli policy. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create policy POLICY-NAME POLICY-FILE-PATH [flags] ``` Updating policy content creates a new version of the policy. ## Flags | Flag | Type | Description | | :---------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `--comment` | string | \[optional] comment about the change made in a policy file when updating a policy. | | `--description` | string | \[optional] policy description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for policy | | `--type` | string | \[defaulted] the type of policy. One of: \[env] (default "env") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create policy yourPolicyName yourPolicyFile.yml --description yourPolicyDescription --type env ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create policy yourPolicyName yourPolicyFile.yml --description yourPolicyDescription --type env --comment yourChangeComment ``` # kosli create service-account Source: https://docs.kosli.com/client_reference/kosli_create_service-account Create a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create service-account SERVICE-ACCOUNT-NAME [flags] ``` Create a service account. A service account is a non-human identity in your organization. API keys are created separately for it with `kosli create api-key`. ## Flags | Flag | Type | Description | | :-------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] A description for the service account. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for service-account | | `--privilege` | string | The privilege granted to the service account. One of: \[admin, member, snapshotter, reader]. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create service-account yourServiceAccountName --privilege member --description "CI service account" ``` # kosli delete api-key Source: https://docs.kosli.com/client_reference/kosli_delete_api-key Delete one or more API keys for a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete api-key KEY-ID [KEY-ID...] [flags] ``` Delete one or more API keys for a service account. This permanently deletes the API key(s) identified by KEY-ID. Deletion is immediate and cannot be undone. You are asked to confirm before the key is deleted; use `--assume-yes`/`--yes` to skip the confirmation prompt. When stdin is not interactive (e.g. in CI) the prompt cannot be answered and the command fails without deleting anything, so pass `--assume-yes` there. ## Flags | Flag | Type | Description | | :------------------------ | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-y`, `--assume-yes` | bool | \[optional] Skip the confirmation prompt and delete the API key without asking. (alias: `--yes`) | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for api-key | | `-s`, `--service-account` | string | The name of the service account whose API keys are managed. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete api-key yourApiKeyID --service-account yourServiceAccountName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete api-key keyID1 keyID2 --service-account yourServiceAccountName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete api-key yourApiKeyID --service-account yourServiceAccountName --assume-yes ``` # kosli delete service-account Source: https://docs.kosli.com/client_reference/kosli_delete_service-account Delete one or more service accounts. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete service-account SERVICE-ACCOUNT-NAME [SERVICE-ACCOUNT-NAME...] [flags] ``` Delete one or more service accounts. This permanently removes the service account(s) identified by SERVICE-ACCOUNT-NAME from the organization, along with their API keys. Deletion is immediate and cannot be undone. You are asked to confirm before deletion; use `--assume-yes`/`--yes` to skip the confirmation prompt. When stdin is not interactive (e.g. in CI) the prompt cannot be answered and the command fails without deleting anything, so pass `--assume-yes` there. ## Flags | Flag | Type | Description | | :------------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-y`, `--assume-yes` | bool | \[optional] Skip the confirmation prompt and delete the service account without asking. (alias: `--yes`) | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for service-account | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete service-account yourServiceAccountName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete service-account sa1 sa2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli delete service-account yourServiceAccountName --assume-yes ``` # kosli detach-policy Source: https://docs.kosli.com/client_reference/kosli_detach-policy Detach a policy from one or more Kosli environments. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli detach-policy POLICY-NAME [flags] ``` If the environment has no more policies attached to it, then its snapshots' status will become "unknown". ## Flags | Flag | Type | Description | | :-------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--environment` | strings | the list of environment names to detach the policy from | | `-h`, `--help` | bool | help for detach-policy | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli detach-policy yourPolicyName --environment yourFirstEnvironmentName --environment yourSecondEnvironmentName ``` # kosli diff snapshots Source: https://docs.kosli.com/client_reference/kosli_diff_snapshots Diff environment snapshots. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli diff snapshots SNAPPISH_1 SNAPPISH_2 [flags] ``` Diff environment snapshots.\ Specify SNAPPISH\_1 and SNAPPISH\_2 by: * environmentName * the latest snapshot for environmentName, at the time of the request * e.g., **prod** * environmentName#N * the Nth snapshot, counting from 1 * e.g., **prod#42** * environmentName\~N * the Nth snapshot behind the latest, at the time of the request * e.g., **prod\~5** * environmentName@\{YYYY-MM-DDTHH:MM:SS} * the snapshot at specific moment in time in UTC * e.g., **prod@\{2023-10-02T12:00:00}** * environmentName@\{N.`hours|days|weeks|months`.ago} * the snapshot at a time relative to the time of the request * e.g., **prod@\{2.hours.ago}** ## Flags | Flag | Type | Description | | :----------------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for snapshots | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-u`, `--show-unchanged` | bool | \[defaulted] Show the unchanged artifacts present in both snapshots within the diff output. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli diff snapshots' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli diff snapshots aws-beta aws-prod --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "snappish1": { "snapshot_id": "aws-beta#8249", "artifacts": [] }, "snappish2": { "snapshot_id": "aws-prod#5309", "artifacts": [] }, "changed": { "artifacts": [] }, "not-changed": { "artifacts": [ { "fingerprint": "03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:bcac1c1@sha256:03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "most_recent_timestamp": 1788255749, "flow": "differ-ci", "commit_url": "https://github.com/cyber-dojo/differ/commit/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "instance_count": 1 }, { "fingerprint": "06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:84e986a@sha256:06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "most_recent_timestamp": 1788255396, "flow": "saver-ci", "commit_url": "https://github.com/cyber-dojo/saver/commit/84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "instance_count": 1 }, { "fingerprint": "1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:27b3504@sha256:1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "most_recent_timestamp": 1788255750, "flow": "nginx-ci", "commit_url": "https://github.com/cyber-dojo/nginx/commit/27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "instance_count": 1 }, { "fingerprint": "2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:ff9f292@sha256:2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "most_recent_timestamp": 1788255387, "flow": "dashboard-ci", "commit_url": "https://github.com/cyber-dojo/dashboard/commit/ff9f292e809801d35246183988b7812826bc2760", "instance_count": 1 }, { "fingerprint": "28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:a357ebd@sha256:28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "most_recent_timestamp": 1788255750, "flow": "languages-start-points-ci", "commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/a357ebd85acdd54968fa0192405aaf2e289d27c9", "instance_count": 1 }, { "fingerprint": "34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:b12a5c9@sha256:34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "most_recent_timestamp": 1788255398, "flow": "custom-start-points-ci", "commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/b12a5c9b17023462d13e81381a69c7ef05f84dc2", "instance_count": 1 }, { "fingerprint": "36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:cbe481c@sha256:36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "most_recent_timestamp": 1788074889, "flow": "web-ci", "commit_url": "https://github.com/cyber-dojo/web/commit/cbe481c4b842f897e4e9e411cd78461a3a12a334", "instance_count": 3 }, { "fingerprint": "41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:f22a30e@sha256:41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "most_recent_timestamp": 1788255396, "flow": "exercises-start-points-ci", "commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "instance_count": 1 }, { "fingerprint": "6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:90c8d98@sha256:6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "most_recent_timestamp": 1788255396, "flow": "spooler-ci", "commit_url": "https://github.com/cyber-dojo/spooler/commit/90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "instance_count": 1 }, { "fingerprint": "a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:ca65b67@sha256:a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "most_recent_timestamp": 1788255844, "flow": "runner-ci", "commit_url": "https://github.com/cyber-dojo/runner/commit/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "instance_count": 3 }, { "fingerprint": "c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:d64d2b1@sha256:c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "most_recent_timestamp": 1788256052, "flow": "creator-ci", "commit_url": "https://github.com/cyber-dojo/creator/commit/d64d2b11879179255f11dc991e81fbaf4a040264", "instance_count": 1 } ] } } ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli diff snapshots envName~3 envName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli diff snapshots envName1 envName2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli diff snapshots envName1 envName2 --show-unchanged ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli diff snapshots envName@{2.weeks.ago} envName ``` # kosli disable beta Source: https://docs.kosli.com/client_reference/kosli_disable_beta Disable beta features for an organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli disable beta [flags] ``` Disable beta features for an organization. ## Flags | Flag | Type | Description | | :------------- | :--- | :------------ | | `-h`, `--help` | bool | help for beta | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli enable beta Source: https://docs.kosli.com/client_reference/kosli_enable_beta Enable beta features for an organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli enable beta [flags] ``` Enable beta features for an organization. ## Flags | Flag | Type | Description | | :------------- | :--- | :------------ | | `-h`, `--help` | bool | help for beta | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli evaluate input Source: https://docs.kosli.com/client_reference/kosli_evaluate_input Evaluate a local JSON input against a Rego policy. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input [flags] ``` Evaluate a local JSON input against a Rego policy. Read JSON from a file or stdin and evaluate it against a Rego policy. The input file should contain the raw JSON object your policy expects — not the wrapper produced by `--show-input`. Use `jq '.input'` to extract the policy input from a `--show-input --output json` capture. The policy must use `package policy` and define an `allow` rule. An optional `violations` rule (a set of strings) can provide human-readable denial reasons. By default a deny exits with code 1. Pass `--no-assert` to print the verdict and exit 0 even on deny, when this command is feeding another tool as a policy decision point. When `--input-file` is omitted, JSON is read from stdin. Use `--params` to pass configuration data to the policy as `data.params`. This accepts inline JSON or a file reference (`@file.json`). ## Flags | Flag | Type | Description | | :------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `--assert` | bool | \[optional] Exit with a non-zero status when the policy denies. This is the current default; pass `--assert` to lock it in across future releases. | | `-h`, `--help` | bool | help for input | | `-i`, `--input-file` | string | \[optional] Path to a JSON input file. Reads from stdin if omitted. | | `--no-assert` | bool | \[optional] Print the result and always exit 0, even when the policy denies. Use when this command feeds another tool as a policy decision point. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--params` | string | \[optional] Policy parameters as inline JSON or @file.json. Available in policies as data.params. | | `-p`, `--policy` | string | Path or http(s):// URL of a Rego policy to evaluate against the input. | | `--show-input` | bool | \[optional] Include the policy input data in the output. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli evaluate input` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/snyk-scanning/blob/ed3c81d7322bb8058615095f4aab28c147c53933/tests/test_rego_rules.sh#L286) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail TRAIL --flow FLOW --policy allow-all.rego --show-input --output json | jq '.input' > trail-data.json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy policy.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy policy.rego --show-input --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} cat trail-data.json | kosli evaluate input --policy policy.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy policy.rego --params '{"threshold": 3}' ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy policy.rego --params @params.json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy https://policies.example.com/policy.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate input --input-file trail-data.json --policy policy.rego --no-assert ``` # kosli evaluate trail Source: https://docs.kosli.com/client_reference/kosli_evaluate_trail Evaluate a trail against a policy. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail TRAIL-NAME [flags] ``` Evaluate a trail against a policy. Fetch a single trail from Kosli and evaluate it against a Rego policy. The trail data is passed to the policy as `input.trail`. Use `--attestations` to enrich the input with detailed attestation data (e.g. pull request approvers, scan results). Use `--show-input` to inspect the full data structure available to the policy. Use `--output json` for structured output. ## Flags | Flag | Type | Description | | :--------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `--assert` | bool | \[optional] Exit with a non-zero status when the policy denies. This is the current default; pass `--assert` to lock it in across future releases. | | `--attestations` | strings | \[optional] Limit which attestations are included. Plain name for trail-level, dot-qualified (artifact.name) for artifact-level. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for trail | | `--no-assert` | bool | \[optional] Print the result and always exit 0, even when the policy denies. Use when this command feeds another tool as a policy decision point. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--params` | string | \[optional] Policy parameters as inline JSON or @file.json. Available in policies as data.params. | | `-p`, `--policy` | string | Path or http(s):// URL of a Rego policy to evaluate against the trail. | | `--show-input` | bool | \[optional] Include the policy input data in the output. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli evaluate trail` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/snyk-scanning/blob/9cc4c900ed581834931a9596a49b5033b7ffa12f/.github/workflows/artifact_snyk_test.yml#L325) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego --attestations pull-request ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego --show-input --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego --params '{"min_approvers": 2}' ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego --params @params.json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy https://policies.example.com/trail.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail yourTrailName --policy yourPolicyFile.rego --no-assert ``` # kosli evaluate trails Source: https://docs.kosli.com/client_reference/kosli_evaluate_trails Evaluate multiple trails against a policy. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails TRAIL-NAME [TRAIL-NAME...] [flags] ``` Evaluate multiple trails against a policy. Fetch multiple trails from Kosli and evaluate them together against a Rego policy. The trail data is passed to the policy as `input.trails` (an array), unlike `evaluate trail` which passes `input.trail` (a single object). Use `--attestations` to enrich the input with detailed attestation data (e.g. pull request approvers, scan results). Use `--show-input` to inspect the full data structure available to the policy. Use `--output json` for structured output. ## Flags | Flag | Type | Description | | :--------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `--assert` | bool | \[optional] Exit with a non-zero status when the policy denies. This is the current default; pass `--assert` to lock it in across future releases. | | `--attestations` | strings | \[optional] Limit which attestations are included. Plain name for trail-level, dot-qualified (artifact.name) for artifact-level. | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for trails | | `--no-assert` | bool | \[optional] Print the result and always exit 0, even when the policy denies. Use when this command feeds another tool as a policy decision point. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--params` | string | \[optional] Policy parameters as inline JSON or @file.json. Available in policies as data.params. | | `-p`, `--policy` | string | Path or http(s):// URL of a Rego policy to evaluate against the trails. | | `--show-input` | bool | \[optional] Include the policy input data in the output. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy yourPolicyFile.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy yourPolicyFile.rego --attestations pull-request ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy yourPolicyFile.rego --show-input --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy yourPolicyFile.rego --params '{"min_approvers": 2}' ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy https://policies.example.com/trails.rego ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trails yourTrailName1 yourTrailName2 --policy yourPolicyFile.rego --no-assert ``` # kosli fingerprint Source: https://docs.kosli.com/client_reference/kosli_fingerprint Calculate the SHA256 fingerprint of an artifact. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint {IMAGE-NAME | FILE-PATH | DIR-PATH} [flags] ``` Calculate the SHA256 fingerprint of an artifact. Requires `--artifact-type` flag to be set. Artifact type can be one of: "file" for files, "dir" for directories, "oci" for container images in registries or "docker" for local docker images. Fingerprinting container images can be done using the local docker daemon or the fingerprint can be fetched from a remote registry. Note: `--artifact-type=docker` reads the image's repo digest via the local Docker daemon, so the image must have been pushed to or pulled from a registry. A freshly built image (just `docker build`) does not have a repo digest. For images already in a registry, prefer `--artifact-type=oci` to fetch the digest directly from the registry. When fingerprinting a 'dir' artifact, you can exclude certain paths from fingerprint calculation using the `--exclude` flag. Excluded paths are relative to the DIR-PATH and can be literal paths or glob patterns. With a directory structure like this `foo/bar/zam/file.txt` if you are calculating the fingerprint of `foo/bar` you need to exclude `zam/file.txt` which is relative to the DIR-PATH. The supported glob pattern syntax is what is documented here: [https://pkg.go.dev/path/filepath#Match](https://pkg.go.dev/path/filepath#Match) , plus the ability to use recursive globs "\*\*" If the directory structure contains a symbolic link to a *file* (for example, a link 'from/this/file' and a target of 'to/another/file') then: * the name of the link ('from/this/file') *is* included in the fingerprint. * the name of the link ('from/this/file') *is* subject to `.kosli_ignore` entries. * the name of the target ('to/another/file') is *not* included in the fingerprint. * the content of target *is* included in the fingerprint, even if the target is outside the root directory being fingerprinted. If the directory structure contains a symbolic link to a *directory* (for example, a link 'from/this/dir' and a target of 'to/another/dir') then: * the name of the link ('from/this/dir') *is* included in the fingerprint. * the name of the link ('from/this/dir') *is* subject to `.kosli_ignore` entries. * the name of the target ('to/another/dir') *is* included in the fingerprint, even if the target is outside the root directory being fingerprinted. * the name of the target ('to/another/dir') is *not* subject to `.kosli_ignore` entries. * the content of the target is *not* included in the fingerprint. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `-e`, `--e` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. (DEPRECATED: use `-x` instead) | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `-h`, `--help` | bool | help for fingerprint | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli fingerprint` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/snyk-scanning/blob/ed3c81d7322bb8058615095f4aab28c147c53933/.github/workflows/artifact_snyk_test.yml#L179) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type file file.txt ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type dir mydir ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type dir --exclude logs --exclude *.exe mydir ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type dir --exclude **/*.pyc mydir ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} echo bar/file.txt > mydir/.kosli_ignore kosli fingerprint --artifact-type dir mydir ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type docker nginx:latest ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type oci nginx:latest ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli fingerprint --artifact-type oci private:latest \ --registry-username YourUsername \ --registry-password YourPassword ``` # kosli get api-key Source: https://docs.kosli.com/client_reference/kosli_get_api-key Get an API key's metadata for a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get api-key KEY-ID [flags] ``` Get an API key's metadata for a service account. Only the metadata of the API key is returned; the key value itself is never returned (it is only shown once, at creation or rotation time). ## Flags | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for api-key | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-s`, `--service-account` | string | The name of the service account whose API keys are managed. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get api-key yourApiKeyID --service-account yourServiceAccountName ``` # kosli get artifact Source: https://docs.kosli.com/client_reference/kosli_get_artifact Get artifact from a specified flow ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get artifact EXPRESSION [flags] ``` Get artifact from a specified flow You can get an artifact by its fingerprint or by its git commit sha. In case of using the git commit, it is possible to get multiple artifacts matching the git commit. The expected argument is an expression to specify the artifact to get. It has the format `FLOW_NAME``SEPARATOR``COMMIT_SHA1|ARTIFACT_FINGERPRINT` Expression can be specified as follows: * flowName@`fingerprint` artifact with a given fingerprint. The fingerprint can be short or complete. * flowName:`commit_sha` artifact with a given commit SHA. The commit sha can be short or complete. Examples of valid expressions are: * flow\@184c799cd551dd1d8d5c5f9a5d593b2e931f5e36122ee5c793c1d08a19839cc0 * flow\@184c7 * flow:110d048bf1fce72ba546cbafc4427fb21b958dee * flow:110d0 ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for artifact | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-t`, `--trail` | string | \[optional] The Kosli trail name. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get artifact flowName@fingerprint ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get artifact flowName@fingerprint ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get artifact flowName:commitSHA ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get artifact flowName:commitSHA ``` # kosli get attestation Source: https://docs.kosli.com/client_reference/kosli_get_attestation Get an attestation using its name or id. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation [ATTESTATION-NAME] [flags] ``` Get an attestation using its name or id. You can get an attestation from a trail or artifact using its name. The attestation name should be given WITHOUT dot-notation.\ To get an attestation from a trail, specify the trail name using the `--trail` flag.\ To get an attestation from an artifact, specify the artifact fingerprint using the `--fingerprint` flag.\ These flags cannot be used together. In both cases the flow must also be specified using the `--flow` flag.\ If there are multiple attestations with the same name on the trail or artifact, a list of all will be returned. You can also get an attestation by its id using the `--attestation-id` flag. This cannot be used with the attestation name, or any of the `--flow`, `--trail` or `--fingerprint` flags. ## Flags | Flag | Type | Description | | :-------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | | `--attestation-id` | string | \[conditional] The unique identifier of the attestation to retrieve. Cannot be used together with ATTESTATION-NAME. | | `-F`, `--fingerprint` | string | \[conditional] The fingerprint of the artifact for the attestation. Cannot be used together with `--trail` or `--attestation-id`. | | `-f`, `--flow` | string | \[conditional] The name of the Kosli flow for the attestation. Required if ATTESTATION-NAME provided. Cannot be used together with `--attestation-id`. | | `-h`, `--help` | bool | help for attestation | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-t`, `--trail` | string | \[conditional] The name of the Kosli trail for the attestation. Cannot be used together with `--fingerprint` or `--attestation-id`. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli get attestation' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli get attestation snyk-container-scan --flow=differ-ci --fingerprint=0cbbe3a6e73e733e8ca4b8813738d68e824badad0508ff20842832b5143b48c0 --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [ { "schema_version": 2, "attestation_type": "snyk", "attestation_name": "snyk-container-scan", "is_compliant": true, "origin_url": "https://github.com/cyber-dojo/differ/actions/runs/14975901658", "artifact_fingerprint": "0cbbe3a6e73e733e8ca4b8813738d68e824badad0508ff20842832b5143b48c0", "target_artifacts": [ "differ" ], "git_commit_info": { "sha1": "5ccc5c141fdd1fbd97905b7fe0af87e5a592bfb6", "message": "Dockerfile - Automated base-image update (#317)\n\nCo-authored-by: JonJagger@users.noreply.github.com <{{ github.actor }}>", "author": "Jon Jagger ", "branch": "main", "timestamp": 1747062671.0, "url": "https://github.com/cyber-dojo/differ/commit/5ccc5c141fdd1fbd97905b7fe0af87e5a592bfb6" }, "evidence_archive_path": "83acb2bc-2c26-48a7-8b87-90dfcce7/artifact_attestation/05c2fd70-0832-4868-9e56-e268b720/evidence.tgz", "evidence_archive_fingerprint": "8b671e582ee8c9550bb76fb8cef8cb5b4b9f5481737e42f44ad272c931bd82ba", "user_data": {}, "created_at": 1747062776.797778, "processed_snyk_results": { "schema_version": 1, "tool": { "name": "Snyk Container", "version": "1.1296.2" }, "results": [ { "low_count": 0, "medium_count": 0, "high_count": 0 }, { "low_count": 0, "medium_count": 0, "high_count": 0 } ] }, "attestation_id": "f7cd9b3a-2738-47e6-be36-689d511d", "html_url": "https://app.kosli.com/cyber-dojo/flows/differ-ci/trails/5ccc5c141fdd1fbd97905b7fe0af87e5a592bfb6?attestation_id=f7cd9b3a-2738-47e6-be36-689d511d", "flow_name": "differ-ci", "trail_name": "5ccc5c141fdd1fbd97905b7fe0af87e5a592bfb6", "reported_by": "ci-pipelines", "has_audit_package": true, "_links": { "self": { "href": "https://app.kosli.com/api/v2/attestations/cyber-dojo/differ-ci/artifact/0cbbe3a6e73e733e8ca4b8813738d68e824badad0508ff20842832b5143b48c0/snyk-container-scan" }, "evidence": { "href": "https://app.kosli.com/api/v2/attestations/cyber-dojo/differ-ci/trail/5ccc5c141fdd1fbd97905b7fe0af87e5a592bfb6/attestation/f7cd9b3a-2738-47e6-be36-689d511d/evidence" } } } ] ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation attestationName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation attestationName --fingerprint fingerprint ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation --attestation-id attestationID ``` # kosli get attestation-type Source: https://docs.kosli.com/client_reference/kosli_get_attestation-type Get a custom Kosli attestation type. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation-type TYPE-NAME [flags] ``` Get a custom Kosli attestation type.\ The TYPE-NAME can be specified as follows: * customTypeName * Returns the unversioned custom attestation type, containing details of all versions of the type. * e.g. `custom-type` * customTypeName\@vN * Returns the Nth version of the custom attestation type. * If a non-integer version number is given, the unversioned custom attestation type is returned. * e.g. `custom-type@v4` ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for attestation-type | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation-type customTypeName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get attestation-type customTypeName@v1 ``` # kosli get control Source: https://docs.kosli.com/client_reference/kosli_get_control Get a Kosli control. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get control CONTROL-IDENTIFIER [flags] ``` Get a Kosli control. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for control | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get control yourControlIdentifier ``` # kosli get default-org Source: https://docs.kosli.com/client_reference/kosli_get_default-org Get the default organization for the current user. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get default-org [flags] ``` Get the default organization for the current user. The default organization is the one selected by default in the Kosli Web UI when you log in. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for default-org | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get default-org ``` # kosli get environment Source: https://docs.kosli.com/client_reference/kosli_get_environment Get an environment's metadata. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get environment ENVIRONMENT-NAME [flags] ``` Get an environment's metadata. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for environment | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli get environment' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli get environment aws-prod --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "org": "cyber-dojo", "name": "aws-prod", "type": "ECS", "description": "The ECS cluster for production cyber-dojo", "last_modified_at": 1788260398.5436597, "last_reported_at": 1788260398.5436597, "last_changed_at": 1788256325.6192138, "state": true, "include_scaling": false, "tags": { "url": "https://cyber-dojo.org/" }, "policies": [ "production-promotion", "provenance", "pull-request", "snyk-scan-aws-prod", "trail-compliance-aws-prod" ], "included_environments": null } ```
# kosli get flow Source: https://docs.kosli.com/client_reference/kosli_get_flow Get the metadata of a specific flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get flow FLOW-NAME [flags] ``` Get the metadata of a specific flow. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for flow | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli get flow' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli get flow dashboard-ci --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "name": "dashboard-ci", "description": "UX for a group practice dashboard", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: dashboard\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n - name: sonarcloud-scan\n type: sonar\n - name: unit-test\n type: junit\n - name: unit-test-coverage\n type: generic\n", "repo_url": "https://github.com/cyber-dojo/dashboard", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/dashboard", "kind": "build", "env": "aws-beta" } } ```
# kosli get policy Source: https://docs.kosli.com/client_reference/kosli_get_policy Get a policy's metadata. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get policy POLICY-NAME [flags] ``` Get a policy's metadata. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for policy | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli get repo Source: https://docs.kosli.com/client_reference/kosli_get_repo Get a repo for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get repo [REPO-NAME] [flags] ``` Get a repo for an org. The repo is identified either by its name, specified as an argument (e.g. "my-org/my-repo"), or unambiguously by its internal ID via --repo-id. The output includes the repo's internal ID, which is the identifier used to tag the repo (see: kosli tag). Use --provider to disambiguate when multiple repos share the same name across VCS providers. ## Flags | Flag | Type | Description | | :--------------- | :----- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | | `-h`, `--help` | bool | help for repo | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--provider` | string | \[optional] The VCS provider of the repo (e.g. github, gitlab). Required when multiple repos share the same name across providers. | | `--repo-id` | string | \[optional] The repo's internal ID (as shown in the repo output). Identifies the repo unambiguously; cannot be combined with the REPO-NAME argument. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get repo my-org/my-repo ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get repo my-org/my-repo --provider github ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get repo --repo-id yourRepoID ``` # kosli get service-account Source: https://docs.kosli.com/client_reference/kosli_get_service-account Get a service account's metadata. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get service-account SERVICE-ACCOUNT-NAME [flags] ``` Get a service account's metadata. The metadata includes the name, description, privilege, and creation time. The secret values of the account's API keys are never returned. Use `--output json` to get the raw response for scripting. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for service-account | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get service-account yourServiceAccountName ``` # kosli get snapshot Source: https://docs.kosli.com/client_reference/kosli_get_snapshot Get a specified environment snapshot. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot ENVIRONMENT-NAME-OR-EXPRESSION [flags] ``` Get a specified environment snapshot.\ ENVIRONMENT-NAME-OR-EXPRESSION can be specified as follows: * environmentName * the latest snapshot for environmentName, at the time of the request * e.g., **prod** * environmentName#N * the Nth snapshot, counting from 1 * e.g., **prod#42** * environmentName\~N * the Nth snapshot behind the latest, at the time of the request * e.g., **prod\~5** * environmentName@\{YYYY-MM-DDTHH:MM:SS} * the snapshot at specific moment in time in UTC * e.g., **prod@\{2023-10-02T12:00:00}** * environmentName@\{N.`hours|days|weeks|months`.ago} * the snapshot at a time relative to the time of the request * e.g., **prod@\{2.hours.ago}** ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for snapshot | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli get snapshot' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli get snapshot aws-prod --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "index": 5309, "is_latest": true, "next_snapshot_timestamp": null, "artifact_compliance_count": { "true": 11, "false": 0, "null": 0 }, "timestamp": 1788256325.6192138, "type": "ECS", "compliant": true, "html_url": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309", "artifacts": [ { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:d64d2b1@sha256:c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "creationTimestamp": [ 1788256052 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "creator-ci", "git_commit": "d64d2b11879179255f11dc991e81fbaf4a040264", "commit_url": "https://github.com/cyber-dojo/creator/commit/d64d2b11879179255f11dc991e81fbaf4a040264", "html_url": "https://app.kosli.com/cyber-dojo/flows/creator-ci/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=61384b36-4d32-43f2-8d5d-a72e2e7e", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/creator-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/creator/compare/83357f112ef5c10b157cb84732c77965cc8ddc48...d64d2b11879179255f11dc991e81fbaf4a040264", "previous_git_commit": "83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_fingerprint": "adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:83357f1@sha256:adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/creator/commit/83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_trail_name": "83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_template_reference_name": "creator" }, "commit_lead_time": 420668.0, "flows": [ { "flow_name": "creator-ci", "trail_name": "d64d2b11879179255f11dc991e81fbaf4a040264", "template_reference_name": "creator", "git_commit": "d64d2b11879179255f11dc991e81fbaf4a040264", "commit_url": "https://github.com/cyber-dojo/creator/commit/d64d2b11879179255f11dc991e81fbaf4a040264", "git_commit_info": { "sha1": "d64d2b11879179255f11dc991e81fbaf4a040264", "message": "Merge update-base-image into main (#56)\n\n* Dockerfile - Automated base-image update\n\n* Make the test harness work on the simplecov the new base image carries\n\n The automated base-image bump brings simplecov 0.21.2 -> 1.1.1, and\n three things here were written against the older one. Only the first\n fails the build; the other two announce themselves on stderr every run.\n\n simplecov_json.rb reopened SimpleCov::Formatter::JSONFormatter to\n redefine format. In 1.1.1 that class defines format itself, so ruby -w\n reports the redefinition twice and test_log_warnings goes from 0 to 2.\n It is now CoverageMetricsFormatter, named for the coverage_metrics.json\n it writes, which is the same name runner gives the same job. It never\n needed to be that class: what it produces is per-group totals, not the\n per-file shape the shipped formatter writes, so it was only borrowing\n the name to make itself win.\n\n SimpleCov.add_group is deprecated in favour of group. The block\n parameter goes from src to path while passing, since it is a source\n file in both groups and src said otherwise in the test one.\n\n # :nocov: is deprecated in favour of # simplecov:disable / :enable. The\n pair wrapping id58_test_base.rb is the only one in the repo.\n\n Coverage is unchanged: code.lines.total 526, test.lines.total 677,\n nothing missed in either. coverage.rb already cleared filters, so the\n test group survived 1.1.1 tightening the default test_frameworks skip\n to an anchored regex, which is what caught start-points-base out.\n\n---------\n\nCo-authored-by: JonJagger ", "author": "Jon Jagger ", "branch": "", "timestamp": 1787835384.0, "url": "https://github.com/cyber-dojo/creator/commit/d64d2b11879179255f11dc991e81fbaf4a040264" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/creator-ci/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=61384b36-4d32-43f2-8d5d-a72e2e7e", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/creator-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/creator/compare/83357f112ef5c10b157cb84732c77965cc8ddc48...d64d2b11879179255f11dc991e81fbaf4a040264", "previous_git_commit": "83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_fingerprint": "adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:83357f1@sha256:adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/creator/commit/83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_trail_name": "83357f112ef5c10b157cb84732c77965cc8ddc48", "previous_template_reference_name": "creator" }, "commit_lead_time": 420668.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "template_reference_name": "creator", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=5d73a605-4286-4a94-be8c-e2262a67", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:83357f1@sha256:adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "creator-adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_template_reference_name": "creator" }, "commit_lead_time": 594065.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "creator", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=615d01cb-77c4-4429-9531-60460983", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:83357f1@sha256:adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "creator" }, "commit_lead_time": 2939058.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "creator-c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "template_reference_name": "creator", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=d4d51513-4c22-4eb3-b8b3-caa88478", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/7172cc22125f480a9f12127edb481a4d84aabea3...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "7172cc22125f480a9f12127edb481a4d84aabea3", "previous_fingerprint": "e8b5e25c5550658cdbd2b8339684b18bce86aaf6538611124ff62f2582c2e5b6", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:a288de5@sha256:e8b5e25c5550658cdbd2b8339684b18bce86aaf6538611124ff62f2582c2e5b6", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/7172cc22125f480a9f12127edb481a4d84aabea3", "previous_trail_name": "creator-e8b5e25c5550658cdbd2b8339684b18bce86aaf6538611124ff62f2582c2e5b6", "previous_template_reference_name": "creator" }, "commit_lead_time": 594065.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/3497b80bc2ff41e792b5ca4a833882fc", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:27b3504@sha256:1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "creationTimestamp": [ 1788255750 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "nginx-ci", "git_commit": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "commit_url": "https://github.com/cyber-dojo/nginx/commit/27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "html_url": "https://app.kosli.com/cyber-dojo/flows/nginx-ci/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=9045bb07-ea42-482f-99c3-4fe5b86f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/nginx-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/nginx/compare/fb791742054fa28dd89269aac8002ebfd7b3386e...27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "previous_git_commit": "fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_fingerprint": "b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:fb79174@sha256:b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/nginx/commit/fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_trail_name": "fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_template_reference_name": "nginx" }, "commit_lead_time": 1790.0, "flows": [ { "flow_name": "nginx-ci", "trail_name": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "template_reference_name": "nginx", "git_commit": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "commit_url": "https://github.com/cyber-dojo/nginx/commit/27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "git_commit_info": { "sha1": "27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "message": "Merge pull request #169 from cyber-dojo/run-workflow-to-pick-up-fixes-to-snyk-vulns\n\nRun workflow to pick up fixes to new snyk vulns", "author": "Jon Jagger ", "branch": "", "timestamp": 1788253960.0, "url": "https://github.com/cyber-dojo/nginx/commit/27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/nginx-ci/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=9045bb07-ea42-482f-99c3-4fe5b86f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/nginx-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/nginx/compare/fb791742054fa28dd89269aac8002ebfd7b3386e...27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "previous_git_commit": "fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_fingerprint": "b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:fb79174@sha256:b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/nginx/commit/fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_trail_name": "fb791742054fa28dd89269aac8002ebfd7b3386e", "previous_template_reference_name": "nginx" }, "commit_lead_time": 1790.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "template_reference_name": "nginx", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=d14d27b1-2d09-43a9-bf35-f58f3164", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:fb79174@sha256:b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "nginx-b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_template_reference_name": "nginx" }, "commit_lead_time": 593763.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "nginx", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=1b78fe0b-61c8-4e00-bc5a-d54ae788", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:fb79174@sha256:b70ff1f9493f5d4205e0e95e565b3fc4d909de237b10e490b250671d0d6895cf", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "nginx" }, "commit_lead_time": 2938756.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "nginx-1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "template_reference_name": "nginx", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=c340a947-0136-4de1-acc8-2a89f741", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "b7ff2cf22c934716a4280f0450ae52fe822cda7fce7fc5488bf62853860cddc8", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:7065268@sha256:b7ff2cf22c934716a4280f0450ae52fe822cda7fce7fc5488bf62853860cddc8", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "nginx-b7ff2cf22c934716a4280f0450ae52fe822cda7fce7fc5488bf62853860cddc8", "previous_template_reference_name": "nginx" }, "commit_lead_time": 593763.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/675ca6104c294b369094b918f30ab6b9", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:a357ebd@sha256:28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "creationTimestamp": [ 1788255750 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "languages-start-points-ci", "git_commit": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/a357ebd85acdd54968fa0192405aaf2e289d27c9", "html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points-ci/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=8e028a8d-a1f2-4732-8663-47012b29", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/languages-start-points/compare/068b3424c7da843a4f2d428d2e4915f33efc4a02...a357ebd85acdd54968fa0192405aaf2e289d27c9", "previous_git_commit": "068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_fingerprint": "adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:068b342@sha256:adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_trail_name": "068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_template_reference_name": "languages-start-points" }, "commit_lead_time": 10038.0, "flows": [ { "flow_name": "languages-start-points-ci", "trail_name": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "template_reference_name": "languages-start-points", "git_commit": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/a357ebd85acdd54968fa0192405aaf2e289d27c9", "git_commit_info": { "sha1": "a357ebd85acdd54968fa0192405aaf2e289d27c9", "message": "Merge pull request #252 from cyber-dojo/speed-updates-to-slowest-ltfs\n\nSpeed updates to the slowest LTFs", "author": "Jon Jagger ", "branch": "", "timestamp": 1788245712.0, "url": "https://github.com/cyber-dojo/languages-start-points/commit/a357ebd85acdd54968fa0192405aaf2e289d27c9" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points-ci/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=8e028a8d-a1f2-4732-8663-47012b29", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/languages-start-points/compare/068b3424c7da843a4f2d428d2e4915f33efc4a02...a357ebd85acdd54968fa0192405aaf2e289d27c9", "previous_git_commit": "068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_fingerprint": "adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:068b342@sha256:adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_trail_name": "068b3424c7da843a4f2d428d2e4915f33efc4a02", "previous_template_reference_name": "languages-start-points" }, "commit_lead_time": 10038.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "template_reference_name": "languages-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=8b7fa132-7335-4301-a248-b13e4286", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:068b342@sha256:adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "languages-start-points-adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_template_reference_name": "languages-start-points" }, "commit_lead_time": 593763.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "languages-start-points", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=790a39b3-0c7c-4220-9d6b-63bff0f3", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:068b342@sha256:adf2596645ae3fe9b711849a2e9aae3a65173b270963e3214b9c7ea00b03c1cb", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "languages-start-points" }, "commit_lead_time": 2938756.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "languages-start-points-28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "template_reference_name": "languages-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=400979c3-f9c3-4652-8b12-2204fabb", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "b2f51324efc1528e4dda57d235bdbc68d966e1ea23722d5d296f98eefbfc2676", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:7e86fed@sha256:b2f51324efc1528e4dda57d235bdbc68d966e1ea23722d5d296f98eefbfc2676", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "languages-start-points-b2f51324efc1528e4dda57d235bdbc68d966e1ea23722d5d296f98eefbfc2676", "previous_template_reference_name": "languages-start-points" }, "commit_lead_time": 593763.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/cbb20953281f4b168eb98575717b01e7", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:b12a5c9@sha256:34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "creationTimestamp": [ 1788255398 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "custom-start-points-ci", "git_commit": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/b12a5c9b17023462d13e81381a69c7ef05f84dc2", "html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points-ci/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=2aa23627-9e91-488e-b3ea-e4bf2e22", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/custom-start-points/compare/790d86b66f4d86ab47f5c521daf5039dc8aeef4d...b12a5c9b17023462d13e81381a69c7ef05f84dc2", "previous_git_commit": "790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_fingerprint": "8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:790d86b@sha256:8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_trail_name": "790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_template_reference_name": "custom-start-points" }, "commit_lead_time": 416881.0, "flows": [ { "flow_name": "custom-start-points-ci", "trail_name": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "template_reference_name": "custom-start-points", "git_commit": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/b12a5c9b17023462d13e81381a69c7ef05f84dc2", "git_commit_info": { "sha1": "b12a5c9b17023462d13e81381a69c7ef05f84dc2", "message": "Merge pull request #143 from cyber-dojo/update-base-image-ce45d62\n\nMerge update-base-image into main", "author": "Jon Jagger ", "branch": "", "timestamp": 1787838517.0, "url": "https://github.com/cyber-dojo/custom-start-points/commit/b12a5c9b17023462d13e81381a69c7ef05f84dc2" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points-ci/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=2aa23627-9e91-488e-b3ea-e4bf2e22", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/custom-start-points/compare/790d86b66f4d86ab47f5c521daf5039dc8aeef4d...b12a5c9b17023462d13e81381a69c7ef05f84dc2", "previous_git_commit": "790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_fingerprint": "8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:790d86b@sha256:8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_trail_name": "790d86b66f4d86ab47f5c521daf5039dc8aeef4d", "previous_template_reference_name": "custom-start-points" }, "commit_lead_time": 416881.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "template_reference_name": "custom-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=b5dae6e2-12e1-47bc-a361-ead8aa3f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:790d86b@sha256:8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "custom-start-points-8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_template_reference_name": "custom-start-points" }, "commit_lead_time": 593411.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "custom-start-points", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=63e61c31-696e-4465-9145-2c51f6d4", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/81c216a55b2cb1787645e699ceaceca868cad253...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "81c216a55b2cb1787645e699ceaceca868cad253", "previous_fingerprint": "8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:790d86b@sha256:8e965dda26af2d2e68032c25d68e792c85e0c7bd9814862de231bc4c6e935b81", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/81c216a55b2cb1787645e699ceaceca868cad253", "previous_trail_name": "promote-all-31", "previous_template_reference_name": "custom-start-points" }, "commit_lead_time": 2938404.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "custom-start-points-34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "template_reference_name": "custom-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=ff77dce2-dd84-40ff-b134-d21758f5", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "b4448ca68a0926e4a7a800f5b101b63e9c2f38e1caaebb7e929d992763570928", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:6b5c159@sha256:b4448ca68a0926e4a7a800f5b101b63e9c2f38e1caaebb7e929d992763570928", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "custom-start-points-b4448ca68a0926e4a7a800f5b101b63e9c2f38e1caaebb7e929d992763570928", "previous_template_reference_name": "custom-start-points" }, "commit_lead_time": 593411.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/b7894ad2c80e4774adbeab8165291101", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:84e986a@sha256:06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "creationTimestamp": [ 1788255396 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "saver-ci", "git_commit": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "commit_url": "https://github.com/cyber-dojo/saver/commit/84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "html_url": "https://app.kosli.com/cyber-dojo/flows/saver-ci/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=a599cb04-5965-46a6-a774-24dc6341", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/saver-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/saver/compare/36f0420f728fe61e44a3ab0043cf9a3d70863cad...84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "previous_git_commit": "36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_fingerprint": "2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:36f0420@sha256:2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/saver/commit/36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_trail_name": "36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_template_reference_name": "saver" }, "commit_lead_time": 3241.0, "flows": [ { "flow_name": "saver-ci", "trail_name": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "template_reference_name": "saver", "git_commit": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "commit_url": "https://github.com/cyber-dojo/saver/commit/84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "git_commit_info": { "sha1": "84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "message": "Run workflow to pick up fixes to expat vulns (#443)", "author": "Jon Jagger ", "branch": "", "timestamp": 1788252155.0, "url": "https://github.com/cyber-dojo/saver/commit/84e986ad70d32e9be362d5bd9ce7c7af94f6eaab" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/saver-ci/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=a599cb04-5965-46a6-a774-24dc6341", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/saver-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/saver/compare/36f0420f728fe61e44a3ab0043cf9a3d70863cad...84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "previous_git_commit": "36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_fingerprint": "2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:36f0420@sha256:2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/saver/commit/36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_trail_name": "36f0420f728fe61e44a3ab0043cf9a3d70863cad", "previous_template_reference_name": "saver" }, "commit_lead_time": 3241.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "template_reference_name": "saver", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=954a634e-bcc4-4aeb-b74a-3228e48f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:36f0420@sha256:2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "saver-2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_template_reference_name": "saver" }, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "saver", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=ad8076c0-8b7e-47ac-b82a-2f2bb220", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:36f0420@sha256:2ec004d6e7c2668ff407b4384d6b4c62f92d9606ae18447c5fb326211921bc6a", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "saver" }, "commit_lead_time": 2938402.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "saver-06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "template_reference_name": "saver", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=91be21a4-68bf-4710-9f74-0c7a5ac5", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "f5909cc8dd53b2105953d1a72cd5d6181367d3588964aa01a04c056205a5d419", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:8c84fac@sha256:f5909cc8dd53b2105953d1a72cd5d6181367d3588964aa01a04c056205a5d419", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "saver-f5909cc8dd53b2105953d1a72cd5d6181367d3588964aa01a04c056205a5d419", "previous_template_reference_name": "saver" }, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/490f2bdcf1a2453db2a23395e26d2392", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:f22a30e@sha256:41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "creationTimestamp": [ 1788255396 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "exercises-start-points-ci", "git_commit": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points-ci/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=aa4300d4-b690-4d71-9596-6af987e1", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/exercises-start-points/compare/258b6d07d2b28ad5cb2ce6d29934997f72380f1a...f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "previous_git_commit": "258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_fingerprint": "c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:258b6d0@sha256:c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_trail_name": "258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_template_reference_name": "exercises-start-points" }, "commit_lead_time": 416885.0, "flows": [ { "flow_name": "exercises-start-points-ci", "trail_name": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "template_reference_name": "exercises-start-points", "git_commit": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "git_commit_info": { "sha1": "f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "message": "Merge pull request #149 from cyber-dojo/update-base-image-ce45d62\n\nMerge update-base-image into main", "author": "Jon Jagger ", "branch": "", "timestamp": 1787838511.0, "url": "https://github.com/cyber-dojo/exercises-start-points/commit/f22a30ed7659b05a88c22e9f22dc2388f2deb8c8" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points-ci/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=aa4300d4-b690-4d71-9596-6af987e1", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/exercises-start-points/compare/258b6d07d2b28ad5cb2ce6d29934997f72380f1a...f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "previous_git_commit": "258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_fingerprint": "c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:258b6d0@sha256:c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_trail_name": "258b6d07d2b28ad5cb2ce6d29934997f72380f1a", "previous_template_reference_name": "exercises-start-points" }, "commit_lead_time": 416885.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "template_reference_name": "exercises-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=f0d94332-8b7c-4437-adf8-dc070a8e", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:258b6d0@sha256:c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "exercises-start-points-c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_template_reference_name": "exercises-start-points" }, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "exercises-start-points", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=edc896a3-98a0-4cb0-8147-49fd6952", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/81c216a55b2cb1787645e699ceaceca868cad253...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "81c216a55b2cb1787645e699ceaceca868cad253", "previous_fingerprint": "c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:258b6d0@sha256:c7b7fd69d904329f9264e111bd3dc63cf98724cce567bae719e79a171e6925ea", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/81c216a55b2cb1787645e699ceaceca868cad253", "previous_trail_name": "promote-all-31", "previous_template_reference_name": "exercises-start-points" }, "commit_lead_time": 2938402.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "exercises-start-points-41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "template_reference_name": "exercises-start-points", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=601099dd-9069-4756-8c33-35cf65e1", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "f00aa234bebafb1980dced29626750f84a6fe6c9c50f6a90167e4d8e6511a8a8", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:b8e5cbf@sha256:f00aa234bebafb1980dced29626750f84a6fe6c9c50f6a90167e4d8e6511a8a8", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "exercises-start-points-f00aa234bebafb1980dced29626750f84a6fe6c9c50f6a90167e4d8e6511a8a8", "previous_template_reference_name": "exercises-start-points" }, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/ca7755573c354bb191fc03f5496f0e7a", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:90c8d98@sha256:6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "creationTimestamp": [ 1788255396 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "spooler-ci", "git_commit": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "commit_url": "https://github.com/cyber-dojo/spooler/commit/90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "html_url": "https://app.kosli.com/cyber-dojo/flows/spooler-ci/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=6df79438-91a2-4c2b-a945-52fb5218", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/spooler-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/spooler/compare/dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb...90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "previous_git_commit": "dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_fingerprint": "ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:dc7dea2@sha256:ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/spooler/commit/dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_trail_name": "dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_template_reference_name": "spooler" }, "commit_lead_time": 352135.0, "flows": [ { "flow_name": "spooler-ci", "trail_name": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "template_reference_name": "spooler", "git_commit": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "commit_url": "https://github.com/cyber-dojo/spooler/commit/90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "git_commit_info": { "sha1": "90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "message": "Merge pull request #18 from cyber-dojo/give-each-saver-forward-its-own-connection\n\nGive each saver forward its own http connection", "author": "Jon Jagger ", "branch": "", "timestamp": 1787903261.0, "url": "https://github.com/cyber-dojo/spooler/commit/90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/spooler-ci/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=6df79438-91a2-4c2b-a945-52fb5218", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/spooler-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/spooler/compare/dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb...90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "previous_git_commit": "dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_fingerprint": "ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:dc7dea2@sha256:ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/spooler/commit/dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_trail_name": "dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb", "previous_template_reference_name": "spooler" }, "commit_lead_time": 352135.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "template_reference_name": "spooler", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=83b85760-e1f3-476b-9925-19541dee", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/10203d5d23f93844726f204390cf3d5ca8d5c913...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "10203d5d23f93844726f204390cf3d5ca8d5c913", "previous_fingerprint": "ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:dc7dea2@sha256:ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/10203d5d23f93844726f204390cf3d5ca8d5c913", "previous_trail_name": "spooler-ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_template_reference_name": "spooler" }, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "spooler", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=fdd39323-ac61-4894-ae67-fc003bac", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:dc7dea2@sha256:ff871c3c8f4b5cfb60012bed1cd7f020b20f17fdabc2db0d8a5c77e75518fce0", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "spooler" }, "commit_lead_time": 2938402.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "spooler-6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "template_reference_name": "spooler", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=24059058-ed02-4061-a4d1-b9a66269", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": null, "commit_lead_time": 593409.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/61175d755bb64c5bba7130b854325414", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:ff9f292@sha256:2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "creationTimestamp": [ 1788255387 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 1, "now": 1 }, "flow_name": "dashboard-ci", "git_commit": "ff9f292e809801d35246183988b7812826bc2760", "commit_url": "https://github.com/cyber-dojo/dashboard/commit/ff9f292e809801d35246183988b7812826bc2760", "html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=aa6c0c1d-2d5d-4c98-9f9d-1160dd2f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/dashboard/compare/2b300f450f72006f6a9000aaf9cd04485f1e8095...ff9f292e809801d35246183988b7812826bc2760", "previous_git_commit": "2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_fingerprint": "1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:2b300f4@sha256:1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/dashboard/commit/2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_trail_name": "2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_template_reference_name": "dashboard" }, "commit_lead_time": 413493.0, "flows": [ { "flow_name": "dashboard-ci", "trail_name": "ff9f292e809801d35246183988b7812826bc2760", "template_reference_name": "dashboard", "git_commit": "ff9f292e809801d35246183988b7812826bc2760", "commit_url": "https://github.com/cyber-dojo/dashboard/commit/ff9f292e809801d35246183988b7812826bc2760", "git_commit_info": { "sha1": "ff9f292e809801d35246183988b7812826bc2760", "message": "Use the simplecov 1.x spellings (#436)\n\n* Use the simplecov 1.x spellings\n\n The base image now carries simplecov 1.1.1 where it carried 0.21.2.\n Four spellings are deprecated there, each announcing itself on stderr on\n every run:\n\n add_group -> group\n add_filter -> skip\n # :nocov: -> # simplecov:disable / # simplecov:enable\n\n and the formatter reopened SimpleCov::Formatter::JSONFormatter to\n redefine format, which in 1.1.1 makes ruby -w report the redefinition.\n It is now CoverageMetricsFormatter, named for the coverage_metrics.json\n it writes. It never needed to be that class: what it produces is\n per-group totals, not the per-file shape the shipped formatter writes,\n so it was only borrowing the name to make itself win.\n\n The three :nocov: pairs are all in source, guarding the post methods\n that only the fixture scripts in test/scripts reach. The comment in\n create_v2_dashboard.rb naming those markers is renamed with them, so it\n still points at something that exists.\n\n source/client/Dockerfile was pinned to cyberdojo/sinatra-base:759c4e9 on\n Docker Hub, while everything else moved to ghcr.io. The automated\n base-image PR only rewrites the Dockerfile at the repo root, so that pin\n had gone unbumped long enough to be several ruby versions behind. It now\n names the same image as the root.\n\n That bump is unverified. The client tests cannot run: the client asks\n for hostname 'server' (source/client/code/external_dashboard.rb) and\n docker-compose.yml calls that service 'dashboard', so its healthcheck\n never resolves. Nothing noticed because no workflow runs them and the\n Makefile has no client target. Left as found, since dashboard is due to\n be merged into web.\n\n The group block parameter goes from the to path while passing.\n\n Coverage is unchanged: test.lines.total 644, code.lines.total 460,\n nothing missed in either.\n\n* Keep the simplecov markers inside the line length, and let rubocop cache\n\n simplecov:disable is seven characters longer than the :nocov: it\n replaced, which took three comment lines past 80 and failed the lint the\n previous commit had no reason to run. The prose those markers carried\n moves to its own line above them, so the marker line is only a marker\n and its length no longer depends on what is being explained.\n\n Separately, rubocop_lint.sh runs the container as the invoking uid,\n which has no entry in the container's /etc/passwd. HOME falls back to /,\n rubocop cannot create /.cache, and it says so once per file inspected -\n 35 lines of it here, and enough to bury the offences it is reporting.\n Naming a writable HOME lets it cache and say nothing.\n\n Neither changes what is inspected: 35 files, no offences, and the tests\n still report 50 runs with coverage on its limits at 644 and 460.", "author": "Jon Jagger ", "branch": "", "timestamp": 1787841894.0, "url": "https://github.com/cyber-dojo/dashboard/commit/ff9f292e809801d35246183988b7812826bc2760" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=aa6c0c1d-2d5d-4c98-9f9d-1160dd2f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/dashboard/compare/2b300f450f72006f6a9000aaf9cd04485f1e8095...ff9f292e809801d35246183988b7812826bc2760", "previous_git_commit": "2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_fingerprint": "1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:2b300f4@sha256:1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/dashboard/commit/2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_trail_name": "2b300f450f72006f6a9000aaf9cd04485f1e8095", "previous_template_reference_name": "dashboard" }, "commit_lead_time": 413493.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "template_reference_name": "dashboard", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=07236a18-f9e6-440c-8163-89b30638", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:2b300f4@sha256:1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "dashboard-1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_template_reference_name": "dashboard" }, "commit_lead_time": 593400.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "dashboard", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=7d30bba6-9d58-403b-b6d8-efe3ebad", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:2b300f4@sha256:1342e060fb8af6c34d004e474544d1472b940250eb0084f206c3d7bf9d78e2b5", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "dashboard" }, "commit_lead_time": 2938393.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "dashboard-2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "template_reference_name": "dashboard", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=95ee902d-ed5f-49ac-a772-a1ea0d78", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "45513c642ba191052bde056d56eeba8b06b0346eb444ec0008bd59bc0581bb8c", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:87f560f@sha256:45513c642ba191052bde056d56eeba8b06b0346eb444ec0008bd59bc0581bb8c", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "dashboard-45513c642ba191052bde056d56eeba8b06b0346eb444ec0008bd59bc0581bb8c", "previous_template_reference_name": "dashboard" }, "commit_lead_time": 593400.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/f61e1822d26f4aa0a417417c3436c569", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:cbe481c@sha256:36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "creationTimestamp": [ 1788074885, 1788074889, 1788074889 ], "pods": null, "annotation": { "type": "updated-provenance", "was": 3, "now": 3 }, "flow_name": "web-ci", "git_commit": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "commit_url": "https://github.com/cyber-dojo/web/commit/cbe481c4b842f897e4e9e411cd78461a3a12a334", "html_url": "https://app.kosli.com/cyber-dojo/flows/web-ci/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=41957e62-eaad-48d2-af40-46879efb", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/web-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/web/compare/5e4b9873df93525c041c386c06e0ab8fc36b6f33...cbe481c4b842f897e4e9e411cd78461a3a12a334", "previous_git_commit": "5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_fingerprint": "6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:5e4b987@sha256:6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/web/commit/5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_trail_name": "5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_template_reference_name": "web" }, "commit_lead_time": 169904.0, "flows": [ { "flow_name": "web-ci", "trail_name": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "template_reference_name": "web", "git_commit": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "commit_url": "https://github.com/cyber-dojo/web/commit/cbe481c4b842f897e4e9e411cd78461a3a12a334", "git_commit_info": { "sha1": "cbe481c4b842f897e4e9e411cd78461a3a12a334", "message": "Match the siblings on test-output buffering and frozen-string comments (#424)\n\nThe tee in the server test run makes ruby block-buffer stdout, so the\n progress dots only appeared once the whole run had finished. saver sets\n $stdout.sync in its own -e script for exactly this reason; web now does\n too.\n\n Every repo already freezes literals globally via RUBYOPT in up.sh, so a\n per-file magic comment buys nothing. runner, creator and differ exclude\n source/ from the cop, while web grandfathered each file in the todo\n instead, which is why the cop fired on the one newly added file.\n Excluding source/ matches them and leaves the todo holding only the bin/\n script that RUBYOPT does not reach.", "author": "Jon Jagger ", "branch": "", "timestamp": 1787904981.0, "url": "https://github.com/cyber-dojo/web/commit/cbe481c4b842f897e4e9e411cd78461a3a12a334" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/web-ci/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=41957e62-eaad-48d2-af40-46879efb", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/web-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/web/compare/5e4b9873df93525c041c386c06e0ab8fc36b6f33...cbe481c4b842f897e4e9e411cd78461a3a12a334", "previous_git_commit": "5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_fingerprint": "6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:5e4b987@sha256:6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/web/commit/5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_trail_name": "5e4b9873df93525c041c386c06e0ab8fc36b6f33", "previous_template_reference_name": "web" }, "commit_lead_time": 169904.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promotion-one-161", "template_reference_name": "web", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=3e754e79-8e4c-486a-ad94-0b183d32", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:5e4b987@sha256:6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "web" }, "commit_lead_time": 2757891.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "template_reference_name": "web", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=14a0333a-7e59-454f-bcfa-f4c2e34b", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:5e4b987@sha256:6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "web-6f394e0dccb59b852fa52ffa114fde8452280054c84de05b0627b1b0f18657bd", "previous_template_reference_name": "web" }, "commit_lead_time": 412898.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "web-36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "template_reference_name": "web", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=d7711381-757a-437c-9c77-55bcfd5f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "29c69c2f30f261a26fff4793fd8ae44b9081def1d4bcaaa27b0fef0501d949e4", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:f66cc5c@sha256:29c69c2f30f261a26fff4793fd8ae44b9081def1d4bcaaa27b0fef0501d949e4", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "web-29c69c2f30f261a26fff4793fd8ae44b9081def1d4bcaaa27b0fef0501d949e4", "previous_template_reference_name": "web" }, "commit_lead_time": 412898.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/d68ae20a684745c6ba576ab68a51dd25", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:ca65b67@sha256:a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "creationTimestamp": [ 1788255749, 1788255749, 1788255844 ], "pods": null, "annotation": { "type": "unchanged", "was": 3, "now": 3 }, "flow_name": "runner-ci", "git_commit": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "commit_url": "https://github.com/cyber-dojo/runner/commit/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "html_url": "https://app.kosli.com/cyber-dojo/flows/runner-ci/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=3b03ceaf-96a6-4afa-8aa2-179e5fe9", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/runner-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/runner/compare/976b63e8001ec7441ebc7737ca69f620d47e7ffe...ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "previous_git_commit": "976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_fingerprint": "01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:976b63e@sha256:01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/runner/commit/976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_trail_name": "976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_template_reference_name": "runner" }, "commit_lead_time": 92169.0, "flows": [ { "flow_name": "runner-ci", "trail_name": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "template_reference_name": "runner", "git_commit": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "commit_url": "https://github.com/cyber-dojo/runner/commit/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "git_commit_info": { "sha1": "ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "message": "Keep the containers stderr empty (#306)\n\n* Run rm and truncate only when the walk finds files\n\n xargs runs its command once even when its input is empty, on GNU\n findutils and busybox alike. Most katas have no binary files and none\n over the size limit, so remove_binary_files and truncate_large_files\n each ran their command with no file operand and it answered with a\n usage error.\n\n That noise went to the container's own stderr, which is the daemon's\n second attach stream. The kata's stderr is a separate thing, arriving\n as tmp/stderr inside the payload, so nothing in the suite looked at\n the stream that carried it.\n\n --no-run-if-empty is the long form of the flag, and both userlands\n accept it, unlike xargs --null.\n\n* Give tar member names it has nothing to strip\n\n The payload's member names are relative: tmp/stdout, and sandbox/...\n for the kata's own files. runner.rb and Sandbox.out read them by those\n names. tar asked to archive an absolute path makes them relative\n itself, by stripping the leading /, and writes a warning about it to\n the container's stderr. Both tar calls in send_tgz() did that, two\n lines each, four on every test-run.\n\n --directory / hands tar names that are already relative to it, so it\n has nothing to strip and nothing to say. The member names are\n unchanged: GNU tar 1.35 in a language image writes the same list\n either way, tmp/stdout through sandbox/sub/b.txt.\n\n c9Gf21 now pins the whole of it, that the container's stderr is empty.\n That stream is the daemon's second attach stream, and separate from\n the kata's own stderr, which arrives as tmp/stderr inside the payload.", "author": "Jon Jagger ", "branch": "", "timestamp": 1788163580.0, "url": "https://github.com/cyber-dojo/runner/commit/ca65b67c3e311fbdd2435609fdb6f8a5479f66f9" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/runner-ci/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=3b03ceaf-96a6-4afa-8aa2-179e5fe9", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/runner-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/runner/compare/976b63e8001ec7441ebc7737ca69f620d47e7ffe...ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "previous_git_commit": "976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_fingerprint": "01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:976b63e@sha256:01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/runner/commit/976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_trail_name": "976b63e8001ec7441ebc7737ca69f620d47e7ffe", "previous_template_reference_name": "runner" }, "commit_lead_time": 92169.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "template_reference_name": "runner", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=e9d1f562-ed75-4e9a-ac28-18bdf67f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/ad256a36cfd9d90f78acbf393e4bff5a2ef45fcf...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "ad256a36cfd9d90f78acbf393e4bff5a2ef45fcf", "previous_fingerprint": "fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:d7541d3@sha256:fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ad256a36cfd9d90f78acbf393e4bff5a2ef45fcf", "previous_trail_name": "runner-fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_template_reference_name": "runner" }, "commit_lead_time": 593762.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "runner", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=95170cfc-5215-420d-a2b0-83fee5dc", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:976b63e@sha256:01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promotion-one-160", "previous_template_reference_name": "runner" }, "commit_lead_time": 2938755.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "runner-a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "template_reference_name": "runner", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=d21568bf-b02a-4532-a725-6fc824a6", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/ed3c81d7322bb8058615095f4aab28c147c53933...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "previous_fingerprint": "fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:d7541d3@sha256:fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "previous_trail_name": "runner-fd8c68c615a68bfa49569beea07d071950dcfeac676028543f530dd7193f5631", "previous_template_reference_name": "runner" }, "commit_lead_time": 593762.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/a8c4fce1500343aa9d5dd37759266af8", "cluster_name": null, "service_name": null } }, { "name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:bcac1c1@sha256:03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "compliant": true, "deployments": [], "policy_decisions": [ { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] } ], "policy_name": "pull-request" }, { "policy_version": 3, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": true, "exceptions": [] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_satisfied", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null, "for_control": "SDLC-CTRL-0002" } } ] } ], "policy_name": "provenance" }, { "policy_version": 4, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null, "for_control": "SDLC-CTRL-0022" } } ] } ], "policy_name": "snyk-scan-aws-prod" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } } ] }, { "rule": { "type": "attestation", "definition": { "if": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] } ], "policy_name": "production-promotion" }, { "policy_version": 2, "status": "COMPLIANT", "rule_evaluations": [ { "rule": { "type": "provenance", "definition": { "required": false, "exceptions": [] } }, "satisfied": null, "ignored": true, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": null } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": null } } ] }, { "rule": { "type": "trail-compliance", "definition": { "required": true, "exceptions": [ { "if": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] } }, "satisfied": true, "ignored": false, "resolutions": [ { "type": "rule_not_applicable", "context": { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "artifact_status": "COMPLIANT" } }, { "type": "rule_not_applicable", "context": { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "production-promotion", "trail_name": "promote-all-34", "artifact_status": "COMPLIANT" } }, { "type": "rule_satisfied", "context": { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "artifact_status": "COMPLIANT" } } ] } ], "policy_name": "trail-compliance-aws-prod" } ], "reasons_for_incompliance": [], "fingerprint": "03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "creationTimestamp": [ 1788255749 ], "pods": null, "annotation": { "type": "unchanged", "was": 1, "now": 1 }, "flow_name": "differ-ci", "git_commit": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "commit_url": "https://github.com/cyber-dojo/differ/commit/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "html_url": "https://app.kosli.com/cyber-dojo/flows/differ-ci/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=11345222-f37a-4f8d-8051-ec26a321", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/differ-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/differ/compare/108cccf9bccf9af5d455db66c250480b53cbecc7...bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "previous_git_commit": "108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_fingerprint": "31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:108cccf@sha256:31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/differ/commit/108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_trail_name": "108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_template_reference_name": "differ" }, "commit_lead_time": 5862.0, "flows": [ { "flow_name": "differ-ci", "trail_name": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "template_reference_name": "differ", "git_commit": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "commit_url": "https://github.com/cyber-dojo/differ/commit/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "git_commit_info": { "sha1": "bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "message": "Rerun workflow to see if it fixes sonar flake (#469)", "author": "Jon Jagger ", "branch": "", "timestamp": 1788249887.0, "url": "https://github.com/cyber-dojo/differ/commit/bcac1c18385b2573ef6c6e8eeae0f62ed14a03de" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/differ-ci/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=11345222-f37a-4f8d-8051-ec26a321", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/differ-ci", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/differ/compare/108cccf9bccf9af5d455db66c250480b53cbecc7...bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "previous_git_commit": "108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_fingerprint": "31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:108cccf@sha256:31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/differ/commit/108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_trail_name": "108cccf9bccf9af5d455db66c250480b53cbecc7", "previous_template_reference_name": "differ" }, "commit_lead_time": 5862.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-beta-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "template_reference_name": "differ", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=c19121c7-2115-4fe0-b472-1d4ea833", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-beta-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/c0666c020044ac5b5181999ec153db1e7f6cd303...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_fingerprint": "31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:108cccf@sha256:31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/c0666c020044ac5b5181999ec153db1e7f6cd303", "previous_trail_name": "differ-31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_template_reference_name": "differ" }, "commit_lead_time": 593762.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "production-promotion", "trail_name": "promote-all-34", "template_reference_name": "differ", "git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "git_commit_info": { "sha1": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "message": "Drop lone use of = separator on Kosli CLI boolean flag", "author": "JonJagger ", "branch": "main", "timestamp": 1785316994.0, "url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=868b85f5-e442-42ac-9474-0cbb1ab3", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/production-promotion", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/compare/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584...7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_git_commit": "7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_fingerprint": "31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:108cccf@sha256:31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/aws-prod-co-promotion/commit/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584", "previous_trail_name": "promote-all-33", "previous_template_reference_name": "differ" }, "commit_lead_time": 2938755.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] }, { "flow_name": "snyk-aws-prod-per-artifact", "trail_name": "differ-03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "template_reference_name": "differ", "git_commit": "ed3c81d7322bb8058615095f4aab28c147c53933", "commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933", "git_commit_info": { "sha1": "ed3c81d7322bb8058615095f4aab28c147c53933", "message": "Unpack one pinned commit instead of fetching each file\n\n a0c005a moved these two jobs' files to RUNNER_TEMP, which kept them out of\n the caller's checkout but left the prefix repeated at every use. The paths\n are absolute because the run steps stay in the checkout, where the Kosli\n CLI reads git commit information from the working directory, so the prefix\n cannot be dropped. It can only be folded into the definitions, and a\n literal /tmp folds where runner.temp does not: the runner context is\n unavailable in workflow- and job-level env blocks. Both jobs are pinned to\n ubuntu-latest, one fresh VM per job, so /tmp neither collides nor persists.\n\n The files also arrived as five separate fetches of main, one per file, so a\n push landing mid-run could pair a rego policy with params from a different\n commit. find-snyk-vulns already checks this repo out, so it now publishes\n the SHA it resolved, and the two later jobs unpack that exact commit as a\n single tarball. One run reads one version.\n\n An env-var's prefix now says where its file came from: SNYK_SCANNING_ from\n this repo at the pinned commit, CALLER_ from the repo being scanned, TMP_\n produced by the run. That split is worth naming because only one of these\n files is the caller's, and it is the one .snyk that the decision attests\n against. Two bare filenames survive because an artifact name cannot\n contain a '/'.\n\n fetch-url-to-file now has exactly one caller, for that .snyk.", "author": "JonJagger ", "branch": "main", "timestamp": 1787661987.0, "url": "https://github.com/cyber-dojo/snyk-scanning/commit/ed3c81d7322bb8058615095f4aab28c147c53933" }, "html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=d014796c-e7b5-4b48-92f7-99ec7f8f", "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/snyk-aws-prod-per-artifact", "deployment_diff": { "diff_url": "https://github.com/cyber-dojo/snyk-scanning/compare/00c479764cb9eca038fdaaaef108672d0bb0ed26...ed3c81d7322bb8058615095f4aab28c147c53933", "previous_git_commit": "00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_fingerprint": "902ec7af03407049ac6e5ef713146d518bbffd9d99cd28715fa0df973e809b7b", "previous_artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:981dcfc@sha256:902ec7af03407049ac6e5ef713146d518bbffd9d99cd28715fa0df973e809b7b", "previous_artifact_compliance_state": "COMPLIANT", "previous_running": false, "previous_git_commit_url": "https://github.com/cyber-dojo/snyk-scanning/commit/00c479764cb9eca038fdaaaef108672d0bb0ed26", "previous_trail_name": "differ-902ec7af03407049ac6e5ef713146d518bbffd9d99cd28715fa0df973e809b7b", "previous_template_reference_name": "differ" }, "commit_lead_time": 593762.0, "artifact_compliance_in_flow": true, "flow_reasons_for_non_compliance": [] } ], "ecs_context": { "task_arn": "arn:aws:ecs:eu-central-1:274425519734:task/app/2e9f021f4b484d48a46dc90a3b172b31", "cluster_name": null, "service_name": null } } ], "applied_policies": [ { "id": "0b0c4d5a-cc1f-4725-8f97-af256289", "name": "pull-request", "version": 3, "policy_dump": { "schema_version": "1", "artifacts": { "provenance": { "required": false, "exceptions": [] }, "trail_compliance": { "required": false, "exceptions": [] }, "attestations": [ { "if_condition": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "pull_request", "must_be_compliant": true, "for_control": null } ] } }, "failing_artifacts": [] }, { "id": "29f67c3c-1c1f-43f8-97e6-165a4080", "name": "provenance", "version": 3, "policy_dump": { "schema_version": "1", "artifacts": { "provenance": { "required": true, "exceptions": [] }, "trail_compliance": { "required": false, "exceptions": [] }, "attestations": [ { "if_condition": { "text": "flow.tags.kind == \"build\"" }, "name": "*", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0002" } ] } }, "failing_artifacts": [] }, { "id": "93d8505f-bce5-4c7c-a2c8-f98236c8", "name": "snyk-scan-aws-prod", "version": 4, "policy_dump": { "schema_version": "1", "artifacts": { "provenance": { "required": false, "exceptions": [] }, "trail_compliance": { "required": false, "exceptions": [] }, "attestations": [ { "if_condition": { "text": "flow.name == \"snyk-aws-prod-per-artifact\"" }, "name": "snyk-container-scan", "type": "decision", "must_be_compliant": true, "for_control": "SDLC-CTRL-0022" } ] } }, "failing_artifacts": [] }, { "id": "bdb8a802-a406-4c76-b289-3fe30be3", "name": "production-promotion", "version": 2, "policy_dump": { "schema_version": "1", "artifacts": { "provenance": { "required": false, "exceptions": [] }, "trail_compliance": { "required": false, "exceptions": [] }, "attestations": [ { "if_condition": { "text": "flow.name == \"production-promotion\"" }, "name": "snyk-scan", "type": "decision", "must_be_compliant": true, "for_control": null } ] } }, "failing_artifacts": [] }, { "id": "ce498d25-69dc-4f30-a71e-aa333990", "name": "trail-compliance-aws-prod", "version": 2, "policy_dump": { "schema_version": "1", "artifacts": { "provenance": { "required": false, "exceptions": [] }, "trail_compliance": { "required": true, "exceptions": [ { "if_condition": { "text": "exists(flow.tags.env) and flow.tags.env != \"aws-prod\"" } } ] }, "attestations": [] } }, "failing_artifacts": [] } ] } ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot yourEnvironmentName~1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot yourEnvironmentName#23 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot yourEnvironmentName@{2023-02-14T12:00:00} ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get snapshot yourEnvironmentName@{3.weeks.ago} ``` # kosli get trail Source: https://docs.kosli.com/client_reference/kosli_get_trail Get the metadata of a specific trail. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get trail TRAIL-NAME [flags] ``` Get the metadata of a specific trail. ## Flags | Flag | Type | Description | | :--------------- | :----- | :---------------------------------------------------------------------------------------------------- | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for trail | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json, markdown]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli get trail' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli get trail dashboard-ci e4757683b74df7033c95aa544a7824b395c2f8bb --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "name": "e4757683b74df7033c95aa544a7824b395c2f8bb", "description": "", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb" }, "origin_url": "https://github.com/cyber-dojo/dashboard/actions/runs/28969474194", "user_data": {}, "repo_ids": [ "4c546fde-c5ee-4a39-b399-8c71d7e1" ], "last_modified_at": 1783538679.7988548, "created_at": 1783538535.1534083, "compliance_status": { "status": "COMPLIANT", "is_compliant": true, "attestations_statuses": [ { "attestation_name": "pull-request", "attestation_type": "pull_request", "attestation_id": "60045efd-1851-45f4-9b27-5f7ae946", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false } ], "artifacts_statuses": { "dashboard": { "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_id": "cc7c618f-d22e-4d95-b6f1-cea4fded", "status": "COMPLIANT", "is_compliant": true, "attestations_statuses": [ { "attestation_name": "provenance-facts", "attestation_type": "custom:provenance-facts", "attestation_id": "8753765c-0df9-421c-bfe3-c8aa1f8d", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "provenance-decision", "attestation_type": "system:decision", "attestation_id": "b0786932-6ff7-4359-bb20-1bb43671", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "sbom-facts", "attestation_type": "custom:sbom-facts", "attestation_id": "7d834d1e-e7de-4890-870c-a783053b", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "sbom-decision", "attestation_type": "system:decision", "attestation_id": "d37cd3aa-3909-4d0d-a8c3-0c623de1", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "snyk-container-scan", "attestation_type": "system:decision", "attestation_id": "2e01c56f-18f9-4e75-8b45-f7d5846e", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "rubocop-lint", "attestation_type": "junit", "attestation_id": "d81b5df8-7c67-42ce-b332-5f10aba5", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "sonarcloud-scan", "attestation_type": "sonar", "attestation_id": "c955d971-4600-4b45-950f-cd8b3642", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "unit-test", "attestation_type": "junit", "attestation_id": "084be09c-f101-4a29-985e-ee305d60", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false }, { "attestation_name": "unit-test-coverage", "attestation_type": "generic", "attestation_id": "ede0b52b-d56e-474f-b04c-03e6be01", "overridden_attestation_id": null, "status": "COMPLETE", "is_compliant": true, "unexpected": false } ], "unexpected": false, "evaluated_at": 1783538679.7988548, "flow_template_id": "cba69d3f-7f48-4e00-9c23-fb63f98d" } }, "evaluated_at": 1783538658.411656, "flow_template_id": "cba69d3f-7f48-4e00-9c23-fb63f98d" }, "template": { "version": 1, "trail": { "attestations": [ { "name": "pull-request", "type": "pull_request" } ], "artifacts": [ { "name": "dashboard", "attestations": [ { "name": "provenance-facts", "type": "custom:provenance-facts" }, { "name": "provenance-decision", "type": "decision" }, { "name": "sbom-facts", "type": "custom:sbom-facts" }, { "name": "sbom-decision", "type": "decision" }, { "name": "snyk-container-scan", "type": "decision" }, { "name": "rubocop-lint", "type": "junit" }, { "name": "sonarcloud-scan", "type": "sonar" }, { "name": "unit-test", "type": "junit" }, { "name": "unit-test-coverage", "type": "generic" } ] } ] }, "content": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: dashboard\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n - name: sonarcloud-scan\n type: sonar\n - name: unit-test\n type: junit\n - name: unit-test-coverage\n type: generic\n" }, "compliance_state": "COMPLIANT", "is_compliant": true, "events": [ { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538535.1534083, "type": "trail_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538535.13884, "tags": {} }, "setting_user_id": "da5d4ee8-aec0-4264-ab85-c491040c", "trail_data_json": { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "name": "e4757683b74df7033c95aa544a7824b395c2f8bb", "creating_user_id": "da5d4ee8-aec0-4264-ab85-c491040c", "description": "", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb" }, "template_id": "cba69d3f-7f48-4e00-9c23-fb63f98d", "origin_url": "https://github.com/cyber-dojo/dashboard/actions/runs/28969474194", "user_data": "{}", "repo_ids": [ "4c546fde-c5ee-4a39-b399-8c71d7e1" ] } }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538554.443048, "type": "trail_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538554.4352667, "tags": {} }, "attestation_type": "pull_request", "is_compliant": true, "attestation_id": "60045efd-1851-45f4-9b27-5f7ae946", "template_reference_name": "pull-request", "is_reattestation": null }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538566.412186, "type": "trail_attestation_for_artifact_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538566.275227, "tags": {} }, "attestation_type": "junit", "is_compliant": true, "attestation_id": "d81b5df8-7c67-42ce-b332-5f10aba5", "template_reference_name": "rubocop-lint", "is_reattestation": null, "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538599.9910955, "type": "artifact_creation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538599.9776034, "tags": {} }, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "artifact_id": "cc7c618f-d22e-4d95-b6f1-cea4fded", "template_reference_name": "dashboard", "git_commit": "e4757683b74df7033c95aa544a7824b395c2f8bb" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538601.4830513, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538601.4712045, "tags": {} }, "attestation_type": "custom:provenance-facts", "is_compliant": true, "attestation_id": "8753765c-0df9-421c-bfe3-c8aa1f8d", "template_reference_name": "provenance-facts", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538605.8901985, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538605.7439284, "tags": {} }, "attestation_type": "system:decision", "is_compliant": true, "attestation_id": "b0786932-6ff7-4359-bb20-1bb43671", "template_reference_name": "provenance-decision", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538607.5449562, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538607.5226355, "tags": {} }, "attestation_type": "custom:sbom-facts", "is_compliant": true, "attestation_id": "7d834d1e-e7de-4890-870c-a783053b", "template_reference_name": "sbom-facts", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538609.6176646, "type": "trail_attestation_for_artifact_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538609.6101015, "tags": {} }, "attestation_type": "sonar", "is_compliant": true, "attestation_id": "c955d971-4600-4b45-950f-cd8b3642", "template_reference_name": "sonarcloud-scan", "is_reattestation": null, "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538612.6819937, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538612.5687785, "tags": {} }, "attestation_type": "system:decision", "is_compliant": true, "attestation_id": "d37cd3aa-3909-4d0d-a8c3-0c623de1", "template_reference_name": "sbom-decision", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538656.9102154, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538656.7741516, "tags": {} }, "attestation_type": "junit", "is_compliant": true, "attestation_id": "084be09c-f101-4a29-985e-ee305d60", "template_reference_name": "unit-test", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538658.411656, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538658.4029927, "tags": {} }, "attestation_type": "generic", "is_compliant": true, "attestation_id": "ede0b52b-d56e-474f-b04c-03e6be01", "template_reference_name": "unit-test-coverage", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538679.7988548, "type": "artifact_attestation_reported", "git_commit_info": { "sha1": "e4757683b74df7033c95aa544a7824b395c2f8bb", "message": "Update kosli template with provenance facts+decision (#414)", "author": "Jon Jagger ", "author_username": null, "branch": "main", "timestamp": 1783538510.0, "url": "https://github.com/cyber-dojo/dashboard/commit/e4757683b74df7033c95aa544a7824b395c2f8bb", "parents": null, "verified": null, "signature_state": null }, "repo_info": { "inner_id": "4c546fde-c5ee-4a39-b399-8c71d7e1", "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "repo_id": "290597708", "name": "cyber-dojo/dashboard", "url": "https://github.com/cyber-dojo/dashboard", "provider": "github", "description": null, "vcs_instance": null, "namespace_path": null, "additional_info": null, "created_at": 1768639963.3866346, "last_modified_at": 1783538679.7007914, "tags": {} }, "attestation_type": "system:decision", "is_compliant": true, "attestation_id": "2e01c56f-18f9-4e75-8b45-f7d5846e", "template_reference_name": "snyk-container-scan", "is_reattestation": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:e475768", "target_artifact": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783538844.1212204, "type": "artifact_started_running", "git_commit_info": null, "repo_info": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "environment_id": "e44779bb-311d-4bac-9d19-a64a0843", "environment_name": "aws-beta", "snapshot_index": 7637, "replica_number": 1, "template_reference_name": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783618198.4632592, "type": "artifact_started_running", "git_commit_info": null, "repo_info": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "environment_id": "73965c45-e9a1-4bb9-ad01-dc5a526f", "environment_name": "aws-prod", "snapshot_index": 4974, "replica_number": 1, "template_reference_name": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1783660164.0318449, "type": "artifact_stopped_running", "git_commit_info": null, "repo_info": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "environment_id": "e44779bb-311d-4bac-9d19-a64a0843", "environment_name": "aws-beta", "snapshot_index": 7657, "template_reference_name": "dashboard" }, { "org_id": "83acb2bc-2c26-48a7-8b87-90dfcce7", "flow_id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "trail_id": "39e622ec-b847-447b-b7f8-7e9ea745", "timestamp": 1784356018.5146132, "type": "artifact_stopped_running", "git_commit_info": null, "repo_info": null, "artifact_fingerprint": "54f6da185cd0f0ef001a0b33c099565fa736546562e0411f706832e72dca47bb", "environment_id": "73965c45-e9a1-4bb9-ad01-dc5a526f", "environment_name": "aws-prod", "snapshot_index": 5044, "template_reference_name": "dashboard" } ], "created_by": "ci-pipelines", "flow": { "name": "dashboard-ci", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/dashboard", "kind": "build", "env": "aws-beta" } }, "external_urls": null, "html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci/trails/e4757683b74df7033c95aa544a7824b395c2f8bb" } ```
# kosli join environment Source: https://docs.kosli.com/client_reference/kosli_join_environment Join a physical environment to a logical environment. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli join environment [flags] ``` Join a physical environment to a logical environment. ## Flags | Flag | Type | Description | | :---------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for environment | | `--logical` | string | \[required] The logical environment. | | `--physical` | string | \[required] The physical environment. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli join environment --physical prod-k8 --logical prod ``` # kosli list api-keys Source: https://docs.kosli.com/client_reference/kosli_list_api-keys List API keys for a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list api-keys [flags] ``` List API keys for a service account. Only the metadata of each active API key is returned; the key values themselves are never listed (they are only shown once, at creation or rotation time). ## Flags | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for api-keys | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-s`, `--service-account` | string | The name of the service account whose API keys are managed. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list api-keys --service-account yourServiceAccountName ``` # kosli list artifacts Source: https://docs.kosli.com/client_reference/kosli_list_artifacts List artifacts in a flow or repo. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list artifacts [flags] ``` List artifacts in a flow or repo. The results are paginated and ordered from latest to oldest. By default, the page limit is 15 artifacts per page. ## Flags | Flag | Type | Description | | :------------------- | :----- | :------------------------------------------------------------------------------------------ | | `-f`, `--flow` | string | The Kosli flow name. | | `-h`, `--help` | bool | help for artifacts | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--repo` | string | \[optional] The name of a git repo as it is registered in Kosli. e.g kosli-dev/cli | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list artifacts ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list artifacts --repo yourRepoName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list artifacts --page-limit 30 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list artifacts --page-limit 30 --output json ``` # kosli list attestation-types Source: https://docs.kosli.com/client_reference/kosli_list_attestation-types List all Kosli attestation types for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list attestation-types [flags] ``` List all Kosli attestation types for an org. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for attestation-types | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli list controls Source: https://docs.kosli.com/client_reference/kosli_list_controls List controls for an org. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls [flags] ``` List controls for an org. The results are paginated; use --page and --page-limit to navigate the pages. ## Flags | Flag | Type | Description | | :------------------- | :---------- | :---------------------------------------------------------------------------------------------------- | | `--archived` | bool | \[optional] List archived controls instead of active ones. | | `-h`, `--help` | bool | help for controls | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--search` | string | \[optional] Only list controls whose name or identifier contains this substring (case-insensitive). | | `--sort-direction` | string | \[optional] The direction to sort controls in. Valid values are: \[asc, desc]. (defaults to asc) | | `--tag` | stringArray | \[optional] Filter by tag, given as 'key' or 'key:value'. Can be repeated to match more than one tag. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls --page 2 --page-limit 10 --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls --search sdlc ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls --tag framework:finos-sdlc ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls --archived ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list controls --sort-direction desc ``` # kosli list environments Source: https://docs.kosli.com/client_reference/kosli_list_environments List environments for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments [flags] ``` List environments for an org. By default, all environments are returned in one response. When --page or --page-limit is set, the results are paginated and the response includes pagination metadata. The list can be filtered by name, type, space and tags, and sorted with --sort and --sort-direction. ## Flags | Flag | Type | Description | | :------------------- | :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-h`, `--help` | bool | help for environments | | `--name` | string | \[optional] Only list environments whose name contains this substring (case-insensitive). | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--sort` | string | \[optional] The field to sort environments by. Valid values are: \[name, last\_modified\_at, last\_changed\_at]. (defaults to name) | | `--sort-direction` | string | \[optional] The direction to sort environments in. Valid values are: \[asc, desc]. (defaults to asc) | | `--space-id` | strings | \[optional] Only list environments in the space with this ID. Can be repeated to match more than one space. | | `--tag` | stringArray | \[optional] Only list environments that have this tag, given as 'key' or 'key:value'. Can be repeated to match more than one tag. | | `--type` | strings | \[optional] Only list environments of this type. Valid types are: \[K8S, ECS, S3, lambda, server, docker, azure-apps, cloud-run, logical]. Can be repeated to match more than one type. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli list environments' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli list environments --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [ { "org": "cyber-dojo", "name": "aws-beta", "type": "ECS", "description": "The ECS cluster for staging cyber-dojo", "last_modified_at": 1788260423.8795948, "last_reported_at": 1788260423.8795948, "last_changed_at": 1788256284.0239065, "state": true, "include_scaling": false, "tags": { "url": "https://beta.cyber-dojo.org/" }, "policies": [ "provenance", "pull-request", "snyk-scan-aws-beta", "trail-compliance-aws-beta" ], "included_environments": null }, { "org": "cyber-dojo", "name": "aws-beta-terraform-drift-detection", "type": "server", "description": "Detection of drift of the Infrastructure-as-code components of aws-beta", "last_modified_at": 1788260408.588247, "last_reported_at": 1788260408.588247, "last_changed_at": 1788254708.6300995, "state": true, "include_scaling": false, "tags": {}, "policies": [ "provenance" ], "included_environments": null }, { "org": "cyber-dojo", "name": "aws-prod", "type": "ECS", "description": "The ECS cluster for production cyber-dojo", "last_modified_at": 1788260398.5436597, "last_reported_at": 1788260398.5436597, "last_changed_at": 1788256325.6192138, "state": true, "include_scaling": false, "tags": { "url": "https://cyber-dojo.org/" }, "policies": [ "production-promotion", "provenance", "pull-request", "snyk-scan-aws-prod", "trail-compliance-aws-prod" ], "included_environments": null }, { "org": "cyber-dojo", "name": "aws-prod-terraform-drift-detection", "type": "server", "description": "Detection of drift of the Infrastructure-as-code components of aws-prod", "last_modified_at": 1788260312.0991778, "last_reported_at": 1788260312.0991778, "last_changed_at": 1788256412.1366148, "state": true, "include_scaling": false, "tags": {}, "policies": [ "provenance" ], "included_environments": null }, { "org": "cyber-dojo", "name": "production", "type": "logical", "description": "Production environments for cyber-dojo", "last_modified_at": 1788256412.1366148, "last_reported_at": null, "last_changed_at": 1788256412.1366148, "state": true, "include_scaling": false, "tags": {}, "policies": null, "included_environments": [ "aws-prod", "aws-prod-terraform-drift-detection" ] }, { "org": "cyber-dojo", "name": "staging", "type": "logical", "description": "Staging environments for cyber-dojo", "last_modified_at": 1788256284.0239065, "last_reported_at": null, "last_changed_at": 1788256284.0239065, "state": true, "include_scaling": false, "tags": {}, "policies": [], "included_environments": [ "aws-beta", "aws-beta-terraform-drift-detection" ] } ] ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --page 2 --page-limit 25 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --name prod --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --type K8S --type ECS --tag team:platform ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --sort last_changed_at --sort-direction desc ``` # kosli list flows Source: https://docs.kosli.com/client_reference/kosli_list_flows List flows for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows [flags] ``` List flows for an org. By default, all flows for the org are returned. Pass --page-limit and/or --page to paginate the results; when pagination is requested the output includes pagination metadata and a page footer (table) or a "data"/"pagination" envelope (JSON). The list can be filtered by name with --name (and --ignore-case for case-insensitive matching). ## Flags | Flag | Type | Description | | :-------------------- | :----- | :---------------------------------------------------------------------------------------------------------------------- | | `-h`, `--help` | bool | help for flows | | `-i`, `--ignore-case` | bool | \[optional] Perform case-insensitive matching for `--name`. By default matching is case sensitive. | | `-N`, `--name` | string | \[optional] Only list flows whose name contains this substring. The Kosli API supports alphanumeric characters and '-'. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 20) | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli list flows' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli list flows --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [ { "id": "e4e08b57-e36e-4724-acc8-04e7e437", "name": "creator-ci", "description": "UX for Group/Kata creation", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: creator\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n - name: unit-test\n type: junit\n - name: unit-test-coverage\n type: generic\n", "repo_url": "https://github.com/cyber-dojo/creator", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/creator", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788256138.680238, "latest_state": "COMPLIANT" }, { "id": "217f4b82-2fe6-41ef-8214-e34c3a47", "name": "custom-start-points-ci", "description": "Custom exercises choices", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: custom-start-points\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n", "repo_url": "https://github.com/cyber-dojo/custom-start-points", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/custom-start-points", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255478.4228623, "latest_state": "COMPLIANT" }, { "id": "f60c8f3f-67cd-4496-8e17-ed6fdb1e", "name": "dashboard-ci", "description": "UX for a group practice dashboard", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: dashboard\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n - name: sonarcloud-scan\n type: sonar\n - name: unit-test\n type: junit\n - name: unit-test-coverage\n type: generic\n", "repo_url": "https://github.com/cyber-dojo/dashboard", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/dashboard", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255478.4228623, "latest_state": "COMPLIANT" }, { "id": "d398561b-b0a9-4f0e-95a3-bbb0e347", "name": "differ-ci", "description": "Diff files from two traffic-lights", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: differ\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n - name: unit-test\n type: junit\n - name: unit-test-metrics\n type: custom:test-metrics\n - name: unit-test-coverage-metrics\n type: custom:coverage-metrics\n - name: integration-test\n type: junit\n - name: integration-test-metrics\n type: custom:test-metrics\n - name: integration-test-coverage-metrics\n type: custom:coverage-metrics\n - name: sonarcloud-scan\n type: sonar\n", "repo_url": "https://github.com/cyber-dojo/differ", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/differ", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255838.4418423, "latest_state": "COMPLIANT" }, { "id": "c1bb83be-5195-4814-9fae-eac6bf67", "name": "exercises-start-points-ci", "description": "Exercises choices", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: exercises-start-points\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n", "repo_url": "https://github.com/cyber-dojo/exercises-start-points", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/exercises-start-points", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255478.4228623, "latest_state": "COMPLIANT" }, { "id": "0b4a3bb0-4f77-41a9-8dea-733d1dc3", "name": "languages-start-points-ci", "description": "Language+TestFramework choices", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: languages-start-points\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n", "repo_url": "https://github.com/cyber-dojo/languages-start-points", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/languages-start-points", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255838.4418423, "latest_state": "COMPLIANT" }, { "id": "d81371fe-6264-4bb1-aace-9b0af86c", "name": "monorepo-co-deployment", "description": "Bind shared commit deployments", "visibility": "private", "org": "cyber-dojo", "template": "version: 1", "repo_url": "https://github.com/cyber-dojo/monorepo", "tags": {}, "latest_activity_at": 1781600733.1821082, "latest_state": "COMPLIANT" }, { "id": "10751390-44e0-4d32-a860-bd5f7584", "name": "monorepo-creator", "description": "UX for Group/Kata creation", "visibility": "public", "org": "cyber-dojo", "template": "\nversion: 1\ntrail:\n attestations:\n - { name: pull-request, type: pull_request }\n artifacts:\n - name: creator\n attestations:\n - { name: unit-test, type: junit }\n", "repo_url": "https://github.com/cyber-dojo/monorepo", "tags": {}, "latest_activity_at": 1781600708.1972978, "latest_state": "COMPLIANT" }, { "id": "0f0e3f56-f7ac-4830-acc3-3a36e111", "name": "monorepo-dashboard", "description": "UX for a group practice dashboard", "visibility": "public", "org": "cyber-dojo", "template": "\nversion: 1\ntrail:\n attestations:\n - { name: pull-request, type: pull_request }\n artifacts:\n - name: dashboard\n attestations:\n - { name: rubocop, type: junit }\n - { name: snyk-container-scan, type: generic }\n", "repo_url": "https://github.com/cyber-dojo/monorepo", "tags": {}, "latest_activity_at": 1781600707.3320358, "latest_state": "COMPLIANT" }, { "id": "c03d5ba2-cb6e-4f6c-a5ec-05805c49", "name": "monorepo-web", "description": "UX for practicing TDD", "visibility": "public", "org": "cyber-dojo", "template": "\nversion: 1\ntrail:\n attestations:\n - { name: pull-request, type: pull_request }\n artifacts:\n - name: web\n attestations:\n - { name: lint, type: generic }\n - { name: unit-test, type: junit }\n", "repo_url": "https://github.com/cyber-dojo/monorepo", "tags": {}, "latest_activity_at": 1781600712.989079, "latest_state": "COMPLIANT" }, { "id": "28447c7d-904b-4594-8b05-88d5d938", "name": "nginx-ci", "description": "Reverse proxy", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: nginx\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n", "repo_url": "https://github.com/cyber-dojo/nginx", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/nginx", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255838.4418423, "latest_state": "COMPLIANT" }, { "id": "d454e45e-3746-417f-992c-e41515d5", "name": "production-promotion", "description": "Promotes sets of Artifacts from aws-beta to aws-prod", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: all-promotions\n type: generic\n", "repo_url": "https://github.com/cyber-dojo/aws-prod-co-promotion", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/aws-prod-co-promotion", "kind": "release", "env": "aws-prod" }, "latest_activity_at": 1788254949.8226013, "latest_state": "COMPLIANT" }, { "id": "4afd2a1f-5045-4145-934a-64b533a6", "name": "production-server-access", "description": "Flow to track production server access", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: command-logs\n type: generic\n - name: user-identity\n type: generic\n - name: service-identity\n type: generic\n - name: sso-session-data\n type: generic\n", "repo_url": "", "tags": {}, "latest_activity_at": 1711724314.4139948, "latest_state": "COMPLIANT" }, { "id": "a81e8c6d-bb00-474f-b986-a6cb9b08", "name": "runner-ci", "description": "Test runner", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: runner\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n\n - name: unit-test\n type: junit\n - name: unit-test-metrics\n type: custom:test-metrics\n - name: unit-test-coverage-metrics\n type: custom:coverage-metrics\n\n - name: integration-test\n type: junit\n - name: integration-test-metrics\n type: custom:test-metrics\n - name: integration-test-coverage-metrics\n type: custom:coverage-metrics\n", "repo_url": "https://github.com/cyber-dojo/runner", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/runner", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255898.5005004, "latest_state": "COMPLIANT" }, { "id": "e54bdf65-de27-448f-807a-08e09590", "name": "saver-ci", "description": "Group/Kata model+persistence", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: saver\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: unit-test\n type: junit\n - name: unit-test-metrics\n type: custom:test-metrics\n - name: unit-test-coverage-metrics\n type: custom:coverage-metrics\n - name: integration-test\n type: junit\n - name: integration-test-metrics\n type: custom:test-metrics\n - name: integration-test-coverage-metrics\n type: custom:coverage-metrics\n\n", "repo_url": "https://github.com/cyber-dojo/saver", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/saver", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788255478.4228623, "latest_state": "COMPLIANT" }, { "id": "9a967617-89c5-4121-ab26-99e1f4ae", "name": "secrets", "description": "Kosli new/expiring secrets check", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations: []\n artifacts:\n - name: artifact\n attestations: []\n", "repo_url": "", "tags": { "ci": "github", "kind": "run", "repo_url": "https://github.com/cyber-dojo/secrets" }, "latest_activity_at": 1788249204.33249, "latest_state": "NON-COMPLIANT" }, { "id": "a43239d6-fa3d-4e58-b7c4-f00b7432", "name": "snyk-aws-beta-per-artifact", "description": "Snyk vulns in aws-beta artifacts", "visibility": "private", "org": "cyber-dojo", "template": "version: 1", "repo_url": "https://github.com/cyber-dojo/snyk-scanning", "tags": { "ci": "github", "kind": "run", "workflow_url": "https://github.com/cyber-dojo/snyk-scanning/blob/main/.github/workflows/aws-beta.yml", "env": "aws-beta" }, "latest_activity_at": 1788254744.4473586, "latest_state": "COMPLIANT" }, { "id": "e0f4dbb0-0d25-44d0-8aa1-ced9876e", "name": "snyk-aws-beta-per-vuln", "description": "Individual Snyk vuln trails for aws-beta artifacts", "visibility": "private", "org": "cyber-dojo", "template": "version: 1", "repo_url": "", "tags": { "ci": "github", "env": "aws-beta", "kind": "run", "workflow_url": "https://github.com/cyber-dojo/snyk-scanning/blob/main/.github/workflows/artifact_snyk_test.yml" }, "latest_activity_at": 1788252975.2436972, "latest_state": "COMPLIANT" }, { "id": "021d42e3-f52e-4e48-959b-33f1fd60", "name": "snyk-aws-prod-per-artifact", "description": "Snyk vulns in aws-prod artifacts", "visibility": "private", "org": "cyber-dojo", "template": "version: 1", "repo_url": "https://github.com/cyber-dojo/snyk-scanning", "tags": { "ci": "github", "kind": "run", "workflow_url": "https://github.com/cyber-dojo/snyk-scanning/blob/main/.github/workflows/aws-prod.yml", "env": "aws-prod" }, "latest_activity_at": 1788256311.5220706, "latest_state": "COMPLIANT" }, { "id": "7fc06a03-241f-4b17-baa1-05cf7585", "name": "snyk-aws-prod-per-vuln", "description": "Individual Snyk vuln trails for aws-prod artifacts", "visibility": "private", "org": "cyber-dojo", "template": "version: 1", "repo_url": "", "tags": { "ci": "github", "env": "aws-prod", "kind": "run", "workflow_url": "https://github.com/cyber-dojo/snyk-scanning/blob/main/.github/workflows/artifact_snyk_test.yml" }, "latest_activity_at": 1788256281.9068878, "latest_state": "COMPLIANT" }, { "id": "6d59cdf1-0d6b-412a-bd81-ecdc8767", "name": "spooler-ci", "description": "Async write spooler: durable, ordered forwarding to saver", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n artifacts:\n - name: spooler\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: unit-test\n type: junit\n - name: unit-test-metrics\n type: custom:test-metrics\n - name: unit-test-coverage-metrics\n type: custom:coverage-metrics\n - name: integration-test\n type: junit\n - name: integration-test-metrics\n type: custom:test-metrics\n - name: integration-test-coverage-metrics\n type: custom:coverage-metrics\n", "repo_url": "https://github.com/cyber-dojo/spooler", "tags": { "env": "aws-beta" }, "latest_activity_at": 1788255478.4228623, "latest_state": "COMPLIANT" }, { "id": "57de7461-f687-4b93-a1d7-d4268e44", "name": "terraform-apply-beta-creator", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/creator", "tags": {}, "latest_activity_at": 1787836208.8569806, "latest_state": "COMPLIANT" }, { "id": "63ea4110-f185-4a04-ae62-8519474b", "name": "terraform-apply-beta-custom-start-points", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/custom-start-points", "tags": {}, "latest_activity_at": 1787839208.4459617, "latest_state": "COMPLIANT" }, { "id": "ceb02030-a523-436d-86a5-c45270dc", "name": "terraform-apply-beta-dashboard", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/dashboard", "tags": {}, "latest_activity_at": 1787843108.7875247, "latest_state": "COMPLIANT" }, { "id": "92d8c902-3dc1-4db5-ad07-6ceabc1e", "name": "terraform-apply-beta-differ", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/differ", "tags": {}, "latest_activity_at": 1788250508.7286773, "latest_state": "COMPLIANT" }, { "id": "3a0768fb-33b4-47f6-ba63-5c69df8e", "name": "terraform-apply-beta-exercises-start-points", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/exercises-start-points", "tags": {}, "latest_activity_at": 1787839208.4459617, "latest_state": "COMPLIANT" }, { "id": "03286d89-1428-4077-9294-fddf609b", "name": "terraform-apply-beta-languages-start-points", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/languages-start-points", "tags": {}, "latest_activity_at": 1788246608.7289636, "latest_state": "COMPLIANT" }, { "id": "152592aa-87a9-46e5-9b4b-2180b0b5", "name": "terraform-apply-beta-nginx", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/nginx", "tags": {}, "latest_activity_at": 1788254708.6300995, "latest_state": "COMPLIANT" }, { "id": "091c0875-2863-48cb-b1f5-e08bb8dd", "name": "terraform-apply-beta-runner", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/runner", "tags": {}, "latest_activity_at": 1788164408.5952742, "latest_state": "COMPLIANT" }, { "id": "348ea96a-84ba-4c17-8ed9-55b397f2", "name": "terraform-apply-beta-saver", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/saver", "tags": {}, "latest_activity_at": 1788252908.7716892, "latest_state": "COMPLIANT" }, { "id": "418dcba5-0f85-44c1-9bfa-73fe61a2", "name": "terraform-apply-beta-spooler", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/spooler", "tags": {}, "latest_activity_at": 1787904009.021726, "latest_state": "COMPLIANT" }, { "id": "0408259b-db9a-47b4-bd5d-2cafb533", "name": "terraform-apply-beta-terraform-base-infra", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n - name: pull-request\n type: pull_request\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/terraform-base-infra", "tags": {}, "latest_activity_at": 1785232808.6739333, "latest_state": "COMPLIANT" }, { "id": "60bfe410-ffe9-421e-a347-0bbd1554", "name": "terraform-apply-beta-web", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/web", "tags": {}, "latest_activity_at": 1787905808.789012, "latest_state": "COMPLIANT" }, { "id": "61ab4b1c-5b59-4f2b-a484-86b887cb", "name": "terraform-apply-prod-aws-prod-co-promotion", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/runner", "tags": {}, "latest_activity_at": 1788256412.1366148, "latest_state": "COMPLIANT" }, { "id": "72787a36-70df-447a-9fae-9c860aa7", "name": "terraform-apply-prod-runner", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/runner", "tags": {}, "latest_activity_at": 1788074911.8576832, "latest_state": "COMPLIANT" }, { "id": "d32a5b61-d72c-4279-824a-55226c4b", "name": "terraform-apply-prod-terraform-base-infra", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n - name: terraform-apply\n type: generic\n - name: pull-request\n type: pull_request\n artifacts:\n - name: terraform-state\n - name: drift-plan\n", "repo_url": "https://github.com/cyber-dojo/terraform-base-infra", "tags": {}, "latest_activity_at": 1785236322.8149745, "latest_state": "COMPLIANT" }, { "id": "cf915667-e09e-4451-b689-8efe0605", "name": "terraform-plan-beta-terraform-base-infra", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n", "repo_url": "", "tags": {}, "latest_activity_at": 1785166016.9913907, "latest_state": "COMPLIANT" }, { "id": "27cb0696-7226-4420-b4c9-b8c91ed7", "name": "terraform-plan-prod-terraform-base-infra", "description": "", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\ntrail:\n attestations:\n - name: terraform-plan\n type: generic\n", "repo_url": "", "tags": {}, "latest_activity_at": 1785232718.7436328, "latest_state": "COMPLIANT" }, { "id": "fd583a48-28de-4b5c-b4a7-b6356e94", "name": "web-ci", "description": "UX for practicing TDD", "visibility": "private", "org": "cyber-dojo", "template": "version: 1\n\ntrail:\n attestations:\n - name: pull-request\n type: pull_request\n\n artifacts:\n - name: web\n attestations:\n - name: provenance-facts\n type: custom:provenance-facts\n - name: provenance-decision\n type: decision\n\n - name: sbom-facts\n type: custom:sbom-facts\n - name: sbom-decision\n type: decision\n\n - name: snyk-container-scan\n type: decision\n\n - name: rubocop-lint\n type: junit\n\n - name: server-test\n type: junit\n\n - name: test-facts\n type: custom:test-facts\n - name: test-decision\n type: decision\n\n - name: coverage-facts\n type: custom:coverage-facts\n - name: coverage-decision\n type: decision\n", "repo_url": "https://github.com/cyber-dojo/web", "tags": { "ci": "github", "repo_url": "https://github.com/cyber-dojo/web", "kind": "build", "env": "aws-beta" }, "latest_activity_at": 1788074998.5362537, "latest_state": "COMPLIANT" } ] ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows --page-limit 30 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows --page-limit 30 --page 2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows --name backend --output json ``` # kosli list policies Source: https://docs.kosli.com/client_reference/kosli_list_policies List environment policies for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list policies [flags] ``` List environment policies for an org. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for policies | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli list repos Source: https://docs.kosli.com/client_reference/kosli_list_repos List repos for an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos [flags] ``` List repos for an org. The results are always paginated: by default the first page is returned with 15 repos per page. Use --page to select a page and --page-limit to change the page size (maximum 50). The list can be filtered by name with --name (exact match), by name substring with \--search (case-insensitive, mutually exclusive with --name), by VCS provider with \--provider, by external repo ID with --repo-id, and by tags with --tag. Results are sorted by repo name; use --sort-direction to choose asc or desc. ## Flags | Flag | Type | Description | | :------------------- | :---------- | :------------------------------------------------------------------------------------------------------------------------- | | `-h`, `--help` | bool | help for repos | | `--name` | string | \[optional] The repo name to filter by (exact match). | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--provider` | string | \[optional] The VCS provider to filter repos by (e.g. github, gitlab). | | `--repo-id` | string | \[optional] The external repo ID to filter repos by. | | `--search` | string | \[optional] Filter repos whose name contains this substring (case-insensitive). Mutually exclusive with `--name`. | | `--sort-direction` | string | \[optional] The direction to sort repos by name. Valid values are: \[asc, desc]. (defaults to asc) | | `--tag` | stringArray | \[optional] Only list repos that have this tag, given as 'key' or 'key:value'. Can be repeated to match more than one tag. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --name my-org/my-repo ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --search cli ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --provider github --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --tag team:platform ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --sort-direction desc ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list repos --page-limit 25 --page 2 ``` # kosli list service-accounts Source: https://docs.kosli.com/client_reference/kosli_list_service-accounts List service accounts in an organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list service-accounts [flags] ``` List service accounts in an organization. Each entry shows the name, description, privilege, and creation time. The secret values of any API keys are never listed. Use `--output json` to get the raw response for scripting. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for service-accounts | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list service-accounts ``` # kosli list snapshots Source: https://docs.kosli.com/client_reference/kosli_list_snapshots List environment snapshots. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list snapshots ENV_NAME [flags] ``` List environment snapshots. The results are paginated and ordered from latest to oldest. By default, the page limit is 15 snapshots per page. You can optionally specify an INTERVAL between two snapshot expressions with \[expression]..\[expression]. Expressions can be: * \~N N'th behind the latest snapshot * N snapshot number N * NOW the latest snapshot Either expression can be omitted to default to NOW. ## Flags | Flag | Type | Description | | :------------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for snapshots | | `-i`, `--interval` | string | \[optional] Expression to define specified snapshots range. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--reverse` | bool | \[optional] Reverse the order of output list. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli list snapshots' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli list snapshots aws-prod --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [ { "index": 5309, "from": 1788256325.6192138, "to": 0.0, "compliant": true, "duration": 4114.5881407260895 }, { "index": 5308, "from": 1788256258.609352, "to": 1788256325.6192138, "compliant": true, "duration": 67.00986170768738 }, { "index": 5307, "from": 1788256138.680238, "to": 1788256258.609352, "compliant": true, "duration": 119.92911410331726 }, { "index": 5306, "from": 1788256078.451175, "to": 1788256138.680238, "compliant": true, "duration": 60.22906303405762 }, { "index": 5305, "from": 1788255898.5005004, "to": 1788256078.451175, "compliant": true, "duration": 179.950674533844 }, { "index": 5304, "from": 1788255838.4418423, "to": 1788255898.5005004, "compliant": true, "duration": 60.05865812301636 }, { "index": 5303, "from": 1788255778.7566388, "to": 1788255838.4418423, "compliant": true, "duration": 59.685203552246094 }, { "index": 5302, "from": 1788255478.4228623, "to": 1788255778.7566388, "compliant": true, "duration": 300.333776473999 }, { "index": 5301, "from": 1788255418.2849495, "to": 1788255478.4228623, "compliant": true, "duration": 60.13791275024414 }, { "index": 5300, "from": 1788254758.42325, "to": 1788255418.2849495, "compliant": true, "duration": 659.8616995811462 }, { "index": 5299, "from": 1788253018.4181795, "to": 1788254758.42325, "compliant": true, "duration": 1740.0050704479218 }, { "index": 5298, "from": 1788251398.4699006, "to": 1788253018.4181795, "compliant": true, "duration": 1619.9482789039612 }, { "index": 5297, "from": 1788245458.5681827, "to": 1788251398.4699006, "compliant": true, "duration": 5939.90171790123 }, { "index": 5296, "from": 1788245398.8278637, "to": 1788245458.5681827, "compliant": true, "duration": 59.74031901359558 }, { "index": 5295, "from": 1788245338.6744468, "to": 1788245398.8278637, "compliant": true, "duration": 60.153416872024536 } ] ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list snapshots yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list snapshots yourEnvironmentName --page-limit 30 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list snapshots yourEnvironmentName --page-limit 30 --output json ``` # kosli list trails Source: https://docs.kosli.com/client_reference/kosli_list_trails List Trails of an org. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails [flags] ``` List Trails of an org.The list can be filtered by flow, flow tag and artifact fingerprint. When multiple filters are provided, only trails matching all specified criteria are returned. The results are paginated and ordered from latest to oldest. ## Flags | Flag | Type | Description | | :-------------------- | :----- | :------------------------------------------------------------------------------------------ | | `-F`, `--fingerprint` | string | \[optional] The SHA256 fingerprint of the artifact to filter trails by. | | `-f`, `--flow` | string | \[optional] The Kosli flow name. | | `-t`, `--flow-tag` | string | \[optional] A key=value flow tag to filter trails by. | | `-h`, `--help` | bool | help for trails | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 20) | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails --page-limit 30 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails --page-limit 30 --page 2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list trails --fingerprint yourArtifactFingerprint --output json # get a paginated list of trails across all flows tagged with the provided key-value pair: kosli list trails --flow-tag team=backend ``` # kosli log environment Source: https://docs.kosli.com/client_reference/kosli_log_environment List environment events. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment ENV_NAME [flags] ``` List environment events. The results are paginated and ordered from latest to oldest. By default, the page limit is 15 events per page. You can optionally specify an INTERVAL between two snapshot expressions with \[expression]..\[expression]. Expressions can be: * \~N N'th behind the latest snapshot * N snapshot number N * NOW the latest snapshot Either expression can be omitted to default to NOW. You can also filter events by range using --start/--end (snapshot index or time expression such as "NOW" or "1hour") or --start-ts/--end-ts (Unix timestamps). ## Flags | Flag | Type | Description | | :------------------- | :------ | :------------------------------------------------------------------------------------------------------------------- | | `--end` | string | \[optional] The end of the events range. Can be a snapshot index (integer) or a time expression (e.g. NOW, 1hour). | | `--end-ts` | float | \[optional] The end of the events range as a Unix timestamp in seconds (integer or float). | | `-h`, `--help` | bool | help for environment | | `-i`, `--interval` | string | \[optional] Expression to define specified snapshots range. | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `--page` | int | \[defaulted] The page number of a response. (default 1) | | `-n`, `--page-limit` | int | \[defaulted] The number of elements per page. (default 15) | | `--repo` | strings | \[optional] The name of a git repo as it is registered in Kosli. e.g kosli-dev/cli | | `--reverse` | bool | \[optional] Reverse the order of output list. | | `--start` | string | \[optional] The start of the events range. Can be a snapshot index (integer) or a time expression (e.g. NOW, 1hour). | | `--start-ts` | float | \[optional] The start of the events range as a Unix timestamp in seconds (integer or float). | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Example To view a live example of 'kosli log environment' you can run the command below (for the [cyber-dojo](https://app.kosli.com/cyber-dojo) demo organization). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_ORG=cyber-dojo # The API token below is read-only export KOSLI_API_TOKEN=Pj_XT2deaVA6V1qrTlthuaWsmjVt4eaHQwqnwqjRO3A kosli log environment aws-prod --output=json ```
```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [ { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/saver:84e986a@sha256:06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "sha256": "06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "saver-ci", "deployments": [], "flows": [ { "flow_name": "saver-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/saver/compare/36f0420f728fe61e44a3ab0043cf9a3d70863cad...84e986ad70d32e9be362d5bd9ce7c7af94f6eaab", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/saver-ci/fingerprint/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f", "html": "https://app.kosli.com/cyber-dojo/flows/saver-ci/artifacts/06f85cc53010535e46f13c348a1aaf5c8dfee0c0fea7f81105312b6c87d5d05f?artifact_id=a599cb04-5965-46a6-a774-24dc6341" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/nginx:27b3504@sha256:1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "sha256": "1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "nginx-ci", "deployments": [], "flows": [ { "flow_name": "nginx-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/nginx/compare/fb791742054fa28dd89269aac8002ebfd7b3386e...27b350410ebcca5ff192f2ca4cdd0e3e49f5ac65", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/nginx-ci/fingerprint/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21", "html": "https://app.kosli.com/cyber-dojo/flows/nginx-ci/artifacts/1d1a2f8e2ea649bac20578eea7b18c9f03cda4cad5118cefbf425521a77ead21?artifact_id=9045bb07-ea42-482f-99c3-4fe5b86f" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/dashboard:ff9f292@sha256:2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "sha256": "2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "dashboard-ci", "deployments": [], "flows": [ { "flow_name": "dashboard-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/dashboard/compare/2b300f450f72006f6a9000aaf9cd04485f1e8095...ff9f292e809801d35246183988b7812826bc2760", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/dashboard-ci/fingerprint/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f", "html": "https://app.kosli.com/cyber-dojo/flows/dashboard-ci/artifacts/2827829889b4acc994c3ffbfca250346d5f1f0ddf21847bcbe4864ae484ebe4f?artifact_id=aa6c0c1d-2d5d-4c98-9f9d-1160dd2f" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:a357ebd@sha256:28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "sha256": "28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "languages-start-points-ci", "deployments": [], "flows": [ { "flow_name": "languages-start-points-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/languages-start-points/compare/068b3424c7da843a4f2d428d2e4915f33efc4a02...a357ebd85acdd54968fa0192405aaf2e289d27c9", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/languages-start-points-ci/fingerprint/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832", "html": "https://app.kosli.com/cyber-dojo/flows/languages-start-points-ci/artifacts/28bc41a2185a154249b1d06983741c39beb3574ebdce7273963ecde2ae9dd832?artifact_id=8e028a8d-a1f2-4732-8663-47012b29" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:b12a5c9@sha256:34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "sha256": "34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "custom-start-points-ci", "deployments": [], "flows": [ { "flow_name": "custom-start-points-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/custom-start-points/compare/790d86b66f4d86ab47f5c521daf5039dc8aeef4d...b12a5c9b17023462d13e81381a69c7ef05f84dc2", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/custom-start-points-ci/fingerprint/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09", "html": "https://app.kosli.com/cyber-dojo/flows/custom-start-points-ci/artifacts/34fd30b5a876821ef7047c3e3af23158705ec2ea1f63fa784854639ccd807b09?artifact_id=2aa23627-9e91-488e-b3ea-e4bf2e22" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/web:cbe481c@sha256:36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "sha256": "36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "description": "3 instances changed", "reported_at": 1788256325.6192138, "pipeline": "web-ci", "deployments": [], "flows": [ { "flow_name": "web-ci", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/web/compare/5e4b9873df93525c041c386c06e0ab8fc36b6f33...cbe481c4b842f897e4e9e411cd78461a3a12a334", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/web-ci/fingerprint/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc", "html": "https://app.kosli.com/cyber-dojo/flows/web-ci/artifacts/36ad0020c6cd8716c1463808a185ca65379ec8151a9619d72549ee597d86accc?artifact_id=41957e62-eaad-48d2-af40-46879efb" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:f22a30e@sha256:41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "sha256": "41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "exercises-start-points-ci", "deployments": [], "flows": [ { "flow_name": "exercises-start-points-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/exercises-start-points/compare/258b6d07d2b28ad5cb2ce6d29934997f72380f1a...f22a30ed7659b05a88c22e9f22dc2388f2deb8c8", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/exercises-start-points-ci/fingerprint/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6", "html": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points-ci/artifacts/41aab2a45d074e91162ffde031d094118f0be3bdffa4d769ea24b415f5e8a9d6?artifact_id=aa4300d4-b690-4d71-9596-6af987e1" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/spooler:90c8d98@sha256:6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "sha256": "6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "spooler-ci", "deployments": [], "flows": [ { "flow_name": "spooler-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/spooler/compare/dc7dea2d9086fcdfe4629f3ab02501ed92aad1bb...90c8d982d2ff8c4950f7aca4d0a1e9d29ac74e1f", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/spooler-ci/fingerprint/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd", "html": "https://app.kosli.com/cyber-dojo/flows/spooler-ci/artifacts/6440151a9419255a47d8f9fb0e610f5af3f555ad68fa84a50f950abae8b098fd?artifact_id=6df79438-91a2-4c2b-a945-52fb5218" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5309, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:d64d2b1@sha256:c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "sha256": "c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "description": "1 instance changed", "reported_at": 1788256325.6192138, "pipeline": "creator-ci", "deployments": [], "flows": [ { "flow_name": "creator-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/creator/compare/83357f112ef5c10b157cb84732c77965cc8ddc48...d64d2b11879179255f11dc991e81fbaf4a040264", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/creator-ci/fingerprint/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "html": "https://app.kosli.com/cyber-dojo/flows/creator-ci/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=61384b36-4d32-43f2-8d5d-a72e2e7e" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5309", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5309" } } }, { "environment_name": "aws-prod", "snapshot_index": 5308, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:bcac1c1@sha256:03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "sha256": "03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "description": "1 instance changed", "reported_at": 1788256258.609352, "pipeline": "differ-ci", "deployments": [], "flows": [ { "flow_name": "differ-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/differ/compare/108cccf9bccf9af5d455db66c250480b53cbecc7...bcac1c18385b2573ef6c6e8eeae0f62ed14a03de", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/differ-ci/fingerprint/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab", "html": "https://app.kosli.com/cyber-dojo/flows/differ-ci/artifacts/03e520a0dcb9da3889b23ef3ab7f0fa29e4c4a7a9d42c2ce022b78a053157bab?artifact_id=11345222-f37a-4f8d-8051-ec26a321" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5308", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5308" } } }, { "environment_name": "aws-prod", "snapshot_index": 5308, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:ca65b67@sha256:a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "sha256": "a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "description": "3 instances changed", "reported_at": 1788256258.609352, "pipeline": "runner-ci", "deployments": [], "flows": [ { "flow_name": "runner-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "updated-provenance", "code_diff": "https://github.com/cyber-dojo/runner/compare/976b63e8001ec7441ebc7737ca69f620d47e7ffe...ca65b67c3e311fbdd2435609fdb6f8a5479f66f9", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/runner-ci/fingerprint/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638", "html": "https://app.kosli.com/cyber-dojo/flows/runner-ci/artifacts/a1b8379841b440286b5649db7517419457b8fdb01398a661bae9ae0c92b05638?artifact_id=3b03ceaf-96a6-4afa-8aa2-179e5fe9" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5308", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5308" } } }, { "environment_name": "aws-prod", "snapshot_index": 5307, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:83357f1@sha256:adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "sha256": "adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "description": "1 instance stopped running (from 1 to 0)", "reported_at": 1788256138.680238, "pipeline": "creator-ci", "deployments": [], "flows": [ { "flow_name": "creator-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "exited", "code_diff": "https://github.com/cyber-dojo/creator/compare/89019f6d8059406e56fa499b2dec2dbf93f4d5c7...83357f112ef5c10b157cb84732c77965cc8ddc48", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/creator-ci/fingerprint/adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b", "html": "https://app.kosli.com/cyber-dojo/flows/creator-ci/artifacts/adb922d738b50876f1cd13f5a998ade341abfd64b3561d0889264399c33c528b?artifact_id=11539f6a-befb-4b79-9484-fd9f25d3" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5307", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5307" } } }, { "environment_name": "aws-prod", "snapshot_index": 5306, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/creator:d64d2b1@sha256:c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "sha256": "c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "description": "1 instance started running (from 0 to 1)", "reported_at": 1788256078.451175, "pipeline": "creator-ci", "deployments": [], "flows": [ { "flow_name": "creator-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "started-compliant", "code_diff": "https://github.com/cyber-dojo/creator/compare/83357f112ef5c10b157cb84732c77965cc8ddc48...d64d2b11879179255f11dc991e81fbaf4a040264", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/creator-ci/fingerprint/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab", "html": "https://app.kosli.com/cyber-dojo/flows/creator-ci/artifacts/c48710e3304e24406c03381a31d01f520ab2f60846aa0b57adbda0a776ebc1ab?artifact_id=61384b36-4d32-43f2-8d5d-a72e2e7e" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5306", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5306" } } }, { "environment_name": "aws-prod", "snapshot_index": 5305, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/runner:976b63e@sha256:01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "sha256": "01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "description": "1 instance stopped running (from 1 to 0)", "reported_at": 1788255898.5005004, "pipeline": "runner-ci", "deployments": [], "flows": [ { "flow_name": "runner-ci", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "exited", "code_diff": "https://github.com/cyber-dojo/runner/compare/d7541d3fb2c548bd68a81f812b5a6c95fcf9a1bd...976b63e8001ec7441ebc7737ca69f620d47e7ffe", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/runner-ci/fingerprint/01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9", "html": "https://app.kosli.com/cyber-dojo/flows/runner-ci/artifacts/01311f8b73bb61f65baabe680aa75ef9c0e6c5d1697ad81cfd89c89812de6fe9?artifact_id=e63d6d6b-d7ee-4fad-a66a-32a4ebba" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5305", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5305" } } }, { "environment_name": "aws-prod", "snapshot_index": 5304, "artifact_name": "244531986313.dkr.ecr.eu-central-1.amazonaws.com/differ:108cccf@sha256:31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "sha256": "31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "description": "1 instance stopped running (from 1 to 0)", "reported_at": 1788255838.4418423, "pipeline": "differ-ci", "deployments": [], "flows": [ { "flow_name": "differ-ci", "deployments": null }, { "flow_name": "snyk-aws-beta-per-artifact", "deployments": null }, { "flow_name": "production-promotion", "deployments": null }, { "flow_name": "snyk-aws-prod-per-artifact", "deployments": null } ], "artifact_compliance": true, "snapshot_compliance": true, "type": "exited", "code_diff": "https://github.com/cyber-dojo/differ/compare/10e162d4e1294815375a31121f14d57e13183b34...108cccf9bccf9af5d455db66c250480b53cbecc7", "_links": { "artifact": { "self": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/differ-ci/fingerprint/31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac", "html": "https://app.kosli.com/cyber-dojo/flows/differ-ci/artifacts/31a4c3abc3ccef33397ed1d84496a08d94ca9d6f9d0df44b6a72aba9743bc8ac?artifact_id=50b8cff6-1888-4c76-b31a-fdd7a311" }, "snapshot": { "self": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/5304", "html": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/5304" } } } ] ```
## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --page-limit 30 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --page-limit 30 --output json ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --repo yourOrg/yourRepo ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --repo yourOrg/yourRepo1 --repo yourOrg/yourRepo2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --start 5 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --start 1hour --end NOW ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli log environment yourEnvironmentName --start-ts 1700000000 --end-ts 1700086400 ``` # kosli rename environment Source: https://docs.kosli.com/client_reference/kosli_rename_environment Rename a Kosli environment. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rename environment OLD_NAME NEW_NAME [flags] ``` Rename a Kosli environment. The environment will remain accessible under its old name until that name is taken by another environment. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for environment | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rename environment oldName newName ``` # kosli rename flow Source: https://docs.kosli.com/client_reference/kosli_rename_flow Rename a Kosli flow. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rename flow OLD_NAME NEW_NAME [flags] ``` Rename a Kosli flow. The flow will remain accessible under its old name until that name is taken by another flow. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for flow | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rename flow oldName newName ``` # kosli report artifact Source: https://docs.kosli.com/client_reference/kosli_report_artifact Report an artifact creation to a Kosli flow. This command is deprecated. Deprecated commands will be removed in a future release. see kosli attest commands ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli report artifact {IMAGE-NAME | FILE-PATH | DIR-PATH} [flags] ``` Report an artifact creation to a Kosli flow. The artifact fingerprint can be provided directly with the `--fingerprint` flag, or calculated based on `--artifact-type` flag. Artifact type can be one of: "file" for files, "dir" for directories, "oci" for container images in registries or "docker" for local docker images. Note: `--artifact-type=docker` reads the image's repo digest via the local Docker daemon. The image must have been pushed to or pulled from a registry for a repo digest to exist; a freshly built image (just `docker build`) will not have one. If the image is already in a registry, prefer `--artifact-type=oci`, which fetches the digest directly from the registry without needing a local Docker daemon. For `--artifact-type=oci` (and for `--artifact-type=docker` when `--registry-username` is set), registry credentials are resolved as follows: 1. If `--registry-username` (and optionally `--registry-password`) is set, it is used directly. 2. Otherwise, credentials are discovered automatically from: * the Docker config file (`~/.docker/config.json`, populated by `docker login`) * the Podman/containers auth file (`~/.config/containers/auth.json`, or `$REGISTRY_AUTH_FILE`) * any Docker credential helper configured in that config (e.g. `docker-credential-ecr-login` for AWS ECR, `docker-credential-gcloud` for GCR/Artifact Registry, an ACR helper for Azure, or a local keychain helper), invoked as an external binary on `$PATH` * if none of the above yield credentials, the registry is accessed anonymously, which works for public images `--registry-provider` is deprecated and no longer used. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-t`, `--artifact-type` | string | The type of the artifact to calculate its SHA256 fingerprint. One of: \[oci, docker, file, dir]. Only required if you want Kosli to calculate the fingerprint for you (i.e. when you don't specify '`--fingerprint`' on commands that allow it). | | `-b`, `--build-url` | string | The url of CI pipeline that built the artifact. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-u`, `--commit-url` | string | The url for the git commit that created the artifact. (defaulted in some CIs: [docs](/integrations/ci_cd) ). | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for `--artifact-type` dir. | | `-F`, `--fingerprint` | string | \[conditional] The SHA256 fingerprint of the artifact. Only required if you don't specify '`--artifact-type`'. | | `-f`, `--flow` | string | The Kosli flow name. | | `-g`, `--git-commit` | string | \[defaulted] The git commit from which the artifact was created. (defaulted in some CIs: [docs](/integrations/ci_cd), otherwise defaults to HEAD ). | | `-h`, `--help` | bool | help for artifact | | `-n`, `--name` | string | \[optional] Artifact display name, if different from file, image or directory name. | | `--registry-password` | string | \[conditional] The container registry password or access token. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--registry-provider` | string | \[deprecated] The docker registry provider or url. Only required if you want to read docker image SHA256 digest from a remote docker registry. (DEPRECATED: no longer used) | | `--registry-username` | string | \[conditional] The container registry username. Only required if you want to read container image SHA256 digest from a remote container registry and it is not already accessible via Docker/Podman auth files or a credential helper. | | `--repo-root` | string | \[defaulted] The directory where the source git repository is available. (default ".") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli report artifact FILE.tgz --artifact-type file --build-url https://exampleci.com --commit-url https://github.com/YourOrg/YourProject/commit/yourCommitShaThatThisArtifactWasBuiltFrom --git-commit yourCommitShaThatThisArtifactWasBuiltFrom ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli report artifact ANOTHER_FILE.txt --build-url https://exampleci.com --commit-url https://github.com/YourOrg/YourProject/commit/yourCommitShaThatThisArtifactWasBuiltFrom --git-commit yourCommitShaThatThisArtifactWasBuiltFrom --fingerprint yourArtifactFingerprint ``` # kosli rotate api-key Source: https://docs.kosli.com/client_reference/kosli_rotate_api-key Rotate one or more API keys for a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rotate api-key KEY-ID [KEY-ID...] [flags] ``` Rotate one or more API keys for a service account. A new API key is generated immediately. The old key remains valid for a grace period to allow time to update dependent systems; the length of that grace period is server-managed unless overridden with `--grace-period-hours`. The new key value is only returned once, so make sure to store it securely. ## Flags | Flag | Type | Description | | :--------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--expires-at` | string | \[optional] When the API key expires. Accepts an epoch timestamp or a date like '2026-06-04', '2026-06-04 15:04:05', or an RFC3339 timestamp. Defaults to no expiry. | | `-g`, `--grace-period-hours` | int | \[optional] How many hours the old API key remains valid after rotation, to allow time to update dependent systems. Defaults to the server-side value when not set. | | `-h`, `--help` | bool | help for api-key | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | | `-s`, `--service-account` | string | The name of the service account whose API keys are managed. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rotate api-key yourApiKeyID --service-account yourServiceAccountName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rotate api-key keyID1 keyID2 --service-account yourServiceAccountName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli rotate api-key yourApiKeyID --grace-period-hours 48 --service-account yourServiceAccountName ``` # kosli search Source: https://docs.kosli.com/client_reference/kosli_search Search for a git commit or an artifact fingerprint in Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli search {GIT-COMMIT | FINGERPRINT} [flags] ``` Search for a git commit or an artifact fingerprint in Kosli.\ You can use short git commit or artifact fingerprint shas, but you must provide at least 5 characters. ## Flags | Flag | Type | Description | | :--------------- | :----- | :------------------------------------------------------------------------------------------ | | `-h`, `--help` | bool | help for search | | `-o`, `--output` | string | \[defaulted] The format of the output. Valid formats are: \[table, json]. (default "table") | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli search YOUR_GIT_COMMIT ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli search YOUR_ARTIFACT_FINGERPRINT ``` # kosli snapshot azure Source: https://docs.kosli.com/client_reference/kosli_snapshot_azure Report a snapshot of running Azure web apps and function apps in an Azure resource group to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot azure ENVIRONMENT-NAME [flags] ``` Report a snapshot of running Azure web apps and function apps in an Azure resource group to Kosli.\ The reported data includes Azure app names, container image digests and creation timestamps. For Azure Function apps or Web apps which uses zip deployment the fingerprint is calculated based on the content of the zip file. This is the same as unzipping the file and then running `kosli fingerprint -t dir yourDirName`. When doing zip deployment the WEBSITE\_RUN\_FROM\_PACKAGE must NOT be set to 1. This will cause the azure API calls to not return the content of what is running on the server and fingerprint calculations will not match. See [https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#website\_run\_from\_package](https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#website_run_from_package) For zip-deployed apps, the fingerprint respects a `.kosli_ignore` file at the root of the deployed package. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. To authenticate to Azure, you need to create Azure service principal with a secret and provide these Azure credentials via flags or by exporting the equivalent KOSLI env vars (e.g. KOSLI\_AZURE\_CLIENT\_ID). The service principal needs to have the following permissions: 1. Microsoft.Web/sites/Read 2. Microsoft.ContainerRegistry/registries/pull/read ## Flags | Flag | Type | Description | | :---------------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `--azure-client-id` | string | Azure client ID. | | `--azure-client-secret` | string | Azure client secret. | | `--azure-resource-group-name` | string | Azure resource group name. | | `--azure-subscription-id` | string | Azure subscription ID. | | `--azure-tenant-id` | string | Azure tenant ID. | | `--digests-source` | string | \[defaulted] Where to get the digests from. Valid values are 'acr' and 'logs'. (default "acr") | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for azure | | `--zip` | bool | Download logs from Azure as zip files | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot azure yourEnvironmentName --azure-client-id yourAzureClientID --azure-client-secret yourAzureClientSecret --azure-tenant-id yourAzureTenantID --azure-subscription-id yourAzureSubscriptionID --azure-resource-group-name yourAzureResourceGroupName --digests-source acr ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot azure yourEnvironmentName --azure-client-id yourAzureClientID --azure-client-secret yourAzureClientSecret --azure-tenant-id yourAzureTenantID --azure-subscription-id yourAzureSubscriptionID --azure-resource-group-name yourAzureResourceGroupName --digests-source logs ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot azure yourEnvironmentName --azure-client-id yourAzureClientID --azure-client-secret yourAzureClientSecret --azure-tenant-id yourAzureTenantID --azure-subscription-id yourAzureSubscriptionID --azure-resource-group-name yourAzureResourceGroupName ``` # kosli snapshot cloud-run Source: https://docs.kosli.com/client_reference/kosli_snapshot_cloud-run Report a snapshot of Cloud Run services and jobs in a Google Cloud project and region to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot cloud-run ENVIRONMENT-NAME [flags] ``` Report a snapshot of Cloud Run services and jobs in a Google Cloud project and region to Kosli.\ Coverage: | Deploy method | Container? | Reported | Notes | | -------------------------------------------- | ------------------------------------ | -------- | ----------------------------------- | | Cloud Run service (image-deployed) | Yes | ✓ Full | | | Cloud Run service (source / Buildpacks) | Yes (built for you) | ✓ Full | | | Cloud Run Job | Yes | ✓ Full | | | Cloud Run function (Cloud Functions 2nd gen) | Yes (Buildpacks) | ✓ Full | | | Cloud Functions 1st gen | No (Google packages the source) | ✗ | | | App Engine Standard | No (gVisor sandbox, not a container) | ✗ | Not currently supported in the CLI. | | App Engine Flexible | Yes (containers on managed VMs) | ✗ | | | GKE (Standard / Autopilot) | Yes | ✗ | Use `kosli snapshot k8s` instead. | | Cloud Run for Anthos | Yes (knative on GKE) | ✗ | | | Compute Engine + Container-Optimized OS | Yes (Docker on a VM) | ✗ | | Each Cloud Run service contributes one artifact per revision in its traffic configuration. Each Cloud Run Job contributes one artifact, identified by the image bound to the Job (Jobs do not have a revision/traffic-split model). Idle Jobs (no currently-running Execution) are included. GCP authentication uses Application Default Credentials. On a developer machine, run `gcloud auth application-default login`; in GCE/GKE/Cloud Run the metadata server / Workload Identity is used automatically. The caller needs `roles/run.viewer` on the target project, plus `roles/artifactregistry.reader` on the Artifact Registry repository (or the project) for digest and tag resolution on tag-pinned images. Missing the AR role is non-fatal — tag-pinned artifacts then surface with empty digests. Digest and tag resolution is scoped to Artifact Registry (`*-docker.pkg.dev`) and the legacy Container Registry (`*.gcr.io`). Images from other registries (Docker Hub, Quay, ECR, etc.) are reported as-is. Skip all filtering flags to report every service and every job in the given project + region. Use `--include` and/or `--include-regex` to snapshot only a subset, OR `--exclude` and/or `--exclude-regex` to omit a subset; include and exclude are mutually exclusive. Filters apply uniformly to both service and job names and are case-sensitive. Pass `--resolve-names` to rewrite digest-pinned Service artifact names back to their deploy-time tags (commit SHA / version) via an Artifact Registry reverse-lookup. Only supported for Artifact Registry hosts. ## Flags | Flag | Type | Description | | :---------------- | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--exclude` | strings | \[optional] The comma-separated list of Cloud Run service or job names to exclude. Can't be used together with `--include` or `--include-regex`. | | `--exclude-regex` | strings | \[optional] The comma-separated list of Cloud Run service or job name regex patterns to exclude. Can't be used together with `--include` or `--include-regex`. | | `-h`, `--help` | bool | help for cloud-run | | `--include` | strings | \[optional] The comma-separated list of Cloud Run service or job names to snapshot. Can't be used together with `--exclude` or `--exclude-regex`. | | `--include-regex` | strings | \[optional] The comma-separated list of Cloud Run service or job name regex patterns to snapshot. Can't be used together with `--exclude` or `--exclude-regex`. | | `--project` | string | \[required] GCP project ID. | | `--region` | string | \[required] GCP region (e.g. europe-west1). | | `--resolve-names` | bool | \[optional] When set, resolve digest-pinned artifact names back to their deploy-time tags (commit SHA / version) via an Artifact Registry reverse-lookup. Requires roles/artifactregistry.reader. Default: artifacts keep whatever name the Cloud Run API returned (digest-pinned for Services, deploy-time form for Jobs). | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot cloud-run yourEnvironmentName --project yourGCPProject --region yourGCPRegion ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot cloud-run yourEnvironmentName --project yourGCPProject --region yourGCPRegion --include hello-world,sandman-job ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot cloud-run yourEnvironmentName --project yourGCPProject --region yourGCPRegion --exclude kosli-reporter ``` # kosli snapshot docker Source: https://docs.kosli.com/client_reference/kosli_snapshot_docker Report a snapshot of running containers from docker host to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot docker ENVIRONMENT-NAME [flags] ``` Report a snapshot of running containers from docker host to Kosli.\ The reported data includes container image digests and creation timestamps. Containers running images which have not been pushed to or pulled from a registry will be ignored. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for docker | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot docker yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot docker yourEnvironmentName --auto-environment --environment-description "Production docker host" ``` # kosli snapshot ecs Source: https://docs.kosli.com/client_reference/kosli_snapshot_ecs Report a snapshot of running containers in one or more AWS ECS cluster(s) to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs ENVIRONMENT-NAME [flags] ``` Report a snapshot of running containers in one or more AWS ECS cluster(s) to Kosli.\ Skip all filtering flags to report everything running in all clusters in a given AWS account. Use `--clusters` and/or `--clusters-regex` OR `--exclude` and/or `--exclude-regex` to filter the clusters to snapshot. You can also filter the services within a cluster using `--services` and/or `--services-regex`. Or use `--exclude-services` and/or `--exclude-services-regex` to exclude some services. Note that service filtering is applied to all clusters being snapshot. All filtering options are case-sensitive. The reported data includes cluster and service names, container image digests and creation timestamps. To authenticate to AWS, you can either: 1. provide the AWS static credentials via flags or by exporting the equivalent KOSLI env vars (e.g. KOSLI\_AWS\_KEY\_ID) 2. export the AWS env vars (e.g. AWS\_ACCESS\_KEY\_ID). 3. Use a shared config/credentials file under the \$HOME/.aws Option 1 takes highest precedence, while option 3 is the lowest. More details can be found here: [https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials) ## Flags | Flag | Type | Description | | :------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--aws-key-id` | string | The AWS access key ID. | | `--aws-region` | string | The AWS region. | | `--aws-secret-key` | string | The AWS secret access key. | | `-C`, `--cluster` | strings | The name of the ECS cluster. (DEPRECATED: use `--clusters` instead) | | `--clusters` | strings | \[optional] The comma-separated list of ECS cluster names to snapshot. Can't be used together with `--exclude` or `--exclude-regex`. | | `--clusters-regex` | strings | \[optional] The comma-separated list of ECS cluster name regex patterns to snapshot. Can't be used together with `--exclude` or `--exclude-regex`. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--exclude` | strings | \[optional] The comma-separated list of ECS cluster names to exclude. Can't be used together with `--clusters` or `--clusters-regex`. | | `--exclude-regex` | strings | \[optional] The comma-separated list of ECS cluster name regex patterns to exclude. Can't be used together with `--clusters` or `--clusters-regex`. | | `--exclude-services` | strings | \[optional] The comma-separated list of ECS service names to exclude. Can't be used together with `--services` or `--services-regex`. | | `--exclude-services-regex` | strings | \[optional] The comma-separated list of ECS service name regex patterns to exclude. Can't be used together with `--services` or `--services-regex`. | | `-h`, `--help` | bool | help for ecs | | `-s`, `--service-name` | string | \[deprecated] The name of the ECS service. Use `--services` instead. (DEPRECATED: it will be removed in a future release) | | `--services` | strings | \[optional] The comma-separated list of ECS service names to snapshot. Can't be used together with `--exclude-services` or `--exclude-services-regex`. | | `--services-regex` | strings | \[optional] The comma-separated list of ECS service name regex patterns to snapshot. Can't be used together with `--exclude-services` or `--exclude-services-regex`. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs yourEnvironmentName --aws-key-id yourAWSAccessKeyID --aws-secret-key yourAWSSecretAccessKey --aws-region yourAWSRegion ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey export AWS_REGION=yourAWSRegion kosli snapshot ecs yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters-regex "^my-cluster-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster1,my-cluster2 ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude my-cluster ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude-regex "^my-cluster-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude my-cluster1,my-cluster2 ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster --services backend-app ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster --services-regex "^backend-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --services-regex ".*-prod-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --services backend-app ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --services backend-app,frontend-app ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster --exclude-services-regex "^backend-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude-services-regex ".*-prod-.*" ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --clusters my-cluster --exclude-services backend-app ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude-services backend-app ... ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot ecs my-env --exclude-services backend-app,frontend-app ... ``` # kosli snapshot k8s Source: https://docs.kosli.com/client_reference/kosli_snapshot_k8s Report a snapshot of running pods in a K8S cluster or namespace(s) to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot k8s ENVIRONMENT-NAME [flags] ``` Report a snapshot of running pods in a K8S cluster or namespace(s) to Kosli.\ Skip `--namespaces` and `--namespaces-regex` to report all pods in all namespaces in a cluster. The reported data includes pod container images digests and creation timestamps. You can customize the scope of reporting to include or exclude namespaces. ## Flags | Flag | Type | Description | | :--------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--config-file` | string | \[optional] The path to a YAML config file that maps multiple Kosli environments to namespace selectors. Cannot be used with a positional environment name argument or namespace flags. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude-namespaces` | strings | \[optional] The comma separated list of namespaces names to exclude from reporting artifacts info from. Requires cluster-wide read permissions for pods and namespaces. Can't be used together with `--namespaces` or `--namespaces-regex`. | | `--exclude-namespaces-regex` | strings | \[optional] The comma separated list of namespaces regex patterns to exclude from reporting artifacts info from. Requires cluster-wide read permissions for pods and namespaces. Can't be used together with `--namespaces` or `--namespaces-regex`. | | `-h`, `--help` | bool | help for k8s | | `-k`, `--kubeconfig` | string | \[defaulted] The kubeconfig path for the target cluster. (default "\$HOME/.kube/config") | | `-n`, `--namespaces` | strings | \[optional] The comma separated list of namespaces names to report artifacts info from. Can't be used together with `--exclude-namespaces` or `--exclude-namespaces-regex`. | | `--namespaces-regex` | strings | \[optional] The comma separated list of namespaces regex patterns to report artifacts info from. Requires cluster-wide read permissions for pods and namespaces. Can't be used together with `--exclude-namespaces` `--exclude-namespaces-regex`. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot k8s yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_API_TOKEN=yourAPIToken export KOSLI_ORG=yourOrgName kosli snapshot k8s yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot k8s yourEnvironmentName --exclude-namespaces kube-system,utilities ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot k8s yourEnvironmentName --namespaces your-namespace ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot k8s yourEnvironmentName --kubeconfig /path/to/kube/config ``` # kosli snapshot lambda Source: https://docs.kosli.com/client_reference/kosli_snapshot_lambda Report a snapshot of artifacts deployed as one or more AWS Lambda functions and their digests to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot lambda ENVIRONMENT-NAME [flags] ``` Report a snapshot of artifacts deployed as one or more AWS Lambda functions and their digests to Kosli.\ Skip `--function-names` and `--function-names-regex` to report all functions in a given AWS account. Or use `--exclude` and/or `--exclude-regex` to report all functions excluding some. To authenticate to AWS, you can either: 1. provide the AWS static credentials via flags or by exporting the equivalent KOSLI env vars (e.g. KOSLI\_AWS\_KEY\_ID) 2. export the AWS env vars (e.g. AWS\_ACCESS\_KEY\_ID). 3. Use a shared config/credentials file under the \$HOME/.aws Option 1 takes highest precedence, while option 3 is the lowest. More details can be found here: [https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials) ## Flags | Flag | Type | Description | | :----------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--aws-key-id` | string | The AWS access key ID. | | `--aws-region` | string | The AWS region. | | `--aws-secret-key` | string | The AWS secret access key. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `--exclude` | strings | \[optional] The comma-separated list of AWS Lambda function names to be excluded. Cannot be used together with `--function-names` | | `--exclude-regex` | strings | \[optional] The comma-separated list of name regex patterns for AWS Lambda functions to be excluded. Cannot be used together with `--function-names`. Allowed regex patterns are described in [RE2 syntax](https://github.com/google/re2/wiki/Syntax) | | `--function-name` | strings | \[optional] The name of the AWS Lambda function. (DEPRECATED: use `--function-names` instead) | | `--function-names` | strings | \[optional] The comma-separated list of AWS Lambda function names to be reported. Cannot be used together with `--exclude` or `--exclude-regex`. | | `--function-names-regex` | strings | \[optional] The comma-separated list of AWS Lambda function names regex patterns to be reported. Cannot be used together with `--exclude` or `--exclude-regex`. | | `--function-version` | string | \[optional] The version of the AWS Lambda function. (DEPRECATED: `--function-version` is no longer supported. It will be removed in a future release.) | | `-h`, `--help` | bool | help for lambda | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot lambda yourEnvironmentName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot lambda yourEnvironmentName --exclude function1,function2 --exclude-regex "^not-wanted.*" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot lambda yourEnvironmentName --function-names yourFunctionName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot lambda yourEnvironmentName --function-names-regex yourFunctionNameRegexPattern ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot lambda yourEnvironmentName --function-names yourFirstFunctionName,yourSecondFunctionName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot lambda yourEnvironmentName --function-names yourFunctionName --aws-key-id yourAWSAccessKeyID --aws-secret-key yourAWSSecretAccessKey --aws-region yourAWSRegion ``` # kosli snapshot path Source: https://docs.kosli.com/client_reference/kosli_snapshot_path Report a snapshot of a single artifact running in a specific filesystem path to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot path ENVIRONMENT-NAME [flags] ``` Report a snapshot of a single artifact running in a specific filesystem path to Kosli.\ You can report a directory or file artifact. For reporting multiple artifacts in one go, use "kosli snapshot paths". You can exclude certain paths or patterns from the artifact fingerprint using `--exclude`. The supported glob pattern syntax is documented here: [https://pkg.go.dev/path/filepath#Match](https://pkg.go.dev/path/filepath#Match) , plus the ability to use recursive globs "\*\*" To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma-separated list of literal paths or glob patterns to exclude when fingerprinting the artifact. | | `-h`, `--help` | bool | help for path | | `--name` | string | The reported name of the artifact. | | `--path` | string | The base path for the artifact to snapshot. | | `--watch` | bool | \[optional] Watch the filesystem for changes and report snapshots of artifacts running in specific filesystem paths to Kosli. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot path yourEnvironmentName --path path/to/your/artifact/dir/or/file --name yourArtifactDisplayName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot path yourEnvironmentName --path path/to/your/artifact/dir --name yourArtifactDisplayName --exclude **/log,unwanted.txt,path/**/output.txt ``` # kosli snapshot paths Source: https://docs.kosli.com/client_reference/kosli_snapshot_paths Report a snapshot of artifacts running in specific filesystem paths to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot paths ENVIRONMENT-NAME [flags] ``` Report a snapshot of artifacts running in specific filesystem paths to Kosli.\ You can report directory or file artifacts in one or more filesystem paths. Artifacts names and the paths to include and exclude when fingerprinting them can be defined in a paths file which can be provided using `--paths-file`. Paths files can be in YAML, JSON or TOML formats. They specify a list of artifacts to fingerprint. For each artifact, the file specifies a base path to look for the artifact in and (optionally) a list of paths to exclude. Excluded paths are relative to the artifact path(s) and can be literal paths or glob patterns.\ The supported glob pattern syntax is documented here: [https://pkg.go.dev/path/filepath#Match](https://pkg.go.dev/path/filepath#Match) , plus the ability to use recursive globs "\*\*" To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. This is an example YAML paths spec file: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} version: 1 artifacts: artifact_name_a: path: dir1 exclude: [subdir1, **/log] ``` ## Flags | Flag | Type | Description | | :---------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for paths | | `--paths-file` | string | The path to a paths file in YAML/JSON/TOML format. Cannot be used together with `--path` . | | `--watch` | bool | \[optional] Watch the filesystem for changes and report snapshots of artifacts running in specific filesystem paths to Kosli. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot paths yourEnvironmentName --paths-file path/to/your/paths/file ``` # kosli snapshot s3 Source: https://docs.kosli.com/client_reference/kosli_snapshot_s3 Report a snapshot of the content of an AWS S3 bucket to Kosli. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot s3 ENVIRONMENT-NAME [flags] ``` Report a snapshot of the content of an AWS S3 bucket to Kosli. To authenticate to AWS, you can either: 1. provide the AWS static credentials via flags or by exporting the equivalent KOSLI env vars (e.g. KOSLI\_AWS\_KEY\_ID) 2. export the AWS env vars (e.g. AWS\_ACCESS\_KEY\_ID). 3. Use a shared config/credentials file under the \$HOME/.aws Option 1 takes highest precedence, while option 3 is the lowest. More details can be found here: [https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials) You can report the entire bucket content, or filter some of the content using `--include` / `--exclude` (literal prefix match) or `--include-regex` / `--exclude-regex` (Go regular expressions matched against the full object key). In all cases, the content is reported as one artifact. If you wish to report separate files/dirs within the same bucket as separate artifacts, you need to run the command twice. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :----------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--aws-key-id` | string | The AWS access key ID. | | `--aws-region` | string | The AWS region. | | `--aws-secret-key` | string | The AWS secret access key. | | `--bucket` | string | The name of the S3 bucket. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-x`, `--exclude` | strings | \[optional] The comma separated list of file and/or directory paths in the S3 bucket to exclude when fingerprinting. Paths match by literal prefix. Cannot be used together with `--include` or `--include-regex`. | | `--exclude-regex` | strings | \[optional] The comma separated list of Go regular expressions matched against object keys in the S3 bucket to exclude when fingerprinting. Cannot be used together with `--include` or `--include-regex`. | | `-h`, `--help` | bool | help for s3 | | `-i`, `--include` | strings | \[optional] The comma separated list of file and/or directory paths in the S3 bucket to include when fingerprinting. Paths match by literal prefix. Cannot be used together with `--exclude` or `--exclude-regex`. | | `--include-regex` | strings | \[optional] The comma separated list of Go regular expressions matched against object keys in the S3 bucket to include when fingerprinting. Cannot be used together with `--exclude` or `--exclude-regex`. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot s3 yourEnvironmentName --bucket yourBucketName ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot s3 yourEnvironmentName --bucket yourBucketName --aws-key-id yourAWSAccessKeyID --aws-secret-key yourAWSSecretAccessKey --aws-region yourAWSRegion ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot s3 yourEnvironmentName --bucket yourBucketName --include file.txt,path/within/bucket ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export AWS_REGION=yourAWSRegion export AWS_ACCESS_KEY_ID=yourAWSAccessKeyID export AWS_SECRET_ACCESS_KEY=yourAWSSecretAccessKey kosli snapshot s3 yourEnvironmentName --bucket yourBucketName --exclude file.txt,path/within/bucket ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot s3 yourEnvironmentName --bucket yourBucketName --exclude-regex '.*\.png$' ``` # kosli snapshot server Source: https://docs.kosli.com/client_reference/kosli_snapshot_server Report a snapshot of artifacts running in a server environment to Kosli. This command is deprecated. Deprecated commands will be removed in a future release. use 'kosli snapshot paths' instead ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli snapshot server ENVIRONMENT-NAME [flags] ``` Report a snapshot of artifacts running in a server environment to Kosli.\ You can report directory or file artifacts in one or more server paths. When fingerprinting a 'dir' artifact, you can exclude certain paths from fingerprint calculation using the `--exclude` flag. Excluded paths are relative to the DIR-PATH and can be literal paths or glob patterns. With a directory structure like this `foo/bar/zam/file.txt` if you are calculating the fingerprint of `foo/bar` you need to exclude `zam/file.txt` which is relative to the DIR-PATH. The supported glob pattern syntax is what is documented here: [https://pkg.go.dev/path/filepath#Match](https://pkg.go.dev/path/filepath#Match) , plus the ability to use recursive globs "\*\*" If the directory structure contains a symbolic link to a *file* (for example, a link 'from/this/file' and a target of 'to/another/file') then: * the name of the link ('from/this/file') *is* included in the fingerprint. * the name of the link ('from/this/file') *is* subject to `.kosli_ignore` entries. * the name of the target ('to/another/file') is *not* included in the fingerprint. * the content of target *is* included in the fingerprint, even if the target is outside the root directory being fingerprinted. If the directory structure contains a symbolic link to a *directory* (for example, a link 'from/this/dir' and a target of 'to/another/dir') then: * the name of the link ('from/this/dir') *is* included in the fingerprint. * the name of the link ('from/this/dir') *is* subject to `.kosli_ignore` entries. * the name of the target ('to/another/dir') *is* included in the fingerprint, even if the target is outside the root directory being fingerprinted. * the name of the target ('to/another/dir') is *not* subject to `.kosli_ignore` entries. * the content of the target is *not* included in the fingerprint. To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a `.kosli_ignore` file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using `#`. The `.kosli_ignore` will be treated as part of the artifact like any other file, unless it is explicitly ignored itself. ## Flags | Flag | Type | Description | | :---------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-e`, `--e` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. (DEPRECATED: use `-x` instead) | | `-x`, `--exclude` | strings | \[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. | | `-h`, `--help` | bool | help for server | | `-p`, `--paths` | strings | The comma separated list of absolute or relative paths of artifact directories or files. Can take glob patterns, but be aware that each matching path will be reported as an artifact. | ## Flags inherited from parent commands | Flag | Type | Description | | :-------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-a`, `--api-token` | string | The Kosli API token. | | `-A`, `--auto-environment` | bool | \[optional] Create the environment (with the type inferred from the snapshot subcommand) if it does not already exist, before reporting the snapshot. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `--environment-description` | string | \[optional] The environment description. | | `--exclude-scaling` | bool | \[optional] Exclude scaling events for snapshots. Snapshots with scaling changes will not result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `--include-scaling` | bool | \[optional] Include scaling events for snapshots. Snapshots with scaling changes will result in new environment records. (DEPRECATED: this flag is deprecated and will be removed in a future version. Scaling events do not trigger new snapshots.) | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # report directory artifacts running in a server at a list of paths: kosli snapshot server yourEnvironmentName \ --paths a/b/c,e/f/g \ --api-token yourAPIToken \ --org yourOrgName # exclude certain paths when reporting directory artifacts: # in the example below, any path matching [a/b/c/logs, a/b/c/*/logs, a/b/c/*/*/logs] # will be skipped when calculating the fingerprint kosli snapshot server yourEnvironmentName \ --paths a/b/c \ --exclude logs,"*/logs","*/*/logs" --api-token yourAPIToken \ --org yourOrgName # use glob pattern to match paths to report them as directory artifacts: # in the example below, any path matching "*/*/src" under top-dir/ will be reported as a separate artifact. kosli snapshot server yourEnvironmentName \ --paths "top-dir/*/*/src" \ --api-token yourAPIToken \ --org yourOrgName ``` # kosli status Source: https://docs.kosli.com/client_reference/kosli_status Check the status of a Kosli server. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli status [flags] ``` Check the status of a Kosli server.\ The status is logged and the command always exits with 0 exit code.\ If you like to assert the Kosli server status, you can use the `--assert` flag or the "kosli assert status" command. ## Flags | Flag | Type | Description | | :------------- | :--- | :--------------------------------------------------------------------- | | `--assert` | bool | \[optional] Exit with non-zero code if Kosli server is not responding. | | `-h`, `--help` | bool | help for status | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # kosli tag Source: https://docs.kosli.com/client_reference/kosli_tag Tag a resource in Kosli with key-value pairs. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag RESOURCE-TYPE [RESOURCE-ID] [flags] ``` Tag a resource in Kosli with key-value pairs.\ use --set to add or update tags, and --unset to remove tags. Valid resource types are: flow, flows, env, environment, environments, control, controls, repo, repos. Repos are identified by their name. If multiple repos share the same name across VCS providers, use --provider to disambiguate, or tag the repo unambiguously by its internal ID with --repo-id (see: kosli get repo). Note: in dry-run mode the repo name is not resolved to its internal ID (no request is made to Kosli), so the previewed request URL contains the name as-is, whereas a real run sends the resolved ID. ## Flags | Flag | Type | Description | | :---------------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for tag | | `--provider` | string | \[optional] The VCS provider of the repo (e.g. github, gitlab). Only valid when tagging repos; required when multiple repos share the same name across providers. | | `--repo-id` | string | \[optional] The repo's internal ID (see: kosli get repo). Only valid when tagging repos; replaces the RESOURCE-ID argument and identifies the repo unambiguously. | | `-s`, `--set` | stringToString | \[optional] The key-value pairs to tag the resource with. The format is: key=value | | `-u`, `--unset` | strings | \[optional] The list of tag keys to remove from the resource. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Live Examples in different CI systems View an example of the `kosli tag` command in GitHub. In [this YAML file](https://github.com/cyber-dojo/aws-prod-co-promotion/blob/7494758f8bbc4e66cb5df90ef4cd6b72d75ca584/.github/workflows/promote_one.yml#L74) View an example of the `kosli tag` command in GitLab. In [this YAML file](https://gitlab.com/cyber-dojo/creator/-/blob/42876c4da26ee74e4bbfe14c2949cc7cb2d3345e/.gitlab/workflows/main.yml#L55) ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag flow yourFlowName --set key1=value1 --set key2=value2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env yourEnvironmentName --set key1=value1 --set key2=value2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env yourEnvironmentName --set key1=value1 --set key2=value2 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env yourEnvironmentName --unset key1=value1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag control yourControlIdentifier --set key1=value1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag repo yourOrg/yourRepoName --set key1=value1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag repo yourOrg/yourRepoName --provider github --set key1=value1 ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag repo --repo-id yourRepoID --set key1=value1 ``` # kosli unarchive control Source: https://docs.kosli.com/client_reference/kosli_unarchive_control Unarchive a Kosli control. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli unarchive control CONTROL-IDENTIFIER [flags] ``` Unarchive a Kosli control. Restores a previously archived control to the active state. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for control | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli unarchive control yourControlIdentifier ``` # kosli update control Source: https://docs.kosli.com/client_reference/kosli_update_control Update a Kosli control. This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update control CONTROL-IDENTIFIER [flags] ``` Update a Kosli control. Only the flags you provide are changed; omitted fields are left untouched. Providing `--link` replaces all of the control's existing links. ## Flags | Flag | Type | Description | | :-------------------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] The control description. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for control | | `--link` | stringToString | \[optional] A link for the control, given as 'name=url'. Can be repeated. Replaces all existing links. | | `-n`, `--name` | string | \[optional] The new control name. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update control yourControlIdentifier --name "New control name" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update control yourControlIdentifier --description "what this control checks" --link runbook=https://example.com/runbook ``` # kosli update default-org Source: https://docs.kosli.com/client_reference/kosli_update_default-org Set the default organization for the current user. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update default-org ORG-NAME [flags] ``` Set the default organization for the current user. The default organization is the one selected by default in the Kosli Web UI when you log in. ## Flags | Flag | Type | Description | | :---------------- | :--- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for default-org | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update default-org yourOrgName ``` # kosli update service-account Source: https://docs.kosli.com/client_reference/kosli_update_service-account Update a service account. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update service-account SERVICE-ACCOUNT-NAME [flags] ``` Update a service account. Only the flags you provide are changed; omitted fields are left untouched. ## Flags | Flag | Type | Description | | :-------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- | | `-d`, `--description` | string | \[optional] A description for the service account. | | `-D`, `--dry-run` | bool | \[optional] Run in dry-run mode. When enabled, no data is sent to Kosli and the CLI exits with 0 exit code regardless of any errors. | | `-h`, `--help` | bool | help for service-account | | `--privilege` | string | The privilege granted to the service account. One of: \[admin, member, snapshotter, reader]. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | ## Examples Use Cases These examples all assume that the flags `--api-token`, `--org`, `--host`, (and `--flow`, `--trail` when required), are [set/provided](/getting_started/install/#assigning-flags-via-environment-variables). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update service-account yourServiceAccountName --description "new description" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli update service-account yourServiceAccountName --privilege member ``` # kosli version Source: https://docs.kosli.com/client_reference/kosli_version Print the version of a Kosli CLI. ## Synopsis ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli version [flags] ``` Print the version of a Kosli CLI.\ The output will look something like this: version.BuildInfo\{Version:"v0.0.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.16.3"} * Version is the semantic version of the release. * GitCommit is the SHA for the commit that this version was built from. * GitTreeState is "clean" if there are no local code changes when this binary was built, and "dirty" if the binary was built from locally modified code. * GoVersion is the version of Go that was used to compile Kosli CLI. ## Flags | Flag | Type | Description | | :-------------- | :--- | :--------------------------------------------------- | | `-h`, `--help` | bool | help for version | | `-s`, `--short` | bool | \[optional] Print only the Kosli CLI version number. | ## Flags inherited from parent commands | Flag | Type | Description | | :------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | `-a`, `--api-token` | string | The Kosli API token. | | `-c`, `--config-file` | string | \[optional] The Kosli config file path. (default "kosli") | | `--debug` | bool | \[optional] Print debug logs to stdout. | | `-H`, `--host` | string | \[defaulted] The Kosli endpoint. (default "[https://app.kosli.com](https://app.kosli.com)") | | `--http-proxy` | string | \[optional] The HTTP proxy URL including protocol and port number. e.g. `http://proxy-server-ip:proxy-port` | | `-r`, `--max-api-retries` | int | \[defaulted] How many times should API calls be retried when the API host is not reachable. (default 3) | | `--org` | string | The Kosli organization. | | `-q`, `--quiet` | bool | \[optional] Suppress non-critical warning messages. Errors and normal output are not affected. If both `--quiet` and `--debug` are set, `--debug` wins. | # Output and verbosity Source: https://docs.kosli.com/client_reference/output_and_verbosity How the Kosli CLI writes output, what warnings mean, and how to control verbosity. This page explains where the Kosli CLI writes its output, what `[warning]` messages mean, and how to control verbosity in scripts and CI/CD pipelines. ## Where output goes The CLI splits its output across two streams: * **stdout** — Command results: created object IDs, JSON, tables, and any value intended to be piped or captured. * **stderr** — Warnings, debug lines, and the "new version available" update notice. The **exit code** is the authoritative success or failure signal. A non-zero exit code means the command failed; zero means it succeeded, regardless of what appeared on stderr. ## Warning messages Warnings are written in the form `[warning] ` and indicate a non-fatal condition that the CLI worked around. Examples: ```text theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} [warning] failed to get git repo info.
[warning] Repo URL will not be reported,
[warning] failed to remove evidence file :
``` Warnings: * Are always written to **stderr**. * **Never** affect the exit code. * Are not errors — the command completed successfully. If you see a warning in a pipeline that you have already validated end-to-end, it is safe to suppress it (see below). If a warning is new or unexpected, read the message and address the underlying cause. ## Verbosity controls | Flag | Effect | | --------------- | ------------------------------------------------------------------------------------------------------------------------ | | *(default)* | Errors and `[warning]` lines to stderr. Results to stdout. | | `-q`, `--quiet` | Suppresses `[warning]` lines. Errors still print. | | `--debug` | Adds `[debug]` lines to stderr. Overrides `--quiet`. | | `--debug=false` | Explicit-off form. Useful when a parent process or env var has enabled debug and you want to disable it for one command. | When both `--quiet` and `--debug` are set, `--debug` wins and a debug notice is printed explaining the override. Both flags have equivalent environment variables, following the standard `KOSLI_` prefix: * `KOSLI_QUIET=true` * `KOSLI_DEBUG=true` ## Warnings in CI/CD pipelines CI systems including Jenkins, Azure DevOps, Bitbucket Pipelines, and GitHub Actions multiplex stdout and stderr into a single build log. Some render stderr lines in red or with error-level styling. This makes non-fatal `[warning]` lines look alarming to pipeline reviewers even though they have no effect on the build. Once you have validated a workflow end-to-end, add `--quiet` (or set `KOSLI_QUIET=true`) to the Kosli CLI invocations to keep build logs clean: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic --quiet ... ``` Avoid redirecting all of stderr to `/dev/null` (for example, `kosli ... 2>/dev/null`). That hides genuine error messages and makes failures much harder to diagnose. Prefer `--quiet`, which suppresses only `[warning]` lines and keeps real errors visible. If you are capturing CLI output in a shell subshell and seeing debug or warning lines mixed into the captured value, see [CLI in subshell captures stderr](/troubleshooting/subshell_stderr). ## See also * [kosli root command and global flags](/client_reference/kosli) * [CLI in subshell captures stderr](/troubleshooting/subshell_stderr) # CLI Reference Source: https://docs.kosli.com/client_reference/overview Reference documentation for the Kosli CLI. This reference was generated from Kosli CLI **v2.39.2**. The Kosli CLI allows you to interact with Kosli from your terminal and CI/CD pipelines. For installation instructions, see [Install the Kosli CLI](/getting_started/install). ## Commands Browse the CLI commands using the sidebar navigation, or start with the [kosli](/client_reference/kosli) root command to see global flags and environment variable configuration. ## Output and verbosity See [Output and verbosity](/client_reference/output_and_verbosity) for how the CLI uses stdout and stderr, what `[warning]` messages mean, and how to control output in scripts and CI/CD pipelines with `--quiet` and `--debug`. # FAQ Source: https://docs.kosli.com/faq/faq Frequently asked questions Kosli API documentation is available for logged-in Kosli users at [app.kosli.com/api/v2/doc](https://app.kosli.com/api/v2/doc/). You can also find the link at [app.kosli.com](https://app.kosli.com) after clicking your avatar (top-right corner of the page). A number of flags won't change their values often (or at all) between commands, like `--org` or `--api-token`. Some will differ between e.g. workflows, like `--flow`. You can define them as environment variables to avoid unnecessary redundancy. Check [Environment variables](/getting_started/install#assigning-flags-via-environment-variables) to learn more. You can use dry run to disable writing to `app.kosli.com` — e.g. if you're just trying things out, or troubleshooting (dry run will print the payload the CLI would send in a non dry run mode). There are three ways to enable a dry run: 1. Use the `--dry-run` flag (no value needed) to enable it per command 2. Set the `KOSLI_DRY_RUN` environment variable to `true` to enable it globally (e.g. in your terminal or CI) 3. Set the `KOSLI_API_TOKEN` environment variable to `DRY_RUN` to enable it globally (e.g. in your terminal or CI) A config file is an alternative to using Kosli flags or environment variables. Usually you'd use a config file for values that rarely change — like api token or org — but you can represent all Kosli flags in a config file. The key for each value is the same as the flag name, capitalized, so `--api-token` becomes `API-TOKEN`, and `--org` becomes `ORG`, etc. You can use JSON, YAML, or TOML format: ```json kosli-conf.json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "ORG": "my-org", "API-TOKEN": "123456abcdef" } ``` ```yaml kosli-conf.yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ORG: "my-org" API-TOKEN: "123456abcdef" ``` ```toml kosli-conf.toml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ORG = "my-org" API-TOKEN = "123456abcdef" ``` When calling a Kosli command you can skip the file extension. For example, to list environments with `org` and `api-token` in the configuration file: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --config-file kosli-conf ``` `--config-file` defaults to `kosli`, so if you name your file `kosli.` and the file is in the same location as where you run Kosli commands from, you can skip the `--config-file` altogether. If an artifact or evidence is reported multiple times there are a few corner cases: **Template** — When an artifact is reported, the template for the flow is stored together with the artifact. If the template has changed between reports, the last template is considered the template for that artifact. **Evidence** — If a given named evidence is reported multiple times, the compliance status of the last reported version is considered the compliance state of that evidence. If an artifact is reported multiple times with different git-commits, the last reported version of the named commit-evidence is considered the compliance state. **Evidence outside the template** — If an artifact has evidence (commit or artifact evidence) that is not part of the template, the state of the extra evidence will affect the overall compliance of the artifact. The `--compliant` flag is a [boolean flag](#boolean-flags). To report generic evidence as non-compliant use `--compliant=false`: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli report evidence artifact generic server:1.0 \ --artifact-type docker \ --name test \ --description "generic test evidence" \ --compliant=false \ --flow server ``` `--compliant` is set to `true` by default, so to report as compliant simply skip the flag altogether. If you sign in to Kosli with GitHub, you must have a verified email address on your GitHub account — otherwise login will fail. You can check the status of your email addresses at [github.com/settings/emails](https://github.com/settings/emails). It's not possible to delete a policy in Kosli. This is by design, because there can be snapshots that were previously evaluated using the policy. Deleting it would compromise the integrity of those historical evaluations. Archiving policies isn't available yet. If this is something you'd find useful, we'd love to hear about your use case — reach out to us at [support@kosli.com](mailto:support@kosli.com). ## Boolean flags Flags with values can usually be specified with an `=` or with a **space** as a separator. For example, `--artifact-type=file` or `--artifact-type file`. Boolean flags accept both forms from CLI v2.36.0 onwards: ``` kosli attest generic Dockerfile --artifact-type file --compliant false ... ``` On earlier versions an explicitly specified boolean flag value **must** use an `=`. Either upgrade the CLI, or write the flag as `--compliant=false`. Without the `=` the command above fails with: ``` Error: accepts at most 1 arg(s), received 2 ``` because `--compliant` is parsed as if *implicitly* defaulting to `--compliant=true`, leaving: ``` kosli attest generic Dockerfile false ... ``` The parser then sees `Dockerfile` and `false` as the two arguments to `kosli attest generic`. ## Empty flag values A flag given an empty value is an error from CLI v2.37.0 onwards: ``` kosli attest generic Dockerfile --artifact-type file --exclude "" ... Error: flag '--exclude' was given an empty value ``` The usual cause is a shell variable that is unset, so `--exclude "$BUILD_TMP"` reaches the CLI as `--exclude ""`. The same applies to a value from a `KOSLI_` environment variable or from `~/.kosli.yml`, and to an empty element of a comma-separated list such as `--exclude "node_modules,,vendor"`. On earlier versions most of these were accepted silently. `--exclude ""` excluded nothing, so the fingerprint was one no artifact matched; `--fingerprint ""` recorded an attestation against the trail rather than the artifact named; `--redact-commit-info ""` sent the commit author and message the flag exists to withhold. Each exited 0 and printed what success prints. Either give the flag a real value, or remove it. In almost every case an empty value did what leaving the flag out does, so removing it keeps the earlier behavior and says so plainly. Leaving a flag out is unchanged, including the values filled in from your CI environment, such as `--build-url`, `--commit-url` and `--repository`. One case the CLI cannot catch: a boolean flag written without quotes loses the empty value in the shell rather than in the CLI, so `--compliant ${UNSET}` arrives as `--compliant` with nothing after it, which is indistinguishable from typing `--compliant` deliberately. Quote the variable, `--compliant "${VAR}"`, and it is refused like any other empty value. # Artifacts Source: https://docs.kosli.com/getting_started/artifacts Learn how to attest artifacts to Kosli and establish binary provenance. In software processes, you typically generate one or more artifacts that are deployed or distributed, such as docker images, archives, binaries, etc. You can ensure traceability for the creation of these artifacts by attesting them to Kosli, thereby establishing a binary provenance for each one. ## Binary provenance Binary provenance for artifacts refers to the ability to trace and verify the origins, history, and journey of the artifacts throughout their lifecycle. This involves recording immutable attestations about the artifact creation, risk controls performed on it, deployments, and execution/usage. Artifacts are uniquely identified by their SHA256 fingerprints. When attesting an artifact to Kosli, you have the option to either provide the fingerprint manually or allow Kosli CLI to calculate it automatically for you. By leveraging the artifact's fingerprint, Kosli can establish connections between the creation of the artifact and its runtime-related events, such as when the artifact starts or ceases execution within a specific environment. By establishing and maintaining binary provenance for artifacts, Kosli enables you to: 1. **Track Changes**: Trace how your Flow artifacts change over time. 2. **Identify Sources**: Understand where your artifacts originated from, which can help in identifying vulnerabilities or issues. 3. **Monitor Compliance**: Ensure that the artifacts adhere to your compliance requirements. 4. **Enable Audits**: Access audit packages on demand allowing audits and investigations into the software supply chain. 5. **Enhance Trust**: Build trust among users, customers, and stakeholders by providing transparent and verified information about the software's history. ## Attesting artifacts To attest an artifact, you can run a command similar to the one below: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact project-a-app.bin \ --artifact-type file \ --build-url https://exampleci.com \ --commit-url https://github.com/ProjectA/ProjectAApp/commit/e67f2f2b121f9325ebf166b7b3c707f73cb48b14 \ --commit e67f2f2b121f9325ebf166b7b3c707f73cb48b14 \ --flow project-a \ --trail trail-1 \ --name backend ``` The `--artifact-type` flag is used to determine the type of artifact being attested. The following types are supported: * **file**: for any single file artifacts (e.g. a binary, Jar file, etc.) * **dir**: for directory artifacts. * **docker**: for docker images that are pulled on the machine. This option depends on having a running Docker daemon on the machine. * **oci**: for container images in docker or OCI format. The fingerprint is fetched directly from the registry. **`docker` requires the image to exist in a registry.** Kosli reads the image's repo digest via the local Docker daemon, and a freshly built image (just `docker build`) does not have one until it has been pushed to or pulled from a registry. If you attest an image that has only been built locally, you will see: ``` Error: repo digest unavailable for the image, has it been pushed to or pulled from a registry? ``` You have two options: * Push the image to a registry first, then attest it. * Use `--artifact-type=oci` and let Kosli fetch the digest directly from the registry. See [repo digest unavailable](/troubleshooting/repo_digest_unavailable) for more detail. See [kosli attest artifact](/client_reference/kosli_attest_artifact/) for more details. ## The `--dry-run` flag All Kosli CLI commands which write data accept the `--dry-run` [boolean flag](/faq/#boolean-flags). When this flag is used, a CLI command: * Does not communicate with Kosli at all * Prints the payload it would have sent * Exits with a zero status code We recommend using the `KOSLI_DRY_RUN` environment variable to automatically set the `--dry-run` flag. This will allow you to instantly turn off all Kosli CLI commands if Kosli is down, as detailed in [this tutorial](/troubleshooting/what_do_i_do_if_kosli_is_down). The `--dry-run` flag is also useful when trying commands locally. For example: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact cyberdojo/differ:dde3b2a \ --artifact-type=docker \ --org=cyber-dojo \ --flow=differ-ci \ --trail=$(git rev-parse HEAD) \ --dry-run \ ... { "fingerprint": "0f53b5b9e7c266defe6984deafe039b116295b2df4a409ba6288c403f2451a9f", "filename": "cyberdojo/differ:dde3b2a", "git_commit": "fbb9e8000e2344323040e348a54b33ecbf67f273", "git_commit_info": { "sha1": "fbb9e8000e2344323040e348a54b33ecbf67f273", "message": "improve coverage report info (#2796)", "author": "Jon Jagger \u003cjon@jaggersoft.com\u003e", "timestamp": 1733724563, "branch": "master", "url": "https://github.com/kosli-dev/server/commit/fbb9e8000e2344323040e348a54b33ecbf67f273" }, "build_url": "https://github.com/cyber-dojo/differ/actions/runs/11777650898", "commit_url": "https://github.com/cyber-dojo/differ/commit/dde3b2a7dab8e4567038e4c66ac68f0f01d0f704", "repo_url": "https://github.com/kosli-dev/server", "template_reference_name": "differ", "trail_name": "dde3b2a7dab8e4567038e4c66ac68f0f01d0f704" } $ echo $? 0 ``` # Attestations Source: https://docs.kosli.com/getting_started/attestations Learn how to make attestations to Kosli to prove compliance in your software supply chain. Attestations are how you record the facts you care about in your software supply chain. They are the evidence that you have performed certain activities, such as running tests, security scans, or ensuring that a certain requirement is met. Kosli allows you to report different types of attestations about artifacts and trails. Kosli will process the evidence you provide and conclude whether the evidence proves compliance or otherwise. Let's take a look at this example to understand how to make attestations to Kosli. ## Example overview The following compliance template is expecting 4 attestations, each with its own `name`. ```yml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/flow-template/v1.json version: 1 trail: attestations: - name: jira-ticket type: jira artifacts: - name: backend attestations: - name: unit-tests type: junit - name: security-scan type: snyk ``` See the [Flow Template reference](/template-reference/flow_template) for the full specification, available attestation types, and editor validation with JSON Schema. It expects `jira-ticket` on the trail, the `backend` artifact, with `unit-tests` and `security-scan` attached to it. When you make an attestation, you have the choice of what `name` to attach it to. ### Steps The following sections show how to make each of the four attestations defined in the template above. The `jira-ticket` attestation belongs to a single trail and is not linked to a specific artifact. In this example, the id of the trail is the git commit. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest jira \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --name jira-ticket ... ``` Some attestations are attached to a specific artifact, like the unit tests for the `backend` artifact. Often, evidence like unit tests are created *before* the artifact is built. To attach the evidence to the artifact before its creation, use `backend` (the artifact's `name` from the template), as well as `unit-tests` (the attestation's `name` from the template). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest junit \ --name backend.unit-tests \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ ... ``` This attestation belongs to any artifact attested with the matching `name` from the template (in this example `backend`) and a matching git commit. Notice this command has **no fingerprint**, no `--artifact-type`, and no positional artifact argument. When you pass `--commit` without a fingerprint, Kosli does not calculate or assume any fingerprint — it stores the attestation as *pending* against the artifact's **template name + commit** and binds it to the real fingerprint later, when an `artifact` attestation arrives for that same template name and commit. The match key is `(template artifact name, git commit)` — not the fingerprint. The fingerprint is only resolved retroactively once the artifact itself is reported. Order doesn't matter: you can report `backend.unit-tests` before or after `backend` itself. See [Reporting a custom attestation → Attest before the artifact exists](/tutorials/attest_custom#3-attest-before-the-artifact-exists) for the full subtleties. Once the artifact has been built, it can be attested with the following command. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact my_company/backend:latest \ --artifact-type docker \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --name backend ... ``` In this case the Kosli CLI will calculate the fingerprint of the docker image called `my_company/backend:latest` and attest it as the `backend` artifact `name` in the trail. In all attestation commands the Kosli CLI automatically gathers the git commit and other information from the current git repository and the [CI environment](/integrations/ci_cd). This is how the git commit is used to match attestations to artifacts. Often, evidence like snyk reports are created *after* the artifact is built. In this case, you can attach the evidence to the artifact after its creation. Use `backend` (the artifact's `name` from the template), as well as `security-scan` (the attestation's `name` from the template) to name the attestation. The following attestation will only belong to the artifact `my_company/backend:latest` attested above and its fingerprint, in this case calculated by the Kosli CLI. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest snyk \ --artifact-type docker my_company/backend:latest \ --name backend.security-scan \ --flow backend-ci \ --trail $(git rev-parse HEAD) ... ``` ## Compliance ### Attesting with a template The four attestations above are all made against a Flow named `backend-ci` and a Trail named after the git commit. Typically, the Flow and Trail are explicitly setup before making the attestations (e.g. at the start of a CI workflow). This is done with the `create flow` and `begin trail` commands, either of which can specify the name of the template yaml file above (e.g. `.kosli.yml`) whose contents define overall compliance. For example: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow backend-ci \ --template-file .kosli.yml ... kosli begin trail $(git rev-parse HEAD) \ --flow backend-ci \ ... ``` An attested `backend` artifact is then compliant if and only if all the template attestations have been made against it and are themselves compliant: * `jira-ticket` on its Trail * `backend.unit-tests` for its junit evidence * `backend.security-scan` for its snyk evidence If any of these attestations are missing, or are individually non-compliant then the `backend` artifact is non-compliant. ### Attesting without a template An attestation can also be made against a Flow and Trail **not** previously explicitly setup. In this case a Flow and Trail will be automatically setup but there will be no template yaml file defining overall compliance. The compliance of any attested artifact will depend only on the compliance of the attestations actually made and never because a specific attestation is missing. ### Attestation immutability You can set/edit the template yml file for the Flow/Trail at any time. This will affect compliance evaluations made after the edit. It will not affect earlier records of compliance evaluations (e.g. in Environment Snapshots). Attestations are append-only immutable records. You can report the same attestation multiple times, and each report will be recorded. However, only the latest version of the attestation is considered when evaluating compliance. ## Evidence Vault Along with attestations data, you can attach additional supporting evidence files. These will be securely stored in Kosli's **Evidence Vault** and can easily be retrieved when needed. Alternatively, you can store the evidence files in your own preferred storage and only attach links to it in the Kosli attestation. For `JUnit` attestations (see below), Kosli automatically stores the JUnit XML results files in the Evidence Vault. You can disable this by setting `--upload-results=false` ## Attaching data to attestations All `kosli attest` commands support flags for attaching additional data. These flags accept file paths but serve different purposes: | Flag | Available on | Purpose | | -------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------- | | `--user-data` | All evidence attest commands | Attach structured JSON metadata that is stored and visible alongside the attestation in the Kosli UI | | `--attachments` | All evidence attest commands | Upload files or directories to the Evidence Vault as compressed archives for later download | | `--attestation-data` | `attest custom` only | Provide the JSON payload that the custom type's jq rules evaluate to determine compliance | | `--annotate` | All evidence attest commands | Attach `key=value` annotations that are displayed as a label/value pair on the attestation in the Kosli UI | ### When to use which Use **`--user-data`** when you want to store additional context — such as build metadata, environment variables, or tool versions — that is visible alongside the attestation in the Kosli UI. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic \ --name security-scan \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --user-data scan-metadata.json ``` Use **`--attachments`** when you want to archive files for audit purposes — such as test reports, scan output, or policy files — in the Evidence Vault for later retrieval. Provide multiple paths as a comma-separated list. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic \ --name security-scan \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --attachments scan-report.html,scan-config.yml ``` Use **`--attestation-data`** on `kosli attest custom` to provide the JSON data that the custom attestation type's jq expression evaluates. This is what determines the compliance status of the attestation. See the [Custom](#custom) attestation type below for details. The `--attestation-data` JSON payload sent to Kosli is limited to 1 MB; larger payloads fail with a 400 error. For larger reports, distill the data you need into a summary and attach the full document separately — see [Attesting large documents](/tutorials/attest_large_documents). ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom \ --type coverage-metrics \ --name unit-tests \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --attestation-data coverage-results.json ``` These flags can be combined. For example, you can use `--attestation-data` for compliance evaluation, `--user-data` to store extra metadata, and `--attachments` to archive the full report — all on the same attestation. ### Annotating attestations Use **`--annotate`** to attach lightweight `key=value` pairs to an attestation. Annotations are intended for short, human-readable context (links, ticket IDs, build numbers, environment names, etc.) that should appear directly on the attestation in the Kosli UI. For larger structured metadata, prefer `--user-data`. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest generic \ --name security-scan \ --flow backend-ci \ --trail $(git rev-parse HEAD) \ --annotate scan_tool=trivy \ --annotate report_url=https://ci.example.com/runs/42 ``` Keys may only contain `[A-Za-z0-9_]` (letters, digits, and underscores). You can pass `--annotate` multiple times to add several annotations to the same attestation. **How annotations appear in the Kosli UI** Annotation **keys** are automatically humanized for display: underscores become spaces and the first letter is capitalized. For example, the key `something_key` is rendered as `Something key`. Annotation **values** are displayed as-is, except that values that are valid URLs are automatically rendered as clickable links. Choose your annotation keys with this transformation in mind — e.g. use `report_url` (displayed as `Report url`) rather than mixed-case or camelCase keys. ## Attestation types Currently, we support the following types of evidence: If you use GitHub, Bitbucket, Gitlab or Azure DevOps you can use Kosli to verify if a given git commit comes from a pull/merge request. Currently, the status of the PR does NOT impact the compliance status of the attestation. If there is no pull request for the commit, the attestation will be reported as `non-compliant`. You can choose to short-circuit execution in case pull request is missing by using the `--assert` flag. See the CLI reference for the following commands for more details and examples: * [attest Github PR ](/client_reference/kosli_attest_pullrequest_github/) * [attest Bitbucket PR ](/client_reference/kosli_attest_pullrequest_bitbucket/) * [attest Gitlab PR ](/client_reference/kosli_attest_pullrequest_gitlab/) * [attest Azure Devops PR ](/client_reference/kosli_attest_pullrequest_azure/) If you produce your test results in JUnit format, you can attest the test results to Kosli. Kosli will analyze the JUnit results and determine the compliance status based on whether any tests have failed and/or errored or not. See [attest JUnit results to an artifact or a trail](/client_reference/kosli_attest_junit/) for usage details and examples. You can report results of a Snyk security scan to Kosli and it will analyze the Snyk scan results and determine the compliance status based on whether vulnerabilities were found or not. See [attest Snyk results to an artifact or a trail](/client_reference/kosli_attest_snyk/) for usage details and examples. You can use the Jira attestation to verify that a git commit or branch contains a reference to a Jira issue and that an issue with the same reference does exist in Jira. If Jira reference is found in a commit message, that reference will be reported as evidence. If the reference is not found in the commit message, Kosli CLI will check if it's a part of a branch name. Kosli CLI will also verify and report if the detected issue reference is found and accessible on Jira (reported as compliant) or not (reported as non compliant). See [attest Jira issue to an artifact or a trail](/client_reference/kosli_attest_jira/) for usage details and examples. You can report the results of a SonarQube Server or SonarQube Cloud scan to Kosli. Kosli will use the status of the scan's Quality Gate (passing or failing) to determine the compliance status. These scan result can be attested in two ways: * Using Kosli's [webhook integration](/integrations/sonar) with Sonar * Using [Kosli's CLI](/client_reference/kosli_attest_sonar) The above attestations are all "fully typed" - each one knows how to interpret its own particular kind of input. For example, `kosli attest snyk` interprets the sarif file produced by a snyk container scan to determine the `true/false` value. If you're using a tool that does not yet have a corresponding kosli attest command we recommend creating your own custom attestation type. A custom attestation type specifies one or more arbitrary evaluation rules. These rules can have an optional schema specifying the types of the names used in the rules, whether they are required, whether they have defaults, etc. When a custom attestation is made using this type its rules are applied to the provided custom attestation data to determine its `true/false` compliance status. For example, suppose you wish to attest coverage metrics captured as part of a unit-test run. The coverage metrics are being saved in a file called `unit-test-coverage.json` as follows: ```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "code": { "lines": { "missed": 32, "total": 1209 } }, ... } ``` You could create a custom attestation type called `coverage-metrics` using a [jq expression](https://jqlang.org/manual/) rule defining a minimum line coverage of 95%: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type coverage-metrics --jq=".code.lines.missed / .code.lines.total * 100 <= 5" ``` You could then make your custom attestation with the json file: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest custom --type=coverage-metrics --attestation-data=unit-test-coverage.json ... ``` For this attestation, Kosli would: * Evaluate the rule `.code.lines.missed / .code.lines.total * 100 <= 5` * Using the values from the file `unit-test-coverage.json` * `.code.lines.missed` is `32` * `.code.lines.total` is `1209` * So `32 / 1209 * 100 <= 5` evaluates to `2.64 <= 5` which is `true` See: * [create custom attestation type](/client_reference/kosli_create_attestation-type) and * [report custom attestation to an artifact or a trail](/client_reference/kosli_attest_custom/) for usage details and examples. Generic attestations are an earlier, much less sophisticated version of custom attestations. We recommend using custom attestations instead of generic attestations. See [report generic attestation to an artifact or a trail](/client_reference/kosli_attest_generic/) for usage details and examples. # Authenticating to Kosli Source: https://docs.kosli.com/getting_started/authenticating_to_kosli How to get an API token for the Kosli CLI and API, and where to manage credentials. Most interactions with Kosli — from the CLI, the API, or CI/CD pipelines — require an API token. This page covers the quickest path to getting one and points to the deeper documentation for each topic. ## Pick a credential type | Use case | Credential | Where to manage it | | ------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------- | | CI/CD, runtime reporters, automation | **Service account API key** (recommended) | [Service accounts](/administration/authentication/service_accounts) | | Interactive scripts tied to your user | **Personal API key** | [Personal API keys](/user/personal_api_keys) | For anything automated, use a service account. Personal API keys inherit your user's permissions across every organization you belong to, which is rarely what you want for a pipeline. ## Quick start: get a token Open the Kosli web app and sign in: * EU: [app.kosli.com](https://app.kosli.com) * US: [app.us.kosli.com](https://app.us.kosli.com) * **For CI/CD**, follow [Service accounts](/administration/authentication/service_accounts) to create a service account and generate its first API key. * **For your own scripts**, follow [Personal API keys](/user/personal_api_keys) to generate a key tied to your user. Kosli stores only a hash of the token, so the original is shown once and cannot be retrieved later. Paste it straight into your secret store. ## Use the token Pass the token as a bearer token when calling the API directly: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -H "Authorization: Bearer <>" \ https://app.kosli.com/api/v2/environments/<> ``` For CLI usage, basic auth, and full examples, see [API authentication methods](/administration/authentication/api_authentication_methods). ## See also * [Service accounts](/administration/authentication/service_accounts) — admin lifecycle for machine credentials. * [API key rotation](/administration/authentication/api_key_rotation) — how rotation works, with a [step-by-step tutorial](/tutorials/rotating_api_keys). * [Roles in Kosli](/administration/managing_users/roles_in_kosli) — what users and service accounts can do at each role. # Enforce policies Source: https://docs.kosli.com/getting_started/enforce_policies Block non-compliant artifacts from deploying by enforcing policies in CI/CD pipelines, via the API, or with Kubernetes admission controllers. Environment policies define what an artifact needs to be compliant. Policy enforcement gates check artifacts against those requirements and block deployments when they fall short. You can enforce policies: * As a **CI/CD pipeline step** that fails the build on non-compliance * Through the **Kosli API** for custom tooling * Via a **Kubernetes admission controller** that rejects non-compliant pods All methods use the same assertion: checking an artifact's fingerprint against an environment, specific policies, or a flow template. ## Assertion scopes `kosli assert artifact` (and its API equivalent) supports three assertion modes: | Mode | CLI flag | When to use | | ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------ | | Environment | `--environment` | Check all policies attached to the target environment. The most common choice for deployment gates. | | Specific policies | `--policy` | Check one or more named policies, regardless of environment attachment. Useful for promotion gates between stages. | | Flow templates | *(no scope flag)* | Check against the template files of the flows the artifact appears in. | `--environment` and `--policy` are mutually exclusive. `--flow` can be combined with any mode to narrow the lookup to a specific flow. Without `--flow`, all flows containing the artifact (by fingerprint) are considered. See [`kosli assert artifact`](/client_reference/kosli_assert_artifact) for the full flag reference. ## Enforce in CI/CD pipelines Add `kosli assert artifact` as a step before your deployment step. If the artifact is non-compliant, the command exits with a non-zero status and the pipeline fails. ### Assert against an environment Check all policies attached to the target environment: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Assert artifact compliance env: KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} KOSLI_ORG: my-org run: | kosli assert artifact ${{ env.IMAGE }} \ --artifact-type oci \ --environment production ``` ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} assert-compliance: stage: deploy script: - kosli assert artifact $IMAGE \ --artifact-type oci \ --environment production variables: KOSLI_API_TOKEN: $KOSLI_API_TOKEN KOSLI_ORG: my-org ``` ### Assert against specific policies Check one or more named policies directly. This is useful when gating a promotion between stages or checking policies that are not attached to an environment: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli assert artifact $IMAGE \ --artifact-type oci \ --policy has-tests,has-review ``` Use `--dry-run` to test assertions without sending data to Kosli. The CLI prints the compliance result but always exits with code 0. ## Enforce via the API For custom deployment tooling or non-CI contexts, call the assert endpoint directly: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -s \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ "https://app.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?environment_name=production" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -s \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ "https://app.us.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?environment_name=production" ``` The response includes: * `compliant` — `true` or `false` * `policy_evaluations` — detailed results per policy (when asserting against an environment) * `compliance_status` — per-attestation compliance breakdown To assert against specific policies instead of an environment: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -s \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ "https://app.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?policy_name=has-tests&policy_name=has-review" ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -s \ -H "Authorization: Bearer $KOSLI_API_TOKEN" \ "https://app.us.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?policy_name=has-tests&policy_name=has-review" ``` See the [Assert artifact API reference](/api-reference/asserts/assert-artifact) for the full response schema. You can also try it out directly in the API playground on that page. ## Enforce with a Kubernetes admission controller A Kubernetes [validating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) can call the Kosli assert API when a pod is created and reject pods whose images are non-compliant. The flow is: Kubernetes calls your admission webhook before scheduling the pod. The webhook reads the container image reference from the pod spec and resolves its SHA256 digest. The webhook sends a request to the [assert endpoint](/api-reference/asserts/assert-artifact) with the fingerprint and the target environment name. If `compliant` is `true`, the pod is admitted. If `false`, the webhook rejects the pod with a message explaining which policy requirements were not met. **Experimental example:** [`kosli-dev/kosli-admission-webhook`](https://github.com/kosli-dev/kosli-admission-webhook) is a reference implementation of a Kubernetes admission webhook that asserts container image compliance in Kosli before scheduling. It is provided as an example to get you started and not a supported product — feedback is welcome! The [Kosli K8S Reporter](/helm/k8s_reporter) reports what is running in your Kubernetes environments to Kosli. Pair it with an admission controller to both enforce and monitor compliance. ## What happens on failure **CLI:** A non-compliant artifact causes `kosli assert artifact` to exit with a non-zero code. CI/CD pipelines treat this as a failed step and stop the deployment. Use `--output json` to get machine-readable compliance details. **API:** The response body returns `compliant: false` with a `compliance_status` object describing which attestations are missing or non-compliant, and `policy_evaluations` listing per-policy results. # Environments Source: https://docs.kosli.com/getting_started/environments Learn how to create and manage Kosli environments to track your runtime artifacts. Kosli environments allow you to record the artifacts running in your runtime environments and how they change. Every time an environment change (or a set of changes) is reported, Kosli creates a new environment snapshot containing the status of the environment at a given point in time. The change record created in Kosli enables you to retrospectively perform runtime forensics about what ran where and when. ## Create an environment You can create Kosli environments via the CLI, UI or the API. When you create an environment, you give it a name, a description and select its type. Make sure that type of Kosli environment matches the type of the environment you'll be reporting from. To create an environment via CLI, you would run a command like this: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create environment quickstart \ --type docker \ --description "quickstart environment for tutorial" ``` See [kosli create environment](/client_reference/kosli_create_environment/) for CLI usage details and examples. You can also create an environment directly from [app.kosli.com](https://app.kosli.com). * Make sure you've selected the organization you want to use from the orgs dropdown in the top left corner. * Click on `Environments` in the left navigation menu. * Click the `Add new environment` button * Fill in the environment name and description and select a type, then click `Save Environment`. After the new environment is created you'll be redirected to its page, which will initially have no snapshots. Once you start reporting your actual runtime environment to Kosli you'll be able to find snapshots and events (such as which artifacts started or stopped running) listed on that page. ## Snapshoting an environment To record the current status of your environment you need to use the Kosli CLI to snapshot the running artifacts in it and report it to Kosli. When Kosli receives an environment report, if the received list of running artifacts is different than what is in the latest environment snapshot, a new snapshot is created. Snapshots are immutable and can't be tampered with. Currently, the following environment types are supported: * Kubernetes * Docker * Paths on a server * AWS Simple Storage Service (S3) * AWS Lambda * AWS Elastic Container Service (ECS) * Azure Web Apps and Function Apps * Google Cloud Run (services and jobs) You can report environment snapshots manually using the `kosli snapshot [...]` commands for testing. For production use, however, you would configure the reporting to happen automatically on regular intervals, e.g. via a cron job or scheduled CI job, or on certain events. You can follow one of the tutorials below to setup automatic snapshot reporting for your environment: * [Kubernetes environment reporting](/tutorials/report_k8s_envs) * [AWS ECS/S3/Lambda environment reporting](/tutorials/report_aws_envs) * [Cloud Run environment reporting](/tutorials/report_cloud_run_envs) ### Snapshotting scopes Depending on the type of your environment, you can scope what to snapshot from the environment. The following table shows the different scoping options currently available for different environment types: | what to snapshot -> | all resources | resources by names | resources by Regex | exclude by names | exclude by Regex | | ----------------------------- | ------------- | ------------------ | ------------------ | ---------------- | ---------------- | | ECS (clusters) | √ | √ | √ | √ | √ | | Lambda (functions) | √ | √ | √ | √ | √ | | S3 (buckets) | | | | | | | docker (containers) | √ | | | | | | k8s (namespaces) | √ | √ | √ | √ | √ | | azure (functions and apps) | √ | | | | | | cloud-run (services and jobs) | √ | √ | √ | √ | √ | ## Environment Compliance An environment's compliance state is determined by its attached policies. The compliance state can be: * Compliant - All artifacts in the snapshot satisfy the requirements defined in attached policies * Non-compliant - One or more artifacts violate the requirements defined in attached policies * Unknown - No policies are attached to the environment, compliance requirements are undefined When you create a new environment, it starts with an Unknown compliance state since no policies are attached by default. To establish compliance requirements, you need to attach at least one policy to the environment (see [Environment Policies](/getting_started/policies)) If you detach all policies from an environment, its compliance state returns to Unknown since there are no longer any defined requirements for artifacts running in it. ## Tagging environments Tags are custom key-value pairs you attach to environments to categorize, filter, and add metadata. Common patterns include tagging by deployment stage (`tier=prod`), owning team (`team=platform`), or region (`region=eu-west-1`). You can add tags via the CLI, Terraform, or the API: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli tag env production-k8s \ --set tier=prod \ --set team=platform \ --set region=eu-west-1 ``` Tags can also be referenced in [Environment Policy](/getting_started/policies) expressions to make attestation requirements conditional — for example, requiring security scans only for flows tagged `risk-level=high`. For the full guide on managing tags, recommended patterns, and usage in policies, see [Managing Tags](/administration/managing_tags). ## Logical Environments Logical environments are a way to group your Kosli environments so you can view all changes happening in your group in the same place. For example, if what you consider to be “Production” is a combination of a Kubernetes cluster, an S3 bucket, and a configuration file, you can combine the reports sent to these Kosli environments into a “Production” logical environment. A logical environment can be created in the app or the CLI, and physical environments can be assigned to it in the app or with the [`kosli join environment`](/client_reference/kosli_join_environment/) command. # Flows Source: https://docs.kosli.com/getting_started/flows Learn about Kosli Flows, how to create and manage them. A Kosli Flow represents a business or software process that requires change tracking. It allows you to monitor changes across all steps within a process or focus specifically on a subset of critical steps. In all the commands below we skip the required `--api-token` and `--org` flags for brevity. These can be set as described [here](/getting_started/install#assigning-flags-via-config-files). ## Create a flow To create a Flow, you can run: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow process-a --description "My SW delivery process" \ --use-empty-template ``` ## Flow template When creating a Flow, you can optionally provide a `Flow Template`. This template defines the necessary steps within the business or software process represented by a Kosli Flow. The compliance of Flow trails and artifacts will be assessed using the template. A Flow template is a YAML file following the syntax outlined in the [flow template spec](/template-reference/flow_template). Here is an example: ```yml sw-delivery-template.yml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/flow-template/v1.json version: 1 trail: attestations: - name: jira-ticket type: jira artifacts: - name: backend attestations: - name: unit-tests type: junit ``` ### Create a Flow with a template To create a Flow with a template, you can run: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow process-a --description "My SW delivery process" \ --template-file sw-delivery-template.yml ``` ## Update a Flow Rerunning the command with different description or template file will update the Flow. See [kosli create flow](/client_reference/kosli_create_flow/) for more details. # Install Kosli CLI Source: https://docs.kosli.com/getting_started/install Instructions to install Kosli CLI on various platforms Kosli CLI can be installed from package managers, by Curling pre-built binaries, or can be used from the distributed Docker images. You can download the correct Kosli CLI for your platform, given that you can run shell scripts on it, by invoking this one-line script: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -fL https://raw.githubusercontent.com/kosli-dev/cli/refs/heads/main/install-cli.sh | sh ``` You can run the Kosli CLI with docker: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} docker run --rm ghcr.io/kosli-dev/cli:v{{< cli-version >}} ``` The `entrypoint` for this container is the kosli command. To run any kosli command you append it to the `docker run` command above – without the `kosli` keyword. For example to run `kosli version`: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} docker run --rm ghcr.io/kosli-dev/cli:v{{< cli-version >}} version ``` If you have [Homebrew](https://brew.sh/) (available on MacOS, Linux or Windows Subsystem for Linux), you can install the Kosli CLI by running: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} brew install kosli-cli ``` On Ubuntu or Debian Linux, you can use APT to install the Kosli CLI by running: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} sudo sh -c 'echo "deb [trusted=yes] https://apt.fury.io/kosli/ /" > /etc/apt/sources.list.d/fury.list' # On a clean debian container/machine, you need ca-certificates sudo apt install ca-certificates sudo apt update sudo apt install kosli ``` On RedHat Linux, you can use YUM to install the Kosli CLI by running: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} cat <> /etc/yum.repos.d/kosli.repo [kosli] name=Kosli public Repo baseurl=https://yum.fury.io/kosli/ enabled=1 gpgcheck=0 EOT ``` If you get mirrorlist errors (likely if you are on a clean centos container): ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} cd /etc/yum.repos.d/ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* ``` ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} yum update -y yum install kosli ``` You can download the Kosli CLI from [GitHub](https://github.com/kosli-dev/cli/releases). Make sure to choose the correct tar file for your system. For example, on Mac with AMD: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -L https://github.com/kosli-dev/cli/releases/download/v{{< cli-version >}}/kosli_{{< cli-version >}}_darwin_amd64.tar.gz | tar zx sudo mv kosli /usr/local/bin/kosli ``` If you have [Node.js](https://nodejs.org/) (v18 or later), you can install the Kosli CLI globally via npm: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} npm install -g @kosli/cli ``` Or using npx to run it without installing: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} npx @kosli/cli version ``` You can build Kosli CLI from source by running: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} git clone git@github.com:kosli-dev/cli.git cd cli make build ``` Run this command: ```shell {.command} theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli version ``` The expected output should be similar to this: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} version.BuildInfo{Version:"{{< cli-version >}}", GitCommit:"Homebrew", GitTreeState:"clean", GoVersion:"go1.23.4"} ``` New to Kosli? The [Kosli Learning Labs](/labs) provide a guided, project-based introduction covering Flows, Trails, attestations, and runtime compliance. ## Using the CLI The [CLI Reference](/client_reference/) section contains all the information you may need to run the Kosli CLI. The CLI flags offer flexibility for configuration and can be assigned in three distinct manners: 1. Directly on the command line. 2. Via environment variables. 3. Within a config file. Among these options, priority is given in the following order: Option 1 holds the highest precedence, followed by Option 2, with Option 3 being the least prioritized. ### Assigning flags via environment variables To assign a CLI flag using environment variables, generate a variable prefixed with KOSLI\_. Use the flag's name in uppercase and substitute any internal dashes with underscores. For instance: * `--api-token` corresponds to `KOSLI_API_TOKEN` * `--org` corresponds to `KOSLI_ORG` ### Assigning flags via config files A config file is an alternative to using Kosli flags or environment variables. You could use a config file for the values that rarely change - like API token or org, but you can represent all Kosli flags in a config file. Each key in the config file corresponds to the flag name, capitalized. For instance: * `--api-token` would become `API-TOKEN`. * `--org` would become `ORG`. Config files can be written in JSON, YAML, or TOML formats. To direct Kosli CLI to use a config file, employ the --config-file flag when executing Kosli commands. By default, the CLI looks for a config file called `kosli.` Below are examples of different config file formats: ```json kosli-conf.json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "ORG": "my-org", "API-TOKEN": "123456abcdef" } ``` ```yaml kosli-conf.yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ORG: "my-org" API-TOKEN: "123456abcdef" ``` ```toml kosli-conf.toml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ORG = "my-org" API-TOKEN = "123456abcdef" ``` When using the `--config-file` flag you can skip the file extension. For example, to list environments with `org` and `api-token` in the configuration file you would run: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list environments --config-file=kosli-conf ``` # Environment Policies Source: https://docs.kosli.com/getting_started/policies Define and enforce compliance requirements for artifact deployments across different environments. Environment Policies enable you to define and enforce compliance requirements for artifact deployments across different environments. With Environment Policies, you can: * Define specific requirements for each environment (e.g, dev, staging, prod) * Enforce consistent compliance standards across your deployment pipeline * Prevent non-compliant artifacts from being deployed (via admission controllers) Policies are written in YAML and are immutable (updating a policy creates a new version). They can be attached to one or more environments, and an environment can have one or more policies attached to it. ## Create a Policy You can create a policy via CLI or via the API. Here is a basic policy that requires provenance and specific attestations: ```yaml prod-policy.yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: # the rules apply to artifacts in an environment snapshot provenance: required: true # all artifacts must have provenance attestations: - name: dependency-scan # all artifacts must have dependency-scan attestation type: "*" # any attestation type - name: unit-test # all artifacts must have unit-test attestation type: junit # must be a 'junit' attestation type ``` You can create and manage policies using the Kosli CLI (global flags like org and api-token are omitted for brevity): ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create policy prod-requirements prod-policy.yaml ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get policy prod-requirements ``` See [kosli create policy](/client_reference/kosli_create_policy/) for usage details and examples. Once you create a policy, you will be able to see it in the UI under `policies` in the left navigation menu. ## Policy rules A policy consists of rules which are applied to artifacts in an environment snapshot. ### Provenance When `provenance` is set to `required: true`, the artifact must be part of a Kosli Flow (i.e., it must have provenance information). ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} artifacts: provenance: required: true ``` ### Trail compliance When `trail-compliance` is set to `required: true`, the artifact must be part of a compliant Trail in its Flow. ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} artifacts: trail-compliance: required: true ``` ### Specific attestations ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} artifacts: attestations: - name: "*" # attestation name can be anything type: pull-request - name: acceptance-test type: "*" # attestation type can be any built-in or existing custom type - name: security-scan type: snyk - name: coverage-metrics type: custom:my-coverage-metrics # custom attestation type ``` ### Exceptions You can add exceptions to policy rules using [policy expressions](/policy-reference/environment_policy#policy-expressions). ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: provenance: required: true exceptions: # provenance is required except when one of the expressions evaluates to true - if: ${{ matches(artifact.name, "^datadog:.*") }} trail-compliance: required: true exceptions: - if: ${{ matches(artifact.name, "^datadog:.*") }} attestations: - if: ${{ flow.tags.risk-level == "high" }} # only required when expression is true name: unit-tests type: junit ``` For the complete YAML specification — fields, types, defaults, expression language, and constraints — see the [Environment Policy reference](/policy-reference/environment_policy). ## Attaching/Detaching Policies to/from Environments Once you define your policies, you can attach them to environments via CLI or API: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attach-policy prod-requirements --environment=aws-production ``` To detach a policy from an environment: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli detach-policy prod-requirements --environment=aws-production ``` Any attachment/detachment operation automatically triggers an evaluation of the latest environment snapshot and creates a new one with an updated compliance state. If you detach all attached policies from an environment, the environment compliance state will become Unknown since there are no longer any defined requirements for artifacts running in it. The environment will continue to track snapshots, but its compliance cannot be evaluated without policies. ## Enforcing policies Once policies are attached to environments, you can enforce them as deployment gates in your CI/CD pipeline, via the API, or with a Kubernetes admission controller. See [Enforce policies](/getting_started/enforce_policies) for setup instructions. # Trails Source: https://docs.kosli.com/getting_started/trails Learn about Kosli Trails, how to create and manage them. Every time you execute a process represented by a Kosli Flow, you would initiate a `trail` to record the changes made during that specific execution. You have the flexibility to determine the boundaries of what you consider a single execution of your process. For instance, in a software delivery process, an execution instance might be defined by: The trail represents changes recorded from a single commit (as reported from CI). The trail represents changes recorded throughout the life of a single pull request (can span multiple commits). The trail represents changes recorded throughout the life of a single ticket/issue (can span multiple pull requests and commits). Each trail must possess a unique name within the Flow. This name typically follows a custom pattern, depending on how you define the scope of a single process execution. ## Begin a trail To begin a Trail, you can run a command similar to the one below: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli begin trail trail-1 --flow process-1 --description "My first trail" ``` Rerunning the command with different description or template file will update the Trail. See [kosli begin trail](/client_reference/kosli_begin_trail/) for more details. You can overwrite the flow template for each trail using `--template-file`. By default, the trail inherits the template from its Flow. # GitHub Action Source: https://docs.kosli.com/github-action-reference/setup_cli_action Reference for the setup-kosli-cli GitHub Action that installs the Kosli CLI on GitHub Actions runners. The [`kosli-dev/setup-cli-action`](https://github.com/kosli-dev/setup-cli-action) GitHub Action (`setup-kosli-cli`) installs the [Kosli CLI](/client_reference) on GitHub Actions runners. After the action runs, every CLI command is available in later steps of the job. The action runs on `ubuntu-latest`, `windows-latest`, and `macos-latest` runners. This page documents the action itself. For a broader guide to using Kosli in GitHub Actions, including the command flags that are defaulted from GitHub CI variables, see [CI/CD](/integrations/ci_cd). ## Usage Install the latest release of the Kosli CLI: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} steps: - uses: kosli-dev/setup-cli-action@v5 ``` Install a specific version: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} steps: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 with: version: 2.11.43 ``` ## Inputs | Input | Required | Default | Description | | :------------- | :------- | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------- | | `version` | No | `latest` | Version of the Kosli CLI to install. See [Version selection](#version-selection). | | `github-token` | No | `${{ github.token }}` | Token used to authenticate the GitHub API calls that resolve `latest` or a major/minor pin. You normally do not need to set this. | ## Outputs | Output | Description | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `version` | The resolved Kosli CLI version that was installed. When `version` is `latest` or a major/minor pin, this is the concrete semver that was selected (e.g. `2.12.0`). | Reference the resolved version in later steps: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} steps: - name: Setup Kosli CLI id: setup uses: kosli-dev/setup-cli-action@v5 - name: Print installed version run: echo "Installed Kosli CLI ${{ steps.setup.outputs.version }}" ``` ## Version selection The `version` input accepts: * **A full semver**, e.g. `2.11.43` — installed as-is. * **A major pin**, e.g. `"2"` — resolves to the newest stable `2.x` release, and never `3.0.0`. * **A major.minor pin**, e.g. `"2.11"` — resolves to the newest stable `2.11.z` patch. * **`latest`** — resolves to the newest stable release of [`kosli-dev/cli`](https://github.com/kosli-dev/cli). This is the default. Major and minor pins resolve at runtime and never select a pre-release or a higher major. Quote partial versions. In YAML, `version: 2.10` is parsed as the number `2.1`, which is not what you mean. Always quote a major or minor pin: `version: "2"`, `version: "2.10"`. Track a major version and pick up every update within it without ever jumping to the next (breaking) major: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} steps: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 with: version: "2" # newest stable 2.x, never 3.x ``` ## Example job Secrets in GitHub Actions are not automatically exported as environment variables, so set the API token explicitly. All CLI flags can be set as environment variables by adding the `KOSLI_` prefix and capitalizing them. ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} jobs: build-image: runs-on: ubuntu-latest env: KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} KOSLI_ORG: my-org KOSLI_FLOW: my-flow KOSLI_TRAIL: ${{ github.sha }} IMAGE_NAME: my-registry/my-image:latest steps: - name: Build and push Docker image id: build uses: docker/build-push-action@v5 with: push: true tags: ${{ env.IMAGE_NAME }} - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 - name: Attest image provenance run: kosli attest artifact "${IMAGE_NAME}" --artifact-type=oci ``` For a complete example of a GitHub workflow using Kosli, see the Kosli CLI's [own workflow](https://github.com/kosli-dev/cli/blob/main/.github/workflows/docker.yml). ## References * Action source: [`kosli-dev/setup-cli-action`](https://github.com/kosli-dev/setup-cli-action) * Marketplace listing: [setup-kosli-cli](https://github.com/marketplace/actions/setup-kosli-cli) * [CI/CD integration guide](/integrations/ci_cd) * [Kosli CLI reference](/client_reference) # Configuration reference Source: https://docs.kosli.com/helm/k8s_reporter/configuration All values.yaml options for the Kosli k8s-reporter Helm chart. ## General Affinity rules for scheduling the reporter pod. Supports nodeAffinity, podAffinity and podAntiAffinity. Specifies how to treat concurrent executions of a Job that is created by this CronJob. The cron schedule at which the reporter is triggered to report to Kosli. Specifies the number of failed finished jobs to keep. Overrides the fullname used for the created k8s resources. It has higher precedence than `nameOverride`. Overrides the name used for the created k8s resources. If `fullnameOverride` is provided, it has higher precedence than this one. Node labels for scheduling the reporter pod. On EKS with Karpenter, use this to pin the reporter to a stable managed node group (e.g. `eks.amazonaws.com/nodegroup: `) so it does not interfere with node consolidation. See [Running on EKS with Karpenter](/helm/k8s_reporter/karpenter). Annotations to add to the CronJob object itself. For pod-level annotations (added to each reporter pod), use `podTemplateAnnotations` instead. Custom labels to add to pods. Annotations to add to the reporter pod template (applied to each Job pod that the CronJob creates). Specifies the number of successful finished jobs to keep. Tolerations for scheduling the reporter pod, e.g. to run on a dedicated or tainted node group. ## Image The kosli reporter image pull policy. The kosli reporter image repository. The kosli reporter image tag, overrides the image tag whose default is the chart appVersion. ## Reporter configuration Create each Kosli environment (type K8S) if it does not already exist, before reporting the snapshot. Whether the dry run mode is enabled or not. In dry run mode, the reporter logs the reports to stdout and does not send them to kosli. Description applied to every environment auto-created in this run. Only used when `autoEnvironment` is true; existing environments are never modified. Note: a single value is shared by all environments created during the run. List of Kosli environments to report to. Each entry has required 'name' and optional namespace selectors. Use one entry to report a single environment; use multiple entries to report to multiple environments with different selectors. Per entry: name (required), namespaces, namespacesRegex, excludeNamespaces, excludeNamespacesRegex (optional). Leave namespace fields unset for an entry to report the entire cluster to that environment. The http proxy url. **Deprecated and ignored** — used to control whether scaling (replica count) changes were recorded for environments auto-created in this run. Scaling events no longer trigger new snapshots and an environment can no longer have scaling capture turned on, so the `--include-scaling` / `--exclude-scaling` flags this passed to the CLI had stopped having any effect. As of chart version 2.7.0 the flags are no longer passed. Setting this value does nothing; remove it from your values. The name of the Kosli org. The security context for the reporter cronjob. Set to null or to disable security context entirely (not recommended). For OpenShift with SCC, explicitly set runAsUser to null to let OpenShift assign the UID from the allowed range. Simply omitting runAsUser from your values override will not work because Helm deep-merges with these defaults. Example OpenShift override: securityContext: allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: null. Whether to allow privilege escalation. Whether to run as non root. The user id to run as. For OpenShift environments with SCC, set to null (runAsUser: null) to allow automatic UID assignment. Simply omitting this field will not work due to Helm's deep merge with chart defaults. ## Kosli API token The name of the key in the secret data which contains the Kosli API token. The name of the secret containing the kosli API token. ## Environment variables Map of plain environment variables to inject into the reporter container. For a single-tenant Kosli instance, set `KOSLI_HOST` to `https://INSTANCE_NAME.kosli.com`. Additional environment variables to inject into the reporter container. List of `{name, value}` or `{name, valueFrom}` entries, rendered verbatim into the container env. Supports plain values and valueFrom (`secretKeyRef` / `configMapKeyRef`). Note: entries here are appended after the chart's own env entries; on duplicate names the later entry wins. ## Volumes Additional container-level volumeMounts for the reporter container. Rendered verbatim into the container spec alongside the chart's own mounts. Additional Pod-level volumes to attach to the reporter pod. Rendered verbatim into the Pod spec alongside the chart's own volumes. Use together with `extraVolumeMounts` to mount Secrets, ConfigMaps, or other volumes into the container. ## Custom CA Convenience wrapper for mounting a corporate / custom CA bundle. See [Running behind a TLS-inspecting proxy](/helm/k8s_reporter/tls-proxy) for usage. Enable mounting a corporate/custom CA bundle into the trust store. Key within the Secret that holds the PEM-formatted CA certificate (single cert or multi-cert PEM bundle). Name of an existing Secret in the same namespace containing the CA bundle. ## Resources The cpu limit. The memory limit. The memory request. ## Service account Annotations to add to the service account. Specifies whether a service account should be created. The name of the service account to use. If not set and create is true, a name is generated using the fullname template. Specifies whether to create cluster-wide permissions for the service account or namespace-scoped permissions. Allowed values are: `cluster` or `namespace`. *** Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2). # Installing the chart Source: https://docs.kosli.com/helm/k8s_reporter/installing Install the Kosli k8s-reporter Helm chart via the Kosli Helm repository. To install this chart via the Helm chart repository: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} helm repo add kosli https://charts.kosli.com/ && helm repo update ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kubectl create secret generic kosli-api-token --from-literal=key= ``` Configure **reporterConfig.environments** (required). Each entry has required `name` and optional `namespaces`, `namespacesRegex`, `excludeNamespaces`, `excludeNamespacesRegex`. Omit namespace fields for an entry to report the entire cluster to that environment. **One environment, entire cluster:** ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # values.yaml reporterConfig: kosliOrg: environments: - name: ``` **One environment, specific namespaces:** ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} reporterConfig: kosliOrg: environments: - name: namespaces: [namespace1, namespace2] ``` **Multiple environments with different selectors:** ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} reporterConfig: kosliOrg: environments: - name: prod-env namespaces: [prod-ns1, prod-ns2] - name: staging-env namespacesRegex: ["^staging-.*"] - name: infra-env excludeNamespaces: [prod-ns1, prod-ns2, default] ``` ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} helm install kosli-reporter kosli/k8s-reporter -f values.yaml ``` See all available options in the [configuration reference](/helm/k8s_reporter/configuration). # Running on EKS with Karpenter Source: https://docs.kosli.com/helm/k8s_reporter/karpenter Keep the k8s-reporter out of Karpenter's way so nodes can still consolidate. By default the reporter runs as a CronJob every 5 minutes. On clusters that use [Karpenter](https://karpenter.sh) for node autoscaling, this frequent scheduling can prevent nodes from being **consolidated** (scaled down). The cause is Karpenter's `consolidateAfter` timer: Karpenter only consolidates a node once it has seen no pod scheduling activity on it for the configured window. A reporter pod arriving every 5 minutes keeps resetting that timer, so any node whose `consolidateAfter` is longer than the reporter interval never becomes eligible for consolidation (see [karpenter#1921](https://github.com/kubernetes-sigs/karpenter/issues/1921)). This is Karpenter working as designed, not a reporter bug. Frequent snapshots are what let Kosli surface drift or an unauthorized change quickly, so the best fix keeps the 5-minute cadence and moves the reporter out of Karpenter's way. Widening the interval trades away that detection speed and should be a last resort. ## 1. Pin the reporter to a stable node group (recommended) If you run a stable managed node group that Karpenter does not manage, schedule the reporter there so it never disturbs Karpenter-managed nodes. Use `nodeSelector`, and `tolerations` if that node group is tainted: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} nodeSelector: eks.amazonaws.com/nodegroup: system # your managed node group tolerations: - key: dedicated operator: Equal value: system effect: NoSchedule ``` To steer the reporter away from Karpenter-managed nodes instead, use `affinity` (a plain `nodeSelector` cannot express "not on these nodes"): ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: karpenter.sh/nodepool operator: DoesNotExist ``` ## 2. Run the reporter out of the cluster For zero footprint on cluster nodes, run `kosli snapshot k8s` on a schedule outside the cluster (for example a CI cron job) with kubeconfig access, keeping your reporting cadence without placing a pod on the cluster's nodes. See the [Kubernetes environment reporting tutorial](/tutorials/report_k8s_envs). ## 3. Widen the report interval (last resort) Only if you cannot pin the reporter or move it out of cluster: set `cronSchedule` longer than your NodePool's `consolidateAfter` so nodes get quiet windows long enough to consolidate. This works, but a longer interval widens the window in which a change can go unreported, so prefer the options above. ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} cronSchedule: "*/15 * * * *" ``` `karpenter.sh/do-not-disrupt: "true"` is **not** a fix here. It prevents Karpenter from disrupting the pod, which protects a mid-run report from interruption but makes consolidation of that node *less* likely, not more. Likewise `cluster-autoscaler.kubernetes.io/safe-to-evict` only affects the Kubernetes Cluster Autoscaler and is ignored by Karpenter. # Kubernetes Reporter Helm Chart Source: https://docs.kosli.com/helm/k8s_reporter/overview A Helm chart for installing the Kosli K8s reporter as a CronJob. This reference applies to **chart version 2.7.0**, which defaults to CLI **v2.36.1** via `appVersion`. Override with `image.tag`. A Helm chart for installing the Kosli K8s reporter as a CronJob. The chart allows you to create a Kubernetes CronJob and all its necessary RBAC to report running images to Kosli at a given cron schedule. Configuration is done via **reporterConfig.environments**: a list of Kosli environments to report to. Each entry has a required `name` and optional namespace selectors. Use one entry for a single environment, or multiple entries to report to different environments with different selectors. Chart source can be found at [GitHub](https://github.com/kosli-dev/cli/tree/main/charts/k8s-reporter). ## In this section # Prerequisites Source: https://docs.kosli.com/helm/k8s_reporter/prerequisites Requirements for installing the Kosli k8s-reporter Helm chart. * A Kubernetes cluster (minimum supported version is `v1.21`) * Helm v3.0+ * If you want to report artifacts from just one namespace, you need to have permissions to `get` and `list` pods in that namespace. * If you want to report artifacts from multiple namespaces or entire cluster, you need to have cluster-wide permissions to `get` and `list` pods. # Running behind a TLS-inspecting proxy Source: https://docs.kosli.com/helm/k8s_reporter/tls-proxy Trust a corporate / custom CA bundle when running the k8s-reporter behind a TLS-inspecting proxy. If your network sits behind a TLS-inspecting appliance (Zscaler, Netskope, Palo Alto, etc.) that re-signs HTTPS traffic with a corporate CA certificate, the reporter will fail with `x509: certificate signed by unknown authority`. To fix this, make the appliance's CA bundle available to the reporter. The chart offers two ways to do this. Use whichever fits your deployment flow. ## Option 1 — customCA convenience wrapper (recommended for the common case) PEM format, single cert or bundle: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kubectl create secret generic corporate-ca-bundle --from-file=ca.crt=/path/to/corporate-ca.crt ``` ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} customCA: enabled: true secretName: corporate-ca-bundle key: ca.crt ``` The chart mounts the certificate as a single file at `/etc/ssl/certs/kosli-custom-ca.crt` using `subPath`. Go's standard library on Linux loads CA roots in two independent passes — it reads the system bundle file (e.g. `/etc/ssl/certs/ca-certificates.crt`) and **also** scans `/etc/ssl/certs/` for additional certificate files. The mounted file is picked up by the directory scan and added to the trust store alongside the system roots, so no `SSL_CERT_FILE` env var is needed. The wrapper deliberately does **not** set `SSL_CERT_FILE`. Setting it would replace the system bundle entirely with the customer's file, breaking trust for any public CAs the bundle does not include. ## Option 2 — generic extraVolumes / extraVolumeMounts / extraEnvVars Use these when you need a non-default mount path, a ConfigMap instead of a Secret, multiple volumes, or any other shape the wrapper does not cover: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} extraVolumes: - name: corporate-ca secret: secretName: corporate-ca-bundle extraVolumeMounts: - name: corporate-ca mountPath: /etc/ssl/certs/corporate readOnly: true ``` If you mount the CA outside `/etc/ssl/certs/` and set `SSL_CERT_FILE` via `extraEnvVars`, your bundle must include the public CAs you also need to trust — Go uses only that file when `SSL_CERT_FILE` is set. ## Pod Security Standards Both options use `secret`-backed volumes, which are permitted under the Pod Security Standards `restricted` profile. `hostPath` mounts are not permitted under that profile and should not be used here. ## Cluster-wide alternative If you already run [cert-manager's trust-manager](https://cert-manager.io/docs/trust/trust-manager/) to distribute a corporate CA bundle into a well-known ConfigMap in every namespace, point `extraVolumes` / `extraVolumeMounts` at that ConfigMap instead of creating a per-namespace Secret. # Uninstalling the chart Source: https://docs.kosli.com/helm/k8s_reporter/uninstalling Remove the Kosli k8s-reporter release from your cluster. To remove the k8s-reporter release and its resources from your cluster: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} helm uninstall kosli-reporter ``` # Upgrading the chart Source: https://docs.kosli.com/helm/k8s_reporter/upgrading Upgrade an existing Kosli k8s-reporter release, including migration notes for v2.0.0. ## Breaking change in v2.0.0 Version 2.0.0 removes the previous single-environment mode (`kosliEnvironmentName` and the `namespaces` / `namespacesRegex` / `excludeNamespaces` / `excludeNamespacesRegex` flags). You now configure one or more environments only via **reporterConfig.environments**. To report a single environment, use a list with one entry. If upgrading from v1.x to v2.0.0, migrate your values to the **environments** list format (see [Installing the chart](/helm/k8s_reporter/installing)). ## Deprecated and ignored in v2.7.0: `reporterConfig.includeScaling` `reporterConfig.includeScaling` no longer has any effect. Scaling events do not trigger new snapshots, and an environment can no longer have scaling capture turned on, so the `--include-scaling` / `--exclude-scaling` flags this value passed to the CLI had already stopped doing anything — they only produced a deprecation warning in the reporter's logs on every run. Version 2.7.0 stops passing them, which removes that warning. Nothing else changes: the reporter created environments with scaling off before this version and still does. The value is still accepted, but it does nothing and will be removed in a future major version. Remove it from your values. ## Upgrade command ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} helm upgrade kosli-reporter kosli/k8s-reporter -f values.yaml ``` # Application Developers Source: https://docs.kosli.com/implementation_guide/phase_1/roles_and_responsibilities/app_developers Role guide for Application Developers using Kosli You build and maintain services, applications, or APIs that deliver customer or business value. You write code, push changes, and expect your work to move safely from commit to production. You care about quality, security, and release velocity, but you do not want to be slowed down by compliance overhead. # How Kosli helps you Kosli captures the evidence that your changes have passed the right controls, like tests, code reviews, security scans, and approvals, so you can deploy with confidence and stay focused on building. With Kosli, you can: * Ship code without worrying about compliance gates or approval tickets * Get clarity on why something cannot deploy, and what needs to happen * Use existing CI workflows without learning new tools * Trace what changed, where it went, and whether it passed all required controls ## Your role in using Kosli As an application developer, you are a contributor to the system of record that Kosli observes. You may: * Write code that passes through a Flow defined by your platform team * Produce build artifacts and test results that Kosli records as evidence * Trigger attestations through CI jobs (e.g., when tests run or scans complete) * Occasionally check compliance status in the UI or via pull request checks You are usually not responsible for setting up Kosli. It runs quietly underneath your normal delivery workflows. ## What you’ll Work with You typically interact with Kosli through: * **Your CI/CD pipeline**, which calls Kosli CLI under the hood * **Pull requests or merge gates**, where Kosli may block or allow merges based on compliance * **The Kosli UI**, to check deployment or compliance status if needed * **Your platform team's guidance**, for understanding what evidence is expected You do not need to memorize Kosli commands or manage configurations. Most of it is abstracted away by your Platform team ## What success looks like * You write and commit code as usual, and your changes flow smoothly through CI and into production * You do not need to fill out compliance tickets or wait for manual approvals * If something is blocked, Kosli tells you what evidence is missing and how to resolve it * You gain confidence that your work is secure and production-ready without extra effort ## Common questions you might have Most likely a required check did not run, failed, or was not reported to Kosli. Your pipeline or platform team can help you identify what is missing. No. Kosli is used behind the scenes by your platform team. You may see its results in PR checks or dashboards, but you do not need to run it manually. You can use the Kosli UI to trace a git commit, artifact, or deployment. Kosli shows where it is running and what evidence was attached. Yes. Kosli helps you trace what changed and when across environments. You can see exactly what was deployed and what passed or failed. ## Required Kosli User Roles To perform the responsibilities described above, users in this role typically need: * **Recommended role**: Member * **Alternative role**: Reader (for developers who only need visibility) Developers typically need to report attestations and manage flows for their applications. The Member role enables this. Some developers may only need visibility into deployments and compliance status, making the Reader role sufficient. Learn more about [Kosli user roles and permissions](/administration/managing_users/roles_in_kosli). ## Where to start * [**Getting Started**](): Follow this if you're curious about how Kosli works behind the scenes * [**Querying Kosli**](): Learn how to search for artifacts or changes * [**Concepts**](): Understand what Kosli tracks and why # Overview Source: https://docs.kosli.com/implementation_guide/phase_1/roles_and_responsibilities/overview Define roles and responsibilities for Kosli implementation Kosli supports multiple stakeholders across engineering, security, and compliance. Successful adoption depends on clear ownership and collaboration across roles. This guide provides: * A RACI matrix to define responsibilities per phase * Role-by-role expectations during rollout * Links to relevant documentation for each group ## Phases of Implementation 1. **Discovery and Planning:** Understand what to track, who is involved, and which flows to start with. 2. **Initial Setup and Pilot:** Configure Kosli for a single service or team. Validate the model and gather feedback. 3. **Rollout and Scale:** Extend flows and policies across teams and services. Standardize and automate. 4. **Governance and Optimization:** Measure success, refine policies, and prepare for audits with real data. ## Stakeholders 1. **[Platform Engineers and DevOps](/implementation_guide/phase_1/roles_and_responsibilities/platform_engineers)**: Leads technical implementation and pipeline integration 2. **[Application Developer](/implementation_guide/phase_1/roles_and_responsibilities/app_developers)**: Builds code and produces evidence automatically 3. **[Security and Compliance](/implementation_guide/phase_1/roles_and_responsibilities/security_compliance)**: Defines control objectives and verifies evidence 4. **Sponsors**: Champions adoption, aligns on outcomes, and tracks impact ## RACI Matrix The RACI model helps teams and stakeholders know who to talk to, who drives a decision, and who just needs visibility. It’s especially helpful when rolling out tools like Kosli across multiple teams with different priorities and domain focus. | Task | Platform Engineer | Application Developer | Security & Compliance | Sponsor | | ----------------------------------- | ----------------- | --------------------- | --------------------- | ------- | | Identify key flows and services | R | C | C | A | | Define success criteria and metrics | C | C | C | A | | Select pilot team/service | R | C | C | A | | Set up Kosli CLI and pipelines | A | I | C | C | | Define attestation types | R | C | A | C | | Configure environment snapshots | A | I | C | C | | Set up environment policies | R | I | A | C | | Validate compliance controls | R | C | A | C | | Export and review audit packages | C | I | A | C | | Roll out to additional teams | R | C | C | A | | Track measures of success | R | C | C | A | **Roles explained** The owner of the outcome. This is the person who ensures the task is completed successfully, even if others do the work. There should only be one "A" per task. The doer. This person (or team) performs the work. They are hands-on with the implementation and execution of the task. Someone who provides input, guidance, or subject matter expertise. This is a two-way communication role. Their feedback is important for shaping the work. Kept in the loop. This person doesn't need to be consulted during the task but should be notified of progress or outcomes. It's a one-way communication role. ## Connecting Responsibilities to Permissions The RACI matrix above describes responsibilities during Kosli implementation. To perform these responsibilities, users need appropriate Kosli user roles (Admin, Member, Snapshotter, or Reader) assigned in the platform. Kosli user roles control what actions someone can perform in the Kosli system: * **Admin**: Full control, including user management and organization settings * **Member**: Can create and modify resources, manage service accounts, and configure integrations * **Snapshotter**: Can report environment snapshots, create environments, and manage service accounts, with read-only access to other resources * **Reader**: Read-only access to view data and compliance status For guidance on which Kosli user role to assign based on organizational responsibilities, see [Roles in Kosli](/administration/managing_users/roles_in_kosli) and [Mapping users to roles](/administration/managing_users/mapping_users_to_roles). # Platform Engineers Source: https://docs.kosli.com/implementation_guide/phase_1/roles_and_responsibilities/platform_engineers Role guide for Platform and DevOps Engineers using Kosli You build the internal tooling, workflows, and golden paths that help developers ship software reliably and securely. You care about scaling delivery without scaling your team. If you’re supporting CI/CD pipelines, infrastructure, or compliance enablement across multiple services or teams, this page is for you. ## How Kosli helps you Kosli gives you a single, unified way to track everything that moves through your delivery pipelines: code, artifacts, tests, approvals, deployments and prove it’s been done safely and correctly. With Kosli, you can: * Automate compliance and eliminate manual change approval processes. * Capture tamper-proof evidence across your SDLC (without slowing down delivery). * Monitor all runtime environments and deployments across teams. * Offer developers secure paved paths that embed governance from the start. ## Your role in using Kosli As a platform engineer, you're typically responsible for: * Setting up Kosli in CI/CD and infrastructure environments. * Creating and maintaining **Flows**, which model how changes move through pipelines. * Defining and triggering **Trails** to capture each run of those pipelines. * Configuring **Attestations** for tests, scans, and internal checks (e.g., Jira, Snyk). * Capturing **Environment Snapshots** and enforcing **Policies** to govern deployments. * Building reusable Kosli integrations (e.g., GitHub Actions, GitLab CI templates) so your dev teams don’t have to think about it. You’ll often be the first person to integrate Kosli into your platform and roll it out to the rest of the org. ## What you’ll work with You’ll primarily interact with: * **Kosli CLI:** integrated into your CI/CD pipelines and scripts. * **Flows** and **Trails:** to represent and track software delivery runs. * **Artifacts** and **Attestations:** to connect builds and compliance evidence. * **Environment Snapshots** & **Policies:** to enforce governance in prod and staging. * **Kosli UI:** to review deployment status, compliance views, and audits. If you're running Kubernetes, Terraform, or other infrastructure tools, Kosli also integrates easily to monitor state and changes. ## What success looks like When Kosli is successfully adopted by platform engineering, you’ll see: * Your pipelines continuously produce verifiable, compliant deployments. * You eliminate the need for spreadsheet-driven approvals and CAB meetings. * Developers onboard Kosli passively via the platform, they rarely have to learn it directly. * Security and compliance teams get everything they need with minimal friction. * Audits are a non-event: you already have the evidence. ## Common questions you might have No major changes. Kosli integrates via CLI commands you can drop into any pipeline. Yes. Use flow templates and reusable CI snippets to roll out a consistent setup. Almost certainly. Kosli is tool-agnostic and supports GitHub Actions, GitLab, Jenkins, Kubernetes, Terraform, and more. Kosli automatically gives you compliance status per environment and per change. You can inspect Trails, download audit packages, and integrate with Slack or through Webhooks for alerts. ## Required Kosli User Roles To perform the responsibilities described above, users in this role typically need: * **Recommended role**: Member * **Alternative role**: Admin (for lead platform engineers managing organization-wide setup) Platform engineers need to set up flows, manage service accounts, configure integrations, and implement Kosli across teams. The Member role provides these capabilities. Lead platform engineers who manage the overall organizational setup may require Admin access to manage users and organization settings. Learn more about [Kosli user roles and permissions](/administration/managing_users/roles_in_kosli). ## Where to start * [**Getting Started Guide**](): For a complete technical setup walkthrough. * [**CLI Reference**](): Full list of commands. * [**Concepts Overview**](): Understand how Flows, Trails, and Attestations fit together. # Security and Compliance Source: https://docs.kosli.com/implementation_guide/phase_1/roles_and_responsibilities/security_compliance How security and compliance teams use Kosli to enforce controls and prepare for audits. You are responsible for ensuring that software delivery meets regulatory, security, or internal governance requirements. You translate frameworks like SOC 2, ISO 27001, or custom internal controls into practical expectations for teams. You may work in AppSec, GRC, risk management, or a compliance function. You care about provable controls, trustworthy evidence, and making audits repeatable and painless. ## How Kosli helps you Kosli creates a continuous, tamper-proof record of how software changes move through your organization. It captures real evidence for controls like peer review, test coverage, security scanning, and approval steps, all without relying on spreadsheets or screenshots. With Kosli, you can: * Automatically collect and store control evidence for every change * Get instant visibility into which changes are compliant and which are not * Replace change request tickets with actual audit-ready data * Export audit packages in seconds for any service, environment, or release ## Your role in using Kosli You help define what counts as compliant. Kosli helps you enforce that through policy and automation. Your responsibilities may include: * Working with platform teams to translate controls into **Attestations** and **Policies** * Reviewing **Environment** or **Trail** compliance reports * Verifying that changes meet requirements for deployment to sensitive environments * Preparing for or responding to internal and external audits using Kosli data You may not configure pipelines directly, but you rely on Kosli’s outputs to validate that controls are working. ## What you’ll work with You interact with Kosli through: * **The Kosli UI**, where you can see compliance status per environment, service, or release * **Audit Packages**, which you can export to support internal reviews or formal audits * **Attestation** and **Policy** definitions, often managed in collaboration with platform or security engineering teams * **Environment Snapshots**, which show what is running and why it is or is not compliant You may also use the **CLI** or **API** if you need detailed reports or integrations. ## What success looks like * You can prove to auditors or regulators that your SDLC is secure and compliant * Controls are codified and enforced consistently across all delivery pipelines * You no longer chase teams for screenshots or spreadsheets during audits * You have full traceability from change request to deployed artifact with supporting evidence ## Common questions you might have Kosli validates Trails and Environments based on policies and recorded attestations. You can view compliant and non-compliant changes in the UI or export audit reports. Yes. Attestations can represent any type of control evidence, such as test results, PR approvals, vulnerability scans, or change reviews. Kosli stores all records immutably and securely. Attestations can include signed metadata and attachments, stored in a tamper-evident Evidence Vault. You can export a complete Audit Package for any Trail, Artifact, or Environment. This includes all recorded evidence and metadata for traceable, reviewable compliance. ## Required Kosli User Roles To perform the responsibilities described above, users in this role typically need: * **Recommended role**: Admin Security and compliance teams need to manage policies, review audit data, control user access, and configure organization-wide settings. The Admin role is required for these governance responsibilities, including the ability to manage users, define policies, and ensure proper access controls are in place. Learn more about [Kosli user roles and permissions](/administration/managing_users/roles_in_kosli). ## Where to start * [**How Kosli works**](/understand_kosli/how_kosli_works): Understand how Flows, Trails, and Attestations fit together. # Sponsors Source: https://docs.kosli.com/implementation_guide/phase_1/roles_and_responsibilities/sponsors How Sponsors can use Kosli to drive safe and compliant software delivery at speed. You’re responsible for making sure your organization delivers software quickly, safely, and in a way that satisfies regulatory, customer, or internal compliance expectations. You might lead an engineering org, oversee platform strategy, or be responsible for DevSecOps or governance transformation. You care about reducing lead time without sacrificing control or trust. ## How Kosli helps you Kosli gives your teams the ability to automate governance across the entire software delivery lifecycle (SDLC). It makes it easy to verify that changes have passed the right checks and policies without slowing down releases. With Kosli, you can: * Replace manual approvals and change control boards with real-time, automated evidence * Give your platform and product teams compliant workflows by default * Get instant answers to “what changed, where, and why” across all environments * Demonstrate governance and audit readiness without adding burden to developers ## Your role in using Kosli As a sponsor, you are the enabler. You set the strategic direction and ensure the right people are equipped to succeed. Your key responsibilities include: * Aligning Kosli adoption with organizational goals around speed, safety, and compliance * Supporting platform teams in rolling out Kosli at scale * Communicating the value of automated governance across the organization * Using Kosli dashboards or reports to track adoption, policy health, and delivery confidence ## What you’ll work with You won’t typically use the CLI. Instead, your interaction with Kosli will focus on: * The Kosli UI to view environment compliance, trail status, and audit readiness * Dashboards to understand where controls are working or missing * Audit Packages and Evidence Vault exports to support reporting or audits * Occasional reference to Kosli’s terminology or data model when aligning internal processes ## What success looks like * You have visibility into delivery health and compliance posture across the org * Product and platform teams operate with fewer manual gates or surprises * You can demonstrate governance to stakeholders without relying on ad hoc processes * Audits are predictable and repeatable * Kosli becomes a quiet enabler. Developers deliver, compliance is provable, and your platform team scales without friction ## Common questions you might have Yes. Kosli automates evidence collection and policy enforcement, reducing the need for manual checks while maintaining control. Yes. Kosli maps technical events to audit-friendly records, with downloadable audit packages and policy enforcement. No. Platform engineers handle setup and integration. Developers rarely need to interact with Kosli directly. You'll see reduced lead times, fewer compliance exceptions, and improved audit efficiency. Kosli makes this visible through environment compliance views and evidence tracking. ## Required Kosli User Roles To perform the responsibilities described above, users in this role typically need: * **Recommended role**: Reader Sponsors need visibility into adoption progress, compliance status, and overall system health but don't need to make technical changes. The Reader role provides necessary oversight without operational access, allowing you to view dashboards, compliance reports, and audit data. Learn more about [Kosli user roles and permissions](/administration/managing_users/roles_in_kosli). ## Where to Start * [**What is Kosli?**](understand_kosli/what_is_kosli/): Understand the value and core ideas * [**Implementing Kosli**](/implementation_guide): A rollout guide aligned to business and technical outcomes * [**How Kosli works**](/understand_kosli/how_kosli_works): Understand how Flows, Trails, and Attestations fit together # Attestation Types Source: https://docs.kosli.com/implementation_guide/phase_2/plan_organizational_structure/naming_conventions/attestation_types Naming convention guidance for custom attestation types following the control-objective, evidence-type, detail, and version pattern. Use clear, descriptive names for custom attestation types to indicate what kind of evidence they represent. Naming convention relates to `TYPE-NAME` in Kosli CLI command: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create attestation-type TYPE-NAME [flags] ``` See [CLI documentation](/client_reference/kosli_create_attestation-type) for more details. **Name Convention:** `control objective`-`evidence type`-`[detail]`-`[version]` * **control objective**: The high-level control or requirement the attestation supports (e.g., control id, code review, security scan, unit test) * **evidence type**: The specific type of evidence being attested (e.g. tool-name, test-suite) * **detail (Optional)**: Additional context or detail about the attestation (e.g., type, severity-level, environment, etc.) * **version (Optional)**: The version of the attestation type or schema. Should follow semantic versioning (e.g., v1, v2) - `detail` element may be repeated to add finer granularity if needed. - You can skip `detail` and `version` if not needed for your use case. - Kosli versions attestation types automatically, so `version` is often unnecessary. However, it can be useful for multiple version running at the same time, for example in shared pipelines. **Examples on `TYPE-NAME`:** * `bc1-version_control-v1` (BC1 version control attestation, version 1) * `code_review-github-pr` (basic code review attestation) * `security_scan-snyk-high` (Custom schema for Snyk scan with high severity detail) * `unit_test-junit-detail1-detail2-v2` (Multiple detail blocks with version) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-z0-9_]*-[a-z][a-z0-9_]*(-[a-z][a-z0-9_]*)*(-v[1-9][0-9]*)?$ ``` **Examples on `TYPE-NAME`:** * `bc1-versionControl-v1` (BC1 version control attestation, version 1) * `codeReview-github-pr` (basic code review attestation) * `securityScan-snyk-high` (Custom schema for Snyk scan with high severity detail) * `unitTest-junit-detail1-detail2-v2` (Multiple detail blocks with version) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-zA-Z0-9]*-[a-z][a-zA-Z0-9]*(-[a-z][a-zA-Z0-9]*)*(-v[1-9][0-9]*)?$ ``` **Examples on `TYPE-NAME`:** * `Bc1-VersionControl-V1` (BC1 version control attestation, version 1) * `CodeReview-Github-Pr` (basic code review attestation) * `SecurityScan-Snyk-High` (Custom schema for Snyk scan with high severity detail) * `UnitTest-Junit-Detail1-Detail2-V2` (Multiple detail blocks with version) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[A-Z][a-zA-Z0-9]*-[A-Z][a-zA-Z0-9]*(-[A-Z][a-zA-Z0-9]*)*(-V[1-9][0-9]*)?$ ``` # Flows and Trails Source: https://docs.kosli.com/implementation_guide/phase_2/plan_organizational_structure/naming_conventions/flows_and_trails Recommended naming conventions for Flows and Trails in Kosli. This document outlines recommended naming conventions for Flows and Trails as they closely relate to each other in Kosli. Adopting these conventions will help maintain clarity and consistency across your organization. ## Flows A clear naming convention transforms a simple ID into a meaningful identifier that everyone understands. This shared language ensures attestations go to the right place and you can track your releases from start to finish. The naming convention relates to `FLOW-NAME` in Kosli CLI command: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow FLOW-NAME [flags] ``` See [CLI documentation](client_reference/kosli_create_flow) for more details. The following sections define conventions for the two main types of Flows in Kosli: Build Flows and Release Flows. ### Build Flows Represent how code changes move from commit to artifact. **Convention:** org unit - repo-\[service] Your organizational unit, division or team name Your repository name The specific service or component that the artifact belongs to You can skip `service` if your repository produces only one artifact, i.e. non-monorepo setups. * `investment-web_app` (single artifact) * `investment-web_app-frontend` (with service: frontend) * `devops_team-mobile_app-backend` (with service: backend) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-z0-9_]*-[a-z][a-z0-9_]*(-[a-z][a-z0-9_]*)?$ ``` * `investment-webApp` (single artifact) * `investment-webApp-frontend` (with service: frontend) * `devopsTeam-mobileApp-backend` (with service: backend) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-zA-Z0-9]*-[a-z][a-zA-Z0-9]*(-[a-z][a-zA-Z0-9]*)?$ ``` * `Investment-WebApp` (single artifact) * `Investment-WebApp-Frontend` (with service: frontend) * `DevOpsTeam-MobileApp-Backend` (with service: backend) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[A-Z][a-zA-Z0-9]*-[A-Z][a-zA-Z0-9]*(-[A-Z][a-zA-Z0-9]*)?$ ``` ### Release Flows Represent how artifacts move from binary repository to deployment. **Name Convention:** `org unit`-`repo` Your organizational unit, division or team name Your repository name * `investment-web_app` * `devops_team-mobile_app` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-z0-9_]*-[a-z][a-z0-9_]*$ ``` * `investment-webApp` * `devopsTeam-mobileApp` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-zA-Z0-9]*-[a-z][a-zA-Z0-9]*$ ``` * `Investment-WebApp` * `DevOpsTeam-MobileApp` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[A-Z][a-zA-Z0-9]*-[A-Z][a-zA-Z0-9]*$ ``` ## Trails The naming convention for Trails depends on the type of Flow they are associated with: Build Flows or Release Flows and relates to `TRAIL-NAME` in Kosli CLI command: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli begin trail TRAIL-NAME \ --flow FLOW-NAME \ # Build or Release Flow [other flags] ``` See [CLI documentation](client_reference/kosli_begin_trail) for more details. ### Associated with [Build Flows](#build-flows) **Name Convention:** `sha` The Git commit HEAD SHA that triggered the build. Casing does not matter for SHA values, so we do not provide multiple casing options here. * `abcdef1234567890abcdef1234567890abcdef12` (full 40-char SHA) * `abcdef123` (short SHA) **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-f0-9]+$ ``` ### Associated with [Release Flows](#release-flows) **Convention:** env - pr number The target deployment environment (e.g., staging, production) The pull request or change request number associated with the deployment. * `staging-42` * `production-108` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-z0-9_]*-[0-9]+$ ``` * `staging-42` * `production-108` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-zA-Z0-9]*-[0-9]+$ ``` * `Staging-42` * `Production-108` **Regex:** ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[A-Z][a-zA-Z0-9]*-[0-9]+$ ``` # Overview Source: https://docs.kosli.com/implementation_guide/phase_2/plan_organizational_structure/naming_conventions/overview Best practices for naming Flows, Attestation Types, and Environments in Kosli. Clear and consistent naming makes it easy for everyone to understand what each item in Kosli represents. Good names help you route attestations correctly and quickly find what you need. Use these conventions for: * **Flows** and **Trails** * **Attestation Types** * **Environments** ## General Guidelines The general guidelines should be considered best practices for all naming conventions in Kosli. You can adapt them to fit your organization’s needs, but consistency is key. All of our proposed conventions follow these general guidelines: **Structure**: `` `` `` ``...`` Choose a delimiter that works for your and stick with it consistently. For example hyphen `-`, underscore `_`, tilde `~` or dot `.`. Avoid mixing delimiters within the same naming scheme. Choose a meaningful case style across elements (e.g., PascalCase, camelCase, snake\_case) and use it consistently. Avoid spaces and clashes with delimiters. Shorter names are easier to read and remember. Aim for concise but descriptive names. Stick to alphanumeric characters and underscores/hyphens Be aware of using underscore `_` as the delimiter, as that conflicts with snake\_case for elements. The rest of this document uses hyphen `-` as the delimiter in examples, but you can choose any delimiter that fits your needs. ### Regular Expression To help enforce these conventions programmatically, here are sample regular expressions you can use based on your chosen case style. Adjust the regex if you choose a different delimiter. **Example**: `element_one`-`element_two`-`element_three` ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-z0-9_]*(-[a-z][a-z0-9_]*)*$ ``` **Example**: `elementOne`-`elementTwo`-`elementThree` ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[a-z][a-zA-Z0-9]*(-[a-z][a-zA-Z0-9]*)*$ ``` **Example**: `ElementOne`-`ElementTwo`-`ElementThree` ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^[A-Z][a-zA-Z0-9]*(-[A-Z][a-zA-Z0-9]*)*$ ``` If you want a specific length limit (e.g., max 50 characters), you can add a lookahead at the start of the regex: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} ^(?=.{1,50}$) # + rest of the regex ``` You can use online regex testers like [regex101](https://regex101.com/) to validate and test these expressions. # CI/CD Source: https://docs.kosli.com/integrations/ci_cd Use Kosli in CI Systems like GitHub Actions, GitLab CI, and more. This section provides how-to guides showing you how to use Kosli to report changes from different CI systems. Note that **all** CLI command flags can be set as environment variables by adding the the `KOSLI_` prefix and capitalizing them. ## Defaulted Kosli command flags from CI variables The following flags are **defaulted** (which means you don't need to provide the flags, they'll be automatically set to values listed below) as follows in the CI systems below: View defaulted Kosli command flags in Github Actions. | Flag | Default | | :-------------- | :--------------------------------------------------------------------- | | --build-url | `//actions/runs/` | | --commit-url | `//commit/` | | --commit | `` | | --git-commit | `` | | --repository | `` | | --repo-id | `` | | --repo-url | `/` | | --repo-provider | `github` | | --github-org | `` | Where `` are Github Actions predefined variables. See [here](https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables) for more details. ## Use Kosli in Github Actions To use Kosli in [Github Actions](https://docs.github.com/en/actions) workflows, you can use the [`setup-kosli-cli` GitHub Action](/github-action-reference/setup_cli_action) to install the CLI on your Github Actions Runner. Then, you can use all the [CLI commands](/client_reference) in your workflows. See the GitHub Action reference for its inputs, outputs, and version-pinning options. ### GitHub Secrets Keep in mind that secrets in Github actions are not automatically exported as environment variables. You need to add required secrets to your GITHUB environment explicitly. E.g. to make kosli\_api\_token secret available for all cli commands as an environment variable use following: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} env: KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} ``` ### Example Here is an example Github Actions workflow snippet using `kosli-dev/setup-cli-action` running `kosli create flow` command: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} jobs: example: runs-on: ubuntu-latest env: KOSLI_API_TOKEN: ${{ secrets.MY_KOSLI_API_TOKEN }} KOSLI_ORG: my-org steps: - name: setup kosli uses: kosli-dev/setup-cli-action@v5 - name: create flow run: kosli create flow my-flow --template pull-request,artifact,test ``` For a complete example of a Github workflow using Kosli, please check the Kosli CLI's [own workflow](https://github.com/kosli-dev/cli/blob/main/.github/workflows/docker.yml). | Flag | Default | | :-------------- | :------------------------------------------ | | --build-url | `` | | --commit-url | `/-/commit/` | | --commit | `` | | --git-commit | `` | | --repository | `` | | --repo-id | `` | | --repo-url | `` | | --repo-provider | `gitlab` | | --gitlab-org | `` | Where `` are GitLab predefined variables. See [here](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) for more details. ## Use Kosli in Gitlab pipelines For a complete example of a Gitlab pipeline using Kosli, please check [this cyber-dojo pipeline](https://gitlab.com/cyber-dojo/creator/-/blob/main/.gitlab/workflows/main.yml). ### CI runner image (Alpine) The Kosli CLI repository ships an Alpine-based [`Dockerfile.alpine`](https://github.com/kosli-dev/cli/blob/main/Dockerfile.alpine) intended for use as a CI runner image. Unlike the default `ghcr.io/kosli-dev/cli` image (which has the `kosli` binary as its entrypoint), the Alpine variant has no entrypoint and bundles `git`, `curl`, and `ca-certificates` alongside the CLI — so it can be used as a general-purpose job image where you also need to clone repos, hit HTTP APIs, or run other shell tooling next to `kosli`. Build and push it to your own registry, pinning the CLI version you want: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Clone or copy Dockerfile.alpine from https://github.com/kosli-dev/cli docker build \ --build-arg KOSLI_VERSION=2.28.0 \ -f Dockerfile.alpine \ -t registry.example.com/ci/kosli-runner:2.28.0 . docker push registry.example.com/ci/kosli-runner:2.28.0 ``` Then use it as the job image in `.gitlab-ci.yml`: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} variables: KOSLI_ORG: my-org KOSLI_HOST: https://app.kosli.com attest: image: registry.example.com/ci/kosli-runner:2.28.0 script: - kosli version - kosli attest generic --flow my-flow --trail "$CI_COMMIT_SHA" --name build --compliant=true # KOSLI_API_TOKEN should be set as a masked GitLab CI/CD variable ``` The image runs as the non-root `kosli` user with `/workspace` as the working directory. `KOSLI_ORG` and `KOSLI_HOST` are exposed as environment variables so they can be overridden in your CI configuration; `KOSLI_API_TOKEN` should be supplied via a masked CI variable rather than baked into the image. View defaulted Kosli command flags in Azure DevOps. | Flag | Default | | :-------------- | :------------------------------------------------------------------------------------------------------ | | --build-url | `//_build/results?buildId=` | | --commit-url | `//_git//commit/` | | --commit | `` | | --git-commit | `` | | --repository | `` | | --repo-id | `` | | --repo-url | `` | | --repo-provider | `azure-devops` | | --project | `` | | --azure-org-url | `` | Where `` are Azure DevOps predefined variables. See [here](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops\&tabs=yaml) for more details. View defaulted Kosli command flags in Bitbucket Cloud. | Flag | Default | | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------- | | --build-url | `https://bitbucket.org///addon/pipelines/home#!/results/` | | --commit-url | `https://bitbucket.org///commits/` | | --commit | `` | | --git-commit | `` | | --repository | `` | | --repo-id | `` | | --repo-url | `` | | --repo-provider | `bitbucket` | | --bitbucket-workspace | `` | Where `` are Bitbucket Cloud predefined variables. See [here](https://support.atlassian.com/bitbucket-cloud/docs/variables-in-pipelines/) for more details. View defaulted Kosli command flags in AWS CodeBuild. | Flag | Default | | :----------- | :-------------------------------------------------------------------------- | | --build-url | `` | | --commit-url | `/commit(s)/` | | --commit | `` | | --git-commit | `` | | --repo-url | `` | Where `` are AWS CodeBuild predefined variables. See [here](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html) for more details. View defaulted Kosli command flags in CircleCI. | Flag | Default | | :----------- | :------------------------------------------------------------------------ | | --build-url | `` | | --commit-url | `(converted to https url)/commit(s)/` | | --commit | `` | | --git-commit | `` | | --repository | `` | | --repo-url | `` | Where `` are CircleCI predefined variables. See [here](https://circleci.com/docs/env-vars/#built-in-environment-variables) for more details. View defaulted Kosli command flags in Teamcity. | Flag | Default | | :----------- | :------------------- | | --git-commit | `` | Where `` are Teamcity predefined variables. See [here](https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html) for more details. # Kosli Actions Source: https://docs.kosli.com/integrations/kosli_actions Automate if-this-then-that workflows with Kosli Actions. You need the Admin or Member role to create, update, and delete Actions. Learn more about roles in Kosli in [Roles in Kosli](/administration/managing_users/roles_in_kosli/). Actions enable you to automate the execution of if-this-do-that workflows based on Kosli events. You can configure actions to either receive a Slack notification or a JSON payload on a custom webhook when certain Kosli events happen. You can configure actions to be triggered by one or more of the following events occurring in one or more environments: * When a new artifact starts execution in an environment. * When an artifact ceases execution in an environment. * When instances of an artifact are scaled up or down. * When an artifact is added to the allow-list in an environment. * When an environment changes state from Compliant to Non-Compliant. * When an environment changes state from Non-Compliant to Compliant. ## Slack Notifications To receive Kosli notifications in Slack, you have two options. You can either use the Kosli Slack App or set up Slack Incoming Webhooks. Both approaches allow you to configure Kosli notifications in Slack, offering flexibility based on your preferences. Subscribe to Kosli notifications using the [Kosli Slack App](/integrations/slack/). This method is recommended for a seamless integration. Use the app to create notification settings by running the `/kosli subscribe` slash command. * Create a [Slack incoming webhook](https://api.slack.com/messaging/webhooks#create_a_webhook). * Use this webhook to [create a notification settings in the Kosli UI](/integrations/kosli_actions/#manage-actions-in-the-ui). ## Custom Webhook Notifications Custom webhook notifications empower you to implement automation workflows for "if-this-then-that" scenarios. Whenever an event that matches your specified notification settings occurs, a JSON payload, as outlined below, is transmitted to your designated custom webhook: ```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "version": "1.0", "timestamp": "1692616493", "org": "cyber-dojo", "environment": "aws-prod", "event_type": "ARTIFACT_STARTED", "description": "1 instance started running (from 0 to 1)", "snapshot": { "index": "1035", "status": "compliant", "html_url": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/1035", "api_url": "https://app.kosli.com/api/v2/snapshots/cyber-dojo/aws-prod/1035" }, "artifact": { "name": "runner", "fingerprint": "719defb995c86ad7c406ad74258fe98b9ebd71dfa80cd786870c967cb6c1f08d", "provenance": { "flow": "runner", "status": "compliant", "commit": "1ac157003dd6fb9ec764daa47726b7bfed65c312", "commit_url": "https://github.com/cyber-dojo/runner/commit/1ac157003dd6fb9ec764daa47726b7bfed65c312", "html_url": "https://app.kosli.com/cyber-dojo/runner/719defb995c86ad7c406ad74258fe98b9ebd71dfa80cd786870c967cb6c1f08d", "api_url": "https://app.kosli.com/api/v2/artifacts/cyber-dojo/runner/fingerprint/719defb995c86ad7c406ad74258fe98b9ebd71dfa80cd786870c967cb6c1f08d", "build_url": "https://github.com/cyber-dojo/runner/actions/runs/5891969166" } } } ``` ## Email Provide a comma-separated list of recipient email addresses. Notifications are sent from `noreply@kosli.com`. # Manage Actions in the UI You can manage Actions for your organization in the Kosli UI from the `Actions` section in the left navigation menu. The Actions sections enables you to: * **Create Notifications:** Create a new notifications settings. * **Delete Notifications:** Remove existing notification settings that are no longer needed. * **Update Notifications:** Modify notification settings as needed. # LaunchDarkly Source: https://docs.kosli.com/integrations/launchdarkly LaunchDarkly feature flag changes can be tracked in Kosli trails. LaunchDarkly feature flag changes can be tracked in [Kosli trails](/getting_started/trails). ## Setting up in Kosli To set up the integration, navigate to the LaunchDarkly integration page of your org in the [Kosli app](https://app.kosli.com/). Descriptive alt text After switching on the integration, you will be provided with a webhook and a secret. ## Setting up in LaunchDarkly You're now just a few steps away from connecting LaunchDarkly to Kosli. In [LaunchDarkly](https://app.launchdarkly.com/): * Navigate to the "Integrations" tab * Create a new webhook integration * Enter the webhook url and secret in the relevant fields * Add policy statements for flags and environments for which you'd like to send information Kosli. By leaving these policy statements blank, all flag changes in all environments will report back to Kosli. * Save the settings ## Testing the integration To make sure the integration is configured properly, switch a feature flag on or off. The first time a flag is changed in a LaunchDarkly environment, a [Flow](/getting_started/flows) will be created in Kosli titled `launch-darkly-`, and inside this flow a trail will be created named after the name of your feature flag. All changes to this flag will be found in the trail. Subsequently, any change to a feature flag in this environment will be tracked in the appropriate trail. # MCP server Source: https://docs.kosli.com/integrations/mcp_server Connect AI assistants such as Claude Code and Claude Desktop to the Kosli API using the Model Context Protocol. The Kosli MCP server is a [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the Kosli API to AI assistants. Once it is connected, you can ask questions like *"which environments are non-compliant, and why?"* and the assistant calls the relevant Kosli endpoints to answer. It is published from [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server) and distributed as an npm package (`@kosli/mcp-server`) and as a `.mcpb` bundle for Claude Desktop. The Kosli MCP server is in beta. Tool names, parameters, and behavior may change between releases. Pin a version if you need stability: `npx -y @kosli/mcp-server@0.5.0`. This server reads the data in your Kosli organization. To let an AI assistant search this documentation instead, see [AI access to these docs](/understand_kosli/ai_docs_access). The two are complementary, and you can connect both. ## How it works Rather than ship one tool per Kosli endpoint, the server generates a catalog of actions from Kosli's OpenAPI spec and exposes three generic tools: | Tool | Purpose | | ---------------------- | ---------------------------------------------------------------------------------------- | | `search_actions` | Fuzzy-search the catalog for relevant actions by natural-language query. | | `execute_read_action` | Invoke any `GET` action by ID. Auto-allowed in MCP clients. | | `execute_write_action` | Invoke any `POST`, `PUT`, `PATCH`, or `DELETE` action by ID. Gated behind user approval. | These are the tool names your client shows as the assistant works, and the name in the prompt when it asks you to approve a write. `execute_write_action` creates, modifies, and deletes real resources in your Kosli organization. MCP clients gate these calls behind an approval prompt, and that prompt is the only checkpoint before the call is made. An assistant may choose the wrong action, or the right action with the wrong parameters, so read the action ID and parameters before approving. Treat deletions and anything touching service accounts or API keys with particular care. ## Prerequisites * Node.js v22 or higher, for the `npx`-based install methods. You do not need it for the `.mcpb` bundle, because Claude Desktop ships its own Node runtime. * A Kosli API key. Use a [personal API key](/user/personal_api_keys) when you run the server on your own machine, or a [service account key](/administration/authentication/service_accounts) for automation. * An MCP-capable client, such as Claude Code or Claude Desktop. ## Install Run this from your project directory, or add `--scope user` to install it globally: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} claude mcp add kosli \ -e KOSLI_API_TOKEN=your-token \ -e KOSLI_ORG=your-org \ -- npx -y @kosli/mcp-server ``` Download the latest `.mcpb` file from the [releases page](https://github.com/kosli-dev/mcp-server/releases) and drag it into Claude Desktop, or double-click it to install. Claude Desktop prompts you for your API key and organization, and stores the secrets in your operating system keychain. This is the recommended method for Claude Desktop. Extensions installed from a file show an "unverified by Anthropic" warning and do not auto-update, so you need to download and reinstall new versions manually. Both limitations go away once the extension is listed in Anthropic's [Connectors Directory](https://claude.com/docs/connectors/building/submission). Add the following to `claude_desktop_config.json`, which you can open from **Settings → Developer → Edit Config**: ```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "mcpServers": { "kosli": { "command": "npx", "args": ["-y", "@kosli/mcp-server"], "env": { "KOSLI_API_TOKEN": "your-token", "KOSLI_ORG": "your-org" } } } } ``` This method auto-updates through `npx` on each restart, but stores your API key in plain text. The server communicates over stdio. Point any MCP-capable client at the package with `npx -y @kosli/mcp-server` and set the environment variables below. ## Configuration The server reads its configuration from environment variables. | Variable | Required | Default | Notes | | ----------------- | -------- | ----------------------- | --------------------------------------------------------------------------------- | | `KOSLI_API_TOKEN` | yes | - | `KOSLI_API_KEY` is accepted as a fallback. | | `KOSLI_ORG` | yes | - | Default org. Used as the `org` path parameter when an action does not supply one. | | `KOSLI_BASE_URL` | no | `https://app.kosli.com` | Use `https://app.us.kosli.com` for US, or your own single-tenant endpoint. | ## Example prompts These prompts only read data, so they run without an approval step. Replace the environment, flow, and trail names with your own. ### Environments and compliance * "Which of my environments are non-compliant, and why?" * "What is running in `prod-aws` right now?" * "Has anything changed in `prod-aws` since yesterday?" The assistant answers these from [environment snapshots](/getting_started/environments), so it can report both the current state and the reasons an environment is not compliant. ### Audit and evidence * "List every deployment to `prod-aws` in the last 30 days." * "What attestations are on trail `release-456` in flow `my-release`?" * "Which artifacts running in `prod-aws` have no security scan attestation?" The last prompt takes several tool calls, because the assistant has to list what is running and then check the [attestations](/getting_started/attestations) on each artifact. Expect it to be slower than a single lookup, and check the artifact list it worked from before relying on the answer. ## Limitations * The action catalog is generated from a snapshot of the OpenAPI spec. New endpoints become available when the catalog is regenerated and a new version of the package is published. * Ambiguous questions may take several `search_actions` calls before the assistant settles on the right action. * Responses are whatever the Kosli API returns. Large responses consume a lot of context, so ask for specific fields when you can. ## Feedback The server is in beta and we want to hear how it works for you. Email [support@kosli.com](mailto:support@kosli.com) or open an issue in [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server/issues). # Slack Source: https://docs.kosli.com/integrations/slack Integrate Kosli with Slack using the Kosli Slack App to receive notifications and query your environments and artifacts directly from Slack. Allows you to configure and receive notifications about changes in your environments and query Kosli about your environments and artifacts without leaving Slack window. Visit [https://slack.kosli.com](https://slack.kosli.com) to add Kosli Slack App to your Slack workspace. Now that Kosli Slack App is installed you can start using all `/kosli` commands in any channel. At any time you can run `/kosli help` to see which commands are available. The next step is connecting your Slack user with your Kosli user, use the command below to do that: ``` /kosli login ``` After that you may want to set up default Kosli organization, so you don't have to provide it every time you want to run `/kosli` commands from slack. E.g. if the organization name is **my-org**: ``` /kosli config org my-org ``` In case of commands referring to snapshots you can specify snapshot(s) you're interested in multiple ways: * `environmentName~N` *N'th behind the latest snapshot* * `environmentName#N` *snapshot number N* * `environmentName@{YYYY-MM-DDTHH:MM:SS}` *snapshot at specific moment in time in UTC* * `environmentName` *the latest snapshot* Here is an example of *search* command and the response: `/kosli search edb1a262` # Sonar Source: https://docs.kosli.com/integrations/sonar The results of SonarQube Server and SonarQube Cloud scans can be tracked in Kosli trails. This integration involves setting up a Sonar webhook in Kosli and a corresponding webhook in SonarQube. The results of SonarQube Server and SonarQube Cloud scans can be tracked in [Kosli trails](/getting_started/trails). This integration involves setting up a Sonar webhook in Kosli and a corresponding webhook in SonarQube. When you run a scan of your SonarQube project, the webhook is triggered and the results of the scan are sent to Kosli. Some parameters must be passed to the Sonar scanner when it is run (e.g. the name of the Flow corresponding to the project, and the name of the trail the results should be attested to); these are sent with the scan results, and allow Kosli to determine the compliance status of the results and attest them to the correct trail/artifact. ## Setting up in Kosli To set up the integration, navigate to the Sonar integration page for your org in the [Kosli app](https://app.kosli.com/). After switching on the integration, you will be provided with a webhook and a secret. #### Configuring the flow name By default, Kosli will use the key of your SonarQube project as the flow name for the sonar attestation. You can configure this flow name in the "Flow Name Options" section on the integration page, by choosing either the project name or key as the base of the flow name, and then optionally adding a prefix and/or suffix. Note that if you set the flow name by sending a parameter to the Sonar Scanner (see [Scanner parameters](#scanner-parameters) below), this configuration will be overridden. ## Setting up Sonar Webhooks You're now just a few steps away from connecting SonarQube to Kosli. Both SonarQube Server and SonarQube Cloud provide two types of webhooks: global (which are triggered when any project in your organization is scanned) and project-specific (which are triggered by a scan for that project only). Kosli supports both types of webhooks. In [SonarQube Cloud](https://sonarcloud.io/) or [SonarQube Server](https://sonarqube.org): ### To create a global webhook: * In SonarQube Cloud: Go to your Organization, then Administration > Webhooks * In SonarQube Server: Go to Administration > Configuration > Webhooks * Create a new Webhook * Add the Kosli webhook URL and secret provided * Click Create Descriptive alt text Descriptive alt text ### To create a project-specific webhook: * Go to the project you want to create a webhook for * Click on Administration (SonarQube Cloud) or Project Settings (SonarQube Server) and go to Webhooks in the dropdown menu * Create a new Webhook * Add the Kosli webhook URL and secret provided * Click Create Descriptive alt text Descriptive alt text ## Setting up the SonarScanner In order for Kosli to know where the scan results should be attested, certain parameters can be passed to the SonarScanner. Note that parameters cannot be passed with SonarQube Cloud's Automatic Analysis - in this case, Kosli determines the relevant Flow and Trail as described below. These parameters can be passed to the scanner in three ways: * As part of the sonar-project.properties file used in CI analysis * As arguments to the scanner in your CI pipeline's YML file ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@master with: args: > -Dsonar.analysis.kosli_flow= -Dsonar.analysis.kosli_trail= ``` * As arguments to the CLI scanner ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} $ sonar-scanner \ -Dsonar.analysis.kosli_flow= \ -Dsonar.analysis.kosli_trail= ``` ### Scanner parameters: * `sonar.analysis.kosli_flow=` * The name of the Flow relevant to your project. If a Flow does not already exist with the given name, it is created. If no Flow name is provided, it is determined using the chosen Flow name configuration (see [Configuring the flow name](#configuring-the-flow-name) above), with any invalid symbols replaced by '-'. * `sonar.analysis.kosli_trail=` * The name of the Trail to attest the scan results. If a Trail does not already exist with the given name it is created. If no Trail name is provided, the revision ID of the SonarQube project (typically defaulted to the Git SHA) is used as the name. * `sonar.analysis.kosli_attestation=` * The name you want to give to the attestation. If not provided, a default name "sonar" is used. If using dot-notation (of the form ``), either the artifact fingerprint or git commit is also required (see below). * `sonar.analysis.kosli_git_commit=` * The git commit for the attestation. If not provided the revision ID of the SonarQube project is used (provided it has the correct format for a git SHA). * `sonar.analysis.kosli_artifact_fingerprint=` * The fingerprint of the artifact you want the attestation to be attached to. Requires that the artifact has already been reported to Kosli. * `sonar.analysis.kosli_flow_description=` * The description for the Kosli Flow being created by this webhook. This will not be used if attesting to an already-existing Flow (i.e. will not change any existing descriptions). * `sonar.analysis.kosli_trail_description=` * The description for the Kosli Trail being created by this webhook. This will not be used if attesting to an already-existing Trail (i.e. will not change any existing descriptions). ## Testing the integration To test the webhook once configured, simply scan a project in SonarQube. If successful, the results of the scan will be attested to the relevant Flow and Trail (and artifact, if applicable) as a sonar attestation. If the webhook fails, check that you have passed the parameters to the scanner correctly, and that the trail name, attestation name and artifact fingerprint are valid. ## Live Example in CI system View an example of a sonar attestation via webhook in Github. In [this YAML file](https://app.kosli.com/api/v2/livedocs/cyber-dojo/yaml?ci=github\&command=-Dsonar.analysis.kosli_flow), which created [this Kosli event](https://app.kosli.com/api/v2/livedocs/cyber-dojo/event?ci=github\&command=-Dsonar.analysis.kosli_flow). ## Alternatives: If you'd rather not use webhooks, or they don't quite fit your use-case, we also have a [CLI command](/client_reference/kosli_attest_sonar) for attesting Sonar scan results to Kosli. # Kosli Learning Labs Source: https://docs.kosli.com/labs/index A hands-on five-lab series taking you from your first Kosli account to full supply chain compliance enforcement. These labs provide a progressive, practical introduction to Kosli's core features. You'll learn how to track your software delivery process from build through deployment, establish compliance requirements, and maintain complete visibility into your software supply chain. Each lab builds on the previous one — complete them in order. Want something shorter first? [Try Kosli locally](/tutorials/try_kosli_locally) is a 10-minute Docker-based demo that requires no GitHub account or CI pipeline. **Prerequisites**: A GitHub account, basic familiarity with Git and CI/CD concepts. No prior Kosli experience required. Fork the sample repository and verify the CI/CD pipeline runs successfully. Install the Kosli CLI, create Flows and Trails, and integrate them into your GitHub Actions workflow. Attest artifacts, attach JUnit test results, and generate and attest a Software Bill of Materials. Define compliance requirements with Flow Templates and gate deployments with `kosli assert artifact`. Create environments, snapshot what's running in production, and enforce compliance policies. The labs use a sample Java application with a pre-built GitHub Actions pipeline. You'll progressively add Kosli integration to that pipeline across Labs 2–5. The standalone lab repository is also available at [github.com/kosli-dev/labs](https://github.com/kosli-dev/labs). # Lab 1: Get Ready Source: https://docs.kosli.com/labs/lab-01-get-ready Fork the sample repository, verify the CI/CD pipeline, and install the Kosli CLI. ## Learning goals * Create a copy of the sample application repository * Verify the CI/CD pipeline runs successfully * Install the Kosli CLI and create an API key * Understand the basic structure of the application and its deployment process ## Introduction Before diving into Kosli's features, you need to set up your account and verify that your sample application builds and deploys correctly. This lab uses a simple Java application with a complete CI/CD pipeline already configured in GitHub Actions. The pipeline builds the application, creates a Docker image, runs tests, and deploys it. In subsequent labs, you'll integrate Kosli to track all these activities. ## Exercise * Navigate to [github.com/kosli-dev/labs](https://github.com/kosli-dev/labs) * Click the **Use this template** button in the top-right corner * Select **Create a new repository** * Set your personal GitHub account as the **Owner** and name the repository `labs` * Click **Create repository from template** From now on, "your repository" refers to your copy of the labs repository at `https://github.com/YOUR-GITHUB-USERNAME/labs`. 1. Go to your repository on GitHub 2. Click the **Actions** tab 3. If prompted, click **I understand my workflows, go ahead and enable them** 4. If the workflow doesn't start automatically, trigger it manually: * Click **Main workflow** in the left sidebar * Click **Run workflow**, select `main`, and click **Run workflow** In the **Actions** tab, click the most recent workflow run and observe the jobs: | Job | What it does | | ---------------- | ------------------------------------------- | | Build | Compiles the Java application using Gradle | | Linting | Checks code quality (warnings are expected) | | Docker-image | Builds and pushes a Docker container image | | Security-scan | Scans the Docker image for vulnerabilities | | Component-test | Runs integration tests | | Performance-test | Runs basic performance checks | | Deploy | Starts and stops the application container | Wait for all jobs to show green checkmarks. GitHub Actions pipeline showing all jobs completing successfully The pipeline may take 3–6 minutes on the first run. GitHub Actions provides free minutes for public repositories. * **Docker-image job fails with permission error**: Make sure your repository has package write permissions enabled. * **Linting shows warnings**: This is expected and won't fail the build (`DISABLE_ERRORS` is set to `true`). Run the one-line install script: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} curl -fL https://raw.githubusercontent.com/kosli-dev/cli/refs/heads/main/install-cli.sh | sh # Verify installation kosli version ``` If this method fails, see [Install Kosli CLI](/getting_started/install) for alternative installation options (Homebrew, APT, Docker, etc.). * Log in to [app.kosli.com/settings/profile](https://app.kosli.com/settings/profile) * Navigate to the **API Keys** section * Click **Add API Key**, give it a name (e.g., "CLI Access"), and copy the key immediately — it won't be shown again Configure it for local use: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export KOSLI_API_TOKEN="your-api-key-here" export KOSLI_ORG="your-gh-username" ``` Verify the CLI can reach Kosli: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli list flows ``` You should see "No flows were found" — which confirms authentication is working. Never commit API keys to your repository. You'll add this key to GitHub Secrets in Lab 2. See [Authenticating to Kosli](/getting_started/authenticating_to_kosli) for more on API key management. In your repository, navigate to `.github/workflows/full-pipeline.yaml` and review the structure: * Notice how it triggers on every push * Observe the environment variables at the top * See how artifacts are shared between jobs using `upload-artifact` and `download-artifact` * Note the dependencies between jobs (e.g., Docker-image requires Build to complete first) In later labs, you'll add Kosli integration to this file. 1. Go to your GitHub profile page 2. Click the **Packages** tab 3. You should see the `labs` package 4. Click it to view the Docker image details — note the image tag (`latest`) and SHA digest The Docker image is automatically published to GitHub Container Registry (`ghcr.io`) by the pipeline. ## Verification checklist Before moving to the next lab, confirm: * [ ] Copy of the labs repository under your GitHub account * [ ] GitHub Actions completed all jobs successfully * [ ] Docker image published to your GitHub Container Registry * [ ] Kosli CLI installed (`kosli version` works) * [ ] API key created and `kosli list flows` returns successfully * [ ] You understand the basic pipeline structure ## Next steps Continue to [Lab 2: Flows and Trails](/labs/lab-02-flows-and-trails) to create your first Flow and Trail and integrate them into your pipeline. # Lab 2: Flows and Trails Source: https://docs.kosli.com/labs/lab-02-flows-and-trails Create Flows and Trails using the Kosli CLI, and integrate them into your GitHub Actions workflow. **Prerequisites**: Complete [Lab 1: Get Ready](/labs/lab-01-get-ready) before starting this lab. You should have the Kosli CLI installed and an API key configured. ## Learning goals * Understand the concepts of Flows and Trails * Create your first Flow using the CLI * Begin a Trail manually to track a process execution * Integrate Flow and Trail creation into your CI/CD workflow ## Introduction Kosli uses **Flows** and **Trails** to organize and track your software delivery processes: * A **Flow** represents a repeatable business or software process (like your CI/CD pipeline). It defines what you want to track and what compliance requirements must be met. * A **Trail** represents a single execution instance of that Flow. For example, each git commit creates a new Trail that tracks all activities for that specific change. Think of a Flow as the template for your process, and Trails as individual instances that record what actually happened. ## Exercise ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow labs-pipeline \ --description "CI/CD pipeline for labs application" \ --use-empty-template # Verify it was created kosli get flow labs-pipeline ``` You should see output like: ``` Name: labs-pipeline Description: CI/CD pipeline for labs application Visibility: private Template: version: 1 Last Deployment At: N/A Tags: None ``` Visit [app.kosli.com](https://app.kosli.com) and navigate to **Flows** to see your newly created Flow. The `--use-empty-template` flag creates a Flow without compliance requirements. In Lab 4, you'll add a template with specific attestation requirements. See [`kosli create flow`](/client_reference/kosli_create_flow) for full flag reference. A Trail represents one execution of your process. Create one using your latest git commit SHA: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Run this inside your copy of the labs repository kosli begin trail $(git rev-parse HEAD) \ --flow labs-pipeline \ --description "Manual trail for testing" # Verify it was created kosli get trail $(git rev-parse HEAD) \ --flow labs-pipeline ``` Make sure you run this inside your copy of the labs repository, not the original. The Trail name is the git commit SHA, which uniquely identifies this execution and lets Kosli connect all activities (builds, tests, deployments) for that specific commit. You can use any naming scheme for Trails (commit SHA, PR number, Jira ticket, etc.). Git commits are common because they're unique and tied to your source code. Kosli web interface showing the first trail under labs-pipeline See [`kosli begin trail`](/client_reference/kosli_begin_trail) for full flag reference. Everything in a Kosli trail is immutable — updates are append-only. This is critical for compliance: if data could be changed, it could be tampered with. Run `begin trail` again on the same commit with a slightly different description: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli begin trail $(git rev-parse HEAD) \ --flow labs-pipeline \ --description "Manual trail for testing." ``` Now get the trail again: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli get trail $(git rev-parse HEAD) \ --flow labs-pipeline ``` Notice the **Events** section shows both the original `trail started` event and a new `trail updated` event — the history is preserved, not overwritten. 1. In your repository, go to **Settings → Secrets and variables → Actions** 2. Click **New repository secret**, name it `KOSLI_API_TOKEN`, and paste your API key 3. Click **Variables → New repository variable**, name it `KOSLI_ORG`, and enter your GitHub username Never commit API keys to your repository. Always use GitHub Secrets. Open `.github/workflows/full-pipeline.yaml` and make the following changes: **1. Add global environment variables** at the top of the file: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} env: KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} KOSLI_ORG: ${{ vars.KOSLI_ORG }} # ... other existing env vars ... ``` **2. Add Kosli steps** just after the `actions/checkout` step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Clone down repository uses: actions/checkout@v7 - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 with: version: 2.28.0 - name: Create/Update Flow run: | kosli create flow ${APP_NAME}-pipeline \ --description "CI/CD pipeline for ${APP_NAME} application" \ --use-empty-template - name: Begin Trail run: | kosli begin trail ${GIT_COMMIT} \ --flow ${APP_NAME}-pipeline \ --description "Build ${BUILD_NUMBER}: ${GIT_BRANCH}" ``` The `kosli-dev/setup-cli-action` installs the CLI in CI. The global `env` variables authenticate all subsequent CLI calls automatically. ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} git add .github/workflows/full-pipeline.yaml git commit -m "Add Kosli Flow and Trail steps" git push origin main ``` In GitHub Actions, watch the workflow run and confirm the **Setup Kosli CLI**, **Create/Update Flow**, and **Begin Trail** steps complete successfully. Then visit [app.kosli.com](https://app.kosli.com) → your Flow → you should see a new Trail corresponding to your commit. ## Verification checklist * [ ] `KOSLI_API_TOKEN` and `KOSLI_ORG` added to GitHub Secrets/Variables * [ ] Flow created manually via CLI * [ ] Trail created manually using a git commit SHA * [ ] Workflow updated with Kosli steps and runs successfully * [ ] Flow and Trails visible in the Kosli web interface If anything didn't go to plan, refer to the reference solution at `pipelines/02-complete.yaml` in the [labs repository](https://github.com/kosli-dev/labs). ## Next steps Continue to [Lab 3: Build Controls](/labs/lab-03-build-controls) to attest artifacts and attach evidence to your Trails. **Further reading:** * [Flows](/getting_started/flows) * [Trails](/getting_started/trails) # Lab 3: Build Controls Source: https://docs.kosli.com/labs/lab-03-build-controls Attest artifacts, attach JUnit test results, and generate and attest a Software Bill of Materials. **Prerequisites**: Complete [Lab 2: Flows and Trails](/labs/lab-02-flows-and-trails) before starting this lab. ## Learning goals * Understand what attestations are and why they matter for compliance * Attest a JAR file and Docker image as artifacts * Attach JUnit test results as attestations * Attach a Software Bill of Materials (SBOM) as an attestation * Integrate all attestation commands into your CI/CD pipeline ## Introduction **Attestations** are how you record facts about your software supply chain in Kosli. They are immutable pieces of evidence that prove certain activities occurred — like tests passing, security scans completing, or artifacts being built. Kosli supports several attestation types: * **Built-in**: `artifact`, `generic`, `junit`, `snyk`, `sonar`, `pull_request`, `jira` * **Custom**: Types you define yourself with [`kosli create attestation-type`](/client_reference/kosli_create_attestation-type) Each attestation is linked to a Trail and optionally to a specific artifact, creating an auditable chain of evidence. ### Artifact fingerprints Kosli identifies artifacts by their **SHA256 fingerprint**. This uniquely identifies the artifact regardless of where it's stored or what it's named. The CLI can calculate fingerprints for: * `--artifact-type file` — JAR files, binaries * `--artifact-type dir` — source code, build outputs * `--artifact-type docker` — images from local Docker daemon * `--artifact-type oci` — images from container registries Using fingerprints ensures you're tracking the exact artifact, not just its name or tag. See [Artifacts](/getting_started/artifacts) for more. ## Exercise In `.github/workflows/full-pipeline.yaml`, find the `Build` job and add this step after the "Build application" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Attest application artifact run: | JAR_FILE=$(ls app/build/libs/app-*.jar) kosli attest artifact ${JAR_FILE} \ --artifact-type file \ --flow ${APP_NAME}-pipeline \ --trail ${GIT_COMMIT} \ --name application \ --build-url ${BUILD_URL} \ --commit-url ${COMMIT_URL} ``` The `--name application` gives this artifact a logical name in your Flow. This name is used to attach further attestations (like tests) to this specific artifact. See [`kosli attest artifact`](/client_reference/kosli_attest_artifact) for full flag reference. Still in the `Build` job, add this step after the test step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Attest JUnit test results run: | kosli attest junit \ --flow ${APP_NAME}-pipeline \ --trail ${GIT_COMMIT} \ --name application.unit-tests \ --results-dir app/build/test-results/test/ ``` The dot notation (`application.unit-tests`) tells Kosli this attestation belongs to the `application` artifact. Attestations without a dot belong to the Trail itself. Kosli automatically parses the JUnit XML to determine pass/fail status. See [`kosli attest junit`](/client_reference/kosli_attest_junit). In the `Docker-image` job, add these steps after the "push docker" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 with: version: 2.28.0 - name: Attest Docker image run: | IMAGE_NAME="ghcr.io/${IMAGE}:latest" kosli attest artifact ${IMAGE_NAME} \ --artifact-type oci \ --flow ${APP_NAME}-pipeline \ --trail ${GIT_COMMIT} \ --name docker-image \ --build-url ${BUILD_URL} \ --commit-url ${COMMIT_URL} \ --registry-username ${{ github.actor }} \ --registry-password ${{ secrets.GITHUB_TOKEN }} ``` Using `--artifact-type oci` tells Kosli to fetch the image manifest directly from the registry, without needing Docker installed locally. This is more reliable in CI. Your workflow already generates an SBOM using Anchore. Add this step to the `Docker-image` job after the "Generate SBOM" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Attest SBOM run: | IMAGE_NAME="ghcr.io/${IMAGE}:latest" kosli attest generic \ --flow ${APP_NAME}-pipeline \ --trail ${GIT_COMMIT} \ --name docker-image.sbom \ --artifact-type oci ${IMAGE_NAME} \ --attachments sbom.spdx.json \ --registry-username ${{ github.actor }} \ --registry-password ${{ secrets.GITHUB_TOKEN }} ``` The SBOM attestation is linked to the `docker-image` artifact via the `docker-image.sbom` name. Kosli stores the SBOM file in its Evidence Vault. An SBOM (Software Bill of Materials) lists all components and dependencies in your software — crucial for tracking vulnerabilities and license compliance. ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} git add .github/workflows/full-pipeline.yaml git commit -m "Add Kosli attestation steps" git push origin main ``` Watch the workflow run and confirm all attestation steps complete successfully. Then in [app.kosli.com](https://app.kosli.com), navigate to your Flow → latest Trail and verify: * **Artifacts**: JAR file and Docker image with fingerprints * **Attestations**: Unit tests attached to `application`, SBOM attached to `docker-image` * **Timeline**: When each attestation was recorded Click individual attestations to view JUnit test counts and SBOM component details. Your workflow already runs Trivy security scans. You can extend this lab by attesting the scan results as a generic attestation: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} export DOCKER_IMAGE="/labs" kosli attest generic \ --flow labs-pipeline \ --trail $(git rev-parse HEAD) \ --name docker-image.security-scan \ --artifact-type oci ghcr.io/${DOCKER_IMAGE}:latest \ --compliant=true \ --description "Trivy scan completed" ``` In production you'd parse Trivy results and set `--compliant` based on severity thresholds. ## Verification checklist * [ ] Workflow updated with attestation steps * [ ] All attestation steps pass in the workflow * [ ] Artifacts visible in the Kosli Trail with fingerprints * [ ] JUnit test results attached to the `application` artifact * [ ] SBOM attached to the `docker-image` artifact If anything didn't go to plan, refer to the reference solution at `pipelines/03-complete.yaml` in the [labs repository](https://github.com/kosli-dev/labs). ## Next steps Continue to [Lab 4: Release Controls](/labs/lab-04-release-controls) to define compliance requirements and gate deployments. **Further reading:** * [Attestations](/getting_started/attestations) * [Artifacts](/getting_started/artifacts) # Lab 4: Release Controls Source: https://docs.kosli.com/labs/lab-04-release-controls Define compliance requirements with Flow Templates and gate deployments with kosli assert artifact. **Prerequisites**: Complete [Lab 3: Build Controls](/labs/lab-03-build-controls) before starting this lab. ## Learning goals * Understand Flow Templates and how they define compliance requirements * Update an existing Flow to enforce specific attestations * Understand the difference between compliant and non-compliant Trails * Use `kosli assert artifact` to gate deployments based on compliance status ## Introduction In the previous labs, you've been recording evidence (attestations) for your builds. However, recording evidence is only half the picture — you also need to ensure the *required* evidence is actually present before allowing a release. **Flow Templates** define the "shape" of a compliant release. They specify: * Which artifacts are expected in the Trail * Which attestations are required for each artifact * Which attestations are required at the Trail level When a Trail is evaluated against its Flow Template, Kosli determines if it is Compliant or Non-compliant. By adding `kosli assert artifact` to your pipeline, you can automatically block deployments that don't meet your compliance standards. See [Flow Templates](/template-reference/flow_template) for the full template specification. ## Exercise Create a file named `flow-template.yaml` in the root of your repository: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/flow-template/v1.json version: 1 trail: artifacts: - name: application attestations: - name: unit-tests type: junit - name: docker-image attestations: - name: sbom type: generic ``` This template matches the attestations you set up in Lab 3: 1. An `application` artifact that must have `unit-tests` 2. A `docker-image` artifact that must have an `sbom` In `.github/workflows/full-pipeline.yaml`, find the `Create/Update Flow` step (added in Lab 2) and replace `--use-empty-template` with `--template-file`: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Create/Update Flow run: | kosli create flow ${APP_NAME}-pipeline \ --description "CI/CD pipeline for ${APP_NAME} application" \ --template-file flow-template.yaml ``` In the `Deploy` job, add the following steps **before** the "Deploy to production" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v5 with: version: 2.28.0 - name: Assert compliance run: | IMAGE_NAME="ghcr.io/${IMAGE}:latest" kosli assert artifact ${IMAGE_NAME} \ --artifact-type oci \ --flow ${APP_NAME}-pipeline ``` This command asks Kosli: *"Is this artifact and its Trail compliant?"* * Compliant (all required attestations present and none failing): exits `0` — pipeline continues to deploy * Non-compliant (missing or failing attestations): exits `1` — pipeline fails, deployment is blocked See [`kosli assert artifact`](/client_reference/kosli_assert_artifact) for full flag reference. ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} git add flow-template.yaml .github/workflows/full-pipeline.yaml git commit -m "Add Flow Template and Release Gate" git push origin main ``` Watch the workflow run. Since you're providing all required attestations from Lab 3, the `Assert compliance` step should pass (green). Then in [app.kosli.com](https://app.kosli.com), navigate to your Flow → latest Trail. The **Compliance** status should show Compliant with all template requirements checked off. To see the gate in action, add a non-existent attestation requirement to `flow-template.yaml`: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: docker-image attestations: - name: sbom type: generic - name: performance-test # We haven't implemented this yet! type: generic ``` Commit and push. The `Assert compliance` step should **fail**, preventing the deploy step from running. The Trail in Kosli will be marked Non-compliant. Remember to revert this change to make your pipeline green again. ## Verification checklist * [ ] `flow-template.yaml` created in repository root * [ ] Workflow updated to apply the template * [ ] `kosli assert artifact` added to the Deploy job * [ ] A fully attested build passes the compliance gate * [ ] Trail shows as Compliant in the Kosli web interface If anything didn't go to plan, refer to the reference solution at `pipelines/04-complete.yaml` in the [labs repository](https://github.com/kosli-dev/labs). ## Next steps Continue to [Lab 5: Runtime Controls](/labs/lab-05-runtime-controls) to track what's running in production and enforce compliance policies. **Further reading:** * [Flows](/getting_started/flows) * [Flow Template reference](/template-reference/flow_template) # Lab 5: Runtime Controls Source: https://docs.kosli.com/labs/lab-05-runtime-controls Create environments, snapshot what's running in production, and enforce compliance policies. **Prerequisites**: Complete [Lab 4: Release Controls](/labs/lab-04-release-controls) before starting this lab. ## Learning goals * Understand Kosli Environments and how they track runtime state * Create a Kosli Environment representing your deployment target * Snapshot a Docker environment to report what's running * Create and configure compliance Policies * Attach Policies to Environments for enforcement * Integrate environment snapshotting into your CI/CD pipeline ## Introduction **Kosli Environments** allow you to track what's actually running in your runtime environments (dev, staging, production). By taking regular **snapshots**, Kosli creates an immutable record of: * What artifacts are running, identified by their SHA256 digest * When they started and stopped * Whether they comply with your policies * The complete change history over time **Policies** define compliance requirements for environments — rules like "all artifacts must have provenance", "all artifacts must have passed unit tests", or "all artifacts must have an SBOM". Together, Environments and Policies give you runtime visibility and enforcement for your software supply chain. ### Environment types Kosli supports several environment types: | Type | Tracks | | -------- | ----------------------------- | | `docker` | Docker containers on a host | | `k8s` | Kubernetes pods in namespaces | | `ecs` | AWS ECS tasks | | `lambda` | AWS Lambda functions | | `s3` | Files in S3 buckets | | `server` | Files on a server filesystem | See [Environments](/getting_started/environments) for more. ## Exercise Your application deploys as a Docker container, so create a `docker` type environment: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create environment labs-prod \ --type docker \ --description "Production environment for labs application" # Verify it was created kosli get environment labs-prod ``` Visit [app.kosli.com](https://app.kosli.com) → **Environments** and you should see `labs-prod` listed (with no snapshots yet). See [`kosli create environment`](/client_reference/kosli_create_environment) for full flag reference. To see a real-world example, navigate to the [Cyber-Dojo AWS Beta environment](https://app.kosli.com/cyber-dojo/environments/aws-beta/snapshots/). Here you can see a history of snapshots taken from a production AWS environment. Each snapshot shows: * **Running artifacts**: Container images currently running * **Compliance status**: Whether they meet policy requirements * **Events**: What started or stopped since the last snapshot * **Duration**: How long the application has been running Each snapshot is immutable. If nothing changed since the last snapshot, Kosli won't create a new one — only real changes produce new snapshots. In `.github/workflows/full-pipeline.yaml`, add this step to the `Deploy` job **after** the "Deploy to production" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Snapshot environment run: kosli snapshot docker labs-prod ``` This captures what's running immediately after deployment. Create `.kosli-policy.yml` in the root of your repository: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: provenance: required: true # All artifacts must be part of a Flow attestations: - name: unit-tests type: junit - name: sbom type: "*" # Any attestation type ``` This policy requires: 1. All running artifacts must have been attested to Kosli (provenance) 2. All artifacts must have JUnit test results 3. All artifacts must have an SBOM Then create the policy in Kosli: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create policy labs-prod-requirements .kosli-policy.yml # View it kosli get policy labs-prod-requirements ``` See [`kosli create policy`](/client_reference/kosli_create_policy) and [Policies](/getting_started/policies) for more details. ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attach-policy labs-prod-requirements --environment labs-prod # Verify attachment kosli get environment labs-prod ``` Attaching a policy automatically triggers a new snapshot evaluation. Kosli immediately checks if currently running artifacts meet the requirements. See [`kosli attach-policy`](/client_reference/kosli_attach-policy) for full flag reference. In the `Deploy` job, add these steps **before** the "Assert compliance" step: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} - name: Update policy run: kosli create policy labs-prod-requirements .kosli-policy.yml - name: Attach policy to environment run: kosli attach-policy labs-prod-requirements --environment labs-prod ``` ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} git add .kosli-policy.yml .github/workflows/full-pipeline.yaml git commit -m "Add Kosli environment and policy management" git push origin main ``` Watch the workflow execute. After it completes, in [app.kosli.com](https://app.kosli.com): * Navigate to **Environments → labs-prod** → latest snapshot * Check the compliance status — it should be Compliant, since you've been attesting unit tests and SBOM since Lab 3 * Click on the running artifact to see which attestations are present - Verify the attestation names in your workflow match the names in `.kosli-policy.yml` exactly - Check that all attestation steps completed successfully in the previous workflow run - Confirm the artifact fingerprint matches what was attested You can also use policies as deployment gates, preventing non-compliant artifacts from deploying: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Assert against specific policies before deployment kosli assert artifact ghcr.io/${IMAGE}:latest \ --policy labs-prod-requirements ``` If the artifact is non-compliant, this command exits with a non-zero status, failing the deployment step. See [`kosli assert artifact`](/client_reference/kosli_assert_artifact) for more details. Policies support conditional logic for sophisticated compliance rules: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} artifacts: attestations: # Only require security scans for production flow - if: ${{ flow.name == "production" }} name: security-scan type: snyk # Exceptions for specific artifacts - name: unit-tests type: junit exceptions: - if: ${{ artifact.name == "legacy-component" }} ``` See [Policy expressions](/policy-reference/environment_policy#policy-expressions) for more. ## Verification checklist * [ ] `labs-prod` environment of type `docker` created * [ ] Explored the Cyber-Dojo environment in Kosli * [ ] `.kosli-policy.yml` created with compliance requirements * [ ] Policy created in Kosli and attached to the environment * [ ] Workflow updated with policy update and snapshot steps * [ ] Workflow runs successfully * [ ] Environment snapshots visible in Kosli * [ ] Running artifact shows as Compliant ## Congratulations! You've completed all five Kosli Learning Labs. You now know how to: 1. Set up Kosli and integrate it with a CI/CD pipeline 2. Create Flows and Trails to track your software delivery process 3. Attest artifacts and attach evidence (tests, SBOMs, scans) 4. Define compliance requirements and gate releases 5. Create environments, track what's running, and enforce policies You have full visibility and control over your software supply chain, from build to deployment. ## Explore further * [Custom attestation types](/getting_started/attestations) for your specific tools * [Kubernetes environment reporting](/tutorials/report_k8s_envs) if you use K8s **Further reading:** * [Environments](/getting_started/environments) * [Policies](/getting_started/policies) # Environment Policy Source: https://docs.kosli.com/policy-reference/environment_policy Reference for the YAML policy files used to define compliance requirements for Kosli environments. An environment policy is a YAML file that declares compliance requirements for artifacts running in a Kosli environment. You pass the file to [`kosli create policy`](/client_reference/kosli_create_policy) to create or update a policy. For concepts, workflow, and enforcement, see [Environment Policies](/getting_started/policies). Prefer to build a policy interactively? Use the [Policy builder](/policy-reference/policy_builder) to assemble a valid policy file in your browser and copy the YAML. ## Specification Version identifier and [JSON Schema](https://docs.kosli.com/schemas/policy/v1.json) URL for the policy format. The final path segment must match `/v{n}` where `n` is a supported major version. Currently only `v1` is supported. ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/policy/v1.json _schema: https://docs.kosli.com/schemas/policy/v1 ``` Rules applied to artifacts in an environment snapshot. Omitted keys use server defaults. Requires artifacts to have provenance (i.e., be part of a Kosli flow). When `true`, every artifact in the snapshot must have provenance. List of conditions under which the provenance requirement is waived. Each element is an object with a single `if` key containing a [policy expression](#policy-expressions). ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} exceptions: - if: ${{ matches(artifact.name, "^datadog:.*") }} ``` Requires artifacts to belong to a compliant trail in their flow. When `true`, every artifact must be part of a compliant trail. List of conditions under which the trail-compliance requirement is waived. Same structure as `provenance.exceptions`. List of attestations every artifact must have. Each element is a required-attestation rule. The [attestation type](#attestation-types) to require. Cannot be `*` when `name` is also `*`. Attestation name to match. `*` matches any name. Cannot be `*` when `type` is also `*`. A [policy expression](#policy-expressions). When present, this attestation is only required when the expression evaluates to `true`. ## Attestation types | Value | Description | | --------------- | -------------------------------------------------------------------------------------------------------------- | | `generic` | Generic attestation | | `junit` | JUnit test results | | `snyk` | Snyk security scan | | `pull_request` | Pull request evidence | | `jira` | Jira ticket reference | | `sonar` | SonarQube analysis | | `*` | Matches any built-in or custom type | | `custom:` | A [custom attestation type](/client_reference/kosli_create_attestation-type) (e.g., `custom:coverage-metrics`) | ## Policy expressions Expressions are boolean conditions evaluated against flow and artifact context. They are wrapped in `${{ }}` and can appear in `if` and `exceptions[].if` fields. ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} if: ${{ flow.tags.risk-level == "high" and matches(artifact.name, "^prod:.*") }} ``` ### Operators | Operator | Category | Example | | -------- | ---------- | ------------------------------------------- | | `==` | Comparison | `flow.name == "runner"` | | `!=` | Comparison | `flow.tags.risk-level != "high"` | | `<` | Comparison | `flow.tags.priority < 3` | | `>` | Comparison | `flow.tags.priority > 1` | | `<=` | Comparison | `flow.tags.risk-level <= 2` | | `>=` | Comparison | `flow.tags.risk-level >= 2` | | `and` | Logical | `flow.name == "a" and artifact.name == "b"` | | `or` | Logical | `flow.name == "a" or flow.name == "b"` | | `not` | Logical | `not flow.tags.risk-level == "high"` | | `in` | Membership | `flow.name in ["runner", "saver"]` | Parentheses control precedence: `${{ flow.name == 'prod' and (flow.tags.team == "a" or artifact.name == 'svc') }}`. ### Contexts Information about the Kosli flow the artifact belongs to. Name of the flow. Flow tags, accessed by key: `flow.tags.risk-level`, `flow.tags.team`. Keys containing dots are supported: `flow.tags.key.with.dots`. Information about the artifact being evaluated. Name of the artifact. SHA256 fingerprint of the artifact. ### Functions | Function | Description | Example | | ----------------------- | --------------------------------------------------------- | ---------------------------------------------- | | `exists(arg)` | Returns `true` if `arg` is not null. | `${{ exists(flow) }}` | | `matches(input, regex)` | Returns `true` if `input` matches the regular expression. | `${{ matches(artifact.name, "^datadog:.*") }}` | ## Constraints * `_schema` is the only required field. All other fields are optional and use server defaults when omitted. * An attestation rule must not have both `name` and `type` set to `*`. * Expressions must evaluate to a boolean. An invalid expression causes a policy evaluation error. ## Example ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/policy/v1.json _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: provenance: required: true exceptions: - if: ${{ matches(artifact.name, "^datadog:.*") }} trail-compliance: required: true attestations: - name: security-scan type: snyk - name: pull-request type: pull_request if: ${{ flow.tags.risk-level == "high" }} - name: coverage type: custom:coverage-metrics ``` ## Editor validation The `_schema` URL resolves to a [JSON Schema](https://docs.kosli.com/schemas/policy/v1.json) for the environment policy format. To enable inline validation and autocomplete in VS Code (requires the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)) and other schema-aware editors, add a `yaml-language-server` directive: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/policy/v1.json _schema: https://docs.kosli.com/schemas/policy/v1 ``` ## See also * [Policy builder](/policy-reference/policy_builder) — build a policy file interactively in the browser * [Environment Policies](/getting_started/policies) — concepts, workflow, and enforcement * [`kosli create policy`](/client_reference/kosli_create_policy) — create or update a policy * [`kosli attach-policy`](/client_reference/kosli_attach-policy) — attach a policy to an environment * [`kosli assert artifact`](/client_reference/kosli_assert_artifact) — enforce policies on an artifact * [Terraform: kosli\_policy](/terraform-reference/resources/policy) — manage policies via Terraform # Environment Policy Builder Source: https://docs.kosli.com/policy-reference/policy_builder Build a Kosli environment policy YAML interactively in the browser and copy the result into your repo. Use this builder to assemble an [environment policy](/policy-reference/environment_policy). Toggle the requirements you need, add attestation rules and exceptions, then copy the generated YAML into a file in your repo. The output conforms to the [v1 policy schema](https://docs.kosli.com/schemas/policy/v1.json) and runs entirely in your browser — nothing is sent to Kosli. ## Next steps * Save the YAML as a file (e.g. `policy.yaml`) in your repo. * Create or update the policy with [`kosli create policy`](/client_reference/kosli_create_policy). * Attach it to an environment with [`kosli attach-policy`](/client_reference/kosli_attach-policy). ## See also * [Environment Policy](/policy-reference/environment_policy) — full schema reference and field descriptions * [Environment Policies](/getting_started/policies) — concepts, workflow, and enforcement # Rego Policy Source: https://docs.kosli.com/policy-reference/rego_policy Reference for Rego policy files used with kosli evaluate trail and kosli evaluate trails. A Rego policy defines the rules Kosli evaluates trail data against. You pass a `.rego` file to [`kosli evaluate trail`](/client_reference/kosli_evaluate_trail) or [`kosli evaluate trails`](/client_reference/kosli_evaluate_trails) via the `--policy` flag. Kosli includes a built-in Rego evaluator with no OPA installation required. ## Policy contract These rules are Kosli-specific conventions, not OPA built-ins. Kosli queries `data.policy.*` to find them. Every policy must declare `package policy`. Kosli queries `data.policy.allow` and `data.policy.violations` to read the result. Must evaluate to a boolean. Kosli exits with code `0` when `true`, code `1` when `false`. Always define `allow` with a fail-safe default and drive it through a positive assertion, not through the absence of violations. See [Safe policy design](#safe-policy-design). ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} default allow := false allow if trail_is_compliant(input.trail) ``` Optional but recommended. A set of human-readable strings explaining why the policy denied. Kosli displays these when `allow` is `false`. Each message should identify the offending resource and the reason. Violations are diagnostics only. They must not drive the `allow` decision. See [Safe policy design](#safe-policy-design). ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} violations contains msg if { # ... rule body ... msg := sprintf("descriptive message about %v", [resource]) } ``` ## Safe policy design Three rules prevent a policy from incorrectly reporting a non-compliant trail as compliant. ### Rule 1: use a fail-safe default Always start with `default allow := false`. A trail must be explicitly approved rather than allowed by the absence of evidence against it. Use parameter aliases at the top of the policy file rather than hardcoding threshold values. If a required param is absent from the params file, any rule that references its alias will fail to evaluate, and `allow` will correctly remain `false`. ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} max_days_by_severity := data.params.max_days_by_severity max_ignore_expiry_days := data.params.max_ignore_expiry_days ``` See [Evaluate trails with OPA policies](/tutorials/evaluate_trails_with_opa) for a detailed walkthrough. ### Rule 2: drive `allow` through positive assertions Drive the `allow` decision through a condition that must be true for the trail to be compliant. Do not write: ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Unsafe: allow depends on the absence of violations allow if { count(violations) == 0 } ``` When a `violations` rule body encounters an undefined reference, such as a missing param or an absent attestation field, OPA silently skips that rule body and adds no message to the set. The set is then empty, `count(violations) == 0` evaluates to `true`, and `allow` fires even though the policy never verified compliance. This produces a false-positive compliant result. The safe pattern makes compliance explicit: ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Safe: allow fires only when trail_is_compliant is positively true allow if trail_is_compliant(input.trail) ``` If any field referenced inside `trail_is_compliant` is undefined, the rule body fails to evaluate and `allow` remains `false`. See [Evaluate trails with OPA policies](/tutorials/evaluate_trails_with_opa) for a detailed walkthrough. ### Rule 3: violations are diagnostics only In a `violations` rule, an undefined reference causes the rule body to fail silently: no message is added. This is the safe failure mode for diagnostics. Violations explain a denial determined by the `allow` rule and must not determine it themselves. See [Evaluate trails with OPA policies](/tutorials/evaluate_trails_with_opa) for a detailed walkthrough. ## Params Policies can read external configuration via the `--params` flag. Params are available in the policy as `data.params.*`. This separates policy logic from the thresholds it enforces, so one `.rego` file can cover multiple environments with different params files. ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Inline JSON kosli evaluate trail "$TRAIL_NAME" \ --policy my-policy.rego \ --params '{"max_high": 0}' \ --org "$ORG" \ --flow "$FLOW" # JSON file kosli evaluate trail "$TRAIL_NAME" \ --policy my-policy.rego \ --params @rego.params.prod.json \ --org "$ORG" \ --flow "$FLOW" ``` Alias params at the top of the policy file so that missing values cause rules to fail rather than silently proceeding: ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} max_high := data.params.max_high ``` If `max_high` is absent, `max_high` is undefined and any rule that references it fails to evaluate, leaving `allow` at its `false` default. ## Input data The data structure passed to the policy as `input` depends on which command you use. ### Single trail (`kosli evaluate trail`) The policy receives `input.trail`, a single trail object. The trail being evaluated. The trail name (git commit SHA or custom name). Compliance data for the trail. Whether the trail is compliant against its flow template. Compliance status string, e.g. `"COMPLIANT"` or `"INCOMPLIANT"`. Map of attestation name to attestation status object. Each object contains the attestation's data, including type-specific fields enriched via `--attestations`. For example, a `pull-request` attestation includes a `pull_requests` array, each with an `approvers` array and a `url` string. Map of artifact name to artifact status object. Each artifact has its own `attestations_statuses` map with the same structure as above. ### Multiple trails (`kosli evaluate trails`) The policy receives `input.trails`, an array of trail objects with the same structure as `input.trail` above. Array of trail objects. Each element has the same structure as `input.trail` described above. Use `--show-input` with `--output json` to print the full input structure for a given trail. Pipe through `jq` to explore specific fields: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli evaluate trail "$TRAIL_NAME" \ --policy my-policy.rego \ --org "$ORG" \ --flow "$FLOW" \ --show-input \ --output json 2>/dev/null | jq '.input' ``` ## Local testing Use [`kosli evaluate input`](/client_reference/kosli_evaluate_input) to test a policy against captured trail data without making live Kosli API calls: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Capture trail data once kosli evaluate trail "$TRAIL_NAME" \ --policy allow-all.rego \ --show-input --output json | jq '.input' > trail-data.json # Iterate on the policy locally kosli evaluate input \ --input-file trail-data.json \ --policy my-policy.rego \ --params '{"max_high": 0}' ``` ## Exit codes | Code | Meaning | | ---- | ----------------------------------------------------------------------------------------------------------- | | `0` | Policy allowed (`allow = true`) | | `1` | Policy denied (`allow = false`) **or** command error (network failure, invalid Rego, policy file not found) | Exit code `1` is used for both denial and failure. To distinguish between them in CI, use `--output json` and read the `allow` field directly from the output rather than relying on the exit code. ## Examples ### Check pull request approvals across multiple trails Allows only when every trail in `input.trails` has at least one pull request with at least one approver. The attestation name is read from params so the same policy works across orgs that use different naming conventions. ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} package policy import rego.v1 pr_attestation_name := data.params.pr_attestation_name default allow := false trail_has_approved_pr(trail) if { some pr in trail.compliance_status.attestations_statuses[pr_attestation_name].pull_requests count(pr.approvers) > 0 } allow if { every trail in input.trails { trail_has_approved_pr(trail) } } violations contains msg if { some trail in input.trails some pr in trail.compliance_status.attestations_statuses[pr_attestation_name].pull_requests count(pr.approvers) == 0 msg := sprintf("trail '%v': pull-request %v has no approvers", [trail.name, pr.url]) } ``` ### Check Snyk scan results on a single trail Allows only when every artifact in the trail has a Snyk scan where the high-severity vulnerability count does not exceed `max_high`. Both the attestation name and the threshold are read from params. ```rego theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} package policy import rego.v1 snyk_attestation_name := data.params.snyk_attestation_name max_high := data.params.max_high default allow := false artifact_within_threshold(artifact) if { snyk := artifact.attestations_statuses[snyk_attestation_name] every result in snyk.processed_snyk_results.results { result.high_count <= max_high } } trail_is_compliant(trail) if { every name, artifact in trail.compliance_status.artifacts_statuses { artifact_within_threshold(artifact) } } allow if trail_is_compliant(input.trail) violations contains msg if { some name, artifact in input.trail.compliance_status.artifacts_statuses snyk := artifact.attestations_statuses[snyk_attestation_name] some result in snyk.processed_snyk_results.results result.high_count > max_high msg := sprintf("artifact '%v': snyk scan found %d high severity vulnerabilities (limit: %d)", [name, result.high_count, max_high]) } ``` ## Further reading * [Rego Style Guide](https://www.openpolicyagent.org/docs/style-guide): naming, rule structure, and test conventions * [OPA Annotations](https://www.openpolicyagent.org/docs/policy-language#annotations): including `entrypoint: true` for use with `opa build` * [Tutorial: Evaluate trails with OPA policies](/tutorials/evaluate_trails_with_opa) # Flow Template Source: https://docs.kosli.com/template-reference/flow_template Reference for the YAML template file used to define compliance controls for a Kosli flow. A flow template defines what attestations are required for a trail and its artifacts to be compliant. You pass the template file when creating or updating a flow with [`kosli create flow --template-file`](/client_reference/kosli_create_flow). ## Specification The version of the specification schema. Currently only `1` is supported. The trail specification. Defines what must be attested at the trail level and what artifacts are expected. Attestations required at the trail level for it to be compliant. A unique name for the attestation within this template. The attestation type. One of: `generic`, `jira`, `junit`, `pull_request`, `snyk`, `sonar`, `*` (matches any type). Artifacts expected to be produced in the trail. Each artifact can have its own attestation requirements. A reference name for the artifact (e.g. `frontend-app`, `backend`). Attestations required for this artifact to be compliant. A unique name for the attestation within this artifact. The attestation type. One of: `generic`, `jira`, `junit`, `pull_request`, `snyk`, `sonar`, or `custom:` for [custom attestation types](/client_reference/kosli_create_attestation-type). ## Example Add the `$schema` comment to get editor validation and autocomplete: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/flow-template/v1.json version: 1 trail: attestations: - name: jira-ticket type: jira - name: risk-level-assessment type: generic artifacts: - name: backend attestations: - name: unit-tests type: junit - name: security-scan type: snyk - name: frontend attestations: - name: manual-ui-test type: generic - name: coverage-metrics type: custom:coverage-metrics ``` ## Using the template Pass the template file when creating or updating a flow: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli create flow my-flow --template-file ./flow-template.yml ``` Once the flow exists, start a trail with [`kosli begin trail`](/client_reference/kosli_begin_trail) and record attestations using the [`kosli attest`](/client_reference/kosli_attest_generic) commands. Kosli evaluates trail compliance against the template automatically. Trail-level attestations apply to the entire trail. Artifact-level attestations apply to a specific artifact produced within the trail. ## Editor validation A [JSON Schema](https://docs.kosli.com/schemas/flow-template/v1.json) is available for the flow template format. Add the following comment to the top of your template file to enable inline validation and autocomplete in VS Code (requires the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)) and other schema-aware editors: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # yaml-language-server: $schema=https://docs.kosli.com/schemas/flow-template/v1.json ``` # kosli_action data source Source: https://docs.kosli.com/terraform-reference/data-sources/action Fetches details of an existing Kosli action. Fetches details of an existing Kosli action. Use this data source to reference existing actions and access metadata such as the environments being monitored and the trigger types configured. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing action data "kosli_action" "compliance_alerts" { name = "compliance-alerts" } output "action_number" { description = "Server-assigned number of the action" value = data.kosli_action.compliance_alerts.number } output "action_environments" { description = "Environments monitored by this action" value = data.kosli_action.compliance_alerts.environments } ``` ## Schema ### Required * `name` (String) The name of the action to query. ### Read-only * `created_by` (String) User who created the action. * `environments` (List of String) List of environment names this action monitors. * `last_modified_at` (Number) Unix timestamp (with fractional seconds) of when the action was last modified. * `number` (Number) Server-assigned numeric identifier for the action. * `triggers` (List of String) List of trigger event types that activate this action. # kosli_control data source Source: https://docs.kosli.com/terraform-reference/data-sources/control Fetches details of an existing Kosli control. Use this data source to reference controls and access metadata such as the version, tags, and referencing policies. Fetches details of an existing Kosli control. Use this data source to reference controls and access metadata such as the version, tags, and referencing policies. Controls is a **beta** feature and must be enabled for your organization; API requests return `403 Forbidden` otherwise. Use this data source to: * Reference an existing control managed outside Terraform * Read control metadata such as `version`, `tags`, and `policies_referencing` * Read a specific historical version of a control's `name`, `description`, and `links` * Read a previously-archived control by opting in with `archived = true` ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Create a control resource "kosli_control" "binary_provenance" { identifier = "SDLC-001" name = "Binary provenance" description = "All production artifacts must have build provenance attestations" } # Look up the control via data source data "kosli_control" "binary_provenance" { identifier = kosli_control.binary_provenance.identifier } # Reference control metadata output "control_version" { description = "Current version of the control" value = data.kosli_control.binary_provenance.version } output "control_policies" { description = "Environment policies referencing the control" value = data.kosli_control.binary_provenance.policies_referencing } output "control_tags" { description = "Tags on the control" value = data.kosli_control.binary_provenance.tags } ``` ## Read-only access Data sources provide read-only access to control metadata. To create or modify controls, use the [`kosli_control` resource](/terraform-reference/resources/control). ## Schema ### Required * `identifier` (String) The unique identifier of the control to query (e.g. `SDLC-001`). ### Optional * `archived` (Boolean) Whether the control is archived. Deleting a `kosli_control` resource archives the control rather than hard-deleting it, and by default reading an archived control fails as if it did not exist. Set to `true` to read an archived control. Defaults to `false`. * `version` (Number) Version of the control to read. Every update to a control creates a new version; set this to read the `name`, `description`, and `links` of a specific version. Defaults to the latest version. ### Read-only * `created_at` (String) RFC3339 UTC timestamp of when the control was created. When `version` is set, this is when that version was created. * `created_by` (String) Identifier of the user who created the control. When `version` is set, this is who created that version. * `description` (String) The description of the control. * `links` (Map of String) Named links related to the control, as a map of link name to URL. * `name` (String) Human-readable display name of the control. * `policies_referencing` (List of String) Names of the environment policies that reference this control. * `status` (String) Status of the requested version (e.g. `created`). Only populated when `version` is set; the latest-control endpoint does not report a status. * `tags` (Map of String) Tags on the control, as a map of tag key to value. # kosli_custom_attestation_type data source Source: https://docs.kosli.com/terraform-reference/data-sources/custom_attestation_type Fetches details of an existing custom attestation type from Kosli. Custom attestation types define how Kosli validates and evaluates evidence from proprietary tools, custom metrics, or specialized compliance requirements. Fetches details of an existing custom attestation type from Kosli. Custom attestation types define how Kosli validates and evaluates evidence from proprietary tools, custom metrics, or specialized compliance requirements. Use this data source to retrieve information about an existing custom attestation type. This is useful for: * Referencing existing attestation types in other configurations * Creating variants of existing types with modified rules * Querying attestation type metadata and schemas ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing custom attestation type data "kosli_custom_attestation_type" "security" { name = "security-scan" } # Use the queried schema in a new attestation type resource "kosli_custom_attestation_type" "security_strict" { name = "security-scan-strict" description = "Stricter security requirements" # Reuse the schema and summary rows from the existing type schema = data.kosli_custom_attestation_type.security.schema summary = data.kosli_custom_attestation_type.security.summary # Apply stricter validation rules jq_rules = [ ".critical_vulnerabilities == 0", ".high_vulnerabilities == 0", ".medium_vulnerabilities < 3" ] } # Reference attestation type metadata output "security_scan_description" { description = "Description of the security scan attestation type" value = data.kosli_custom_attestation_type.security.description } output "security_scan_rules" { description = "JQ rules for the security scan attestation type" value = data.kosli_custom_attestation_type.security.jq_rules } output "security_scan_summary" { description = "Summary rows shown on the attestation detail page, as a JSON array" value = data.kosli_custom_attestation_type.security.summary } output "security_scan_archived" { description = "Whether the security scan attestation type is archived" value = data.kosli_custom_attestation_type.security.archived } ``` ## Querying archived types By default, the data source retrieves active (non-archived) attestation types. Archived types can be queried but are read-only and typically represent historical configurations. The `archived` attribute indicates whether an attestation type has been deleted/archived in Kosli. Archived types cannot be modified through Terraform. ## Schema ### Required * `name` (String) The name of the custom attestation type. Must start with a letter or number and contain only letters, numbers, periods, hyphens, underscores, and tildes. ### Read-only * `archived` (Boolean) Whether this attestation type has been archived. * `description` (String) A description of what this attestation type validates. * `jq_rules` (List of String) List of jq expressions that define evaluation rules. All rules must evaluate to `true` for compliance. * `schema` (String) JSON Schema that defines the structure of attestation data. * `summary` (String) JSON array of ordered, labelled jq expressions rendered as rows on the attestation detail page in Kosli. Each element is an object with a `name` and an `expression`. Null when the type defines no summary. # kosli_environment data source Source: https://docs.kosli.com/terraform-reference/data-sources/environment Fetches details of an existing Kosli environment. Use this data source to reference environments and access metadata like last modified and last reported timestamps. Fetches details of an existing Kosli environment. Use this data source to reference environments and access metadata like last modified and last reported timestamps. Environments represent runtime locations where artifacts are deployed and tracked for compliance monitoring. Use this data source to: * Reference existing environment configurations in other resources * Monitor environment activity (last modified, last reported timestamps) * Create conditional logic based on environment state * Build alerts and notifications based on environment metadata ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing environment data "kosli_environment" "production" { name = "production-k8s" } # Use the data source to create a similar environment resource "kosli_environment" "staging" { name = "staging-k8s" type = data.kosli_environment.production.type description = "Staging environment similar to ${data.kosli_environment.production.name}" } # Reference environment metadata for monitoring output "production_last_modified" { description = "Timestamp of when production environment was last modified" value = data.kosli_environment.production.last_modified_at } output "production_last_reported" { description = "Timestamp of when production environment last reported a snapshot" value = data.kosli_environment.production.last_reported_at } output "production_type" { description = "Type of the production environment" value = data.kosli_environment.production.type } # Access tags applied to the environment output "production_tags" { description = "Tags applied to the production environment" value = data.kosli_environment.production.tags } # Check if a specific tag exists output "production_managed_by" { description = "Who manages the production environment (from tags)" value = try(data.kosli_environment.production.tags["managed-by"], "unknown") } # Conditional logic based on environment metadata locals { # Check if environment has never reported a snapshot needs_attention = data.kosli_environment.production.last_reported_at == null } output "production_needs_attention" { description = "Whether production environment needs attention (never reported)" value = local.needs_attention } ``` ## Monitoring with data sources The data source exposes timestamp fields that are useful for monitoring: * `last_modified_at`: Unix timestamp of when the environment configuration was last changed * `last_reported_at`: Unix timestamp of when the environment last reported a snapshot (can be null if never reported) These timestamps enable you to: * Create alerts for environments that haven't reported in a certain time period * Track configuration changes across your infrastructure * Build dashboards showing environment activity * Implement conditional deployment logic based on environment state ## Read-only access Data sources provide read-only access to environment metadata. To modify environment configurations, use the [`kosli_environment` resource](/terraform-reference/resources/environment). ## Schema ### Required * `name` (String) The name of the environment to query. ### Read-only * `description` (String) The description of the environment. * `last_modified_at` (Number) Unix timestamp (with fractional seconds) of when the environment was last modified. * `last_reported_at` (Number) Unix timestamp (with fractional seconds) of when the environment was last reported. May be null if never reported. * `tags` (Map of String) Key-value pairs tagging the environment. * `type` (String) The environment type (e.g., K8S, ECS, S3, docker, server, lambda). # kosli_flow data source Source: https://docs.kosli.com/terraform-reference/data-sources/flow Fetches details of an existing Kosli flow. Use this data source to reference flow configurations and templates. Fetches details of an existing Kosli flow. A flow represents a business or software process that requires change tracking. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing flow data "kosli_flow" "example" { name = "my-application-flow" } # Create a new flow reusing the template from an existing one resource "kosli_flow" "copy" { name = "my-application-flow-copy" description = data.kosli_flow.example.description template = data.kosli_flow.example.template } output "flow_name" { description = "The name of the flow" value = data.kosli_flow.example.name } output "flow_template" { description = "The YAML template of the flow" value = data.kosli_flow.example.template } output "flow_tags" { description = "The tags of the flow" value = data.kosli_flow.example.tags } ``` ## Schema ### Required * `name` (String) The name of the flow to query. ### Read-only * `description` (String) The description of the flow. * `tags` (Map of String) Key-value pairs tagging the flow. * `template` (String) YAML template defining the flow structure (trails, artifacts, attestations). # kosli_logical_environment data source Source: https://docs.kosli.com/terraform-reference/data-sources/logical_environment Fetches details of an existing Kosli logical environment. Use this data source to reference logical environments and access their aggregated physical environments. Fetches details of an existing Kosli logical environment. Use this data source to reference logical environments and access their aggregated physical environments. Use this data source to query existing logical environments in Kosli. This is useful for: * **Referencing metadata**: Access `last_modified_at` timestamps and other computed attributes * **Cross-stack references**: Reference logical environments created outside Terraform * **Dynamic configuration**: Use existing logical environment configurations to create variants * **Validation**: Verify logical environments exist before referencing them * **Monitoring**: Create conditional logic based on logical environment state ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing logical environment data "kosli_logical_environment" "production" { name = "production-aggregate" } # Use the data source to create a similar logical environment resource "kosli_logical_environment" "staging" { name = "staging-aggregate" description = "Staging version of ${data.kosli_logical_environment.production.name}" included_environments = data.kosli_logical_environment.production.included_environments } # Reference logical environment metadata output "production_name" { description = "Name of the production logical environment" value = data.kosli_logical_environment.production.name } output "production_type" { description = "Type of the environment (should be 'logical')" value = data.kosli_logical_environment.production.type } output "production_description" { description = "Description of the production logical environment" value = data.kosli_logical_environment.production.description } output "production_environments" { description = "List of physical environments included in production aggregate" value = data.kosli_logical_environment.production.included_environments } output "production_last_modified" { description = "Timestamp of when production logical environment was last modified" value = data.kosli_logical_environment.production.last_modified_at } output "production_tags" { description = "Tags on the production logical environment" value = data.kosli_logical_environment.production.tags } # Count how many environments are aggregated output "production_environment_count" { description = "Number of environments aggregated in production" value = length(data.kosli_logical_environment.production.included_environments) } # Conditional logic based on aggregation locals { # Check if logical environment is empty (no included environments) is_empty = length(data.kosli_logical_environment.production.included_environments) == 0 # Check if it includes a specific environment includes_k8s = contains( data.kosli_logical_environment.production.included_environments, "production-k8s" ) } output "production_is_empty" { description = "Whether production logical environment has no included environments" value = local.is_empty } output "production_includes_k8s" { description = "Whether production aggregates a K8S environment" value = local.includes_k8s } ``` ## Type validation This data source validates that the queried environment is of type `logical`. Attempting to query a physical environment will result in an error. Use the [`kosli_environment` data source](/terraform-reference/data-sources/environment) for physical environments instead. ## Use cases ### Reference metadata Query logical environment metadata for monitoring or conditional logic: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} data "kosli_logical_environment" "production" { name = "production-all" } output "production_last_modified" { value = data.kosli_logical_environment.production.last_modified_at } output "production_environment_count" { value = length(data.kosli_logical_environment.production.included_environments) } ``` ### Create variants Use an existing logical environment as a template for creating similar ones: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} data "kosli_logical_environment" "production" { name = "production-all" } resource "kosli_logical_environment" "staging" { name = "staging-all" description = "Staging version of ${data.kosli_logical_environment.production.name}" # Reuse the same environment structure included_environments = data.kosli_logical_environment.production.included_environments } ``` ### Cross-stack references Reference logical environments created in other Terraform workspaces or outside Terraform: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} data "kosli_logical_environment" "shared_production" { name = "production-all" # Created in infrastructure workspace } # Use in application deployment workspace locals { production_environments = data.kosli_logical_environment.shared_production.included_environments } ``` ### Conditional logic Create conditional logic based on logical environment configuration: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} data "kosli_logical_environment" "production" { name = "production-all" } locals { # Check if environment is empty is_empty = length(data.kosli_logical_environment.production.included_environments) == 0 # Check if it includes a specific environment includes_k8s = contains( data.kosli_logical_environment.production.included_environments, "production-k8s" ) } ``` ## Schema ### Required * `name` (String) The name of the logical environment to query. ### Read-only * `description` (String) The description of the logical environment. * `included_environments` (List of String) List of physical environment names aggregated by this logical environment. * `last_modified_at` (Number) Unix timestamp (with fractional seconds) of when the logical environment was last modified. * `tags` (Map of String) Key-value pairs tagging the logical environment. * `type` (String) The environment type (always `logical` for logical environments). # kosli_policy data source Source: https://docs.kosli.com/terraform-reference/data-sources/policy Fetches details of an existing Kosli policy. Fetches details of an existing Kosli policy. Use this data source to reference existing policies and access metadata such as the policy content, description, and latest version number. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Query an existing policy data "kosli_policy" "production" { name = "prod-requirements" } output "policy_latest_version" { description = "Latest version number of the policy" value = data.kosli_policy.production.latest_version } output "policy_content" { description = "YAML content of the latest policy version" value = data.kosli_policy.production.content } ``` ## Schema ### Required * `name` (String) The name of the policy to query. ### Read-only * `content` (String) YAML content of the latest policy version. Null if the policy has no versions. * `created_at` (Number) Unix timestamp of when the policy was first created. * `description` (String) Description of the policy. * `latest_version` (Number) The version number of the latest policy version. Null if the policy has no versions. # kosli_service_account data source Source: https://docs.kosli.com/terraform-reference/data-sources/service_account Fetches details of an existing Kosli service account. Use this data source to reference service accounts and access metadata such as the privilege, creator, and creation timestamp. Fetches details of an existing Kosli service account. Use this data source to reference service accounts and access metadata such as the privilege, creator, and creation timestamp. Use this data source to: * Reference an existing service account managed outside Terraform * Read the granted privilege, creating user, and creation timestamp * Build conditional logic based on service account metadata ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Create a service account resource "kosli_service_account" "ci" { name = "ci-pipeline" description = "CI/CD pipeline service account" privilege = "member" } # Look up the service account via data source data "kosli_service_account" "ci" { name = kosli_service_account.ci.name } # Reference service account metadata output "ci_privilege" { description = "Privilege (role) of the CI service account" value = data.kosli_service_account.ci.privilege } output "ci_created_at" { description = "RFC3339 UTC timestamp of when the service account was created" value = data.kosli_service_account.ci.created_at } ``` ## Read-only access Data sources provide read-only access to service account metadata. To create or modify service accounts, use the [`kosli_service_account` resource](/terraform-reference/resources/service_account). To manage API keys, use the [`kosli_service_account_api_key` resource](/terraform-reference/resources/service_account_api_key). ## Schema ### Required * `name` (String) The name of the service account to query. ### Read-only * `created_at` (String) RFC3339 UTC timestamp of when the service account was created. * `creating_user_id` (String) Identifier of the user who created the service account. * `description` (String) The description of the service account. * `display_name` (String) The display name of the service account. * `for_webhook` (Boolean) Whether the service account was created for webhook usage. * `privilege` (String) The privilege (role) of the service account within the organization (`admin`, `member`, `snapshotter`, or `reader`). # Kosli Terraform Provider Source: https://docs.kosli.com/terraform-reference/index Manage Kosli resources as Infrastructure-as-Code using Terraform. The Kosli provider allows you to manage Kosli resources as Infrastructure-as-Code using Terraform. Use it to define and manage environments, policies, actions, custom attestation types, and integrate Kosli into your compliance workflows. The provider is officially registered at the [Terraform Registry](https://registry.terraform.io/providers/kosli-dev/kosli/latest/docs). ## Requirements * Terraform >= 1.10 * A Kosli account with API credentials ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Configure the Kosli Provider # Authentication via environment variables (recommended) provider "kosli" { # API token - set via KOSLI_API_TOKEN environment variable # Organization name - set via KOSLI_ORG environment variable # Optional: API endpoint URL (defaults to https://app.kosli.com) # api_url = "https://app.us.kosli.com" # Use US region # Optional: HTTP client timeout in seconds (defaults to 30) # timeout = 60 } ``` ## Authentication The provider requires a Kosli API token and organization name for authentication. These can be configured in two ways (in order of precedence): 1. **Provider configuration** - Set directly in your Terraform configuration 2. **Environment variables** - Use `KOSLI_API_TOKEN` and `KOSLI_ORG` ### Creating an API token To create an API token: 1. Log in to [Kosli](https://app.kosli.com) 2. Navigate to **Settings** → **API Tokens** 3. Click **Create Token** 4. Copy the token and store it securely API tokens grant full access to your Kosli organization. Store them securely and never commit them to version control. ## Regional endpoints Kosli operates in multiple regions. Configure the `api_url` to match your organization's region: * **EU (Default)**: `https://app.kosli.com` * **US**: `https://app.us.kosli.com` ## Schema ### Optional * `api_token` (String, Sensitive) Kosli API token for authentication. Can also be set via KOSLI\_API\_TOKEN environment variable. * `api_url` (String) Kosli API endpoint URL. Defaults to [https://app.kosli.com](https://app.kosli.com) (EU region). Use [https://app.us.kosli.com](https://app.us.kosli.com) for US region. Can also be set via KOSLI\_API\_URL environment variable. * `org` (String) Kosli organization name. Can also be set via KOSLI\_ORG environment variable. * `timeout` (Number) HTTP client timeout in seconds. Defaults to 30 seconds. # kosli_control list resource Source: https://docs.kosli.com/terraform-reference/list-resources/control Lists Kosli controls in the organization for use with terraform query, so existing controls can be discovered and brought under Terraform management without hand-writing one import block per control. Lists Kosli controls in the organization for use with `terraform query` (requires Terraform >= 1.14), so existing controls can be discovered and brought under Terraform management without hand-writing one `import` block per control. Controls is a **beta** feature and must be enabled for your organization; API requests return `403 Forbidden` otherwise. The Kosli list endpoint does not return `policies_referencing`, so when resource data is included in query results that attribute is always reported as an empty list. Archived controls are only returned when `archived = true` is set. ## Example usage Place `list` blocks in a `.tfquery.hcl` file and run `terraform query` (requires Terraform >= 1.14): ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # List all active controls in the organization list "kosli_control" "all" { provider = kosli } # List controls matching a search string, including full resource data # (e.g. for `terraform query -generate-config-out=generated.tf`) list "kosli_control" "sdlc" { provider = kosli include_resource = true config { search = "SDLC" } } # Include archived controls in the results list "kosli_control" "archived" { provider = kosli config { archived = true } } ``` Use `terraform query -generate-config-out=generated.tf` to generate `import` blocks and resource configuration for the discovered controls. To manage the resulting controls, see the [`kosli_control` resource](/terraform-reference/resources/control). ## Schema ### Optional * `archived` (Boolean) Include archived controls in the results. Defaults to `false`. * `search` (String) Case-insensitive substring to match against control names and identifiers. # kosli_action resource Source: https://docs.kosli.com/terraform-reference/resources/action Manages a Kosli action. Actions define webhook notifications triggered by environment compliance events. Manages a Kosli action. Actions define webhook notifications triggered by environment compliance events. Actions are identified internally by a server-assigned `number`. The `name` is used during import to look up the number. Use this resource to configure automated notifications when environments change compliance state. Actions send webhooks to external services such as Slack or Microsoft Teams. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Action that fires on non-compliant environment events resource "kosli_action" "compliance_alerts" { name = "compliance-alerts" environments = ["production-k8s"] triggers = ["ON_NON_COMPLIANT_ENV", "ON_COMPLIANT_ENV"] webhook_url = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX" } # Action that fires on scaling events resource "kosli_action" "scaling_alerts" { name = "scaling-alerts" environments = ["staging-ecs"] triggers = ["ON_SCALED_ARTIFACT"] webhook_url = "https://outlook.office.com/webhook/XXXX" } ``` ## Import Actions can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import an existing action by name terraform import kosli_action.compliance_alerts compliance-alerts ``` ## Schema ### Required * `environments` (List of String) List of environment names this action monitors. * `name` (String) Name of the action. Must be unique within the organization. Changing this will force recreation of the resource. * `triggers` (List of String) List of trigger event types that activate this action (e.g. `ON_NON_COMPLIANT_ENV`, `ON_COMPLIANT_ENV`). * `webhook_url` (String, Sensitive) Webhook URL to send notifications to. ### Read-only * `created_by` (String) User who created the action. * `last_modified_at` (Number) Unix timestamp of when the action was last modified. * `number` (Number) Server-assigned numeric identifier for the action. # kosli_control resource Source: https://docs.kosli.com/terraform-reference/resources/control Manages a Kosli control. Controls are org-level definitions of SDLC requirements whose compliance is evaluated from attestations and enforced through environment policies. Manages a Kosli control. Controls are org-level definitions of SDLC requirements (for example `SDLC-001` "Binary provenance") whose compliance is evaluated from attestations and enforced through environment policies. Controls is a **beta** feature and must be enabled for your organization; API requests return `403 Forbidden` otherwise. Deleting this resource **archives** the control in Kosli rather than hard-deleting it. Creating a new control with the identifier of an archived control fails with a conflict; unarchive the control in Kosli and import it instead. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Control requiring binary provenance for production artifacts resource "kosli_control" "binary_provenance" { identifier = "SDLC-001" name = "Binary provenance" description = "All production artifacts must have build provenance attestations" links = { docs = "https://example.com/sdlc/binary-provenance" } tags = { framework = "finos-sdlc" team = "platform" } } # Minimal control with only the required attributes resource "kosli_control" "peer_review" { identifier = "SDLC-002" name = "Peer review" } ``` ## Import Controls can be imported using their identifier: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import an existing control by identifier terraform import kosli_control.binary_provenance SDLC-001 ``` ## Querying controls To reference an existing control and access metadata such as the current version, tags, and referencing policies, use the [`kosli_control` data source](/terraform-reference/data-sources/control). ## Schema ### Required * `identifier` (String) Unique identifier of the control within the organization (e.g. `SDLC-001`). Must start with a letter or number and contain only letters, numbers, periods (`.`), hyphens (`-`), underscores (`_`), and tildes (`~`). Changing this will force recreation of the resource. * `name` (String) Human-readable display name of the control (e.g. `Binary provenance`). Can be changed without recreating the control. ### Optional * `description` (String) Free-form description of the control. * `links` (Map of String) Named links related to the control (e.g. documentation or runbook URLs), as a map of link name to URL. * `tags` (Map of String) Key-value pairs to tag the control. ### Read-only * `created_at` (String) RFC3339 UTC timestamp of when the control was created. * `created_by` (String) Identifier of the user who created the control. * `policies_referencing` (List of String) Names of the environment policies that reference this control. * `version` (Number) Version number of the control, assigned by the server and incremented on every update. # kosli_custom_attestation_type resource Source: https://docs.kosli.com/terraform-reference/resources/custom_attestation_type Manages a custom attestation type in Kosli. Custom attestation types define how Kosli validates and evaluates evidence from proprietary tools, custom metrics, or specialized compliance requirements. Manages a custom attestation type in Kosli. Custom attestation types define how Kosli validates and evaluates evidence from proprietary tools, custom metrics, or specialized compliance requirements. Custom attestation types define the structure and validation rules for attestations in Kosli. They can include: * A JSON Schema (optional) that defines the expected structure of attestation data * JQ rules (optional) that evaluate the attestation data for compliance **Note**: While both `schema` and `jq_rules` are optional attributes in Terraform, the Kosli API requires at least one of them to be provided when creating or updating a custom attestation type. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Security scan attestation type resource "kosli_custom_attestation_type" "security_scan" { name = "security-scan" description = "Validates security scan results" schema = jsonencode({ type = "object" properties = { critical_vulnerabilities = { type = "integer" } high_vulnerabilities = { type = "integer" } medium_vulnerabilities = { type = "integer" } scan_date = { type = "string" } scanner_version = { type = "string" } report_url = { type = "string" } } required = ["critical_vulnerabilities", "high_vulnerabilities", "scan_date"] }) jq_rules = [ ".critical_vulnerabilities == 0", ".high_vulnerabilities < 5" ] # Ordered, labelled values shown on the attestation detail page in Kosli. # A value that is a valid URL renders as a clickable link. summary = jsonencode([ { name = "Critical", expression = ".critical_vulnerabilities" }, { name = "High", expression = ".high_vulnerabilities" }, { name = "Scanner", expression = ".scanner_version" }, { name = "Report", expression = ".report_url" }, ]) } # Code coverage attestation type resource "kosli_custom_attestation_type" "code_coverage" { name = "code-coverage" description = "Validates code coverage metrics" schema = jsonencode({ type = "object" properties = { line_coverage = { type = "number" minimum = 0 maximum = 100 } branch_coverage = { type = "number" minimum = 0 maximum = 100 } total_lines = { type = "integer" } covered_lines = { type = "integer" } } required = ["line_coverage", "total_lines", "covered_lines"] }) jq_rules = [ ".line_coverage >= 80", ".branch_coverage >= 70" ] } # Attestation type whose schema and summary are kept in standalone JSON files, # so the same definitions can be shared with other tooling resource "kosli_custom_attestation_type" "code_quality" { name = "code-quality" description = "Validates code quality metrics" schema = file("${path.module}/schemas/code-quality.json") summary = file("${path.module}/summaries/code-quality.json") jq_rules = [ ".line_coverage >= 80", ".lint_errors == 0" ] } # Age verification attestation type with only jq rules (no schema) resource "kosli_custom_attestation_type" "age_verification" { name = "age-verification" description = "Verifies age is over 21 using only jq rules without schema validation" jq_rules = [".age > 21"] } # Schema-only attestation type (no jq rules) resource "kosli_custom_attestation_type" "schema_validation" { name = "data-structure-validation" description = "Validates data structure using schema without evaluation rules" schema = jsonencode({ type = "object" properties = { timestamp = { type = "string" } metadata = { type = "object" } status = { type = "string" enum = ["pass", "fail", "skip"] } } required = ["timestamp", "status"] }) } ``` ## Schema validation The `schema` attribute is optional and can contain a valid JSON Schema (draft-07) that defines the structure of attestation data. When provided, attestation data will be validated against this schema. Common schema types: * **Security scans**: Define vulnerability counts and scan metadata * **Code coverage**: Define coverage percentages and test metrics * **Performance tests**: Define response times and error rates ### Schema example ```json theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} { "type": "object", "properties": { "critical_vulnerabilities": { "type": "integer" }, "high_vulnerabilities": { "type": "integer" }, "scan_date": { "type": "string" } }, "required": ["critical_vulnerabilities", "high_vulnerabilities", "scan_date"] } ``` ## JQ rules The `jq_rules` attribute is optional and contains an array of JQ expressions that must ALL evaluate to `true` for an attestation to be considered compliant. When provided, each rule is evaluated against the attestation data. If omitted, no evaluation is performed. ### JQ rules examples ```hcl theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} jq_rules = [ ".critical_vulnerabilities == 0", # No critical vulnerabilities allowed ".high_vulnerabilities < 5", # Less than 5 high vulnerabilities ".scan_date != null" # Scan date must be present ] ``` ## Import Custom attestation types can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import an existing custom attestation type by name terraform import kosli_custom_attestation_type.security_scan security-scan ``` ## Schema ### Required * `name` (String) Name of the custom attestation type. Must start with a letter or number and can only contain letters, numbers, periods, hyphens, underscores, and tildes. Changing this will force recreation of the resource. ### Optional * `description` (String) Description of the custom attestation type. Explains what this attestation type validates. * `jq_rules` (List of String) List of jq evaluation rules. Each rule is a jq expression that must evaluate to true for the attestation to be considered compliant. Example: `[".coverage >= 80"]`. If omitted, no evaluation is performed. * `schema` (String) JSON Schema definition that defines the structure of attestation data. Can be provided inline using heredoc syntax or loaded from a file using `file()`. If omitted, no schema validation is performed. Semantic equality is used for comparison, so formatting differences are ignored. * `summary` (String) JSON array of ordered, labelled jq expressions rendered as rows on the attestation detail page in Kosli. Each element is an object with a `name` (the row label) and an `expression` (a jq expression evaluated against the attestation data); values that are valid URLs render as links. Can be provided inline using `jsonencode()`/heredoc syntax or loaded from a file using `file()`, so the same JSON can be kept in one place and shared with other tooling. Example: `jsonencode([{ name = "Coverage", expression = ".coverage" }])`. If omitted, the attestation detail page falls back to showing the jq evaluation results as a pass/fail checklist; removing it from a type that had one clears the summary. Semantic JSON equality is used when reading the value back from Kosli, so your formatting is preserved rather than being rewritten to the API's compact form. # kosli_environment resource Source: https://docs.kosli.com/terraform-reference/resources/environment Manages a Kosli environment. Environments represent deployment targets where artifacts are deployed. Supports physical environment types: K8S, ECS, S3, docker, server, and lambda. Manages a Kosli environment. Environments represent deployment targets where artifacts are deployed. Supports physical environment types: K8S, ECS, S3, docker, server, and lambda. This resource manages the environment configuration and tags. To attach compliance policies, use the [`kosli_policy_attachment` resource](/terraform-reference/resources/policy_attachment). For querying environment metadata such as `last_modified_at`, `last_reported_at`, and `archived` status, use the [`kosli_environment` data source](/terraform-reference/data-sources/environment). Kosli environments track deployments and provide visibility into what's running in your infrastructure. Physical environments represent actual runtime locations such as: * **K8S**: Kubernetes clusters * **ECS**: Amazon Elastic Container Service clusters * **S3**: Amazon S3 buckets * **docker**: Docker containers * **server**: Bare-metal or VM servers * **lambda**: AWS Lambda functions For aggregating multiple physical environments into logical groups, use the [`kosli_logical_environment` resource](/terraform-reference/resources/logical_environment). To attach compliance policies to environments, use the [`kosli_policy_attachment` resource](/terraform-reference/resources/policy_attachment). ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Basic K8S environment resource "kosli_environment" "production_k8s" { name = "production-k8s" type = "K8S" description = "Production Kubernetes cluster" } # K8S environment with tags resource "kosli_environment" "tagged" { name = "production-k8s-tagged" type = "K8S" description = "Production cluster managed by Terraform" tags = { managed-by = "terraform" environment = "production" team = "platform" } } # ECS environment resource "kosli_environment" "staging_ecs" { name = "staging-ecs" type = "ECS" description = "Staging ECS cluster" } # S3 environment resource "kosli_environment" "data_lake" { name = "data-lake-s3" type = "S3" description = "Data lake S3 bucket environment" } # Docker environment resource "kosli_environment" "local_docker" { name = "local-docker" type = "docker" } # Server environment resource "kosli_environment" "production_servers" { name = "production-servers" type = "server" description = "Production bare-metal servers" } # Lambda environment resource "kosli_environment" "serverless_functions" { name = "serverless-lambda" type = "lambda" description = "AWS Lambda functions" } ``` ## Environment types The `type` attribute must be one of the following physical environment types: * `K8S` - Kubernetes clusters * `ECS` - Amazon Elastic Container Service * `S3` - Amazon S3 buckets * `docker` - Docker containers * `server` - Bare-metal or VM servers * `lambda` - AWS Lambda functions ## Import Environments can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} #!/bin/bash # Import an existing environment by name terraform import kosli_environment.production_k8s production-k8s # Import multiple environments terraform import kosli_environment.staging_ecs staging-ecs terraform import kosli_environment.data_lake data-lake-s3 ``` ## Monitoring environments For querying environment metadata such as `last_modified_at` and `last_reported_at` timestamps, use the [`kosli_environment` data source](/terraform-reference/data-sources/environment). This is useful for monitoring and creating conditional logic based on environment state. ## Schema ### Required * `name` (String) Name of the environment. Must be unique within the organization. Changing this will force recreation of the resource. * `type` (String) Type of the environment. Valid values: `K8S`, `ECS`, `S3`, `docker`, `server`, `lambda`. Changing this will force recreation of the resource. ### Optional * `description` (String) Description of the environment. Explains the purpose and characteristics of this deployment target. * `tags` (Map of String) Key-value pairs to tag the environment. Tags are applied via a diff — only changed tags are sent to the API. An empty map (`tags = {}`) removes all tags. # kosli_flow resource Source: https://docs.kosli.com/terraform-reference/resources/flow Manages a Kosli flow. Flows represent business or software processes that require change tracking. Manages a Kosli flow. A flow represents a business or software process that requires change tracking. It lets you monitor changes across all steps within a process or focus on a subset of critical steps. The `template` attribute accepts a YAML string defining the flow template structure. You can load it from a file using the `file()` function: `template = file("template.yml")`. Minor YAML formatting differences between what you provide and what the API returns may result in a no-op change being shown in plans. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Minimal flow with only a name resource "kosli_flow" "minimal" { name = "my-service" } # Flow with description resource "kosli_flow" "with_description" { name = "api-service" description = "CD pipeline for the API service" } # Flow with tags resource "kosli_flow" "tagged" { name = "api-service-tagged" description = "API service CD pipeline managed by Terraform" tags = { managed-by = "terraform" team = "platform" environment = "production" } } # Flow with a YAML template defining trails and attestations # The template can also be loaded from a file: template = file("template.yml") resource "kosli_flow" "with_template" { name = "backend-service" description = "Backend service CD pipeline with full attestation template" template = <<-YAML version: 1 trail: attestations: - name: pull-request type: pull_request - name: unit-tests type: generic artifacts: - name: docker-image attestations: - name: sbom type: generic - name: security-scan type: snyk YAML } ``` ## Import Flows can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform import kosli_flow.example my-flow-name ``` ## Schema ### Required * `name` (String) Name of the flow. Must be unique within the organization. Changing this will force recreation of the resource. ### Optional * `description` (String) Description of the flow. Explains the purpose and context of this pipeline. * `tags` (Map of String) Key-value pairs to tag the flow. Tags are applied via a diff — only changed tags are sent to the API. An empty map (`tags = {}`) removes all tags. * `template` (String) YAML template defining the flow structure (trails, artifacts, attestations). Can be provided as an inline heredoc or loaded from a file using `file()`. If omitted, the flow is created without a template. # kosli_logical_environment resource Source: https://docs.kosli.com/terraform-reference/resources/logical_environment Manages a Kosli logical environment. Logical environments aggregate multiple physical environments for organizational purposes. Manages a Kosli logical environment. Logical environments aggregate multiple physical environments for organizational purposes. Logical environments can ONLY contain physical environments (K8S, ECS, S3, docker, server, lambda), not other logical environments. Attempting to include a logical environment will result in an error from the Kosli API. This resource manages logical environment configuration and tags. For querying environment metadata such as `last_modified_at` and `archived` status, use the [`kosli_logical_environment` data source](/terraform-reference/data-sources/logical_environment). Logical environments in Kosli aggregate multiple physical environments for organizational purposes, providing: * **Unified visibility**: View compliance status across multiple environments at once * **Flexible grouping**: Organize environments by region, service type, tier, or team * **Simplified reporting**: Generate compliance reports for logical groupings * **Team organization**: Allow different teams to focus on specific environment groups ## Physical environments only Logical environments can ONLY contain physical environments (K8S, ECS, S3, docker, server, lambda), not other logical environments. Attempting to include a logical environment will result in an API error. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # First, create physical environments that will be aggregated resource "kosli_environment" "production_k8s" { name = "production-k8s" type = "K8S" description = "Production Kubernetes cluster" } resource "kosli_environment" "production_ecs" { name = "production-ecs" type = "ECS" description = "Production ECS cluster" } resource "kosli_environment" "production_lambda" { name = "production-lambda" type = "lambda" description = "Production Lambda functions" } # Basic logical environment aggregating production environments resource "kosli_logical_environment" "production_all" { name = "production-aggregate" description = "Aggregates all production environments for unified visibility" included_environments = [ kosli_environment.production_k8s.name, kosli_environment.production_ecs.name, kosli_environment.production_lambda.name, ] } # Logical environment with just two environments resource "kosli_logical_environment" "cloud_services" { name = "cloud-services" description = "All cloud-based services" included_environments = [ kosli_environment.production_ecs.name, kosli_environment.production_lambda.name, ] } # Minimal logical environment with empty list (can be populated later) resource "kosli_logical_environment" "future_environments" { name = "future-environments" included_environments = [] } # Logical environment with tags resource "kosli_logical_environment" "tagged" { name = "production-tagged" description = "Tagged production logical environment" included_environments = [ kosli_environment.production_k8s.name, kosli_environment.production_ecs.name, ] tags = { managed-by = "terraform" environment = "production" team = "platform" } } # Logical environment without description (optional) resource "kosli_logical_environment" "simple" { name = "simple-aggregate" included_environments = [ kosli_environment.production_k8s.name, ] } ``` ## Complete example For a comprehensive example showing logical environments aggregating physical environments by region, service type, and tier, see the [complete logical environments example](https://github.com/kosli-dev/terraform-provider-kosli/tree/main/examples/complete/logical-environments). ## Common use cases ### By environment tier Aggregate all production or staging environments for unified compliance reporting: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "production_all" { name = "production-all" description = "All production environments" included_environments = [ kosli_environment.prod_k8s.name, kosli_environment.prod_ecs.name, kosli_environment.prod_lambda.name, ] } ``` ### By geographic region Group environments by region for regional compliance or disaster recovery: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "production_us_east" { name = "production-us-east" description = "All production environments in US East" included_environments = [ kosli_environment.prod_k8s_us_east.name, kosli_environment.prod_ecs_us_east.name, ] } ``` ### By service type Organize environments by technology stack or service type: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "all_kubernetes" { name = "all-kubernetes-clusters" description = "All Kubernetes clusters across regions" included_environments = [ kosli_environment.k8s_us_east.name, kosli_environment.k8s_eu_west.name, kosli_environment.k8s_ap_south.name, ] } ``` ## Empty logical environments Logical environments can be created with empty `included_environments` lists and populated later: ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} resource "kosli_logical_environment" "future_environments" { name = "planned-expansion" description = "Placeholder for future environments" included_environments = [] } ``` ## Import Logical environments can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} #!/bin/bash # Import an existing logical environment by name terraform import kosli_logical_environment.production_all production-aggregate # Import multiple logical environments terraform import kosli_logical_environment.cloud_services cloud-services terraform import kosli_logical_environment.future_environments future-environments ``` ## Querying metadata ## Schema ### Required * `included_environments` (List of String) List of physical environment names to aggregate. Only physical environments are allowed (K8S, ECS, S3, docker, server, lambda). Can be empty. * `name` (String) Name of the logical environment. Must be unique within the organization. Changing this will force recreation of the resource. ### Optional * `description` (String) Description of the logical environment. Explains the purpose and aggregation strategy. * `tags` (Map of String) Key-value pairs to tag the logical environment. Tags are applied via a diff — only changed tags are sent to the API. An empty map (`tags = {}`) removes all tags. ### Read-only * `type` (String) Type of the environment. Always set to `logical` (computed by provider, not user-configurable). # kosli_policy resource Source: https://docs.kosli.com/terraform-reference/resources/policy Manages a Kosli policy. Policies define artifact compliance requirements that can be attached to environments. Manages a Kosli policy. Policies define artifact compliance requirements (provenance, trail-compliance, attestations) that can be attached to environments. Policies are versioned and immutable: updating `content` or `description` creates a new version rather than modifying the existing one. Deleting this resource removes it from Terraform state only. Kosli has no API endpoint to delete policies, so the policy will remain in Kosli after `terraform destroy`. To attach policies to environments, use the [`kosli_policy_attachment` resource](/terraform-reference/resources/policy_attachment). ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Minimal policy requiring provenance for all artifacts resource "kosli_policy" "minimal" { name = "basic-requirements" content = <<-YAML _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: provenance: required: true YAML } # Production policy with full compliance requirements resource "kosli_policy" "production" { name = "prod-requirements" description = "Compliance requirements for production environments" content = <<-YAML _schema: https://docs.kosli.com/schemas/policy/v1 artifacts: provenance: required: true trail-compliance: required: true attestations: - name: unit-test type: junit - name: dependency-scan type: "*" YAML } ``` ## Import Policies can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import a policy by name. The content attribute is populated from the API response. terraform import kosli_policy.example prod-requirements ``` ## Schema ### Required * `content` (String) YAML content of the policy, conforming to the Kosli policy schema (`_schema: https://docs.kosli.com/schemas/policy/v1`). Supports heredoc syntax for multi-line YAML. Updating this value creates a new policy version. * `name` (String) Name of the policy. Must be unique within the organization. Changing this will force recreation of the resource. ### Optional * `description` (String) Description of the policy. ### Read-only * `created_at` (Number) Unix timestamp of when the policy was first created. * `latest_version` (Number) The version number of the latest policy version. Null if the policy has no versions. # kosli_policy_attachment resource Source: https://docs.kosli.com/terraform-reference/resources/policy_attachment Attaches a Kosli policy to an environment. When this resource is destroyed, the policy is detached from the environment. Attaches a Kosli policy to an environment (physical or logical). When this resource is destroyed, the policy is detached from the environment. Both `environment_name` and `policy_name` are immutable: changing either attribute will destroy the existing attachment and create a new one. Both the policy and environment must exist before creating an attachment. Use the [`kosli_policy` resource](/terraform-reference/resources/policy) and [`kosli_environment` resource](/terraform-reference/resources/environment) to manage them. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Attach a policy to an environment. # Both the policy and environment must exist before creating the attachment. resource "kosli_policy_attachment" "example" { environment_name = "my-environment" policy_name = "my-policy" } ``` ## Import Policy attachments can be imported using the composite ID `environment_name/policy_name`: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import a policy attachment using the composite ID: environment_name/policy_name terraform import kosli_policy_attachment.example my-environment/my-policy ``` ## Schema ### Required * `environment_name` (String) Name of the environment to attach the policy to. Changing this will force recreation of the resource. * `policy_name` (String) Name of the policy to attach. Changing this will force recreation of the resource. # kosli_service_account resource Source: https://docs.kosli.com/terraform-reference/resources/service_account Manages a Kosli service account. Service accounts are non-human identities used to authenticate automation (such as CI/CD pipelines) against the Kosli API. Manages a Kosli service account. Service accounts are non-human identities used to authenticate automation (such as CI/CD pipelines) against the Kosli API. API keys for a service account are managed separately via the [`kosli_service_account_api_key` resource](/terraform-reference/resources/service_account_api_key). Service accounts cannot be created in personal organizations. Only organization admins or the user who created the service account can manage it. Use this resource to manage the lifecycle of a service account. To mint API keys, use the [`kosli_service_account_api_key` resource](/terraform-reference/resources/service_account_api_key). To look up an existing service account's metadata, use the [`kosli_service_account` data source](/terraform-reference/data-sources/service_account). ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Service account for a CI/CD pipeline resource "kosli_service_account" "ci" { name = "ci-pipeline" description = "CI/CD pipeline service account" privilege = "member" } # Read-only service account (e.g. for dashboards) resource "kosli_service_account" "dashboard" { name = "dashboard-readonly" privilege = "reader" } ``` ## Privileges The `privilege` attribute must be one of the following: * `admin` — Full administrative access * `member` — Standard read/write access * `snapshotter` — May report environment snapshots * `reader` — Read-only access You can only create a service account with a privilege equal to or lower than your own. ## Import Service accounts can be imported using their name: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import an existing service account by name terraform import kosli_service_account.ci ci-pipeline ``` ## Managing API keys To mint API keys for a service account, use the [`kosli_service_account_api_key` resource](/terraform-reference/resources/service_account_api_key). To look up an existing service account's metadata, use the [`kosli_service_account` data source](/terraform-reference/data-sources/service_account). ## Schema ### Required * `name` (String) Name of the service account. Must be unique within the organization, contain only alphanumeric characters and hyphens (`^[a-zA-Z0-9\-]+$`), and be at most 64 characters. Changing this will force recreation of the resource. * `privilege` (String) Privilege (role) granted to the service account within the organization. Valid values: `admin`, `member`, `snapshotter`, `reader`. You can only create a service account with a privilege equal to or lower than your own. ### Optional * `description` (String) Free-form description of the service account. ### Read-only * `created_at` (String) RFC3339 UTC timestamp of when the service account was created. * `creating_user_id` (String) Identifier of the user who created the service account. * `display_name` (String) Display name of the service account, assigned by the server. * `for_webhook` (Boolean) Whether the service account was created for webhook usage. # kosli_service_account_api_key resource Source: https://docs.kosli.com/terraform-reference/resources/service_account_api_key Manages an API key for a Kosli service account. The raw key value is returned only once, at creation time, and is stored in Terraform state as a sensitive value. Manages an API key for a Kosli service account. API keys authenticate a service account against the Kosli API. Use this resource to mint and revoke keys for a service account managed with the [`kosli_service_account` resource](/terraform-reference/resources/service_account). The raw `key` value is returned **only once**, at creation time, and is stored in Terraform state as a sensitive value. It is SHA-256 hashed server-side and can never be retrieved again — protect your Terraform state accordingly. API keys are immutable. Changing `description`, `expires_at`, or `service_account_name` revokes the existing key and creates a new one. On `terraform import`, the `key` attribute cannot be populated because the raw value is not retrievable. ## Example usage ```terraform theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} terraform { required_providers { kosli = { source = "kosli-dev/kosli" } } } # Service account that the API key belongs to resource "kosli_service_account" "ci" { name = "ci-pipeline" description = "CI/CD pipeline service account" privilege = "member" } # A non-expiring API key resource "kosli_service_account_api_key" "ci_key" { service_account_name = kosli_service_account.ci.name description = "Production CI key" } # An API key that expires (RFC3339 timestamp) resource "kosli_service_account_api_key" "ci_key_expiring" { service_account_name = kosli_service_account.ci.name description = "Temporary CI key" expires_at = "2100-01-01T00:00:00Z" } # The raw key is only available on creation and is sensitive output "ci_api_key" { value = kosli_service_account_api_key.ci_key.key sensitive = true } ``` ## Expiry The `expires_at` attribute is an RFC3339 timestamp, e.g. `2100-01-01T00:00:00Z` (offsets such as `+01:00` are accepted and normalized to UTC). Omit it for a key that never expires. The timestamp must not be in the past. To derive dates dynamically, use Terraform's built-in functions, e.g. `timeadd("2026-01-01T00:00:00Z", "8760h")`. All timestamps (`expires_at`, `created_at`, `last_used_at`) are RFC3339 UTC strings. `last_used_at` is null for a key that has never been used; `expires_at` is null for a key that never expires. ## Import API keys can be imported using the `/` format: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} # Import an existing API key using the "/" format. # Note: the raw key value cannot be recovered on import (it is only returned once # at creation), so the "key" attribute will be empty after import. terraform import kosli_service_account_api_key.ci_key ci-pipeline/01HXYZ0123456789ABCDEFGHIJ ``` Because the raw key value is only returned at creation time, the `key` attribute is empty after an import. ## Schema ### Required * `description` (String) Description of the API key (at least one character). Changing this forces creation of a new key. * `service_account_name` (String) Name of the service account this API key belongs to. Changing this forces creation of a new key. ### Optional * `expires_at` (String) RFC3339 timestamp at which the key expires, e.g. `2100-01-01T00:00:00Z` (offsets allowed; whole seconds only). Omit for a key that never expires. Must not be in the past (validated server-side at apply time). Changing this forces creation of a new key. Removing a previously set value from configuration leaves the existing expiry unchanged; to get a non-expiring key again, the key must be recreated (e.g. via `terraform taint` or by changing another argument). ### Read-only * `created_at` (String) RFC3339 UTC timestamp of when the API key was created. * `id` (String) Server-assigned identifier of the API key. * `key` (String, Sensitive) The raw API key value. Only available at creation time and stored as a sensitive value. Empty when the resource is imported. * `last_used_at` (String) RFC3339 UTC timestamp of when the API key was last used. Null if the key has never been used. # Docker API version error in GitHub Actions Source: https://docs.kosli.com/troubleshooting/docker_api_version_error How to fix the "client version 1.51 is too new" error when running the Kosli CLI with Docker operations. ## Error ``` Error response from daemon: client version 1.47 is too new. Maximum supported API version is 1.45 ``` **Kosli CLI v2.15.1+:** This error is resolved automatically. The CLI now negotiates the Docker API version with the daemon, so it adapts to whatever Docker Engine version is available. Upgrade to v2.15.1 or later and no workaround is needed. ## Solution for CLI versions before v2.15.1 Set the `DOCKER_API_VERSION` environment variable in your workflow: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} env: DOCKER_API_VERSION: "1.45" ``` ## Context Prior to v2.15.1, the Kosli CLI defaulted to a fixed Docker API version (e.g., 1.47), which could be higher than what the Docker daemon on the host supports. This caused Docker operations (`--artifact-type docker`) to fail with a "client version is too new" error. From v2.15.1 onwards, the CLI automatically negotiates the API version with the Docker daemon, eliminating this issue. # GitHub can't see KOSLI_API_TOKEN secret Source: https://docs.kosli.com/troubleshooting/github_kosli_api_token How to make the KOSLI_API_TOKEN secret available in GitHub Actions workflows. ## Error Kosli CLI commands fail in GitHub Actions because `KOSLI_API_TOKEN` is not set, even though the secret exists in your repository. ## Solution Add the secret to your workflow's environment variables explicitly: ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} env: KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} ``` ## Context Secrets in GitHub Actions are not automatically exported as environment variables. You must map them explicitly in each workflow or job. # Repo digest unavailable Source: https://docs.kosli.com/troubleshooting/repo_digest_unavailable How to fix the "repo digest unavailable for the image" error when running kosli attest artifact with --artifact-type=docker. ## Error ``` Error: repo digest unavailable for the image, has it been pushed to or pulled from a registry? ``` ## Why this happens When `kosli attest artifact` is called with `--artifact-type=docker`, Kosli asks the local Docker daemon for the image's **repo digest** (the SHA256 of the image manifest in a registry). A repo digest is only attached to an image once it has been pushed to or pulled from a registry. A freshly built image (just `docker build`) has an image ID, but no repo digest, and Kosli will refuse to attest it. This often surfaces in CI even when the same command appears to work locally. Locally, the image may have been pushed or pulled at some earlier point and the digest is cached on the machine. On a fresh CI runner, the image is only ever built, so the digest is genuinely missing. You can confirm the difference with: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} docker inspect --format '{{json .RepoDigests}}' ``` A built-but-never-pushed image returns `[]`. An image pulled from or pushed to a registry returns one or more digest entries. ## Solutions Pick whichever fits your pipeline best. ### Push the image first, then attest ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} docker push /: kosli attest artifact /: --artifact-type=docker ... ``` This is the most direct fix and produces an attestation tied to the registry digest. ### Use `--artifact-type=oci` If the image is already in a registry, `oci` fetches the digest directly via the registry API and does not require a local Docker daemon at all: ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} kosli attest artifact /: \ --artifact-type=oci \ --registry-username=$REGISTRY_USER \ --registry-password=$REGISTRY_TOKEN \ ... ``` ### Provide the fingerprint directly If you have already computed a fingerprint elsewhere in your pipeline, pass it with `--fingerprint` and drop `--artifact-type` entirely. The fingerprint must still match what runtime reporters will see for the artifact in your environments, so it should normally be the registry digest. # CLI in subshell captures stderr Source: https://docs.kosli.com/troubleshooting/subshell_stderr How to handle Kosli CLI debug output being captured in subshell variables in CI workflows. ## Error When capturing Kosli CLI output in a subshell variable in CI, the variable contains debug output mixed with the expected value: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} DIGEST="$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker)" echo "DIGEST=${DIGEST}" DIGEST=[debug] calculated fingerprint: 2c6079df5829... 2c6079df58292ed10e8074adcb74be549b7f841a1bd8266f06bb5c518643193e ``` ## Solution Explicitly set `--debug=false` when running Kosli CLI commands in a subshell: ```shell theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}} DIGEST="$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker --debug=false)" ``` ## Context The Kosli CLI writes debug information to `stderr` and all other output to `stdout`. In a local terminal, a `$(subshell)` captures only `stdout`. However, in many CI workflows (including GitHub and GitLab), `stdout` and `stderr` are multiplexed together, causing debug output to leak into captured variables. ## See also * [Output and verbosity](/client_reference/output_and_verbosity) — full reference for the CLI's stdout/stderr behavior, `[warning]` messages, and the `--quiet` and `--debug` flags. # What do I do if Kosli is down? Source: https://docs.kosli.com/troubleshooting/what_do_i_do_if_kosli_is_down This page shows you how to bypass Kosli attestations if Kosli is down so your CI pipelines keep running, and how to re-enable them when it recovers. ## Status of Kosli services