# Custom Checks

If you'd like to create your own checks, you can use JSON Schema (opens new window). This is how built-in Polaris checks are defined as well - you can see all the built-in checks in the checks folder (opens new window) for examples.

If you write a check that could be useful for others, feel free to open a PR to add it in!

# Basic Example

For example, to disallow images from quay.io:

checks:
  imageRegistry: warning

customChecks:
  imageRegistry:
    successMessage: Image comes from allowed registries
    failureMessage: Image should not be from disallowed registry
    category: Security
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          not:
            pattern: ^quay.io

# Available Options

All custom checks should go under the customChecks field in your Polaris config, keyed by the check ID. Note that you'll also have to set its severity in the checks section of your Polaris config.

  • successMessage - the message to show when the check succeeds
  • failureMessage - the message to show when the check fails
  • category - one of Security, Efficiency, or Reliability
  • target - specifies the type of resource to check. This can be:
    • a group and kind, e.g. apps/Deployment or networking.k8s.io/Ingress
    • Controller, to check any resource that creates Pods (e.g. Deployments, CronJobs, StatefulSets), as well as naked Pods
    • PodTemplate, same as Controller, but the schema applies to the Pod template rather than the top-level controller
    • PodSpec, same as Controller, but the schema applies to the Pod spec rather than the top-level controller
    • Container same as Controller, but the schema applies to all Container specs rather than the top-level controller
  • controllers - if target is Controller, PodSpec or Container, you can use this to change which types of controllers are checked
  • controllers.include - only check these controllers
  • controllers.exclude - check all controllers except these
  • containers - if target is Container, you can use this to decide if initContainers, containers, or both should be checked
  • containers.exclude - can be set to a list including initContainer or container
  • schema - the JSON Schema to check against, as a YAML object
  • schemaString - this JSON Schema to check against, as a YAML or JSON string. See Templating below
    • Note: only one of schema and schemaString can be specified.
  • additionalSchemas - see Multi-Resource Checks below
  • additionalSchemaStrings - see Multi-Resource Checks below
    • Note: only one of additionalSchemas and additionalSchemaStrings can be specified.

# Checking CPU and Memory

We extend JSON Schema with resourceMinimum and resourceMaximum fields to help compare memory and CPU resource strings like 1000m and 1G. Here's an example check that memory and CPU falls within a certain range.

customChecks:
  resourceLimits:
    containers:
      exclude:
      - initContainer
    successMessage: Resource limits are within the required range
    failureMessage: Resource limits should be within the required range
    category: Resources
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      required:
      - resources
      properties:
        resources:
          type: object
          required:
          - limits
          properties:
            limits:
              type: object
              required:
              - memory
              - cpu
              properties:
                memory:
                  type: string
                  resourceMinimum: 100M
                  resourceMaximum: 6G
                cpu:
                  type: string
                  resourceMinimum: 100m
                  resourceMaximum: "2"

# Resource Presence

You can test for the presence of a resource in each Namespace. For example, to ensure an AlertmanagerConfig is in every Namespace:

successMessage: Namespace has monitoring configuration
failureMessage: Namespace should have monitoring configuration
category: Security
target: Namespace
schema: {}
additionalSchemas:
  monitoring.coreos.com/AlertmanagerConfig: {}

# Templating

You can also utilize go templating in your JSON schema in order to match one field against another. E.g. here is the built-in check to ensure that the name annotation matches the object's name:

successMessage: Label app.kubernetes.io/name matches metadata.name
failureMessage: Label app.kubernetes.io/name must match metadata.name
target: Controller
schema:
  '$schema': http://json-schema.org/draft-07/schema
  type: object
  properties:
    metadata:
      type: object
      required: ["labels"]
      properties:
        labels:
          type: object
          required: ["app.kubernetes.io/name"]
          properties:
            app.kubernetes.io/name:
              const: "{{ .metadata.name }}"
  • The object available via the go template is the full object, and not limited by target.
  • A check of target: PodSpec can directly access the pod specification via the go template variable .Polaris.PodSpec.
  • A check of target: PodTemplate can directly access the pod template via the go template variable .Polaris.PodTemplate.
  • A check of target: Container can directly access the container being checked via the go template variable .Polaris.container. The pod template and pod specification can also be accessed via the respective variables .Polaris.PodTemplate and .Polaris.PodSpec. Access to pod-level fields allows a container check to consult related fields from the pod, such as securityContext.

You can also use the full Go template syntax (opens new window), though you may need to specify your schema as a string in order to use concepts like range. E.g. this check ensures that at least one of the object's labels is present in matchLabels:

schemaString: |
  type: object
  properties:
    spec:
      type: object
      required: ["selector"]
      properties:
        selector:
          type: object
          required: ["matchLabels"]
          properties:
            matchLabels:
              type: object
              anyOf:
              {{ range $key, $value := .metadata.labels }}
              - properties:
                  "{{ $key }}":
                    type: string
                    const: {{ $value }}
                required: ["{{ $key }}"]
              {{ end }}

# Additional Go Template Functions

These functions are also available in the GO template.

For example, the hasPrefix function can be used in a template to determine whether a resource name starts with system:

{{ if hasPrefix .metadata.name "system:" }}

# Multi-Resource Checks

You can write checks that span multiple resources. This is helpful for ensuring e.g. that every Deployment has a PDB or an HPA associated with it.

Here's the check to ensure that every Deployment has a PDB:

successMessage: A PodDisruptionBudget is attached
failureMessage: Should have a PodDisruptionBudget
category: Reliability
target: Controller
controllers:
  include:
  - Deployment
schema:
  '$schema': http://json-schema.org/draft-07/schema
  type: object
  properties:
    metadata:
      type: object
      properties:
        labels:
          type: object
          minProperties: 1
additionalSchemaStrings:
  policy/PodDisruptionBudget: |
    type: object
    properties:
      spec:
        type: object
        required: ["selector"]
        properties:
          selector:
            type: object
            required: ["matchLabels"]
            properties:
              matchLabels:
                type: object
                anyOf:
                {{ range $key, $value := .metadata.labels }}
                - properties:
                    "{{ $key }}":
                      type: string
                      const: {{ $value }}
                  required: ["{{ $key }}"]
                {{ end }}

# JSON vs YAML

Schemas can also be specified as JSON strings instead of YAML, for easier copy/pasting:

customChecks:
  foo:
    jsonSchema: |
      {
        "$schema": "http://json-schema.org/draft-07/schema",
        "type": "object"
      }