A curated collection of Enterprise Policy Management (EPM) recipes for Cloudsmith - combining practical OPA Rego policy samples, action configurations, and testing guides to help you define, simulate, and enforce package lifecycle rules across your repositories.
This repository includes:
- Rego policies tailored for Cloudsmith’s EPM engine, using the supported input schema and policy format.
- Policy action configurations (
SetPackageState
,AddPackageTags
, etc.) with examples showing how to order and associate them by precedence. - Simulation and deployment instructions using Cloudsmith’s API, including how to safely test policies before enforcement.
- Helper scripts and workflows to automate policy testing and promotion.
These recipes are designed to be modular, auditable, and production-ready - with a strong emphasis on policy-as-code best practices.
Name | Description | Rego Playground |
---|---|---|
Enforcing Signed Packages | This policy enforces mandatory GPG/DSA signature checks on packages during their sync/import into Cloudsmith |
Link |
Restriction Based on Tags | This policy checks whether a package includes specific deprecated tag and marks it as match if present |
Link |
Copy-Left licensing | This policy is designed to detect a broad range of copyleft licenses, including free-text and SPDX variants | Link |
Quarantine Debug Builds | Identify and quarantine packages that look like debug/test artifacts based on filename or metadata patterns | Link |
Limit Tag Sprawl | Flag any packages that have more than a threshold number of tags to avoid ungoverned tagging behaviours | Link |
Enforce Consistent Filename | Validate whether the filename convention matches a semantic or naming pattern via Regular Expressions | Link |
Approved Upstreams based on Tags | Only packages from explicitly approved upstream sources are permitted, helping to prevent the propagation of unvetted or insecure dependencies. | Link |
CVSS Policy with Fix Available | Match packages in a specific repo that have high/critical fixed vulnerabilities, excluding specific known CVEs. | Link |
Time-Based CVSS Policy | Evaluate CVEs older than 30 days. Checks CVSS threshold ≥ 7. Filters for a specific repo. Ignores certain CVE | Link |
CVSS with EPSS context | Combines High scoring CVSS vulnerability with EPSS scoring context that go above a specific threshold. | Link |
Architecture allow list | Policy that only allows amd64 architecture packages and blocks others like arm64. |
Link |
Block package if version over 0.16.0 | semver.compare(pkg.version, "0.16.0") == -1 should check if the version is less than 0.16.0 using semver-aware comparison. |
Link |
Block package if version under 1.0.0 | Cloudsmith's EPM currently does not support Rego's semver functions because those require a Rego SDK integration, which Cloudsmith doesn't provide at the moment. This means version comparison must be done via string comparison, which only works safely for zero-padded numeric versions or very simple SemVer patterns. If your versions are formatted like "1.2.3" without pre-release/build tags, you can sometimes get away with lexicographical comparisons. | Link |
Block specific package and version | Blocks a specific package and package version | Link |
Block specific CVE numbers | Blocks a specific package based on known CVE numbers | Link |
Enforce Upload Time Window | Allow uploads during business hours (9 AM – 5 PM UTC), to catch anomalous behaviour like late-night uploads | Link |
Tag-based bypass Exception | This is a simple tag-based exception. | Link |
Exact allowlist with CVSS limit exemption | Use when you want tight control per version, but still prevent exemptions if a CVSS exceeds a ceiling. | Link |
This policy enforces mandatory GPG/DSA signature checks on packages during their sync/import into Cloudsmith
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-1/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Enforcing Signed Packages",
"description": "This policy enforces mandatory GPG/DSA signature checks on packages during their sync/import into Cloudsmith.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 1
}
EOF
Once the policy is created, here is how you can perform a controlled test.
Create a simple dummy python package locally that we know for certain is unsigned.
Your policy will trigger, since input.v0.package.signed
will not be present or will default to false
.
mkdir dummy_unsigned
cd dummy_unsigned
echo "from setuptools import setup; setup(name='dummy_unsigned', version='0.0.1')" > setup.py
python3 -m pip install --upgrade build
apt install python3.10-venv
python3 -m build # produces dist/dummy_unsigned-0.0.1.tar.gz
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO dist/dummy_unsigned-0.0.1.tar.gz -k "$CLOUDSMITH_API_KEY"
This policy checks whether a package includes a specific deprecated
tag and marks it as a match if it does.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-2/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Restricting Package Based on Tags",
"description": "This policy checks whether a package includes a specific DEPRECATED tag.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 2
}
EOF
Once ready, download a random package, in this case a python package called h11
and push the package to Cloudsmith with the deprecated
tag to cause the policy violation:
pip download h11==0.14.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO h11-0.14.0-py3-none-any.whl -k "$CLOUDSMITH_API_KEY" --tags deprecated
This policy is designed to flag packages that use copyleft
or restrictive
open-source licenses, particularly those unsuitable for production use without legal review or approval.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-3/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Copyleft licensing policy",
"description": "This policy checks packages that are unsuitable for production.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 3
}
EOF
Once ready, download the Python Gitlab v.3.1.1
package that we know has a LGPLv3 license
that should trigger the policy:
pip download python-gitlab==3.1.1
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO python_gitlab-3.1.1-py3-none-any.whl -k "$CLOUDSMITH_API_KEY" --tags lgplv3license
cloudsmith list packages acme-corporation/acme-repo-one -k "$CLOUDSMITH_API_KEY" -q "format:python AND tag:lgplv3license"
Note: If you have a tagging response action attached to your policy, you could tag the package with non-compliant-license
for further review:


