tigergate/tigergate-cli — run every TigerGate scanner in your pipeline, upload results, gate the build, and link findings code → cloud.
The TigerGate CLI runs every code scanner (SAST, SCA, secrets, quality, IaC, and
container image), uploads the results, evaluates your quality gate, and exits
with a meaningful status code. It’s the same tool the CI snippets
call.
The CLI is distributed as the Docker image tigergate/tigergate-cli,
published multi-arch (linux/amd64, linux/arm64) to Docker Hub. The image
ships with every scan engine pre-baked, so there are no scanners to provision
on your runners. It does not ship language toolchains (JDK, Maven, Gradle,
.NET SDK) — Java, Gradle, and lockfile-less .NET projects need those to
resolve dependencies. See Language setup for CI/CD.
Its entrypoint is tigergate, so the command after the image name (scan,
gate, …) is a subcommand.
Create a CI/CD key under Settings → Organization → API Keys → CI/CD Keys
(prefix tgci_) — see API keys. Pass it as an env var
(preferred — keeps it out of ps and shell history) or with --api-key:
The CLI talks to one TigerGate region, and tgci_ keys are
region-scoped — a key issued in one region is rejected by every other.--region is a persistent flag, so it works on every subcommand and on either
side of it:
docker run --rm -e TIGERGATE_API_KEY \ -v "$PWD:/workspace" -w /workspace \ tigergate/tigergate-cli:latest \ --region <code> scan --type all --upload
Equivalently, set TIGERGATE_REGION in the runner’s environment, or commit
region: <code> to .tigergate.yml so the whole repo agrees. Run
tigergate regions to list the codes.Resolution order is --api-url / TIGERGATE_API_URL, then --region, then
TIGERGATE_REGION, then .tigergate.yml, then us1. An explicit URL always
wins — that’s the self-hosted and staging path — and pairing it with a region
just logs one line saying the region was ignored. An unknown region code
fails the run instead of falling back.
Omit all of it and you get us1, silently. Nothing changes for pipelines that
never mentioned a region.
Every run is attached to a repository by its full name — my-org/my-service.
That string is what links a scan to its history, its findings and its quality
gate, so the CLI will not upload a run without one.It is resolved in this order, stopping at the first that answers:
1
--repo, or TG_REPOSITORY
An explicit name. Always wins, including over a name that was detected.
2
Your CI provider's environment
Variables every supported CI system sets on its own — nothing to configure.
The exact ones are listed below.
3
The checkout's origin remote
Taken from git config --get remote.origin.url, which covers a plain
git clone on a runner that sets no recognised CI variables.
In a normal pipeline step 2 or 3 answers, and you never need --repo.The CI variables read in step 2, per system:
CI system
Detected by
Repository name from
GitHub Actions
GITHUB_ACTIONS
GITHUB_REPOSITORY
GitLab CI
GITLAB_CI
CI_PROJECT_PATH
Bitbucket Pipelines
BITBUCKET_PIPELINE_UUID
BITBUCKET_REPO_FULL_NAME
Azure Pipelines
TF_BUILD or SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
SYSTEM_TEAMFOUNDATIONCOLLECTIONURI + SYSTEM_TEAMPROJECT + BUILD_REPOSITORY_NAME, joined as organization/project/repository
CircleCI
CIRCLECI
CIRCLE_PROJECT_USERNAME/CIRCLE_PROJECT_REPONAME, else parsed from CIRCLE_REPOSITORY_URL
Travis CI
TRAVIS
TRAVIS_REPO_SLUG
Jenkins
JENKINS_URL, JENKINS_HOME, BUILD_TAG or EXECUTOR_NUMBER
parsed from GIT_URL (Git plugin), else the checkout’s origin remote
If your runner strips these — a docker run step that forwards only the
variables you name is the usual cause — pass the one in the right-hand column
through, or use --repo.
If none of the three answer, the run stops before any scanning happens:
✗ Could not determine the repository name: this git repository has no 'origin' remote, so the repository name could not be detected — add one with `git remote add origin <url>`, or name the repository explicitly: --repo owner/repo (or TG_REPOSITORY=owner/repo)
Two situations produce it:
Situation
Typical cause
Fix
The directory is not a git checkout
An unpacked archive, a COPY’d Docker build context, or a runner that fetches sources without .git
Pass --repo my-org/my-service
It is a checkout with no origin remote
git init locally, or a mirror added under a different remote name
git remote add origin <url>, or pass --repo my-org/my-service
This fails the step rather than warning and carrying on. Without a name we cannot
attach the run to a repository, so it would be stored detached — missing from the
repository page, from trend history and from correlation — while your pipeline
still reported success. Failing costs you one re-run; the silent version costs a
scan you never find.
docker run --rm -e TIGERGATE_API_KEY -v "$PWD:/workspace" -w /workspace \ tigergate/tigergate-cli:latest \ scan --type all --upload --repo my-org/my-service
Use exactly the name the repository is connected under in the dashboard. For
GitHub, GitLab and Bitbucket that is owner/repo; for Azure DevOps it is
organization/project/repository. A name that matches nothing still uploads, but
the run stays unlinked from the repository you expected.
Because --repo overrides detection, it also fixes the opposite problem: a run
that lands under the wrong name because the runner clones through a mirror or
proxy URL that differs from the connected repository.
REPOSITORY --repo repository full name, e.g. "my-org/my-service" [env TG_REPOSITORY] auto-detected from your CI environment or the checkout's "origin" remote — required only when neither exists (see "Repository name" below)SCOPE & TYPE --type sast | sca | secrets | quality | iac | image | all (default all) "all" = SAST + SCA + secrets + quality + IaC, plus the image scan when --image is set --scan-scope diff (changed code) | full (whole repo) | auto (default auto) --exclude comma-separated paths to skip, e.g. "node_modules,dist,vendor"MONOREPO COMPONENTS (see Quality gates -> Monorepos) --component component this build owns, e.g. "web" [env TG_COMPONENT] resolves that component's quality gate and posts its own "TigerGate Security (web)" status check --component-path comma-separated paths the component owns, [env TG_COMPONENT_PATH] e.g. "apps/web,libs/shared" - findings outside are dropped --skip-untouched on a PR build, exit 0 without scanning when the PR changes no file the component owns (default true; =false to always scan, for nightly / post-merge jobs)QUALITY GATE (exit non-zero to block the merge) --quality-gate run the gate check (default true; =false to never block) --fail-on severities that fail the build (default critical,high) --max-critical max new critical allowed (-1 = use org default) --max-high max new high allowed (-1 = use org default)SCA / SAST --sca-ignore-unfixed skip vulnerabilities with no fix available --sast-rules override the SAST rule packs (empty = dashboard config)COVERAGE & QUALITY --coverage-report lcov | cobertura | jacoco | go-cover report path --coverage-html HTML coverage report (uploaded as a downloadable artifact)SDLC COMPLIANCE (supply-chain / repo hygiene) --compliance run the SDLC posture scan + upload scores --compliance-local filesystem-only SDLC scan (no GitHub API/token)CONTAINER / CODE → CLOUD --image image to scan (also runs inside --type all when set) --image-digest sha256 digest of the built image (code → cloud join key; auto-resolved from --image when omitted) [env TG_IMAGE_DIGEST] --deploy-target cluster / service / region being deployed [env TG_DEPLOY_TARGET] --environment production | staging | dev [env TG_ENVIRONMENT]PLUMBING --upload send results to TigerGate (default true) --no-auto-install do not auto-install scanner tools (expect them on PATH) --api-key defaults to $TIGERGATE_API_KEY --region TigerGate region owning your org [env TIGERGATE_REGION] persistent flag; omit for us1 --api-url explicit platform API base — overrides --region; self-hosted / staging only [env TIGERGATE_API_URL]
See Code → cloud tracking for the build/deploy
metadata flags and how findings link to the running cloud asset.
--format accepts sarif, cyclonedx, trivy, grype, junit, or auto
(detect from file content).upload creates a scan run just as scan does, so it needs a repository name on
the same terms — --repo and TG_REPOSITORY work here too. See
Repository name.
--component selects which quality gate applies and names the PR status check
(TigerGate Security (web)). --component-path decides which findings count and whether the
component cares about the PR at all.Paths resolve from the first source that supplies them:
--component-path (or TG_COMPONENT_PATH)
component_paths in .tigergate.yml
Component paths stored on that component’s quality gate in the dashboard
the --component value itself, when it names an existing directory
--component on its own does not scope findings and does not enable the
untouched-component skip — both require resolved paths. Always supply paths too.
With --skip-untouched (on by default), a PR that changes no file the component owns ends the
run early: exit 0, no scan run created, nothing uploaded, and a passing status posted for
that component so a required check never hangs. Detection fails open — when the base-branch diff
can’t be computed the component is scanned rather than skipped.Full behaviour: Monorepos.