wasviking-sentinel in CI/CD
Drop the same Go binary in your pipeline for SBOM, secrets, and policy-driven cloud scans. Three independent gates, one preflight, deterministic exit codes.
The same wasviking-sentinel binary that opens the mTLS tunnel also
runs as a one-shot tool in CI/CD pipelines. In a CI/CD context the
agent does not need to be registered (no mTLS bootstrap, no
certificates). It authenticates with an organization API key.
Three independent gates ship today, each a top-level subcommand:
| Subcommand | Gate | OWASP |
|---|---|---|
wasviking-sentinel sbom |
Vulnerable components (SCA). | A06 |
wasviking-sentinel secrets |
Hard-coded credentials. | A07 / CWE-798 |
wasviking-sentinel scan |
Cloud DAST, template-driven. | varies |
Each subcommand is documented in detail on its own page:
- wasviking-sentinel sbom
- wasviking-sentinel secrets
- (scan subcommand reference: see Cloud DAST below)
Quick start (GitHub Actions)
# .github/workflows/security.yml
- name: WASViking · SCA
run: ./wasviking-sentinel sbom --path . --fail-on high --submit
env:
WASV_API_KEY: ${{ secrets.WASVIKING_CI_KEY }}
- name: WASViking · Secrets
run: ./wasviking-sentinel secrets --path . --verify --submit
env:
WASV_API_KEY: ${{ secrets.WASVIKING_CI_KEY }}
- name: WASViking · Cloud DAST
run: ./wasviking-sentinel scan --template prod-web-strict --target https://staging.example.com
env:
WASV_API_KEY: ${{ secrets.WASVIKING_CI_KEY }}
Equivalent for GitLab, CircleCI, Jenkins, and Buildkite. Any Linux runner that can execute the binary works.
Authentication
export WASV_API_KEY=wv_live_xxxxxxxxxxxxxxxxxxxxxxxx
./wasviking-sentinel version
API keys are created in the portal under Settings → API Keys. The key needs the right scopes for what you actually do:
| Subcommand | Required scopes |
|---|---|
sbom (license check only) |
any active org key |
sbom --submit |
sca:submit |
secrets (license check only) |
any active org key |
secrets --submit |
secrets:submit |
scan |
scans:run, templates:read |
Use a dedicated CI key with only the scopes you need.
License check (preflight)
Every sbom, secrets, and CI-side scan invocation calls
POST /api/v1/sentinel/preflight before doing any work. The preflight
is mandatory: an empty or rejected API key blocks the run.
--api-key(or envWASV_API_KEY) is required, even when you are not submitting results.- Successful approvals cache at
~/.wasviking/preflight_cache.json(mode0600) for 30 minutes. - 24-hour grace window if the API is unreachable but a recent approval exists on disk.
- Active rejection (401 / 403) does not get the grace window: revoked keys block on the next cache expiration.
- Cache invalidates on key rotation (cache key is a truncated SHA-256 of the API key).
For the full preflight model, see the License check section on the sbom page.
SCA gate (sbom)
./wasviking-sentinel sbom \
--path . \
--app-name checkout-api \
--app-version "$CI_COMMIT_TAG" \
--fail-on high \
--submit
Behavior:
- Walk manifests under
--path(recursive). - Build a CycloneDX 1.5 SBOM.
- Enrich with OSV.dev advisories and CISA KEV.
- Apply
--fail-onpolicy. - If
--submit, POST to the WASViking API.
Exit codes:
| Exit code | Meaning |
|---|---|
| 0 | OK. No findings at or above --fail-on. |
| 1 | Generic failure (parse, IO, network). |
| 60 | OSV or KEV enrichment failed but SBOM produced. |
| 61 | Submission failed; SBOM is on disk. |
| 70 | Findings at or above the --fail-on threshold. |
Full flag reference: wasviking-sentinel sbom.
Secrets gate (secrets)
./wasviking-sentinel secrets \
--path . \
--git \
--verify \
--fail-on high \
--submit
Behavior:
- Walk the working tree under
--path. - With
--git, also walk the local git history. - Match against 32 detectors.
- With
--verify, probe provider identity endpoints (read-only) for the 10 detectors that support live verification. - Apply
--fail-onpolicy. - If
--submit, POST to the WASViking API (hash + masked preview; raw secrets never leave the host).
Exit codes:
| Exit code | Meaning |
|---|---|
| 0 | OK. No findings at or above --fail-on. |
| 1 | Generic failure. |
| 70 | Findings at or above the --fail-on threshold. |
Full flag reference: wasviking-sentinel secrets.
Cloud DAST gate (scan)
./wasviking-sentinel scan \
--template prod-web-strict \
--target https://staging.example.com
The scan subcommand triggers a cloud scan using an org-scoped scan
template. The template is resolved server-side, so secrets configured
in the template never reach the CI runner. The binary tracks the scan
to completion and exits with a policy-aware code.
Common exit codes:
| Exit code | Meaning |
|---|---|
| 0 | Scan completed, findings under the template's threshold. |
| 70 | Template not found. |
| 71 | Forbidden (key lacks the scope for this template). |
| 75 | Scan completed, findings exceeded the template's threshold. |
| 76 | Scan failed (engine error or timeout). |
| 77 | Org's concurrent-scan cap reached after the 60-second queue window. |
| 78 | Monthly metering exhausted. |
scan is the cloud counterpart of the local sbom and secrets
gates. It does not require the mTLS agent to be registered.
Concurrency and metering
For the scan subcommand, the platform enforces:
- A concurrent-scan cap per organization. When at the cap, the gate queues briefly (up to 60 seconds) and then either runs or returns exit 77.
- A monthly metering window. When the meter is exhausted, the gate returns exit 78.
Both events are surfaced in the portal's CI Usage tab.
What you should pin in CI
- Binary version. Distribute a specific signed release and verify with cosign before running.
- Template slug for
scan. Templates are versioned server-side; the slug always resolves to the active version of the template. - API key scopes. Use the minimum scope per pipeline stage.
--fail-onthresholds per pipeline lane (strict onmain, permissive on feature branches).
What this binary is NOT in CI mode
- It does not open the mTLS tunnel.
runis the tunneling mode;sbom,secrets, andscanare one-shot CI subcommands. - It does not call the portal's session login. The API key is the credential.
- It does not store findings locally beyond the SBOM / report
artifacts in
--out. Persistence is portal-side after--submit.
