Getting Started with Enterprise Policy Management

An introduction to creating Enterprise policy management policies and actions

This guide offers an introduction to creating Enterprise policy management policies and actions. Using this guide you will:

  • Create policy matching logic using the rego language to match packages above a specified vulnerability threshold.
  • Create a policy via the API which employs this matching logic.
  • Create actions to quarantine and tag matched packages, and assign these actions to the created policy.
  • Use the policy simulator to simulate this policy running without impacting any live packages or data.

📘

Policy Creation

You must have administrator permissions within your Workspace to create or update a policy.

Step 1: Creating policy matching logic with rego

Lets create a policy in rego. This policy will:

  • Check if a package belongs to the target repository (repository-name)
  • Check if any vulnerabilities in the package exceed a CVSS (Common Vulnerability Scoring System) value of 6.

If both of these criteria are met on policy evaluation, the package will be matched (the exported match variable will be true) and any actions associated with the policy will be run against the package.

This policy matching logic is shown below:

package cloudsmith

# Default match rule
default match := false

# Define maximum CVSS score threshold
max_cvss_score := 6

# Target repository for the policy
target_repository := "repository-name"

# Policy match criteria
match if {
    in_target_repository
    count(reason) != 0
}

# Check if the package belongs to the specified repository
in_target_repository if {
    input.v0.repository.name == target_repository
}

# Generate reasons for matching vulnerabilities
reason contains msg if {
    # Loop through all vulnerabilities
    some vulnerability in input.v0.security_scan.Vulnerabilities

    # Check if the vulnerability has a fixed version and is resolved
    vulnerability.FixedVersion
    vulnerability.Status == "fixed"

    # Ensure the CVSS score exceeds the threshold
    some _, val in vulnerability.CVSS
    val.V3Score >= max_cvss_score

    # Message for the reason
    msg := sprintf(
        "CVSS Score > %v",
        [max_cvss_score]
    )
}

Step 2: Create a policy using the API

📘

Placeholder Values

The example API requests in this guide below make use of placeholder variables for consistency and brevity.

It is advised to export the following variables such that they can be used in any example requests:

export CLOUDSMITH_API_KEY=<YOUR_CLOUDSMITH_API_KEY>  
export CLOUDSMITH_WORKPLACE-<YOUR_CLOUDSMITH_WORKSPACE>

Save the rego policy created in Step 1 to a file named policy.rego. Then use the script below to create an JSON request body which includes the rego content in the rego field:

escaped_policy=$(jq -Rs . < policy.rego)

cat <<EOF > payload.json
{
  "name": "cvss_gt_6",
  "description": "Policy to quarantine and tag CVSS > 6",
  "rego": $escaped_policy,
  "enabled": false,
  "is_terminal": false,
  "precedence": 1
}
EOF

📘

Policy testing

When creating a policy via the API, setting the enabled field to false prevents the policy from being triggered, but still allows it to be tested via the Simulation API.

Policies are created using the orgs_policies_create REST API method. The following curl command makes a request to this method, providing in the request the payload.json payload created above:

curl -X POST "https://api.cloudsmith.io/v2/orgs/$CLOUDSMITH_WORKPLACE/policies/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $CLOUDSMITH_API_KEY" \
  -d @payload.json

A successful request will return a HTTP 201 response, indicating the policy was created.

Retrieving a policy's unique identifier

When a policy is created via the API, the unique identifier for the policy will be provided in the slug_perm field in the response body. This identifier will be required for example if you need to update the policy, or add actions to it. This identifier can be retrieved by directly extracting it from the policy creation response (as in the example below):

POLICY_SLUG=$(curl ... | jq -r '.slug_perm')

Or alternatively the policy identifier can be retrieved via the orgs_policies_actions_list REST API method.

Step 3: Adding actions to a policy

After a policy is created, actions can be assigned to it via the orgs_policies_actions_create REST API method.

In this example, two actions will need to be added to the policy:

  1. An action to quarantine a package matched by the matching logic.
  2. An action to tag a packages matched by the matching logic.

Adding an action to quarantine a package

To create an action to quarantine a package, use the curl command below. This example request specifies the required action_type, sets the quarantined package state via the package_state field, and provides an action precedence value of 1:

A successful request will return a HTTP 201 response, with the unique identifier of the action returned in the slug_perm field.

curl -X POST "https://api.cloudsmith.io/v2/orgs/$CLOUDSMITH_WORKPLACE/policies/{POLICY_SLUG}/actions/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $CLOUDSMITH_API_KEY" \
  -d '{
    "action_type": "SetPackageState",
    "precedence": 1,

Adding an action to tag a package

Similarly, to create an action to tag a matched package, the following curl command can be used. This request specifies the required action_type, the relevant tag in the tags array and a precedence value of 32767.

curl -X POST "https://api.cloudsmith.io/v2/orgs/$CLOUDSMITH_WORKPLACE/policies/{POLICY_SLUG}/actions/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $CLOUDSMITH_API_KEY" \
  -d '{
    "action_type": "AddPackageTags",
    "precedence": 32767,
    "tags": ["policy-violated"]
  }'

Step 4: Simulating the policy

The policy referenced in Step 2 was not enabled when it was created. It is possible to test a policy, even if not enabled, using the simulator orgs_policies_simulate_list REST API method.

The response contains a list of packages that were tested, whether or not there was a match for each page, any reason messages, and the actions that would be taken if the policy is enabled.

Step 5: Enabling or disabling a policy

Once you confirm the policy works as expected, the policy can be enabled via a PATCH request. Enabling the policy means it will run matching logic against packages and apply any associated actions (in this example quarantining and tagging) to packages that are matched.

curl -X PATCH "https://api.cloudsmith.io/v2/orgs/$CLOUDSMITH_WORKPLACE/policies/{POLICY_SLUG}/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $CLOUDSMITH_API_KEY" \
  -d '{"enabled": true}'

Similarly, if a policy needs to be disabled either temporarily or otherwise, a PATCH request can be sent for the relevant policy specifying an enabled value of false.

Step 6: Pushing a package to trigger the policy

Once enabled, if you wish to test the policy against an actual package you can trigger this policy by:

  1. Uploading a vulnerable package to the required repository.
  2. Wait for the vulnerability scan to complete. The policy will run at the end of package synchronization.
  3. Confirm the package's status and tags in Cloudsmith.

Checking Decision Logs

📘

Decision Logs

Decision log entries are not added when a policy is simulated via the simulator.

Each time a package is scanned or triggers the policy, EPM creates a decision log entry. These logs can be viewed via the decision_logs_list REST API method. An example request to this method is shown below (this filters logs to a specific policy using the?policy=$POLICY_SLUG query parameter.)

curl -X GET \
  "https://api.cloudsmith.io/v2/orgs/$CLOUDSMITH_WORKPLACE/policies/decision_logs/?policy=$POLICY_SLUG" \
  -H "Accept: application/json" \
  -H "X-Api-Key: $CLOUDSMITH_API_KEY" | jq .

The following will be provided within these logs:

  • started_at/ ended_at: Times the policy evaluation started and ended.
  • policy_input: The exact data used to evaluate the policy.
  • policy_output: The results (match or not, partial rule states).
  • actions: Which actions were invoked against the package.

For more information on building common matching criteria in rego, please see the Enterprise Policy Management Rego Recipes guide.


Cloudsmith is the new standard in Package / Artifact Management and Software Distribution

With support for all major package formats, you can trust us to manage your software supply chain.


Start My Free Trial Now
Cookie Declaration (Manage Cookies)