java-api-app/
โโโ Jenkinsfile
โโโ Dockerfile
โโโ pom.xml
โโโ src/
โ โโโ main/
โ โ โโโ java/... # Application code
โ โโโ test/
โ โโโ java/... # Unit & integration tests
โโโ tests/
โ โโโ api/
โ โ โโโ postman_collection.json
โ โโโ security/
โ โโโ owasp-zap-baseline.conf
โโโ scripts/
โ โโโ generate-sbom.sh
โ โโโ run-trivy.sh
โ โโโ run-anchore.sh
โโโ README.md
pipeline {
agent any
environment {
REGISTRY = "registry.example.com/java-api"
IMAGE_TAG = "${env.BUILD_NUMBER}"
}
stages {
stage('Checkout') {
steps {
git 'https://github.com/example/java-api-app.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Unit Test') {
steps {
sh 'mvn test'
junit 'target/surefire-reports/*.xml'
}
}
stage('Code Quality - SonarQube') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'mvn sonar:sonar'
}
}
}
stage('Generate SBOM') {
steps {
sh './scripts/generate-sbom.sh'
archiveArtifacts artifacts: 'sbom/*.json', fingerprint: true
}
}
stage('Build Docker Image') {
steps {
sh 'docker build -t $REGISTRY:$IMAGE_TAG .'
}
}
stage('Image Scan - Trivy') {
steps {
sh './scripts/run-trivy.sh $REGISTRY:$IMAGE_TAG'
}
}
stage('Image Scan - Anchore/Snyk') {
steps {
sh './scripts/run-anchore.sh $REGISTRY:$IMAGE_TAG'
}
}
stage('Push Image') {
steps {
withCredentials([usernamePassword(credentialsId: 'docker-registry-creds', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
sh "echo $PASS | docker login -u $USER --password-stdin $REGISTRY"
sh 'docker push $REGISTRY:$IMAGE_TAG'
}
}
}
stage('API Tests') {
steps {
sh 'newman run tests/api/postman_collection.json --reporters cli,junit --reporter-junit-export target/api-test-results.xml'
junit 'target/api-test-results.xml'
}
}
}
post {
always {
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
publishHTML(target: [reportDir: 'target/site', reportFiles: 'index.html', reportName: 'Project Report'])
}
}
}FROM eclipse-temurin:17-jdk-alpine
WORKDIR /app
COPY target/java-api.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]#!/bin/bash
mkdir -p sbom
syft . -o cyclonedx-json > sbom/sbom.json#!/bin/bash
image=$1
mkdir -p trivy-reports
trivy image --severity HIGH,CRITICAL --format json --output trivy-reports/${image##*/}.json $image#!/bin/bash
image=$1
anchore-cli image add $image
anchore-cli image wait $image
anchore-cli image vuln $image all --json > anchore-${image##*/}.jsonapiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: container-must-have-owner
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
labels: ["owner"]- Deploy Falco DaemonSet in cluster:
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco- Example Rule: Alert on unexpected binary execution
- rule: Unexpected Binary Execution
desc: Detect execution of untrusted binaries
condition: spawned_process and proc.name in ("nc", "nmap", "curl")
output: "Untrusted binary executed (user=%user.name command=%proc.cmdline)"
priority: WARNING- SonarQube: Code smells, vulnerabilities, coverage
- JUnit: Unit + API test results
- SBOM: CycloneDX JSON artifacts
- Trivy/Anchore: Image CVE reports
- Falco: Runtime security events
- OPA: Admission audit logs
These artifacts should be archived per build and retained for minimum 6 years for CERT-IN.
- Sync Jenkins-deployed images to ArgoCD manifests using
kustomize edit set image - Use ArgoCD image updater plugin or webhook-based syncs