<img src="https://ws.zoominfo.com/pixel/JHVDdRXH2uangmUMQBZd" width="1" height="1" style="display: none;">

Welcome to Magalix Documentation!

These pages cover what Magalix is, how to get started using it, and reference materials for its features and supported cloud providers.

Get started quickly, and get all your questions answered now!

Talk to an Expert

How to Setup DevSecOps Pipeline in GitLab

Demo Overview

This demo shows how Magalix Kubeguard integrates well with other GitLab features to create a DevSecOps end-2-end pipeline.

In this demo, we will build a pipeline that's triggered on every commit. The pipeline has 3 stages:

1- Build: In this stage, we build an example docker image in our repo which has a vulnerability to be tested using GitLab's container scanning feature.

2- Test: In this stage, we have 3 tests:

1- Container Image Scanning Test (GitLab feature).

2- Static Application Security Testing SAST (GitLab feature).

3- IaC Scanning (Magalix Kubeguard feature).

Note: GitLab features require ultimate plan

3- Deploy: In this stage, we deploy an example pod file in our repo on a GKE cluster after it's scanned by Magalix Kubeguard.

Let's Start

1- Log into GitLab and create a new blank project.

2- Add example files that our tests will scan:
  • Dockerfile: This is an example Dockerfile that contains a vulnerability so that we can see the container scanning test results.
 
# Example Dockerfile
 
  FROM node:12-alpine
  RUN apk add --no-cache python g++ make
  RUN echo "HELLO DEVSECOPS"
  • example.py: This is just a simple yaml_to_json parser file. It has a vulnerability that's detected by SAST. You can use any file to be scanned by SAST.
 
import os
  import yaml
  import json
 
  rootdir = '/yamls'
 
  # Loop over dirs and convert each yaml file to json
  def convert_yamls_to_json(rootdir):
    for d in os.listdir(rootdir):
      dir_path = os.path.join(rootdir, d)
      for yaml_file in os.listdir(dir_path):
        file_ext = os.path.splitext(yaml_file)[1]
        if file_ext in [".yml", ".yaml"]:
          # Read YAML
          with open(os.path.join(dir_path, yaml_file)) as infile:
            data_obj = yaml.load(infile, Loader=yaml.FullLoader)
            json_filename = yaml_file.replace(".yaml", ".json")
            json_filename = yaml_file.replace(".yml", ".json")
            # Write JSON file
            with open(os.path.join(dir_path, json_filename), 'w') as outfile:
              json.dump(data_obj, outfile, indent=2)
 
  convert_yamls_to_json(rootdir)
  • k8s/nginx.yaml: (This is a simple K8s nginx pod file that will be scanned by Magalix Kubeguard)
 
apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: nginx-deployment
    labels:
      owner: test
  spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
  • Your repo structure should now look like this:
 
__
  |____ Dockerfile
  |____ example.py
  |____ k8s
        |____ nginx.yaml
3- Create a Magalix Kubeguard and attach your desired policies.

Guard URL: https://console.magalix.com/api/v1/kubeguard/<kubguard_id>

Attached policies: Test Missing Owner Key - Missing Kubernetes App Label

4- In GitLab: From the left sidebar, go to settings then CI/CD then add these masked environment variables to be used in our pipeline
  • GUARD_WEBHOOK: Kubeguard webhook url
  • KUBECONFIG: base64 encrypted string of your cluster kubeconfig file Or GCLOUD_SERVICE_KEY: base64 encrypted string of your gcloud service account key file (Here I've used kubeconfig file)

5- Let's add our .gitlab-ci.yaml file to define our pipeline
 
stages:
    - build
    - test
    - deploy
 
  # variables:
    # specify $DOCKER_IMAGE var if you want container scanning to use a specific image instead of the one built in the build step
    # if the image is in another registry you need to provide $DOCKER_USER and $DOCKER_PASSWORD
    # DOCKER_IMAGE: registry.gitlab.com/test4927/test-kubeguard/main:bb4edb61e2787e4f23a00ccc5ef3ba45b353d53e
 
  include:
    - template: Security/Container-Scanning.gitlab-ci.yml
    - template: Security/SAST.gitlab-ci.yml
 
  build:
    image: docker:19.03.8
    stage: build
    services:
      - docker:19.03.8-dind
    variables:
      IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
    script:
      - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
      - docker build -t $IMAGE_TAG .
      - docker push $IMAGE_TAG
 
  magalix sast:
    image:
    name: ahsayde/mglx-test:latest
    entrypoint: [""]
    stage: test
    script:
      - cd ${CI_PROJECT_DIR}
      - mglx-scanner -w ${GUARD_WEBHOOK} -d . --no-exit-error --sast mglx-sast-result.json
    allow_failure: true
    artifacts:
      reports:
        sast: mglx-sast-result.json
      paths:
        - mglx-sast-result.json
 
  sast:
    stage: test
    artifacts:
      reports:
        sast: gl-sast-report.json
      paths:
        - gl-sast-report.json
 
  gke deploy:
    stage: deploy
    image: google/cloud-sdk
    script:
      # deploy using kubeconfig file with user access token
      - echo $KUBECONFIG | base64 -d > ~/kubeconfig.yaml
      - export KUBECONFIG=~/kubeconfig.yaml
      - kubectl get pods
      - kubectl apply -f k8s/nginx.yaml
      - kubectl get pods
      
      # alternative way to deploy is using service account key file generated from GCP console
      # - echo $GCLOUD_SERVICE_KEY | base64 -d > ~/gcloud-service-key.json
      # - gcloud auth activate-service-account --key-file ~/gcloud-service-key.json
      # - gcloud config set project $GCP_PROJECT_ID
      # - gcloud container clusters get-credentials $CLUSTER_NAME --zone $CLUSTER_ZONE --project $GCP_PROJECT_ID
      # - kubectl apply -f k8s/nginx.yaml

Notes:

  • GitLab container scanning and SAST features require GitLab’s paid ultimate plan.
  • If you want the container scanning test to scan another image you should provide the DOCKER_IMAGE, DOCKER_USER, DOCKER_PASSWORD variables in the .gitlab-ci.yaml.
  • In the magalix sast job, you can use the --no-exit-error option if you want the job to succeed even if there're violations. I used it just to run the pipeline to the end but it should not be used in order to stop the pipeline if the magalix_sast test discovered violations in your k8s files.
  • In the gke deploy job, you have 2 options:

1- Kubeconfig file.

2- GCloud service account key file, You can find the code for each one in the .gitlab-ci.yaml file.
I used the kubeconfig code and commented on the other one.

6- Once you commit your .gitlab-ci.yaml, go to the Pipelines page in GitLab and you'll find our pipeline triggered.

Click on the pipeline and you'll find the 3 stages and their jobs. The bandit sast and semgrep sast jobs are GitLab SAST tests.

7- After some time, the jobs will finish successfully

8- You can then see the violations and vulnerabilities of each job by viewing the job artifacts.
  • Bandit (Python - SAST) artifacts:

  • Container scanning artifacts:

  • Magalix Kubeguard violations:

9- You can configure SAST analyzers to be applied in order to cover languages across your project, by default all analyzers are applied. Go to Security & Compliance then Configuration and click Configure SAST. You'll find the list of SAST analyzers.

10- And the pod is spinned up successfully in the GKE cluster 😎
 
kubectl get pods   
  NAME                                 READY   STATUS    RESTARTS   AGE
  nginx-deployment2-5d59d67564-f9rx7   1/1     Running   0          41s
  nginx-deployment2-5d59d67564-pllcv   1/1     Running   0          41s    
arrow