Skip to main content

Multiple property paths

Sometimes, a property (key/value) that you want to test against will be located in multiple places. For example, if you want to create a custom rule that ensures all container images have a pinned version, you can avoid creating a rule logic that declares all possible paths because checking the value of the image property in two locations can be complex.

  • When kind is Deployment, the value of the property spec.template.spec.containers[].image should have a pinned version

  • When kind is Pod, the value of the property spec.containers[].image should have a pinned version

To avoid this complexity, you can write a JSON Schema with a rule logic that will define the common path and disregard all prefixes:

  • The value of the property **.spec.containers[].image should have a pinned version

Here is an example of what that would look like:

customRules:
- identifier: CUSTOM_CONTAINERS_MISSING_IMAGE_VALUE_VERSION
name: Prevent tag `latest` as container image version [CUSTOM RULE]
defaultMessageOnFailure: |
Not setting image version for your containers is like going to the casino 🎰 - you don't know which version you'll get
schema:
definitions:
imagePattern:
properties:
spec:
properties:
containers:
type: array
items:
properties:
image:
not:
- pattern: .*:(latest|LATEST)$
allOf:
- $ref: '#/definitions/imagePattern'
additionalProperties:
$ref: '#'
items:
$ref: '#'

The above rule is enforcing the same logic as our built-in rule - ☑️ Ensure each container image has a pinned (tag) version.


Here is another example - the following rule schema will verify that all images are pulled from the approved registry (allow list) or not from the unapproved registry (block list):

customRules:
- identifier: CUSTOM_CONTAINERS_INCORRECT_IMAGE_REGISTRY
name: Ensure each container image is pulled from approved registry [CUSTOM RULE]
defaultMessageOnFailure: |
You(r) shell not passed! 🧙‍♂️ All images must be pulled from pre-approved registries
schema:
definitions:
imagePattern:
properties:
spec:
properties:
containers:
type: array
items:
properties:
image:
# allow list example
anyOf:
- pattern: ^allow.list.com/repo-name/.*
# block list example
not:
anyOf:
- pattern: ^block.list.com/repo-name/.*
allOf:
- $ref: "#/definitions/imagePattern"
additionalProperties:
$ref: "#"
items:
$ref: "#"
allOf:
- $ref: '#/definitions/imagePattern'
additionalProperties:
$ref: '#'
items:
$ref: '#'

And the full polices.yaml file for this rule will like that:

apiVersion: v1
policies:
- name: custom_policy
isDefault: true
rules:
- identifier: CUSTOM_CONTAINERS_INCORRECT_IMAGE_REGISTRY
messageOnFailure: This message will override the rule's `defaultMessageOnFailure` property
# - name: staging
# rules:
# - identifier: CUSTOM_CONTAINERS_INCORRECT_IMAGE_REGISTRY
# messageOnFailure: ''

customRules:
- identifier: CUSTOM_CONTAINERS_INCORRECT_IMAGE_REGISTRY
name: Ensure each container image is pulled from approved registry [CUSTOM RULE]
defaultMessageOnFailure: |
You(r) shell not passed! 🧙‍♂️ All images must be pulled from pre-approved registries
schema:
definitions:
imagePattern:
properties:
spec:
properties:
containers:
type: array
items:
properties:
image:
# allow list example
anyOf:
- pattern: ^allow.list.com/repo-name/.*
# block list example
not:
anyOf:
- pattern: ^block.list.com/repo-name/.*
allOf:
- $ref: "#/definitions/imagePattern"
additionalProperties:
$ref: "#"
items:
$ref: "#"
allOf:
- $ref: '#/definitions/imagePattern'
additionalProperties:
$ref: '#'
items:
$ref: '#'