This policy checks whether a package includes specific debug
, test
, or temp
descriptors in the filename.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-4/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Quarantine Debug Builds",
"description": "Identify and quarantine packages that look like debug/test artifacts based on filename or metadata patterns.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 4
}
EOF
Once ready, download debugpy
Python package and push it to Cloudsmith to cause the policy violation:
pip download --no-deps --dest . debugpy
&& cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO debugpy-1.8.14-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl -k "$CLOUDSMITH_API_KEY"
This policy checks whether a package already includes 5
or more assigned tags - conidered as sprawl by some orgs.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-5/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Limit Tag Sprawl",
"description": "Flag packages that have more than a threshold number of tags to avoid ungoverned tagging behaviours.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 5
}
EOF
Once ready, download transformers
Python and assign it 5 tags
during the Cloudsmith push process to cause the policy violation:
pip download transformers --no-deps
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO transformers-4.53.1-py3-none-any.whl -k "$CLOUDSMITH_API_KEY" --tags TAG1,TAG2,TAG3,TAG4,TAG5
Validate filename matches a semantic or naming pattern where MAJOR
.MINOR
, and PATCH
are all numeric.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-6/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Enforce Consistent Filename Convention",
"description": "Validate filename matches a semantic or naming pattern.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 6
}
EOF
A straightforward way to test this policy is to take a package that already has a valid SemVer-compliant filename and rename it by replacing the version number with a placeholder like test
:
pip download h11==0.14.0
mv h11-0.14.0-py3-none-any.whl h11-test.whl
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO h11-test.whl -k "$CLOUDSMITH_API_KEY"
Simply put, this approves packages based on the specified upstream source.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-7/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Approved Upstreams based on Tags",
"description": "Only packages from explicitly approved upstream sources are permitted, helping to prevent the propagation of unvetted or insecure dependencies.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 7
}
EOF
If a package has upstream
and not approved
--> allowed
If a package has approved
--> blocked (even if upstream is present)
This policy is designed to match packages in a specific repository (acme-repo-one
) that have high
or critical
with a Fixed version available
, excluding specific known CVEs
.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-8/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "CVSS with Fix Available",
"description": "Matched packages from a specific repository that have high or critical vulnerabilities that can be patched.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 8
}
EOF
To demonstrate this policy, you can use the requests
Python package, which has a known vulnerability with a high CVSS score.
Vulnerability Details:
- Package: h11
- Affected Version: 0.14.0
- Fixed In: 0.16.0
- CVE Identifier: CVE-2025-43859
- CVSS Context: This CVE record has been marked for NVD enrichment efforts.
- Description: An HTTP request smuggling vulnerability in python-h11.
pip download h11==0.14.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO h11-0.14.0-py3-none-any.whl -k "$CLOUDSMITH_API_KEY"
You'll probably want to enable a Quarantine action for policies dealing with critical vulnerabilities that can be fixed:

This policy is designed to detect and flag packages in a specific repo that contain serious, outdated, but fixed vulnerabilities.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-9/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Time-based CVSS policy",
"description": "Only matches if the vulnerability was published more than 30 days ago.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 9
}
EOF
This CVE was published on 24 April 2025 - much older than the 30 day threshold specified in the policy.
pip download h11==0.14.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO h11-0.14.0-py3-none-any.whl -k "$CLOUDSMITH_API_KEY"
This policy only allows amd64
architecture packages and blocks others like arm64
.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-11/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Architecture-specific allow list",
"description": "Policy that only allows amd64 architecture packages and blocks others like arm64",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 11
}
EOF
To trigger the above policy (which blocks all architectures except amd64
), you'd want to upload or sync a Python package that is built for a non-amd64
architecture - like arm64
.
However, pip by default fetches packages built for your local system architecture, so you typically won't download architecture-specific wheels unless they're explicitly tagged.
Here's a command to download a known Python package with an ARM-specific wheel using pip download:
pip download numpy --platform manylinux2014_aarch64 --only-binary=:all: --python-version 38 --implementation cp --abi cp38
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -k "$CLOUDSMITH_API_KEY"
--platform manylinux2014_aarch64
: targetsarm64
(aarch64
)--only-binary=:all:
: avoid source dist, force binary wheel--python-version 38
and--abi cp38
: simulate Python 3.8 CPython ABI

