Reusable workflow for comprehensive security scanning on pull requests. Supports single app repositories and monorepos with automatic detection of changed components.
- Secret scanning: Trivy filesystem scan for exposed secrets (scans only changed component folder)
- Vulnerability scanning: Docker image vulnerability detection (optional)
- CLI/Non-Docker support: Skip Docker scanning for projects without Dockerfile via
enable_docker_scan: false - Monorepo support: Automatic detection of changed components
- Component-scoped scanning: Only scans the specific component folder that changed, not entire repo
- Multiple architectures: Type 1 and Type 2 monorepo patterns
- SARIF output: Security results in standard format
- Fail-fast on secrets: Workflow fails if secrets are detected
- Docker Hub login: Avoid rate limits during scans
- Slack notifications: Automatic success/failure notifications
Scans entire repository when filter_paths is not provided.
Components in separate folders with individual Dockerfiles:
project/
├── components/
│ ├── onboarding/
│ │ └── Dockerfile
│ ├── transaction/
│ │ └── Dockerfile
│ └── console/
│ └── Dockerfile
Backend in root with frontend in separate folder:
project/
├── Dockerfile # Backend
├── api/
├── cmd/
├── internal/
└── frontend/
└── Dockerfile # Frontend
name: PR Security Scan
on:
pull_request:
branches: [develop, release-candidate, main]
jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
dockerhub_org: "lerianstudio"
secrets: inheritname: PR Security Scan
on:
pull_request:
branches: [develop, release-candidate, main]
jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
filter_paths: |-
components/onboarding
components/transaction
components/console
path_level: "2"
dockerhub_org: "lerianstudio"
secrets: inheritname: PR Security Scan
on:
pull_request:
branches: [develop, release-candidate, main]
jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
filter_paths: |-
frontend
cmd
internal
api
pkg
.
path_level: "1"
monorepo_type: "type2"
frontend_folder: "frontend"
dockerhub_org: "lerianstudio"
secrets: inheritFor projects without a Dockerfile (e.g., CLI tools), disable Docker scanning to only run filesystem secret scanning:
name: PR Security Scan
on:
pull_request:
branches: [develop, release-candidate, main]
jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
enable_docker_scan: false
secrets: inheritThis will:
- ✅ Run Trivy filesystem secret scanning
- ❌ Skip Docker image build
- ❌ Skip Docker vulnerability scanning
- ❌ Skip Docker Scout analysis
Enable Docker Scout for additional vulnerability scoring and CVE analysis on your Docker images:
name: PR Security Scan
on:
pull_request:
branches: [develop, release-candidate, main]
jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
enable_docker_scout: true
secrets: inheritThis will run all standard scans plus Docker Scout quickview and CVE analysis.
Requirements:
- Docker Hub account with Scout access (Free, Team, or Business)
DOCKER_USERNAMEandDOCKER_PASSWORDsecrets configuredenable_docker_scanmust also betrue(default) — Scout reuses the same image built for Trivy scanning
| Input | Type | Default | Description |
|---|---|---|---|
runner_type |
string | blacksmith-4vcpu-ubuntu-2404 |
GitHub runner type |
filter_paths |
string | - | Paths to monitor (newline separated). If empty, treats as single app |
path_level |
string | 2 |
Directory depth level to extract app name (monorepo only) |
monorepo_type |
string | type1 |
Monorepo type: type1 or type2 |
frontend_folder |
string | frontend |
Frontend folder name for type2 monorepos |
dockerhub_org |
string | lerianstudio |
DockerHub organization name |
docker_registry |
string | docker.io |
Docker registry URL |
dockerfile_name |
string | Dockerfile |
Name of the Dockerfile |
enable_docker_scan |
boolean | true |
Enable Docker image build and vulnerability scanning. Set to false for projects without Dockerfile (e.g., CLI tools) |
enable_docker_scout |
boolean | false |
Enable Docker Scout image analysis for vulnerability scoring. Requires Docker Hub with Scout access |
| Secret | Description |
|---|---|
docker_username |
Docker registry username |
docker_password |
Docker registry password |
| Secret | Description | Required When |
|---|---|---|
manage_token |
GitHub token for private repositories | Building images that need private repo access |
permissions:
id-token: write # Required for OIDC authentication
contents: read # Required to checkout the repository
pull-requests: write # Allows commenting on PRs
security-events: write # Required for security scanning- Docker Login: Authenticate to avoid rate limits
- Get Changed Paths: Detect which components changed (monorepo only)
- Set Matrix: Build matrix of components to scan
For each component in the matrix:
- Docker Login: Authenticate to registry (avoids rate limits)
- Checkout Repository: Clone the code
- Setup Docker Buildx: Enable multi-platform builds (skipped if
enable_docker_scan: false) - Trivy Secret Scan (Table): Scan filesystem for secrets - fails on detection
- Trivy Secret Scan (SARIF): Generate SARIF report
- Build Docker Image: Build image for vulnerability scanning (skipped if
enable_docker_scan: false) - Trivy Vulnerability Scan (Table): Scan image for vulnerabilities (skipped if
enable_docker_scan: false) - Trivy Vulnerability Scan (SARIF): Generate SARIF report (skipped if
enable_docker_scan: false) - Docker Scout Analysis: Quickview and CVE analysis (skipped unless
enable_docker_scout: trueANDenable_docker_scan: true)
Note: When
enable_docker_scan: false, only filesystem secret scanning runs. This is useful for CLI tools and projects without Dockerfiles.
What it does: Scans repository filesystem for exposed secrets (API keys, tokens, passwords)
Severity: CRITICAL - workflow fails if secrets are found
Skipped directories:
.gitnode_modulesdistbuild.nextcoveragevendor
Exit behavior: exit-code: 1 (fails workflow)
What it does: Scans Docker image for known vulnerabilities
Severity levels: CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN
Vulnerability types:
- OS packages
- Application libraries
Exit behavior: exit-code: 0 (informative only, doesn't fail workflow)
Any changes to backend folders (api, cmd, internal, pkg, .) are consolidated to root:
{
"name": "repository-name",
"working_dir": "."
}Frontend changes are kept separate:
{
"name": "repository-name-frontend",
"working_dir": "frontend"
}Changes to .github and .githooks are ignored in Type 2 monorepos.
on:
pull_request:
branches: [develop, release-candidate, main]with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"secrets: inheritThis passes all repository secrets to the workflow automatically.
Type 1 Monorepo (components in folders):
with:
path_level: "2" # components/onboarding → onboardingType 2 Monorepo (backend in root):
with:
path_level: "1" # api → api, frontend → frontendInclude all directories that should trigger scans:
with:
filter_paths: |-
api
cmd
internal
pkg
frontend
.Issue: Security scan doesn't run on PR
Solutions:
- Check if changed paths match
filter_paths - Verify PR targets correct branch
- Check workflow permissions
Issue: Cannot build Docker image
Solutions:
- Provide
manage_tokenfor private dependencies - Check Dockerfile path
- Verify Docker registry credentials
Issue: Docker Hub rate limit (429 errors)
Solution: Workflow includes automatic Docker login to avoid rate limits. Ensure docker_username and docker_password secrets are set.
Issue: Scan detects test secrets or examples
Solutions:
- Move test secrets to
.env.examplefiles - Use placeholder values in documentation
- Add comments to indicate test data
Issue: All components scanned instead of only changed ones
Solution: Verify filter_paths configuration matches your repository structure.
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
dockerhub_org: "mycompany"
docker_registry: "ghcr.io"
secrets: inheritNote: For GitHub Container Registry (ghcr.io), ensure
DOCKER_USERNAMEandDOCKER_PASSWORDsecrets are configured appropriately.
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
filter_paths: |-
services/auth
services/payment
services/notification
services/user
path_level: "2"
monorepo_type: "type1"
secrets: inheritsecurity-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
filter_paths: |-
web
api
cmd
internal
.
path_level: "1"
monorepo_type: "type2"
frontend_folder: "web"
secrets: inheritname: Pull Request Checks
on:
pull_request:
branches: [develop, release-candidate, main]
permissions:
id-token: write
contents: read
pull-requests: write
security-events: write
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run linters
run: make lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: make test
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.0.0
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
filter_paths: |-
components/onboarding
components/transaction
path_level: "2"
secrets: inheritDisplayed in workflow logs for quick review:
┌─────────────────────────────────────────────────────────────┐
│ Trivy Secret Scan Results │
├─────────────────────────────────────────────────────────────┤
│ No secrets found │
└─────────────────────────────────────────────────────────────┘
Generated for each scan type:
trivy-secret-scan-repo-{app-name}.sariftrivy-vulnerability-scan-docker-{app-name}.sarif
Can be uploaded to GitHub Security tab (currently commented out in workflow).
- GitOps Update - Update deployments after security checks pass
- API Dog E2E Tests - Run E2E tests after security validation
- Release Workflow - Create releases after all checks pass