DVSentry Documentation API referenceOpen the app

The dvsentry.py command-line client

dvsentry.py is one file, Python 3.9+, standard library only, so any CI runner or laptop can use it. Download it from DVSentry:

curl -fsSo dvsentry.py https://app.dvsentry.com/downloads/dvsentry.py
python3 dvsentry.py --version

It has two halves:

Configuration

Configuration comes from the environment only, so the token never appears in a process list or a CI log:

VariableValue
DVSENTRY_URLhttps://app.dvsentry.com (plain http:// only for localhost)
DVSENTRY_TOKENA personal access or service account token
DVSENTRY_TOKEN_FILEOr a file holding the token

Use a token with only the scopes the job needs (API and tokens).

Commands

CommandCallsScopes
whoamiGET /v1/auth/meany
repositories [--limit N --offset N]GET /v1/repositoriesrepositories:read
scan --repository-id ID --scanner S [--scanner S2 ...]POST /v1/security-reports, waits, then gatesscans:trigger, scans:read, gates:read
wait REPORT_IDPolls the report, then gatesscans:read, gates:read
gate REPORT_IDGET /v1/security-reports/{id}/ci-resultgates:read
findings REPORT_ID [--severity high] [--limit --offset]GET /v1/security-reports/{id}/findingsfindings:read
cancel REPORT_IDPOST /v1/security-reports/{id}/cancelscans:trigger
local [PATH]Nothing (offline)none
install-hookNothing (writes .git/hooks/pre-commit)none

Every command takes --json to print the API's JSON instead of text.

scan options

OptionDefaultMeaning
--repository-idrequiredThe DVSentry repository id (repositories lists them)
--scannerrequired, repeatableScanner ids, for example semgrep-local, gitleaks, osv-dependencies, trivy-filesystem, syft-sbom
--refthe repository's defaultBranch, tag or commit; pass the CI commit SHA
--path.Path inside the repository; repeat for several
--environmentdevelopmentdevelopment, staging or production (policies can differ per environment)
--strategyfullfull or incremental
--nameCI scanReport name
--scan-timeout600The scanners' own time budget in seconds (the server raises it to each scanner's floor)
--idempotency-keya new UUIDPin it to the CI build id so a retried step returns the same scan
--no-waitoffQueue the scan and exit 0
--timeout1800Seconds to wait for the scan
--poll-interval10Seconds between checks

A server-side --scanner smart / full profile is planned (it needs a new API field) and not on main yet; list scanners explicitly for now.

Exit codes

CodeMeaning
0The policy gate passed (or --no-wait)
1The policy gate failed
2The scan did not finish: error, cancelled, or still running at --timeout
3Usage or configuration error
4The API refused the request or could not be reached

The POST is retried safely thanks to the idempotency key; reads are retried on 429/502/503/504. Redirects are never followed, so the token cannot be carried to another host.

Example

$ export DVSENTRY_URL=https://app.dvsentry.com DVSENTRY_TOKEN_FILE=~/.dvsentry-token
$ python3 dvsentry.py repositories
3f0c5a1e-...  payments  https://github.com/acme/payments
1 of 1 repositories
$ python3 dvsentry.py scan --repository-id 3f0c5a1e-... \
    --scanner semgrep-local --scanner gitleaks --scanner osv-dependencies \
    --ref "$(git rev-parse HEAD)" --environment production
queued report 9a1e...
report 9a1e...: running (40%)
report 9a1e...: completed (100%)
FAIL: 1 policy rule(s) were violated.
  - Production release bar: 3 active finding(s) meet or exceed the HIGH threshold.
$ echo $?
1
$ python3 dvsentry.py findings 9a1e... --severity high

Local scan: nothing uploaded

local runs the scanners already installed on your machine, offline, and prints what they found. It makes no network call, needs no URL or token, strips DVSENTRY_* variables from the scanners' environment, and never prints a secret's value.

python3 dvsentry.py local .                              # every installed scanner
python3 dvsentry.py local --scanner gitleaks .           # one scanner
python3 dvsentry.py local --semgrep-config rules/ .      # Semgrep only ever uses rules you point it at
python3 dvsentry.py local --staged .                     # only what is staged for commit (secrets)
python3 dvsentry.py local --fail-on critical --json .    # machine-readable, fail only on critical
ScannerRunsOffline because
gitleaksdetect --no-git (protect --staged with --staged), --redactit never calls out
trivyfs --skip-db-update --offline-scan --scanners vuln,misconfigit uses the cached database only; with no database it is reported as failed
semgrepscan --metrics off --disable-version-check --config <yours>only with --semgrep-config; registry rules are never fetched

A scanner that is not installed, times out (--scanner-timeout, 600 s) or fails is listed as skipped with the reason. Exit codes: 0 nothing at or above --fail-on (default high), 1 something is, 2 no scanner ran, 3 usage error.

Pre-commit hook

python3 dvsentry.py install-hook                  # writes .git/hooks/pre-commit running `local --staged`
python3 dvsentry.py install-hook --fail-on medium --force
git commit --no-verify                            # skip it once

It refuses to replace a hook it did not write unless --force.

IDE extension

The VS Code extension (extensions/vscode/ in the repository) shows the open findings of the repository you have open, and runs dvsentry.py local. It is read only: it can never start a scan or change a finding.

  1. Set dvsentry.serverUrl (default https://app.dvsentry.com).
  2. Run DVSentry: Sign in. The editor shows an eight-letter code and opens /ide/activate.
  3. In the browser, check the code, pick the organization and approve (with your MFA code if you use MFA).

The editor receives a token with the single scope ide:read, for one organization, for 30 days, kept in VS Code's SecretStorage and listed under Settings → Personal access tokens. Build and install it from the folder:

cd extensions/vscode && npx @vscode/vsce package && code --install-extension dvsentry-0.1.0.vsix

The extension is not published to the VS Code Marketplace; JetBrains IDEs are not supported.

Something missing or unclear? Tell us with Feedback in the app.