Thousands of findings and nobody reads the report; day-one global blocking and a company-wide allowlist three days later—usually not “missing a scanner,” but the wrong pacing.
This article is the schedule: SBOM → VEX → observe → “refuse download when checks fail.” Integration and policy fields: how to block vulns and licenses at admission. Ownership split: platform supply chain. Sample host repo.anguskit.com.
Product boundary:
- AngusRepo = in-repo policies, vuln desk, download enforcement; deep SCA / cross-repo findings belong to AngusSecurity.
- Without Security integration you rarely get a real vuln gate—do not pretend “upload means scanned.”
- Push/upload auto-check is off by default; “refuse download when checks fail” is off by default.
- Policies bind only to HOSTED / PROXY—not GROUP or Raw. Manual: security scanning.
Rule of thumb: See first (SBOM), discriminate next (VEX), observe before you enforce. In the console the switch is “refuse download when checks fail” (aka autoBlock below).
1. Two failure scripts, two fixes
| Failure | Symptom | Fix |
|---|---|---|
| Detection only | Reports pile up; prod still pulls old packages | Inventory + archive, then enforce |
| Over-enforcement | Company-wide pull 403 on day one |
Observe, clear FPs with VEX, open narrow |
Order of the trilogy: SBOM (see) → VEX (discriminate) → refuse download (stop). Shuffle it and you replay the table.
Division of labor vs the admission article: that one covers Security integration and policy fields; this one covers when to open each step and what to clear before blocking.
2. SBOM: give every artifact an inventory
An SBOM answers: what is actually inside this artifact?
After checks run, Security → scan history can export SBOM (CycloneDX / SPDX) for finished tasks. Right usage is not “generate and archive”—it is:
| Scenario | Practice |
|---|---|
| New CVE drops | Reverse-lookup against existing SBOM / scan indexes—minutes, not days |
| Compliance delivery | Archive SBOM with the release; export on audit |
| Release gate | Confirm SBOM retained before promote (see release practices) |
How scans are triggered (product-accurate)
| Trigger | Notes |
|---|---|
| Policy: check on push/upload | Off by default; opens a task for new HOSTED/PROXY artifacts |
| Policy: scheduled scan | Covers inventory; optional force-rescan for audit trail |
| Immediate scan | Console Security / repo Scan |
| Explicit pipeline wait | After publish, wait for the task before deploy |
No ready engine / no integration → no trustworthy vuln results. “Two lights” detail: admission article.
3. VEX: separate “has a CVE” from “should block”
Scanners cry wolf: a CVE anywhere in the tree turns red, reachable or not. Real threats drown in thousands of alerts; teams learn to ignore red.
In Repo Security → Vulnerabilities you can import VEX (standard OpenVEX JSON). Updates disposition by CVE + component (suppress FPs, mark unreachable, etc.). VEX does not replace a scan.
| Verdict (concept) | Follow-up |
|---|---|
| Not Affected / unreachable | Denoise alerts; keep rationale |
| Affected | Remediation queue; counts toward the gate if over threshold |
| Under Investigation | Deadline + owner |
Process rules:
- Named owner and SLA (e.g. Under Investigation ≤ 5 business days).
- Waivers live on the repo vuln desk—not scattered project
.ignore/ allowlists. - After the gate is on: console suppress / accept risk does not lift quarantine—fix and republish, or raise threshold and rescan (see the manual gate section).
4. “Refuse download when checks fail”: flip last
When on: failing artifacts are quarantined; download / preview / image pull denied (clients often see 403); bytes stay in the repo. Failed or incomplete checks also block. Multiple policies on one repo → strictest wins.
Canary pacing (never fleet-enable on day one)
- Preflight — engine/integration healthy; critical HOSTED baseline scanned; intel sync works.
- ~Two weeks observe — gate off, reports only; daily “what would have blocked”; clear via VEX / fixes.
- Narrow → wide — non-prod first; start at high severity; then prod.
- Escape hatch — emergency waiver (approval + TTL) rehearsed; a gate with no hatch gets bypassed wholesale.
After enabling, existing artifacts wait for the next check before quarantine—use Immediate scan on the policy for instant effect. Disable the gate with no other gating policy → quarantine immediately lifts.
Counterintuitive: a gate’s value is not block count, but fewer blocks after deterrence—upstream CI learns to self-check; block events should trend down.
5. Wire CI (AngusGit first)
Wait for the gate before deploy. Prefer AngusGit / AngusCICD (credentials = Repo Deploy Token). YAML intro: AngusCICD. Skeleton also in Jenkins build-test-publish.
# .anguscicd/publish-then-gate.yaml (sketch)
version: "1"
name: publish-then-gate
triggers:
- on: tag
branches: ["v*"]
pipeline:
publish:
runner:
mode: DOCKER
image: node:20
labels: ["linux", "docker"]
credentials: ["NPM_TOKEN"]
steps:
- name: publish HOSTED
run: |
npm config set //repo.anguskit.com/npm/npm-hosted/:_authToken "$NPM_TOKEN"
npm publish --access restricted
timeout: 600
# Wait for scan/gate: follow console policy and documented APIs
# Failure logs should be readable (CVE / policy), not a bare 403
CI pre-scan does not replace Repo enforcement on published coordinates.
6. Failure table
| Symptom | Likely cause | Fix |
|---|---|---|
| Upload OK but “never scanned” | No integration / auto-check off / engine not ready | Check Security link + policy |
| Fleet paralysis on enable | No observe, no VEX, prod first | Disable → observe → non-prod pilot |
| False 403 | Threshold too strict / FP not in VEX | Import VEX or retune + rescan |
| Old packages still pull after enable | Inventory not rescanned | Policy Immediate scan |
| “No vulns” treated as safe | Job never ran / LOCAL_ONLY | Scan history + integration status |
7. Landing checklist
- [ ] Security integration health check green (deep scan on)
- [ ] Critical HOSTED/PROXY have policies; GROUP/Raw not mis-bound
- [ ] Push auto-check or schedule covers new + existing
- [ ] Can export CycloneDX/SPDX; one CVE reverse-lookup drill done
- [ ] VEX import has owner/SLA; waivers not in project files
- [ ] “Refuse download” observe first, then non-prod
- [ ] Waiver path (approval + TTL) rehearsed ≥ once
- [ ] Pipelines deploy only after the gate passes
8. FAQ
How is this different from the admission article?
Admission covers integration + policy fields + verification; this article covers SBOM/VEX/enable pacing. Integrate first, then schedule here.
Does a successful upload mean it was scanned?
No. Auto-check is off by default; without integration, vuln tasks rarely appear.
Can suppress unlock download?
With “refuse download” on: no—suppress/accept risk does not lift quarantine. See the manual.
Can a GROUP repo enable the gate?
Policies cannot bind to GROUP. Put the gate on member HOSTED (or relevant PROXY).
9. Takeaways
- Order: SBOM → VEX → observe → refuse download when checks fail.
- Repo enforces; Security runs the engine; green upload ≠ scanned.
- Non-prod first, narrow first; rehearse the escape hatch.

Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.