<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IKER ALBERTO SIERRA RUIZ</title>
    <description>The latest articles on DEV Community by IKER ALBERTO SIERRA RUIZ (@ikers).</description>
    <link>https://dev.to/ikers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3970252%2Ff93176e6-638d-421f-95a2-26e5cc7760df.jpg</url>
      <title>DEV Community: IKER ALBERTO SIERRA RUIZ</title>
      <link>https://dev.to/ikers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ikers"/>
    <language>en</language>
    <item>
      <title>Applying Checkov to Terraform as Code – A TFSEC Alternative</title>
      <dc:creator>IKER ALBERTO SIERRA RUIZ</dc:creator>
      <pubDate>Fri, 05 Jun 2026 18:21:04 +0000</pubDate>
      <link>https://dev.to/ikers/applying-checkov-to-terraform-as-code-a-tfsec-alternative-5gm</link>
      <guid>https://dev.to/ikers/applying-checkov-to-terraform-as-code-a-tfsec-alternative-5gm</guid>
      <description>&lt;p&gt;Static Application Security Testing (SAST) is a critical practice in modern DevSecOps. While tools like SonarQube, Snyk, and Veracode are popular, this article focuses on &lt;strong&gt;GitHub CodeQL&lt;/strong&gt; – a semantic code analysis engine that treats code as a database. We will apply it to a vulnerable Java Spring Boot application to detect SQL Injection and Path Traversal.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why CodeQL?
&lt;/h2&gt;

&lt;p&gt;Unlike pattern-based scanners, CodeQL builds a relational database of your code, including abstract syntax trees, control flow graphs, and data flow graphs. This allows it to track tainted data across functions, classes, and files, drastically reducing false positives.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 Target Application (Vulnerable Java App)
&lt;/h2&gt;

&lt;p&gt;Let's look at a simple REST API with two vulnerable endpoints. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;UserController.java&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.demo.controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.demo.model.User&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.jdbc.core.JdbcTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.file.Files&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.file.Paths&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;JdbcTemplate&lt;/span&gt; &lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Vulnerability 1: SQL Injection&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/users"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM users WHERE id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Dangerous concatenation&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rowNum&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Vulnerability 2: Path Traversal&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/file"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"filename"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAllBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/var/data/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Installing and Configuring CodeQL CLI
&lt;/h2&gt;

