Secrets, Dependency/Supply-Chain Signals, and Advanced Security Boundaries: Guided Hands-On Workflow
Run a disposable Community Build analysis with nonfunctional secret-shaped fixtures and a synthetic SARIF dependency signal, then prove which tool owns each state.
Learning objectives
- Create a disposable Community Build project containing only nonfunctional secret-shaped values and synthetic dependency metadata.
- Prove native secret-analysis scope from scanner/UI evidence before interpreting findings.
- Generate and import a valid SARIF 2.1.0 dependency-risk signal without pretending it is native Sonar SCA.
-
Preserve revision, report path, scanner logs,
ceTaskId, Compute Engine state, and native/external issue identity. - Map detection, inventory, remediation, rotation, and SBOM responsibilities to their owning systems.
- Clean up the project and revoke the disposable analysis token without touching shared resources.
1. Disposable lab contract
| Item | Lab value |
|---|---|
| SonarQube |
Community Build 26.9.0.129388 at
http://localhost:9000
|
| Scanner | SonarScanner CLI 8.1.0.6389 |
| Project key | sq-ch16-security-boundary |
| Source |
Tiny Python/config fixture + synthetic
requirements.txt
|
| Authentication |
Disposable project-analysis token in
SONAR_TOKEN
|
| SCA | No native SCA required; synthetic external dependency issue imported through SARIF |
| Commercial path | Optional only; no Advanced Security license is required |
2. Preflight: prove environment and create the disposable project first
export SONAR_HOST_URL="http://localhost:9000"
export SONAR_PROJECT_KEY="sq-ch16-security-boundary"
git --version
python --version
sonar-scanner --version
curl -fsS "$SONAR_HOST_URL/api/system/status"
# In the local SonarQube UI:
# 1) Create project sq-ch16-security-boundary.
# 2) Create a project-analysis token for that project.
# 3) Export it only into this shell; never commit it.
read -rsp "Disposable Sonar token: " SONAR_TOKEN; echo
export SONAR_TOKEN
Creating the project before the project-analysis token keeps the credential scope narrow. Routine analysis does not need a global administrator token.
3. Create fake-secret and dependency metadata fixtures
The AWS-looking strings below are widely used nonfunctional
documentation examples and contain the word EXAMPLE.
They are intentionally safe teaching material. If your current
secret rules do not flag them, inspect the active Secrets rules and
substitute another clearly nonfunctional pattern from the rule
documentation.
mkdir -p sq-ch16-security-boundary/{src,config,reports,evidence}
cd sq-ch16-security-boundary
git init
git config user.email "learner@example.invalid"
git config user.name "SonarQube Learner"
cat > src/app.py <<'PY'
import os
def cloud_region() -> str:
return os.environ.get("DEMO_REGION", "us-test-1")
PY
cat > config/demo.env <<'ENV'
# NONFUNCTIONAL documentation-style values for local secret-scanner training only.
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
ENV
cat > requirements.txt <<'REQ'
demo-web-framework==1.0.0
demo-parser==2.4.0
REQ
cat > sonar-project.properties <<'EOF'
sonar.projectKey=sq-ch16-security-boundary
sonar.projectName=SQ Chapter 16 Security Boundary Lab
sonar.sources=src,config,requirements.txt
sonar.sourceEncoding=UTF-8
sonar.text.inclusions=**/*.env,**/*.properties,requirements.txt
EOF
cat > .gitignore <<'EOF'
.scannerwork/
reports/
evidence/
EOF
git add src config requirements.txt sonar-project.properties .gitignore
git commit -m "chapter16 synthetic secret and dependency fixture"
git rev-parse HEAD | tee baseline-revision.txt
4. Run 1: native Community Build analysis only
mkdir -p evidence/native
sonar-scanner -X 2>&1 | tee evidence/native/scanner.log
cp .scannerwork/report-task.txt evidence/native/report-task.txt
TASK1="$(sed -n 's/^ceTaskId=//p' .scannerwork/report-task.txt)"
echo "$TASK1" | tee evidence/native/ce-task-id.txt
curl -fsS -H "Authorization: Bearer $SONAR_TOKEN" \
"$SONAR_HOST_URL/api/ce/task?id=$TASK1" \
| tee evidence/native/ce-task.json
Wait for terminal Compute Engine success before inspecting the
Issues view. Record whether either synthetic value matched a
currently active secret rule, the rule key, source line, issue
state, and the scanner evidence that
config/demo.env was included in text analysis.
5. Create a synthetic dependency-risk SARIF report
This report is deliberately fabricated and names no real CVE. Its only purpose is to exercise the ownership boundary.
cat > reports/dependency-demo.sarif <<'JSON'
{
"version": "2.1.0",
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"runs": [{
"tool": {
"driver": {
"name": "SyntheticDependencyAudit",
"version": "1.0.0",
"rules": [{
"id": "DEMO-DEPENDENCY-RISK-001",
"shortDescription": {"text": "Synthetic dependency advisory"},
"defaultConfiguration": {"level": "warning"}
}]
}
},
"results": [{
"ruleId": "DEMO-DEPENDENCY-RISK-001",
"level": "warning",
"message": {"text": "Synthetic training advisory for demo-parser==2.4.0; this is not a real CVE."},
"locations": [{
"physicalLocation": {
"artifactLocation": {"uri": "requirements.txt"},
"region": {"startLine": 2}
}
}]
}]
}]
}
JSON
python -m json.tool reports/dependency-demo.sarif > /dev/null
sha256sum reports/dependency-demo.sarif | tee evidence/sarif-sha256.txt
SARIF 2.1.0 requires UTF-8 and fields such as the tool name, rule ID, and result message. The checksum becomes part of the producer evidence.
6. Run 2: import the external dependency signal at the same source revision
git rev-parse HEAD | tee evidence/import-revision.txt
mkdir -p evidence/imported
sonar-scanner -X \
-Dsonar.sarifReportPaths=reports/dependency-demo.sarif \
2>&1 | tee evidence/imported/scanner.log
cp .scannerwork/report-task.txt evidence/imported/report-task.txt
TASK2="$(sed -n 's/^ceTaskId=//p' .scannerwork/report-task.txt)"
curl -fsS -H "Authorization: Bearer $SONAR_TOKEN" \
"$SONAR_HOST_URL/api/ce/task?id=$TASK2" \
| tee evidence/imported/ce-task.json
curl -fsS -H "Authorization: Bearer $SONAR_TOKEN" \
"$SONAR_HOST_URL/api/issues/search?componentKeys=$SONAR_PROJECT_KEY&ps=100" \
| tee evidence/imported/issues.json
The Git SHA should match Run 1. The changed analysis input is the
SARIF report path/content. After Compute Engine success, identify
the external issue and prove that its rule belongs to
SyntheticDependencyAudit rather than a Sonar quality
profile.
7. Prove what did not happen
| Observation | Correct conclusion | Incorrect conclusion |
|---|---|---|
| External dependency issue appears | SARIF producer evidence was imported successfully. | Community Build performed native SCA. |
requirements.txt exists |
Dependency metadata is present in the repository. | A complete transitive dependency graph exists. |
| No Dependencies/SBOM evidence on Community Build | Native Advanced Security SCA is outside this mandatory edition. | The scanner silently created an SBOM somewhere else. |
| Native secret issue appears | A source/config pattern matched a Sonar secret rule. | The owning credential has been rotated. |
8. Remove the fake hard-coded secret pattern and reanalyze
cat > config/demo.env <<'ENV'
# Safe configuration contract: runtime values are injected by the environment.
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
ENV
git add config/demo.env
git commit -m "remove synthetic hard-coded credentials"
git rev-parse HEAD | tee evidence/remediated-revision.txt
sonar-scanner -X \
-Dsonar.sarifReportPaths=reports/dependency-demo.sarif \
2>&1 | tee evidence/remediated-scanner.log
If a native secret issue was raised previously, correlate its post-analysis state to this new revision. Because the values were always fake, there is no real provider rotation step—but your governance note must state that a real incident would require immediate revocation/rotation before or alongside source cleanup.
9. Map each signal to its owning control
signal: native secret finding
inventory owner: SonarQube rule/profile
remediation owner: source team
real-credential lifecycle owner: external vault/provider/CI secret store
verification: source diff + provider revocation record (real incident) + reanalysis
signal: SyntheticDependencyAudit external issue
inventory/detection owner: SyntheticDependencyAudit (simulated external SCA)
remediation owner: dependency owner
SonarQube role: import/display/gate/governance surface
SBOM owner: external SCA/SBOM process unless licensed Sonar Advanced Security is actually used
10. Challenge: choose the missing layer
A team deletes a secret from Git and the Sonar issue disappears. The token was real and had been pushed to a shared remote. What must happen next?
Answer before revealing: the Git remediation proves only source state. The credential must be revoked/rotated in its issuing system, downstream consumers updated, exposure investigated, and the rotation/audit evidence retained. SonarQube cannot infer that lifecycle completion from the source diff.
Knowledge check
Why use the same Git SHA for the no-SARIF and SARIF runs?
It isolates the changed analysis input—the external report—so the new external issue can be attributed to the import rather than a source revision.
Where is an imported SARIF rule configured?
In the producing external tool. It is not a Sonar quality-profile rule.
Why are the AWS-looking strings acceptable in this lab?
They are explicit nonfunctional documentation examples used only to exercise detection; no real credential is created or exposed.
If Community Build shows an imported dependency issue, what native SCA evidence should you expect?
None merely from that import. Native dependency inventory/SCA/SBOM requires the relevant Advanced Security capability.
Why keep the SARIF SHA-256?
It identifies the exact external evidence consumed by the scan, improving reproducibility and auditability.
Official references and version notes
- SonarQube downloads / feature comparison — current Community Build 26.9.0.129388; basic secret detection in Community Build; broader commercial secret/security features.
- Community Build — Secrets — secret scope, text inclusions, file processing, and Community limitation on custom patterns.
- SonarQube Server — Secrets — current server secret configuration and custom secret-pattern behavior; custom patterns start in Enterprise edition.
- About external issues — imported-rule ownership and the fact that Sonar issue workflow changes do not update the external producer.
-
SARIF reports
— SARIF 2.1.0 requirements and
sonar.sarifReportPaths. - SonarQube Advanced Security — Enterprise-edition-and-above add-on boundary.
- Analyzing projects for dependencies (SCA) — native dependency-risk analysis prerequisites, build-environment implications, and licensing.
- Viewing dependencies / SBOM — native dependency inventory and SBOM evidence when Advanced Security is licensed.
- SonarScanner CLI 8.1.0.6389 — scanner baseline used by the local path.
Rechecked 2026-09-08. Mandatory examples target SonarQube Community Build 26.9.0.129388 and SonarScanner CLI 8.1.0.6389. Commercial reference streams are SonarQube Server 2026 Release 4.1 and 2026.1.5 LTA. Community Build currently provides basic secrets detection and SARIF/generic external-issue import. Current product packaging expands secret coverage in commercial Server editions, while organization-specific custom secret patterns start in Enterprise edition. SonarQube Advanced Security SCA is a Server add-on starting in Enterprise edition; native dependency inventory/risk/SBOM evidence must not be claimed on Community Build merely because a manifest exists or a SARIF dependency issue was imported. Recheck secret rules, text inclusion defaults, external-report schema, supported package managers/languages, and license entitlements before automating another release.
SonarQube product names, editions, release trains, scanner runtimes, APIs, authentication options, and platform prerequisites can change independently. Re-check the linked SonarSource primary documentation for the exact target release before applying version-sensitive commands or operational guidance outside the disposable course environment.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.