{"id":32005,"date":"2026-08-18T17:47:49","date_gmt":"2026-08-18T12:17:49","guid":{"rendered":"https:\/\/opstree.com\/blog\/?p=32005"},"modified":"2026-08-18T17:47:49","modified_gmt":"2026-08-18T12:17:49","slug":"production-ready-devsecops-pipeline","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/production-ready-devsecops-pipeline\/","title":{"rendered":"Building a Production-Ready DevSecOps Pipeline with Jenkins, Trivy and GitHub Integration"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>In modern DevOps workflows, security is a fundamental requirement. Organizations expect visibility of vulnerabilities, exposed secrets, and code quality directly within GitHub, especially during Pull Request reviews.<\/p>\n<p>While GitHub provides native security capabilities, these features may not always be available or enabled across all environments.<\/p>\n<p>This raises an important question:<\/p>\n<p>Can we build a <a href=\"https:\/\/opstree.com\/blog\/how-to-build-a-successful-devsecops-pipeline\/\" target=\"_blank\" rel=\"noopener\">production-ready DevSecOps pipeline<\/a> using open-source tools while still maintaining visibility inside GitHub?<\/p>\n<p>In this article, I walk through how I implemented an end-to-end DevSecOps pipeline using Jenkins, Gitleaks, and Trivy, and integrated the results into GitHub through Pull Request comments, commit status checks, and security reporting.<\/p>\n<h2>Architecture Overview<\/h2>\n<p>The workflow is designed as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-32011\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart-1024x512.png\" alt=\"\" width=\"1024\" height=\"512\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart-1024x512.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart-300x150.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart-768x384.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart-1536x768.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/Flow-chart.png 1774w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>This setup enables:<\/p>\n<ul>\n<li>Automated security scanning during CI<\/li>\n<li>Visibility directly in Pull Requests<\/li>\n<li>Structured reporting and feedback for developers<\/li>\n<\/ul>\n<h2>Tools Used<\/h2>\n<ul>\n<li>Jenkins (CI\/CD orchestration)<\/li>\n<li>Gitleaks (secret detection)<\/li>\n<li>Trivy (vulnerability scanning)<\/li>\n<li>GitHub CLI (<code>gh<\/code>) for API interaction<\/li>\n<li>Jenkins HTML Publisher Plugin (for report visualization)<\/li>\n<\/ul>\n<div style=\"border: 1px solid #d1d5db; padding: 16px; margin: 20px 0; background-color: #f0f4f8;\">\n<p style=\"margin: 0; font-weight: 600; font-size: 16px;\">Also Read: <a href=\"https:\/\/buildpiper.io\/blogs\/jenkins-alternatives-for-cost-effective-ci-cd-platforms\/\" target=\"_blank\" rel=\"noopener\">Jenkins Alternatives in 2026<\/a><\/p>\n<\/div>\n<p><!-- notionvc: 8089e297-426e-4359-a43e-1f43724256be --><\/p>\n<h2>Pipeline Workflow<\/h2>\n<p>The pipeline is structured into the following stages:<\/p>\n<ol>\n<li>Checkout source code from GitHub<\/li>\n<li>Run Gitleaks for secret detection<\/li>\n<li>Run Trivy for vulnerability scanning<\/li>\n<li>Generate reports in JSON, SARIF, and HTML formats<\/li>\n<li>Publish HTML reports in Jenkins UI<\/li>\n<li>Create a summarized Pull Request comment<\/li>\n<li>Upload SARIF reports for <a href=\"https:\/\/opstree.com\/blog\/how-github-advanced-security-solves-modern-devsecops-challenges\/\" target=\"_blank\" rel=\"noopener\">GitHub security<\/a> visibility<\/li>\n<li>Update commit status based on scan results<\/li>\n<\/ol>\n<p><!-- notionvc: b6194333-558e-49e9-8a34-7b92d401be7f --><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-32006\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77-1024x231.png\" alt=\"\" width=\"1024\" height=\"231\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77-1024x231.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77-300x68.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77-768x173.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77-1536x347.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-77.png 1829w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<h2>Key Features Implemented<\/h2>\n<ul>\n<li>Secret scanning using Gitleaks<\/li>\n<li>Vulnerability scanning using Trivy<\/li>\n<li>HTML reports accessible within Jenkins<\/li>\n<li>Automated Pull Request comments with scan summaries<\/li>\n<li>Commit status checks indicating success or failure<\/li>\n<li>Integration with GitHub security reporting using SARIF<\/li>\n<\/ul>\n<p><!-- notionvc: beca733d-1635-41fc-8a69-272a454a59f5 --><\/p>\n<h2>Challenges and Solutions<\/h2>\n<p>This implementation involved several practical challenges.<\/p>\n<h3>1. Jenkins Detached HEAD Issue<\/h3>\n<p><a href=\"https:\/\/opstree.com\/blog\/a-guide-to-jenkins-high-availability-and-disaster-recovery-in-ci-cd\/\" target=\"_blank\" rel=\"noopener\">Jenkins<\/a> checks out code in detached HEAD mode, which prevents direct branch detection.<\/p>\n<p><strong>Problem:<\/strong><\/p>\n<p><!-- notionvc: 5a2f1caf-a414-44a5-81bb-767df6c13e53 --><\/p>\n<div style=\"margin: 20px 0;\">\n<pre style=\"background: #1e1e1e !important; color: #d4d4d4 !important; padding: 18px; border-radius: 8px; overflow-x: auto; font-family: Consolas,'Courier New',monospace; font-size: 14px; line-height: 1.6;\"><code style=\"background: transparent !important; color: inherit !important; padding: 0 !important; border: none !important;\">git rev-parse --abbrev-ref HEAD \u2192 HEAD<\/code><\/pre>\n<\/div>\n<p><strong>Solution:<\/strong><\/p>\n<p>The default branch was dynamically extracted using:<\/p>\n<p><!-- notionvc: 1502e8fa-ff18-4dfb-9aff-de037eba7bcd --><\/p>\n<div style=\"margin: 20px 0;\">\n<pre style=\"background: #1e1e1e !important; color: #d4d4d4 !important; padding: 18px; border-radius: 8px; overflow-x: auto; font-family: Consolas,'Courier New',monospace; font-size: 14px; line-height: 1.6;\"><code style=\"background: transparent !important; color: inherit !important; padding: 0 !important; border: none !important;\">git remote show origin | grep 'HEAD branch'<\/code><\/pre>\n<\/div>\n<h3>2. SARIF Upload Failure<\/h3>\n<p>Initial attempts to upload SARIF reports to GitHub resulted in API errors.<\/p>\n<p><strong>Root cause:<\/strong><\/p>\n<p>The GitHub API expects SARIF data to be compressed and encoded.<\/p>\n<p><strong>Solution:<\/strong><\/p>\n<ul>\n<li>SARIF files were compressed using gzip<\/li>\n<li>Encoded using base64<\/li>\n<li>Uploaded using <a href=\"https:\/\/opstree.com\/blog\/ci-cd-with-github-actions-concepts\/\" target=\"_blank\" rel=\"noopener\">GitHub API<\/a><\/li>\n<\/ul>\n<h3>3. Missing commit_sha and ref<\/h3>\n<p>The SARIF upload API requires explicit commit and branch references.<\/p>\n<p><strong>Solution:<\/strong><\/p>\n<p><!-- notionvc: 0793b909-7e67-4279-8810-bd0c77aa1071 --><\/p>\n<div style=\"margin: 20px 0;\">\n<pre style=\"background: #1e1e1e !important; color: #d4d4d4 !important; padding: 18px; border-radius: 8px; overflow-x: auto; font-family: Consolas,'Courier New',monospace; font-size: 14px; line-height: 1.6;\"><code style=\"background: transparent !important; color: inherit !important; padding: 0 !important; border: none !important;\">commit_sha = $GIT_COMMIT\r\nref = refs\/heads\/&lt;branch&gt;<\/code><\/pre>\n<\/div>\n<h3>4. Private Repository Limitation<\/h3>\n<p>SARIF uploads failed when using private repositories or restricted organizational environments.<\/p>\n<p><strong>Learning:<\/strong><\/p>\n<p>GitHub security reporting using SARIF is not always available in private repositories or organization-level setups without additional configuration or subscription.<!-- notionvc: e6ddcb07-ac4a-49b0-81cb-13c0f714bf4e --><\/p>\n<h2>Working with Private and Organization Repositories<\/h2>\n<p>While full SARIF-based integration works smoothly with public repositories, limitations arise when working with private repositories or organization environments.<\/p>\n<p>In such scenarios, direct integration with the GitHub Security dashboard may not be available.<\/p>\n<h3>Temporary Workaround<\/h3>\n<p>To maintain visibility without relying on platform-specific features, an alternative approach was implemented:<\/p>\n<ul>\n<li>Security scan results were summarized and posted as Pull Request comments<\/li>\n<li>Commit status checks were updated based on scan outcomes<\/li>\n<li>Jenkins HTML reports provided detailed insights<\/li>\n<\/ul>\n<p>This ensured that:<\/p>\n<ul>\n<li>Developers continued to receive immediate feedback in Pull Requests<\/li>\n<li>Security issues remained visible during code reviews<\/li>\n<li>The workflow maintained enforcement of security checks<\/li>\n<\/ul>\n<p>Although this approach does not provide native dashboard-level visibility, it serves as a practical and effective solution in constrained environments.<\/p>\n<p><!-- notionvc: 7ac66dad-7e00-447a-8acd-93e5d620edf8 --><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-32007\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79-1024x440.png\" alt=\"\" width=\"1024\" height=\"440\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79-1024x440.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79-300x129.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79-768x330.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79-1536x660.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-79.png 1827w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<h2>Final Output<\/h2>\n<p>After successful pipeline execution:<\/p>\n<h3>Jenkins<\/h3>\n<ul>\n<li>HTML reports for Trivy and Gitleaks<\/li>\n<li>Centralized visibility of scan results<\/li>\n<\/ul>\n<h3>GitHub Pull Request<\/h3>\n<ul>\n<li>Automated comments summarizing findings<\/li>\n<li>Commit status indicating pass or failure<\/li>\n<\/ul>\n<h3>GitHub Security Visibility<\/h3>\n<ul>\n<li>Structured security reporting using SARIF (where supported)<\/li>\n<\/ul>\n<p><!-- notionvc: c7da980a-da7e-4093-b73c-315fadf3a993 --><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-32008\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80-1024x513.png\" alt=\"\" width=\"1024\" height=\"513\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80-1024x513.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80-300x150.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80-768x385.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80-1536x770.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/image-80.png 1819w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<h2>Cost Comparison<\/h2>\n<div style=\"overflow-x: auto; margin: 25px 0;\">\n<table style=\"width: 100%; border-collapse: collapse; min-width: 600px; font-family: Arial,Helvetica,sans-serif; font-size: 14px;\">\n<thead>\n<tr style=\"background: #f5f7fa;\">\n<th style=\"border: 1px solid #ddd; padding: 12px; text-align: left;\">Approach<\/th>\n<th style=\"border: 1px solid #ddd; padding: 12px; text-align: left;\">Cost<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 12px;\">Platform-native security features<\/td>\n<td style=\"border: 1px solid #ddd; padding: 12px;\">Paid<\/td>\n<\/tr>\n<tr style=\"background: #fafafa;\">\n<td style=\"border: 1px solid #ddd; padding: 12px;\">Jenkins with open-source tools<\/td>\n<td style=\"border: 1px solid #ddd; padding: 12px;\">Free<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>This approach demonstrates that similar DevSecOps capabilities can be achieved using open-source tools with proper integration.<\/p>\n<h2>Key Learnings<\/h2>\n<ul>\n<li>DevSecOps is primarily about integration rather than individual tools<\/li>\n<li>GitHub APIs require strict formatting, especially for SARIF uploads<\/li>\n<li>Jenkins pipelines do not provide GitHub context by default and must be handled explicitly<\/li>\n<li><a href=\"https:\/\/opstree.com\/opstree-open-source\/\" target=\"_blank\" rel=\"noopener\">Open-source tools<\/a> can achieve production-grade outcomes when integrated correctly<\/li>\n<\/ul>\n<p><!-- notionvc: efe2aa4a-ddb4-4680-8cac-dd590006a18c --><\/p>\n<h2>Conclusion<\/h2>\n<p>This implementation demonstrates how a production-ready DevSecOps pipeline can be built using open-source tools while maintaining strong visibility within the development workflow.<\/p>\n<p>By integrating Jenkins, Gitleaks, Trivy and GitHub APIs, we achieved:<\/p>\n<ul>\n<li>Automated security scanning<\/li>\n<li>Developer feedback in Pull Requests<\/li>\n<li>Structured reporting<\/li>\n<li><a href=\"https:\/\/opstree.com\/services\/cloud-migration-and-modernization-services\/\" target=\"_blank\" rel=\"noopener\">Cost-effective implementation<\/a><\/li>\n<\/ul>\n<p><!-- notionvc: 9d3b6322-bd00-4540-909e-1ea9247baa8c --><\/p>\n<h2>Final Note<\/h2>\n<p>This was not a straightforward implementation. It required iterative debugging, handling API constraints, and understanding how GitHub processes security data.<\/p>\n<p>However, this process resulted in a practical, scalable, and production-relevant <a href=\"https:\/\/opstree.com\/services\/devops-and-devsecops-services\/\" target=\"_blank\" rel=\"noopener\">DevSecOps solution<\/a>.<\/p>\n<h2>Related Searches<\/h2>\n<ul>\n<li><a href=\"https:\/\/opstree.com\/blog\/data-integration-with-azure-event\/\" target=\"_blank\" rel=\"noopener\">Modernizing Healthcare Data Integration with Azure Event Hubs \u2013 OpsTree<\/a><\/li>\n<li><a href=\"https:\/\/opstree.com\/blog\/azure-event-hubs-real-time-streaming\/\" target=\"_blank\" rel=\"noopener\">Azure Event Hubs Explained for Real Time Data Streaming<\/a><\/li>\n<li><a href=\"https:\/\/opstree.com\/blog\/event-hub-vs-confluent-cloud\/\" target=\"_blank\" rel=\"noopener\">Event Hub vs Confluent Cloud: Which One Should You Use and When?<\/a><\/li>\n<\/ul>\n<h2>Related Solutions<\/h2>\n<ul>\n<li><a href=\"https:\/\/opstree.com\/services\/database-and-data-engineering\/\" target=\"_blank\" rel=\"noopener\">Data Engineering Solutions<\/a><\/li>\n<li><a href=\"https:\/\/opstree.com\/services\/cloud-migration-and-modernization-services\/\" target=\"_blank\" rel=\"noopener\">Cloud Migration Services<\/a><\/li>\n<li><a href=\"https:\/\/opstree.com\/blog\/data-engineering-companies\/\" target=\"_blank\" rel=\"noopener\">Data Engineering Services and Solutions companies<\/a><\/li>\n<\/ul>\n<p><!-- notionvc: fba6a471-56be-4c7b-b191-6316dd6af369 --><\/p>\n<p><!-- notionvc: 55738c31-0e4c-4e2f-854a-29f70110e17f --><\/p>\n<p><!-- notionvc: 417d8d4a-3cf9-4584-a69d-caab2017108b --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In modern DevOps workflows, security is a fundamental requirement. Organizations expect visibility of vulnerabilities, exposed secrets, and code quality directly within GitHub, especially during Pull Request reviews. While GitHub provides native security capabilities, these features may not always be available or enabled across all environments. This raises an important question: Can we build a [&hellip;]<\/p>\n","protected":false},"author":244582727,"featured_media":32012,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[768739629],"tags":[768739654,768739700,5603054,768739299],"class_list":["post-32005","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devsecops","tag-devsecops-consulting-services","tag-devsecops-pipeline","tag-github","tag-jenkins"],"blocksy_meta":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/08\/COVER-IMAGE.png","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-8kd","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/32005","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/244582727"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=32005"}],"version-history":[{"count":4,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/32005\/revisions"}],"predecessor-version":[{"id":32015,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/32005\/revisions\/32015"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/32012"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=32005"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=32005"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=32005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}