-
Notifications
You must be signed in to change notification settings - Fork 338
docs: adding JFrog OPA policy allowing evidence checking on images, policy … #721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| resources: | ||
| - template.yaml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| apiVersion: constraints.gatekeeper.sh/v1beta1 | ||
| kind: jfrogcheckevidence | ||
| metadata: | ||
| name: jfrog-check-evidence | ||
| spec: | ||
| match: | ||
| kinds: | ||
| - apiGroups: [""] | ||
| kinds: ["Pod"] | ||
| parameters: | ||
| checkedRegistries: ["my-jfrog-registry.jfrog.io"] | ||
| # add whitelist for repositories, uncomment to enable | ||
| # checkedRepositories: ["docker-local"] | ||
| checkedPredicateTypes: ["https://slsa.dev/provenance/v1"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| apiVersion: v1 | ||
| kind: Pod | ||
| metadata: | ||
| name: your-jfrog-testing-pod | ||
| spec: | ||
| containers: | ||
| - name: testing | ||
| image: my-jfrog-registry.jfrog.io/docker-local/your-valid-testing-image:1.0.0 | ||
| imagePullPolicy: Always | ||
| imagePullSecrets: | ||
| - name: jfrog-secret |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| apiVersion: v1 | ||
| kind: Pod | ||
| metadata: | ||
| name: your-jfrog-testing-pod | ||
| spec: | ||
| containers: | ||
| - name: testing | ||
| image: my-jfrog-registry.jfrog.io/docker-local/your-invalid-testing-image:1.0.0 | ||
| imagePullPolicy: Always | ||
| imagePullSecrets: | ||
| - name: jfrog-secret |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||
| kind: Suite | ||||||
| apiVersion: test.gatekeeper.sh/v1alpha1 | ||||||
| metadata: | ||||||
| name: replicalimits | ||||||
|
||||||
| name: replicalimits | |
| name: k8sjfrogcheckevidence |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test name is incorrect. It should relate to jfrog evidence checking instead of "replica-limit", which appears to be copy-pasted from another test suite.
| - name: replica-limit | |
| - name: jfrog-evidence-check |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,100 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apiVersion: templates.gatekeeper.sh/v1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kind: ConstraintTemplate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: jfrogcheckevidence | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| annotations: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata.gatekeeper.sh/title: "Check JFrog Evidence" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata.gatekeeper.sh/version: 1.0.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: >- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Checks if the images in a pod comply with regulations or corporate policies by validating they have required verified evidence. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This policy is based on the JFrog OPA provider. To deploy JFrog OPA Provider, please visit: https://github.com/jfrog/jfrog-opa-policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spec: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crd: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spec: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| names: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kind: jfrogcheckevidence | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
carmithersh marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openAPIV3Schema: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| properties: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkedPredicateTypes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| items: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkedRegistries: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| items: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkedRepositories: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+30
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkedPredicateTypes: | |
| type: array | |
| items: | |
| type: string | |
| checkedRegistries: | |
| type: array | |
| items: | |
| type: string | |
| checkedRepositories: | |
| checkedPredicateTypes: | |
| description: >- | |
| List of predicate types to check for each image. Each entry is | |
| a string that will be concatenated into a comma-separated | |
| value and passed as part of the key set to the JFrog evidence | |
| OPA provider. | |
| type: array | |
| items: | |
| type: string | |
| checkedRegistries: | |
| description: >- | |
| List of container registry prefixes to include in the check. | |
| Only images whose names start with one of these prefixes will | |
| be evaluated by this constraint. | |
| type: array | |
| items: | |
| type: string | |
| checkedRepositories: | |
| description: >- | |
| List of repository path substrings to include in the check. | |
| Only images whose names contain one of these substrings will | |
| be evaluated by this constraint. |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package name does not follow the established codebase convention. All policies in src/general use the "k8s" prefix in their package names. This package should be named "k8sjfrogcheckevidence" instead of "jfrogcheckevidence" for consistency.
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The policy does not check ephemeralContainers for images, which could be a security gap. Other similar policies like imagedigests check containers, initContainers, and ephemeralContainers. Consider adding a check for ephemeralContainers to ensure comprehensive coverage.
| # append target_images, target_init_images | |
| checked_images := array.concat(target_images, target_init_images) | |
| # get ephemeral container images | |
| ephemeral_images := [img | img = input.review.object.spec.ephemeralContainers[_].image] | |
| target_ephemeral_images := [img | img = ephemeral_images[_] | |
| filter_images.is_checked_registry(img) | |
| filter_images.is_checked_repository(img) | |
| ] | |
| # append target_images, target_init_images, target_ephemeral_images | |
| tmp_checked_images := array.concat(target_images, target_init_images) | |
| checked_images := array.concat(tmp_checked_images, target_ephemeral_images) |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment contains a typo. "arreay" should be "array".
| # convert arreay input.parameters.checkedPredicateTypes to string | |
| # convert array input.parameters.checkedPredicateTypes to string |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,38 @@ | ||||||||||||
| apiVersion: templates.gatekeeper.sh/v1 | ||||||||||||
| kind: ConstraintTemplate | ||||||||||||
| metadata: | ||||||||||||
| name: jfrogcheckevidence | ||||||||||||
|
carmithersh marked this conversation as resolved.
Outdated
|
||||||||||||
| annotations: | ||||||||||||
| metadata.gatekeeper.sh/title: "Check JFrog Evidence" | ||||||||||||
| metadata.gatekeeper.sh/version: 1.0.0 | ||||||||||||
| description: >- | ||||||||||||
| Checks if the images in a pod comply with regulations or corporate policies by validating they have required verified evidence. | ||||||||||||
| This policy is based on the JFrog OPA provider. To deploy JFrog OPA Provider, please visit: https://github.com/jfrog/jfrog-opa-policy | ||||||||||||
| spec: | ||||||||||||
| crd: | ||||||||||||
| spec: | ||||||||||||
| names: | ||||||||||||
| kind: jfrogcheckevidence | ||||||||||||
|
carmithersh marked this conversation as resolved.
Outdated
|
||||||||||||
| validation: | ||||||||||||
| openAPIV3Schema: | ||||||||||||
| type: object | ||||||||||||
| properties: | ||||||||||||
| checkedPredicateTypes: | ||||||||||||
| type: array | ||||||||||||
| items: | ||||||||||||
| type: string | ||||||||||||
| checkedRegistries: | ||||||||||||
| type: array | ||||||||||||
| items: | ||||||||||||
| type: string | ||||||||||||
| checkedRepositories: | ||||||||||||
| type: array | ||||||||||||
|
carmithersh marked this conversation as resolved.
|
||||||||||||
| items: | ||||||||||||
| type: string | ||||||||||||
| targets: | ||||||||||||
| - target: admission.k8s.gatekeeper.sh | ||||||||||||
| code: | ||||||||||||
| - engine: Rego | ||||||||||||
| source: | ||||||||||||
| rego: | | ||||||||||||
|
carmithersh marked this conversation as resolved.
Outdated
|
||||||||||||
| {{ file.Read "src/general/jfrog-evidence/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} | ||||||||||||
|
||||||||||||
| {{ file.Read "src/general/jfrog-evidence/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} | |
| {{ file.Read "src/general/jfrog-evidence/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} | |
| libs: | |
| - rego: | | |
| {{ file.Read "src/general/jfrog-evidence/lib_filter_images.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||||||||||||||||||||||||
| package jfrogcheckevidence | ||||||||||||||||||||||||||||
|
carmithersh marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||
| import data.lib.filter_images | ||||||||||||||||||||||||||||
| import future.keywords.in | ||||||||||||||||||||||||||||
| import future.keywords.contains | ||||||||||||||||||||||||||||
| # get all images | ||||||||||||||||||||||||||||
| all_images := [img | img = input.review.object.spec.containers[_].image] | ||||||||||||||||||||||||||||
| target_images := [img | img = all_images[_] | ||||||||||||||||||||||||||||
| filter_images.is_checked_registry(img) | ||||||||||||||||||||||||||||
| filter_images.is_checked_repository(img) | ||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||
| # get init images | ||||||||||||||||||||||||||||
| init_images := [img | img = input.review.object.spec.initContainers[_].image] | ||||||||||||||||||||||||||||
| target_init_images := [img | img = init_images[_] | ||||||||||||||||||||||||||||
| filter_images.is_checked_registry(img) | ||||||||||||||||||||||||||||
| filter_images.is_checked_repository(img) | ||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # append target_images, target_init_images | ||||||||||||||||||||||||||||
| checked_images := array.concat(target_images, target_init_images) | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| # append target_images, target_init_images | |
| checked_images := array.concat(target_images, target_init_images) | |
| # get ephemeral container images | |
| ephemeral_images := [img | img = input.review.object.spec.ephemeralContainers[_].image] | |
| target_ephemeral_images := [img | img = ephemeral_images[_] | |
| filter_images.is_checked_registry(img) | |
| filter_images.is_checked_repository(img) | |
| ] | |
| # append target_images, target_init_images, target_ephemeral_images | |
| checked_images := array.concat(target_images, array.concat(target_init_images, target_ephemeral_images)) |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment contains a typo. "arreay" should be "array".
| # convert arreay input.parameters.checkedPredicateTypes to string | |
| # convert array input.parameters.checkedPredicateTypes to string |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the checkedPredicateTypes parameter is an empty array, the concat function will produce an empty string, which may not be the intended behavior when communicating with the JFrog provider. Consider adding validation to ensure checkedPredicateTypes is not empty, or handle the empty case explicitly to avoid unexpected behavior from the external provider.
| # convert arreay input.parameters.checkedPredicateTypes to string | |
| types := concat(",", input.parameters.checkedPredicateTypes) | |
| typesArray := [types] | |
| # build typesArray from input.parameters.checkedPredicateTypes only when non-empty | |
| typesArray := [types] { | |
| params := object.get(input, "parameters", {}) | |
| checked_predicate_types := object.get(params, "checkedPredicateTypes", []) | |
| count(checked_predicate_types) > 0 | |
| types := concat(",", checked_predicate_types) | |
| } | |
| default typesArray := [] |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function "has_check_registry_images_parameter" is defined but never used in the policy. This unused code should be removed to improve maintainability.
| has_check_registry_images_parameter { | |
| input.parameters.checkedRegistries != null | |
| } |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "libs:" section should not be in the src.rego file. Based on codebase conventions, the libs should be defined in the constraint.tmpl file. See examples: src/general/imagedigests/constraint.tmpl:39-41, src/general/containerresources/constraint.tmpl:52-54. The library code should be in a separate file and referenced in the constraint template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constraint kind does not match the expected naming convention. Since the ConstraintTemplate should be named "k8sjfrogcheckevidence" (following codebase conventions), this kind should also be "k8sjfrogcheckevidence" instead of "jfrogcheckevidence".