This policy matches any h11
packages with a version older than 0.16.0
:
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-12/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Forced Upgrade of Package Versions",
"description": "Forces teams to periodically upgrade versions of certain package dependencies, so they don't fall too far behind.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 12
}
EOF
If you want to match versions less than 1.0.0
, such as 0.14.0
:
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-13/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "match versions less than 1.0.0",
"description": "match versions less than 1.0.0, such as 0.14.0",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 13
}
EOF
pip download h11==0.14.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO h11-0.14.0-py3-none-any.whl -k "$CLOUDSMITH_API_KEY"

Alternatively, here’s a simple (but fragile) example using string comparison:
package cloudsmith
default match := false
match if count(reason) > 0
reason contains msg if {
pkg := input.v0["package"]
startswith(pkg.version, "1.")
msg := sprintf("Package version '%s' is less than 2.0.0", [pkg.version])
}
This will match versions like "1.9.9
" or "1.0.0
", but not "1.10.0
" being greater than "1.2.
0" — since it's string-based.
- "
1.10.0
" < "1.2.0
" is true in string comparison, but false semantically. - Pre-release versions like "
2.0.0-beta
" may confuse logic unless handled explicitly. - Multi-digit segments break string comparisons unless you zero-pad them ("
01.02.003
").
If version control is essential:
- Add strict prefix/regex filters (example:
startswith(pkg.version, "2.")
) - Combine with file naming conventions or upload context
- Enforce via CI before publishing, if possible
package cloudsmith
default match := false
match if count(reason) > 0
reason contains msg if {
pkg := input.v0["package"]
pkg.version < "2.0.0"
msg := sprintf("Package version '%s' is below required threshold of 2.0.0", [pkg.version])
}
So: this works in simple cases, but not trustworthy for tight numeric ranges unless all version segments are zero-padded (for example: "01.09.000
").
This policy will specifically block the Python package requests
on version 2.6.0
:
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-14/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Block specific package and version",
"description": "match requests python package o v.2.6.0",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 14
}
EOF
pip download requests==2.6.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO requests-2.6.0-py2.py3-none-any.whl -k "$CLOUDSMITH_API_KEY"

Again, the Python package requests
version 2.6.0
has the known vulnerability CVE-2018-18074
:
We have commented out the other CVEs in this policy, but feel free remove those comments and add additional CVEs as a list.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-15/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Block specific CVE numbers",
"description": "This policy is only blocking CVE-2018-18074 specifically",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 15
}
EOF
pip download requests==2.6.0
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO requests-2.6.0-py2.py3-none-any.whl -k "$CLOUDSMITH_API_KEY"

Assuming your organisation don't expect packages to be uploaded or modified at specific times, the below policy can detect package uploads at 9am-11am UTC
- regardless of the package name.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-16/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Package Upload Window",
"description": "Flag any package uploaded outside of working hours",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 16
}
EOF
pip download <package-name>
cloudsmith push python $CLOUDSMITH_ORG/$CLOUDSMITH_REPO <package-name>.whl -k "$CLOUDSMITH_API_KEY"
Use this policy when you need a quick, time-boxed exception. For example, policy can quarantine by severity; where a separate terminal exemption policy matches if a package has an exempt tag and stops further evaluation.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-17/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Tag based exception",
"description": "Exception policy based on basic tagging",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 17
}
EOF
Trade-off: While the tag remains, new CVEs on that package won’t trigger quarantine. You'll need to review those tags regularly.
Use when you want tight control per version, but still prevent exemptions if a CVSS exceeds a ceiling.
Download the policy.rego
and create the associated payload.json
with the below command:
wget https://raw.githubusercontent.com/cloudsmith-io/rego-recipes/refs/heads/main/recipe-18/policy.rego
escaped_policy=$(jq -Rs . < policy.rego)
cat <<EOF > payload.json
{
"name": "Specific allowlist exception",
"description": "Controls based on exact version but still prevent exemptions if a CVSS exceeds a ceiling.",
"rego": $escaped_policy,
"enabled": true,
"is_terminal": false,
"precedence": 18
}
EOF
Trade-off: While the tag remains, new CVEs on that package won’t trigger quarantine. You'll need to review those tags regularly.