&lt;p&gt;You can run CodeQL locally to analyze your code before pushing it to a repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Download CodeQL from GitHub releases:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="o"&gt;[&lt;/span&gt;https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip]&lt;span class="o"&gt;(&lt;/span&gt;https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Unzip and add to PATH:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unzip codeql-linux64.zip &lt;span class="nt"&gt;-d&lt;/span&gt; ~/tools/
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:~/tools/codeql/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create a CodeQL database from your source code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codeql database create ./codeql-db &lt;span class="nt"&gt;--language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;java &lt;span class="nt"&gt;--source-root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Download the standard query suite:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="o"&gt;[&lt;/span&gt;https://github.com/github/codeql.git]&lt;span class="o"&gt;(&lt;/span&gt;https://github.com/github/codeql.git&lt;span class="o"&gt;)&lt;/span&gt; ~/codeql-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Run the analysis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codeql database analyze ./codeql-db &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sarif-latest &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;results.sarif ~/codeql-repo/java/ql/src/codeql-suites/java-security-and-quality.qls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Interpreting SARIF Results
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;results.sarif&lt;/code&gt; file (in JSON format) will reveal the vulnerabilities found. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule ID:&lt;/strong&gt; &lt;code&gt;java/sql-injection&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location:&lt;/strong&gt; &lt;code&gt;line 18, column 20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code flow:&lt;/strong&gt; from user-controlled parameter &lt;code&gt;userId&lt;/code&gt; to the SQL query sink.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This confirms a critical SQL Injection vulnerability traced straight to the source.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 CI/CD Integration with GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Running CodeQL locally is great, but automating it is better. Here is how to create a GitHub Actions workflow to scan your code automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;.github/workflows/codeql-analysis.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CodeQL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Security&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Scan"&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;develop&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;analyze&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;security-events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v4&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;temurin'&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/init@v3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;languages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;java-kotlin'&lt;/span&gt;
        &lt;span class="na"&gt;queries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security-extended&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/autobuild@v3&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/analyze@v3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;On every pull request, CodeQL will run and upload the results directly to the "Security" tab of your repository.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Custom Queries (Advanced)
&lt;/h2&gt;

&lt;p&gt;Because CodeQL treats your code like a database, you can write custom queries to find specific anti-patterns. For example, to detect the use of &lt;code&gt;printStackTrace()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;CustomLogging.ql&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java

from MethodCall call, Method m
where m.hasName("printStackTrace") and call.getMethod() = m
select call, "Use of printStackTrace() may expose internal details."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run it with:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codeql query run CustomLogging.ql &lt;span class="nt"&gt;--database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./codeql-db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;CodeQL provides deep, semantic SAST analysis. Integrated into CI/CD, it becomes an automated gatekeeper against critical vulnerabilities like SQL Injection and Path Traversal. It is a powerful, enterprise-grade alternative to commercial tools, especially for teams already utilizing the GitHub ecosystem.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>devsecops</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Applying Checkov to Terraform as Code: A TFSEC Alternative</title>
      <dc:creator>IKER ALBERTO SIERRA RUIZ</dc:creator>
      <pubDate>Fri, 05 Jun 2026 18:10:55 +0000</pubDate>
      <link>https://dev.to/ikers/applying-checkov-to-terraform-as-code-a-tfsec-alternative-3nga</link>
      <guid>https://dev.to/ikers/applying-checkov-to-terraform-as-code-a-tfsec-alternative-3nga</guid>
      <description>&lt;p&gt;Infrastructure as Code (IaC) brings version control to infrastructure, but it also introduces the risk of deploying architecture-level misconfigurations at scale. While TFSEC is well known in the community, this article demonstrates &lt;strong&gt;Checkov&lt;/strong&gt; – an open-source static analysis tool with graph-based scanning, over 1,000 built-in policies, and robust support for Terraform, CloudFormation, Kubernetes, and more.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why Checkov?
&lt;/h2&gt;

&lt;p&gt;Checkov (developed by Bridgecrew) scans IaC for security and compliance violations. Unlike traditional pattern-based checkers that only look at resources in isolation, Checkov builds a &lt;strong&gt;graph of resources and their relationships&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This allows it to detect complex issues, such as an S3 bucket that is set to private but is missing an account-level public access block.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 The Problem: Vulnerable Terraform Configuration
&lt;/h2&gt;

&lt;p&gt;Let's look at a problematic &lt;code&gt;main.tf&lt;/code&gt; file. On the surface, it deploys standard AWS resources, but it contains three major security violations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Violation 1: Public S3 bucket&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"data_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-company-data-2026"&lt;/span&gt;
  &lt;span class="nx"&gt;acl&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public-read"&lt;/span&gt;   &lt;span class="c1"&gt;# Checkov: CKV_AWS_18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Violation 2: SSH open to world&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"web_sg"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"web_sg"&lt;/span&gt;
  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="c1"&gt;# Checkov: CKV_AWS_5&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Violation 3: RDS without encryption&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_db_instance"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;allocated_storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mysql"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_class&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db.t3.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;storage_encrypted&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;   &lt;span class="c1"&gt;# Checkov: CKV_AWS_16&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Installing and Running Checkov
&lt;/h2&gt;

&lt;p&gt;You can easily install Checkov via Python's package manager or run it directly through Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install via pip:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;checkov
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Or use Docker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--tty&lt;/span&gt; &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:/tf"&lt;/span&gt; bridgecrew/checkov &lt;span class="nt"&gt;--directory&lt;/span&gt; /tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run the scan in your project directory:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;checkov &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample Output
&lt;/h3&gt;

&lt;p&gt;Checkov instantly identifies the vulnerable configurations and maps them to specific AWS security policies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Check: CKV_AWS_18: "Ensure the S3 bucket has public access blocks"
        FAILED for resource: aws_s3_bucket.data_bucket
        File: /main.tf:6-10

Check: CKV_AWS_5: "Ensure security groups restrict SSH from 0.0.0.0/0"
        FAILED for resource: aws_security_group.web_sg

Check: CKV_AWS_16: "Ensure all data stored in the RDS is securely encrypted at rest"
        FAILED for resource: aws_db_instance.default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Remediation Steps
&lt;/h2&gt;

&lt;p&gt;To pass the Checkov scan, we need to apply the following fixes to our infrastructure code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Fix the S3 Bucket:&lt;/strong&gt;&lt;br&gt;
Set the ACL to private and attach a Public Access Block resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"data_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-company-data-2026"&lt;/span&gt;
  &lt;span class="nx"&gt;acl&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"block"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Fix the Security Group:&lt;/strong&gt; Change &lt;code&gt;cidr_blocks = ["10.0.0.0/16"]&lt;/code&gt; to restrict SSH access to an internal network only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Fix the RDS Instance:&lt;/strong&gt; Set &lt;code&gt;storage_encrypted = true&lt;/code&gt; and ensure it references a valid KMS key.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 CI/CD Integration with GitLab CI
&lt;/h2&gt;

&lt;p&gt;Finding vulnerabilities locally is good, but preventing them from being merged is better. Here is how to integrate Checkov into your GitLab CI pipeline by creating a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;validate&lt;/span&gt;

&lt;span class="na"&gt;checkov-scan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;validate&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridgecrew/checkov:latest&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkov --directory . --quiet --output cli --soft-fail&lt;/span&gt;
  &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;terraform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checkov_report.json&lt;/span&gt;
  &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;merge_requests&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; We use &lt;code&gt;--soft-fail&lt;/code&gt; so the pipeline does not break on violations (it only reports them). Once your team is accustomed to the tool, remove &lt;code&gt;--soft-fail&lt;/code&gt; to enforce hard security gates.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚙️ Custom Policies with YAML
&lt;/h2&gt;

&lt;p&gt;Checkov allows you to write custom organizational rules. For example, if you want to prevent developers from provisioning specific instance types to control costs, you can create a &lt;code&gt;.checkov.yaml&lt;/code&gt; config map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;custom-policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Prohibit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;t2.micro&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;instances"&lt;/span&gt;
    &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;custom_policies/prohibit_t2_micro.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Content of &lt;code&gt;prohibit_t2_micro.yaml&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CUSTOM_1&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;t2.micro&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;allowed"&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COST_OPTIMIZATION"&lt;/span&gt;
&lt;span class="na"&gt;definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cond_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;attribute"&lt;/span&gt;
  &lt;span class="na"&gt;resource_types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws_instance"&lt;/span&gt;
  &lt;span class="na"&gt;attribute&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;instance_type"&lt;/span&gt;
  &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_equals"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t2.micro"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run Checkov with your new custom policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;checkov &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--external-checks-dir&lt;/span&gt; ./custom_policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⏭️ Skipping False Positives
&lt;/h2&gt;

&lt;p&gt;Sometimes, a resource like an S3 bucket &lt;em&gt;needs&lt;/em&gt; to be public (e.g., for static website hosting). You can suppress Checkov warnings by adding a simple inline comment inside your Terraform code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"data_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;# checkov:skip=CKV_AWS_18:This bucket is for public static website hosting&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-public-website"&lt;/span&gt;
  &lt;span class="nx"&gt;acl&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public-read"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;Checkov is a mature, highly active SAST tool for Infrastructure as Code. By integrating it into your CI/CD pipeline, you prevent misconfigurations—like open S3 buckets or unencrypted databases—from ever reaching production. &lt;/p&gt;

&lt;p&gt;As a TFSEC alternative, it stands out by offering broader framework support (including Kubernetes, CloudFormation, and Pulumi) and intelligent, graph-based security analysis.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>security</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Bulletproof Your Java APIs: Automating Tests with REST-Assured</title>
      <dc:creator>IKER ALBERTO SIERRA RUIZ</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:53:59 +0000</pubDate>
      <link>https://dev.to/ikers/bulletproof-your-java-apis-automating-tests-with-rest-assured-4adb</link>
      <guid>https://dev.to/ikers/bulletproof-your-java-apis-automating-tests-with-rest-assured-4adb</guid>
      <description>&lt;p&gt;As backend architectures shift increasingly toward microservices, validating the communication between these services is paramount. Relying solely on manual API testing is no longer viable. Developers and QA engineers need frameworks that integrate seamlessly into their codebase and CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;According to comprehensive industry reviews of API tools, REST-Assured is a standout open-source tool for Java developers. It is a Java Domain-Specific Language (DSL) specifically designed to simplify testing REST services. One of its most powerful features is its support for the BDD (Behavior-Driven Development) Given/When/Then syntax. This syntax makes test cases incredibly readable, meaning you don't necessarily need to be an HTTP expert to understand what the test is doing. It also integrates seamlessly with automation frameworks like Serenity to generate beautiful reports.&lt;/p&gt;

&lt;p&gt;Applying REST-Assured: A Real-World Example&lt;br&gt;
Imagine you are building an e-commerce platform and need to test an endpoint that fetches a user's profile information (GET /api/users/{id}). The API requires a Bearer token for authorization.&lt;/p&gt;

&lt;p&gt;Here is how you would apply REST-Assured to automate this test in a real-world Java project:&lt;/p&gt;

&lt;p&gt;`import io.restassured.RestAssured;&lt;br&gt;
import io.restassured.http.ContentType;&lt;br&gt;
import org.testng.annotations.Test;&lt;br&gt;
import static io.restassured.RestAssured.given;&lt;br&gt;
import static org.hamcrest.Matchers.*;&lt;/p&gt;

&lt;p&gt;public class UserProfileApiTest {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
public void verifyUserProfileDataAndSecurity() {
    // Set the base URI for our API
    RestAssured.baseURI = "https://api.ecommerce-realworld.com";

    // Applying the Given/When/Then BDD approach
    given()
        .header("Authorization", "Bearer valid_secure_token_here")
        .contentType(ContentType.JSON)
        .pathParam("userId", "1045")
    .when()
        .get("/api/users/{userId}")
    .then()
        .log().ifValidationFails() // Good practice for debugging CI/CD failures
        .statusCode(200)
        .body("id", equalTo(1045))
        .body("email", equalTo("customer@example.com"))
        .body("role", equalTo("PREMIUM_USER"))
        .body("data.preferences", hasItem("electronics")); // Validating JSON arrays
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}`&lt;/p&gt;

&lt;p&gt;REST-Assured empowers developers to write powerful, maintainable API tests right alongside their production Java code. By leveraging its baked-in functionalities, teams can avoid coding complex HTTP clients from scratch, ensuring their microservices remain robust, secure, and reliable with every deployment.&lt;/p&gt;

</description>
      <category>java</category>
      <category>restassured</category>
      <category>apitesting</category>
      <category>automation</category>
    </item>
    <item>
      <title>Mastering API Testing with Postman: A Real-World Automation Guide</title>
      <dc:creator>IKER ALBERTO SIERRA RUIZ</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:49:45 +0000</pubDate>
      <link>https://dev.to/ikers/mastering-api-testing-with-postman-a-real-world-automation-guide-24dk</link>
      <guid>https://dev.to/ikers/mastering-api-testing-with-postman-a-real-world-automation-guide-24dk</guid>
      <description>&lt;p&gt;In today’s fast-paced software development lifecycle, API testing is a non-negotiable part of any effective CI/DevOps process. It focuses on determining if your built APIs fulfill expectations for functionality, dependability, performance, and security. While there are many tools available, finding the right balance between usability and power is key.&lt;/p&gt;

&lt;p&gt;As highlighted in recent industry reviews of top API testing tools, Postman consistently ranks in the top three. Originally a simple Chrome browser plugin, it has evolved into a robust native application for Mac, Windows, and Linux. What makes Postman exceptional is its rich interface and low barrier to entry—you don't need an integrated development environment (IDE) or deep programming knowledge to start. Furthermore, it enables teams to easily share knowledge by packaging requests and expected responses into collections.&lt;/p&gt;

&lt;p&gt;Applying Postman: A Real-World Example&lt;br&gt;
Let’s look at a common real-world scenario: testing an authentication endpoint (/api/v1/login). We need to ensure that the API returns a 200 OK status and provides a valid JSON Web Token (JWT) that we can use for subsequent requests.&lt;/p&gt;

&lt;p&gt;In Postman, you can automate this validation using JavaScript in the "Tests" tab of your request:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Verify that the response status is 200 OK&lt;br&gt;
&lt;code&gt;pm.test("Status code is 200", function () {&lt;br&gt;
pm.response.to.have.status(200);&lt;br&gt;
});&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate that the response time is less than 500ms for performance&lt;br&gt;
&lt;code&gt;pm.test("Response time is acceptable", function () {&lt;br&gt;
pm.expect(pm.response.responseTime).to.be.below(500);&lt;br&gt;
});&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extract the token and set it as an environment variable for future requests&lt;br&gt;
`pm.test("Response contains JWT token", function () {&lt;br&gt;
var jsonData = pm.response.json();&lt;/p&gt;

&lt;p&gt;// Assert the token property exists&lt;br&gt;
pm.expect(jsonData).to.have.property('token');&lt;/p&gt;

&lt;p&gt;// Dynamically save the token to the environment&lt;br&gt;
pm.environment.set("jwt_token", jsonData.token);&lt;br&gt;
console.log("Token saved successfully for next API calls.");&lt;br&gt;
});`&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By utilizing Postman's built-in testing snippets and environment variables, testing teams can create automated, dynamic workflows without writing complex code from scratch. Whether you are doing exploratory testing or integrating with a CI/CD pipeline, Postman provides a reliable, user-friendly gateway to API quality assurance.&lt;/p&gt;

</description>
      <category>apitesting</category>
      <category>postman</category>
      <category>devops</category>
      <category>softwaretesting</category>
    </item>
  </channel>
</rss>
