<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Roland Emmanuel Salunga]]></title><description><![CDATA[Occasional ramblings from a self-proclaimed techie about cybersecurity, information security, technology, and the subtleties of life.]]></description><link>https://rolandsalunga.com/</link><image><url>https://rolandsalunga.com/favicon.png</url><title>Roland Emmanuel Salunga</title><link>https://rolandsalunga.com/</link></image><generator>Ghost 5.81</generator><lastBuildDate>Wed, 06 May 2026 02:14:21 GMT</lastBuildDate><atom:link href="https://rolandsalunga.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[DevSecOps Homelab Part 2: Building the Pipeline]]></title><description><![CDATA[<p>Welcome to the second part of our three-part series, where I continue to explore DevSecOps concepts in my homelab and bring you along for the ride. In the last article, I discussed about my motivations for starting this project. Now, let&apos;s get practical and hands-on.</p><blockquote>Note: I am</blockquote>]]></description><link>https://rolandsalunga.com/devsecops-homelab-part-2-building-the-pipeline/</link><guid isPermaLink="false">66214c9f6357270001cadce9</guid><category><![CDATA[homelab]]></category><category><![CDATA[devsecops]]></category><dc:creator><![CDATA[Roland Emmanuel Salunga]]></dc:creator><pubDate>Thu, 09 May 2024 04:41:25 GMT</pubDate><content:encoded><![CDATA[<p>Welcome to the second part of our three-part series, where I continue to explore DevSecOps concepts in my homelab and bring you along for the ride. In the last article, I discussed about my motivations for starting this project. Now, let&apos;s get practical and hands-on.</p><blockquote>Note: I am using a self-hosted Gitea instance to host the project&apos;s repository, store the container images, and manage and execute the CI/CD pipeline.</blockquote><h2 id="tools-of-trade">Tools of Trade</h2><p>Before dive into the nitty-gritty of building and implementing a functional CI/CD pipeline, I&apos;ll introduce the tools I&apos;ll be employing in this project, which are:</p><ul><li><strong>Pygoat</strong>: An intentionally vulnerable application, ripe for testing with our security tools.</li><li><strong>Bandit</strong>: A static code analysis tool, used for scanning Python source code in a &quot;static&quot; state to identify vulnerabilities.</li><li><strong>ZAP</strong>: A dynamic analysis tool, used for scanning code during execution to identify vulnerabilities.</li><li><strong>DependencyCheck</strong>: A software composition analysis tool, used for scanning for vulnerabilities in our app&apos;s dependencies.</li><li><strong>Trufflehog</strong>: A secrets scanning tool, used for scanning the source code for any hard-coded passwords or secrets.</li><li><strong>Trivy</strong>: A container security scanning tool, used for scanning containers or images for known vulnerabilities, malwares, and other potential threats.</li></ul><h2 id="step-by-step-pipeline-workflow">Step-by-step Pipeline Workflow</h2><figure class="kg-card kg-image-card"><img src="https://rolandsalunga.com/content/images/2024/05/blog-1.jpg" class="kg-image" alt loading="lazy" width="1193" height="319" srcset="https://rolandsalunga.com/content/images/size/w600/2024/05/blog-1.jpg 600w, https://rolandsalunga.com/content/images/size/w1000/2024/05/blog-1.jpg 1000w, https://rolandsalunga.com/content/images/2024/05/blog-1.jpg 1193w" sizes="(min-width: 720px) 720px"></figure><p>The image above showcases a very simple diagram illustrating the workflow of the CI/CD pipeline. Essentially, the entire pipeline is triggered by pushing a commit into the Gitea instance. From there, several security scans are performed before proceeding to deploy the application across various environments.</p><h3 id="step-1-creating-the-workflow-yaml">Step 1: Creating the Workflow YAML</h3><p>By default, Gitea uses <a href="https://docs.gitea.com/usage/actions/overview?ref=rolandsalunga.com" rel="noreferrer">Gitea Actions</a> as its built-in CI/CD solution. Gitea Actions is similar and designed to be compatible with GitHub Actions, which means it also uses the same syntax.</p><p>So, as our first step, we need to create a workflow file named <code>devsecops.yaml</code> in the <code>.gitea/workflows</code> directory, adding the following content:</p><pre><code class="language-yaml">name: DevSecOps CI/CD Pipeline
run-name: DevSecOps CI/CD Pipeline
on: [push]

