Command-line client for Reysys. Uploads a Trivy scan report from a pipeline (or a laptop) to your Reysys account, where it is scored and prioritised alongside everything else you scan.
go install github.com/reysys-technology/rscli/cmd/rscli@latestThis is how setup-rscli-action installs it, so it is the path that gets the most
use. Signed binaries and a container image at ghcr.io/reysys-technology/rscli
are published for some releases; check the releases page for the version you want.
rscli authenticates with an OAuth2 client-credentials pair. Create one in the
console under Account Info → API clients, giving it a name that says what
will hold it (frontend-ci, nightly-scan). The secret is shown once, so copy
it then; if you lose it, rotate that client rather than creating another.
A client secret is an administrator credential for your account. It is not scoped to uploading scans: anything the API can do for your account, it can do — read every finding, change integrations, delete data. Treat it the way you would treat an admin password.
What follows from that:
- Keep it in the CI provider's secret store, never in the repository, and never in a file the pipeline checks out.
- Give each pipeline its own named client. When one leaks you rotate that one; the others keep running.
- On a pull-request pipeline, remember that the branch being built is attacker-controlled. Do not expose the secret to jobs that run code from a fork.
- Delete clients you no longer use. A forgotten credential is the one nobody notices being used.
rscli refuses to send either your credentials or the resulting access token over plaintext http:
RS_TOKEN_URLandRS_BASE_URLmust both be https (loopback http is allowed, for local development). Redirecting either one was a way to walk off with a full-access token from a single CI variable.
export RS_CLIENT_ID=...
export RS_CLIENT_SECRET=...Check it works — this uploads nothing:
rscli account get-account-informationrscli configure prints the full reference: every variable, the config-file form,
and the precedence between them.
trivy image --format json -o scan.json ghcr.io/acme/api:1.4.2
rscli trivy upload-trivy-container-image-scan -f scan.jsonSource repositories work the same way — the report says which it is, so the same command handles both:
trivy repo --format json -o scan.json .
rscli trivy upload-trivy-container-image-scan -f scan.jsonKeep the credentials in the CI provider's secret store, never in the repository — and see the warning under Credentials about what one grants.
GitHub Actions
- uses: reysys-technology/setup-rscli-action@v1
- run: trivy image --format json -o scan.json "$IMAGE"
- run: rscli trivy upload-trivy-container-image-scan -f scan.json
env:
RS_CLIENT_ID: ${{ secrets.RS_CLIENT_ID }}
RS_CLIENT_SECRET: ${{ secrets.RS_CLIENT_SECRET }}GitLab CI
scan:
script:
- trivy image --format json -o scan.json "$IMAGE"
- rscli trivy upload-trivy-container-image-scan -f scan.json
variables:
RS_CLIENT_ID: $RS_CLIENT_ID
RS_CLIENT_SECRET: $RS_CLIENT_SECRETDefine a policy in the console, then add --gate:
trivy repo --format json -o scan.json .
rscli trivy upload-trivy-container-image-scan -f scan.json --gateUploaded . (repository) to https://api.reysys.com
Policy: FAILED
target https://github.com/org/repo
59 finding(s) at HIGH or above with a fix available; the budget is 0
FAIL severity_budget 59 finding(s) at HIGH or above with a fix available; the budget is 0
ok kev 0 finding(s) on the CISA Known Exploited Vulnerabilities catalogue
ok secret 0 secret(s) committed to the repository
Every rule is reported, not just the one that failed, so fixing the first does not surface a second you were never told about.
Without --gate the verdict is printed and the command still succeeds. Run
it that way first. A team that meets a blocking gate for the first time as an
unexplained outage turns it off; one that has watched it for a week turns it on.
| Code | Meaning |
|---|---|
| 0 | Uploaded, and passed — or no policy is enforced for this target |
| 1 | The tool could not do its job: bad config, upload failed, or Reysys could not evaluate the scan |
| 2 | The artifact did not meet the policy |
| 3 | The scan could not be judged, and the policy says not to allow that |
Code 1 is never a statement about your code. If our side cannot evaluate a scan we allow the build and report it as a tool error, because a pipeline that reds during our outage — under a message saying the code failed a security policy — is a pipeline whose owner stops gating.
A failed upload also fails the step: a build whose scan never reached Reysys should not look the same as one that did.
Any of them. The gate is an HTTP call and an exit code, so it runs wherever a
binary runs — GitHub Actions, GitLab CI, Azure DevOps, Jenkins, Bitbucket,
CircleCI. What differs between them is only the install step and how the secret
is supplied. setup-rscli-action exists for GitHub Actions; elsewhere,
go install and the provider's own secret store.
go mod tidy && gofmt -s -w . && go vet ./... && go build ./...Set RS_BASE_URL and RS_TOKEN_URL to point at a local stack. RS_INSECURE_SKIP_VERIFY=true
skips TLS verification for a self-signed local certificate — never set it in CI.