stelligent / config-lint

Command line tool to validate configuration files
https://stelligent.github.io/config-lint/#/
MIT License
195 stars 39 forks source link

Containers array searching #153

Closed namloc2001 closed 4 years ago

namloc2001 commented 4 years ago

Hi, do you please know the syntax/have an example of checking for all instances in an array for K8s yaml?

I'm trying to see if all containers in a deployment have declared some specified securitycontexts:

  - id: DEPLOYMENT_CONTAINER_SECURITY_CONTEXT
    severity: NON_COMPLIANT
    message: Deployment container should set securityContexts
    resource: Deployment
    assertions:
      - key: spec.template.spec.containers[].securityContext.runAsNonRoot
        op: eq
        value: true
      - key: spec.template.spec.containers[].securityContext.readOnlyRootFilesystem
        op: eq
        value: true
    tags:
      - deployment
      - security

If I put a "0" in the [] it will correctly identify against the first container.

Thanks,

Matt

phelewski commented 4 years ago

@namloc2001 This seems like the perfect use case for the every operator to go through all of the containers. Without seeing what you are working with I would think something like this might get the results you are looking for. Also note that there is an operator to check for true, I've used it in the example below.

  - id: DEPLOYMENT_CONTAINER_SECURITY_CONTEXT
    severity: NON_COMPLIANT
    message: Deployment container should set securityContexts
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers[]
          expressions:
            - key: securityContext.runAsNonRoot
              op: is-true
            - key: securityContext.readOnlyRootFilesystem
              op: is-true
    tags:
      - deployment
      - security
namloc2001 commented 4 years ago

Ooo I like that. So I'm using:

  - id: DEPLOYMENT_CONTAINER_SECURITY_CONTEXT
    severity: NON_COMPLIANT
    message: Deployment containers should set securityContexts
    resource: Deployment
    assertions:
      - every:
        key: spec.template.spec.containers[]
        expressions:
        - key: securityContext.runAsNonRoot
          op: is-true
        - key: securityContext.readOnlyRootFilesystem
          op: is-true
    tags:
      - deployment
      - security

to check this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      securityContext:
        readOnlyRootFilesystem: true
      restartPolicy: Always
      serviceAccountName: my-app
      containers:
      - name: my-app
        image: "my_image:latest"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
        securityContext:
          readOnlyRootFilesystem: true

But I'm getting:

  {
    "AssertionMessage": "unknown op ",
    "Category": "",
    "CreatedAt": "2020-03-05T17:33:12Z",
    "Filename": "/foobar/configs/deployment.yaml",
    "LineNumber": 0,
    "ResourceID": "my-app",
    "ResourceType": "Deployment",
    "RuleID": "DEPLOYMENT_CONTAINER_SECURITY_CONTEXT",
    "RuleMessage": "Deployment containers should set securityContexts",
    "Status": "NON_COMPLIANT"
  }

Thanks,

Matt

phelewski commented 4 years ago

@namloc2001 my apologies, the formatting from my previous comment didn't paste correctly. I've fixed it for now, but for future reference the tabbing/spacing is important for the operators.

From:

    assertions:
      - every:
        key: spec.template.spec.containers[]
        expressions:
          - key: securityContext.runAsNonRoot
            op: is-true

To:

    assertions:
      - every:
          key: spec.template.spec.containers[]
          expressions:
            - key: securityContext.runAsNonRoot
              op: is-true
namloc2001 commented 4 years ago

Thanks. So I'm using this rule:

  - id: DEPLOYMENT_CONTAINER_SECURITY_CONTEXT
    severity: NON_COMPLIANT
    message: Deployment containers should set securityContexts
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers
          expressions:
            - key: securityContext.runAsNonRoot
              op: is-true
            - key: securityContext.readOnlyRootFilesystem
              op: is-true
    tags:
      - deployment
      - security

Against this config:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      securityContext:
        readOnlyRootFilesystem: true
      restartPolicy: Always
      serviceAccountName: my-app
      containers:
      - name: my-app
        image: "my_image:latest"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
        securityContext:
          readOnlyRootFilesystem: true

Which should detect that 'runAsNonRoot' is missing and so rule violation occurs. This now happens, now get a very full AssertionMessage.

"AssertionMessage": "Every expression fails: And expression fails: securityContext.runAsNonRoot should be 'true', not ''",
phelewski commented 4 years ago

The message is stating what the error is. It's stating that the every expression is failing. This expression includes 2 rules, both must pass. It says that securityContext.runAsNonRoot should be set to true while it returns nothing. The securityContext.runAsNonRoot property doesn't exist in your provided configuration.

Any output other than an empty [] is a violation to the rules.

$ config-lint -rules 153_rules.yml 153_config.yml
[
  {
    "AssertionMessage": "Every expression fails: And expression fails: securityContext.runAsNonRoot should be 'true', not ''",
    "Category": "",
    "CreatedAt": "2020-03-05T18:41:30Z",
    "Filename": "153_config.yml",
    "LineNumber": 0,
    "ResourceID": "my-app",
    "ResourceType": "Deployment",
    "RuleID": "DEPLOYMENT_CONTAINER_SECURITY_CONTEXT",
    "RuleMessage": "Deployment container should set securityContexts",
    "Status": "NON_COMPLIANT"
  }
]
namloc2001 commented 4 years ago

Yeh, reread it and makes sense. Thanks very much.