jobs:
  build-scan-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: &quot;3.8.18&quot;
        env:
          AGENT_TOOLSDIRECTORY: /opt/hostedtoolcache

      - name: Setup JDK 1.8
        uses: actions/setup-java@v4
        with:
          distribution: &quot;zulu&quot;
          java-version: &quot;8&quot;

      - name: Build and Install Dependencies
        run: |
          python -m pip install --upgrade pip</code></pre><p>This configuration instructs the pipeline to activate upon receiving a <code>push</code> event, and defines a single CI/CD job named <code>build-scan-deploy</code>, which executes on the <code>ubuntu-latest</code> runner.</p><blockquote>Note: For the purpose of this demo, we will use <code>push</code> event as the trigger for our pipeline. However, in real-world scenarios, you will need to adjust this according to your specific needs.</blockquote><p>Additionally, we defined the initial four steps for this CI/CD job &#x2013; first, we checkout the source code, then configure Python and JDK, which are pre-requisites by some of the security tools we will be using, and finally we install our pip dependency.</p><h3 id="step-2-setting-up-bandit-for-static-code-analysis">Step 2: Setting up Bandit for Static Code Analysis</h3><p>For our next step, we will install Bandit via pip and execute it to perform static code analysis on our Python source code, we will also configure it to export the results in JSON format.</p><pre><code>      ...
      - name: Static Code Analysis using Bandit
        run: |
          pip install bandit
          bandit -r . -f json -o sast-${{ github.sha }}.reports.json
        continue-on-error: true # only for testing. remove on prod.</code></pre><h3 id="step-3-setting-up-owasp-dependencycheck-for-software-composition-analysis">Step 3: Setting up OWASP DependencyCheck for Software Composition Analysis</h3><p>Moving forward, we will use OWASP DependencyCheck to detect vulnerabilities in third-party dependencies. Initially, we will download its latest version, then execute it. Additionally, we&apos;ll provide our NVD API Key since DependencyCheck now relies on NVD API. Furthermore, we&apos;ll activate the <code>--enableExperimental</code> flag, considering that the Python analyzer remains &quot;experimental&quot;. Lastly, we&apos;ll export the results in XML format.</p><pre><code>      ...
      - name: Download OWASP DependencyCheck
        run: |
          VERSION=$(curl -s https://jeremylong.github.io/DependencyCheck/current.txt)
          curl -sL &quot;https://github.com/jeremylong/DependencyCheck/releases/download/v$VERSION/dependency-check-$VERSION-release.zip&quot; --output dependency-check.zip
          unzip dependency-check.zip

      - name: Software Composition Analysis using DependencyCheck
        run: |
          ./dependency-check/bin/dependency-check.sh \
          --project ${{ github.repository }} \
          --scan . \
          --format &quot;XML&quot; \
          --out sca-${{ github.sha }}.reports.xml \
          --nvdApiKey ${{ secrets.NVD_API_KEY }} \
          --enableExperimental
        continue-on-error: true # only for testing. remove on prod.</code></pre><h3 id="step-4-setting-up-trufflehog-for-secrets-scanning">Step 4: Setting up Trufflehog for Secrets Scanning</h3><p>Following that, we&apos;ll utilize Trufflehog to scan our source code for any leaked credentials and secrets. First, we&apos;ll install Trufflehog binary, then execute it to start the scan, and configure it to export the results in JSON format.</p><pre><code>      ...
      - name: Secrets Scanning using Trufflehog
        run: |
          curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sh -s -- -b /usr/local/bin
          trufflehog filesystem . --fail --json | jq -c &apos;.SourceMetadata&apos; &gt; secrets-${{ github.sha }}.reports.json
        continue-on-error: true # only for testing. remove on prod.</code></pre><h3 id="step-5-build-and-scan-docker-image-using-trivy">Step 5: Build and Scan Docker Image using Trivy</h3><p>Once we&apos;re done with our initial scans, it&apos;s time to build our Docker image. We will then use Trivy to scan for vulnerabilities in the Docker image. Initially, we will install the Trivy binary, then execute it to start the scan, and finally export the results in JSON format.</p><pre><code>      ...
      - name: Build Docker image
        run: |
          docker build -f Dockerfile -t seclab/pygoat:latest .

      - name: Container Scanning using Trivy
        run: |
          curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.50.4
          trivy image -f json -o container-${{ github.sha }}.reports.json seclab/pygoat:latest
        continue-on-error: true # only for testing. remove on prod.</code></pre><h3 id="step-6-deploy-image-as-container-and-setup-zap-for-dynamic-code-analysis">Step 6: Deploy Image as Container and Setup ZAP for Dynamic Code Analysis</h3><p>At last, we&apos;ll proceed to deploy the Docker image as a container, allowing us to conduct vulnerability scans during the application&apos;s runtime. We will be using ZAP to perform this scan. Initially, we&apos;ll deploy ZAP&apos;s dockerized version and specify the local IP address of our deployed application. Additionally, we&apos;ll export the scan results in JSON format.</p><pre><code>      ...
      - name: Deploy Docker image as container
        run: |
          docker run -d -p 8000:8000 --name=seclab-pygoat --restart=always seclab/pygoat:latest
        continue-on-error: true # only for testing. remove on prod.

      - name: Dynamic Code Analysis using ZAP
        run: |
          docker run --user $(id -u):$(id -g) --volume $(pwd):/zap/wrk/:rw --rm \
            -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
            -t http://172.16.30.11:8000 -J dast-${{ github.sha }}.reports.json
        continue-on-error: true # only for testing. remove on prod</code></pre><blockquote>Note: We only performed a &quot;baseline&quot; scan for the purpose of this demo. In real-world scenarios, it&apos;s advisable to conduct comprehensive scans regularly, rather than only when the designated events are triggered, in order to optimize the pipeline&apos;s execution time.</blockquote><h3 id="step-7-results">Step 7: Results</h3><p>If you followed everything correctly, your <code>devsecops.yaml</code> should be resemble the following:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://gist.github.com/rsalunga29/6d056066a87353d0e4c91f0c191e235e?ref=rolandsalunga.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">CI/CD Workflow for DevSecOps Homelab series</div><div class="kg-bookmark-description">CI/CD Workflow for DevSecOps Homelab series. GitHub Gist: instantly share code, notes, and snippets.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt><span class="kg-bookmark-author">Gist</span><span class="kg-bookmark-publisher">262588213843476</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://github.githubassets.com/assets/gist-og-image-54fd7dc0713e.png" alt></div></a></figure><p>Moreover, once the pipeline is triggered, you can track its progress under the &quot;Actions&quot; tab within the repository. It should display something similar to the following:</p><figure class="kg-card kg-image-card"><img src="https://rolandsalunga.com/content/images/2024/05/image.png" class="kg-image" alt loading="lazy" width="831" height="663" srcset="https://rolandsalunga.com/content/images/size/w600/2024/05/image.png 600w, https://rolandsalunga.com/content/images/2024/05/image.png 831w" sizes="(min-width: 720px) 720px"></figure><h2 id="what-comes-next">What comes next?</h2><p>Now that we have a working CI/CD pipeline, our focus shifts to addressing the findings from our security tools. To tackle this, we&apos;ll turn to Application Security Posture Management Platforms (ASPM), which we&apos;ll explore in detail in the upcoming and final article of this series. Stay tuned&#x2014;you won&apos;t want to miss it!</p>]]></content:encoded></item><item><title><![CDATA[DevSecOps Homelab Part 1: Introduction]]></title><description><![CDATA[<h2 id="overview">Overview</h2><p>Alright, let&apos;s kick things off with the first of a three-part series where I share my latest pet project: tinkering with DevSecOps concepts in my homelab. In this article, I&apos;ll dive into the nitty-gritty &#x2013; what&apos;s up with this project, and why am</p>]]></description><link>https://rolandsalunga.com/devsecops-homelab-part-1-introduction/</link><guid isPermaLink="false">661ea15b6357270001cadc2c</guid><category><![CDATA[homelab]]></category><category><![CDATA[devsecops]]></category><dc:creator><![CDATA[Roland Emmanuel Salunga]]></dc:creator><pubDate>Fri, 19 Apr 2024 18:56:59 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1520869562399-e772f042f422?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGhvbWVsYWJ8ZW58MHx8fHwxNzEzMjgzNDU3fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h2 id="overview">Overview</h2><img src="https://images.unsplash.com/photo-1520869562399-e772f042f422?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGhvbWVsYWJ8ZW58MHx8fHwxNzEzMjgzNDU3fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="DevSecOps Homelab Part 1: Introduction"><p>Alright, let&apos;s kick things off with the first of a three-part series where I share my latest pet project: tinkering with DevSecOps concepts in my homelab. In this article, I&apos;ll dive into the nitty-gritty &#x2013; what&apos;s up with this project, and why am I even bothering with it?</p><h2 id="what-is-a-homelab">What is a homelab?</h2><p>First, we need to understand what a homelab is. Simply put, a homelab is a dedicated space where individuals can experiment, learn, and practice various concepts of IT, networking, cybersecurity, or other related fields, in a controlled environment.</p><p>Homelabs typically consists of physical hardware such as servers, switches, and routers, as well as virtualized environments using virtualization software like VMware or VirtualBox. In my case, I rely on virtualization for now as investing in physical hardware isn&apos;t feasible at the moment.</p><h2 id="why-bother-building-a-homelab">Why bother building a homelab?</h2><p>Aside from the reasons mentioned above, they offer a prime opportunity to showcase your skills and knowledge to potential employers. Additionally, having a homelab demonstrates initiative and a genuine passion for your field. It shows that you&apos;re not content to just learn in a classroom or office setting&#x2014;you&apos;re actively seeking out opportunities to expand your skills and knowledge on your own time.</p><p>So, yeah, that&apos;s my main motivation for undertaking this project, it&apos;s to level-up my DevSecOps game, feed my curiosity, and have tons of fun along the way!</p><h2 id="alright-whats-up-next">Alright, what&apos;s up next?</h2><p>Well, I&apos;m not gonna tell you how to build your own virtual homelab. That&apos;s been covered extensively in other tutorials. Instead, in the next article, we&apos;re rolling up our sleeves and jumping straight into setting up the CI/CD pipeline. Keep an eye out for it!</p>]]></content:encoded></item><item><title><![CDATA[A new website - Welcome!]]></title><description><![CDATA[<p>Well then, website iteration #99999...! Ah, yes, it&apos;s the never ending desire to update your personal website. I may have lost count how many times I&apos;ve changed my website over the years, but this ain&apos;t definitely the last one! &#x1F602;</p><p>Anyways, welcome and thanks</p>]]></description><link>https://rolandsalunga.com/a-new-website/</link><guid isPermaLink="false">660f0980877f430001b67018</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[Roland Emmanuel Salunga]]></dc:creator><pubDate>Thu, 04 Apr 2024 20:11:44 GMT</pubDate><content:encoded><![CDATA[<p>Well then, website iteration #99999...! Ah, yes, it&apos;s the never ending desire to update your personal website. I may have lost count how many times I&apos;ve changed my website over the years, but this ain&apos;t definitely the last one! &#x1F602;</p><p>Anyways, welcome and thanks for visiting! This shall serve as my personal website to share my thoughts and experiences on topics that interests me.</p><p>I am also active on <a href="https://twitter.com/RESalunga?ref=rolandsalunga.com" rel="noreferrer">Twitter</a> and <a href="https://www.linkedin.com/in/rsalunga29/?ref=rolandsalunga.com" rel="noreferrer">LinkedIn</a>, feel free to drop a follow!</p>]]></content:encoded></item></channel></rss>