First server: one command and a result in the dashboard

“From the first server to the report”, episode 2 of 9
You have a gap between support requests and want to try one server. You open the dashboard, copy a command and run the script. A machine and its vulnerabilities appear. Time to move on to the next job. But will another result arrive tomorrow?
This episode ends after the first entry appears in the dashboard. It covers downloading and running the agent, checking completeness, and making a separate scheduling decision. The title refers to the command that starts a scan. The dashboard itself separates downloading the file from executing it, and I keep that distinction here.
In my experience, downloading and starting the script takes less than a minute of active work. Preparing a service and timer from the supplied example takes another. I allow two minutes, or up to five to read through the steps. That is my experience, not a benchmark or a promise about scan duration. Database downloads, disk contents and server load can extend the wait for results.
Requirements and permissions
Start with one Linux server whose role you understand. You need Bash, curl and jq, plus wget for the download command displayed by the dashboard. The agent checks for curl and jq and stops with a message if either is missing. Install dependencies using the normal process for your distribution.
If Trivy is unavailable, the script attempts to install it. Scanner and database downloads require network access. On a host with restricted outbound access, identify the failing stage and arrange access under your normal rules. Do not begin by removing firewall restrictions just to make a trial succeed.
A filesystem scan needs permission to read its targets. Without root, the agent warns that some files may be inaccessible. A command reaching its final line does not prove that it could read everything. The examples assume an approved administrative session on the selected machine.
Also settle naming before starting. Without a custom label, the script uses the short hostname. The first episode explains the data scope and local preview. If your organisation does not permit hostnames to be sent, address the current --no-hostname contract issue described there before using the default launch shown here.
Downloading and running the agent
The dashboard provides a download using the project installation token, followed by a separate command using the API key:
wget -O secvalis.sh "https://secvalis.eu/api/agent/install/INSTALL_TOKEN" && chmod +x secvalis.sh
./secvalis.sh YOUR_API_KEY
Both values are placeholders. Use the values from your own project. The download token is not the upload credential, and the endpoint does not embed your API key in the script. You still need to supply that key when running a normal scan.
Read the downloaded file before executing it. The argument form above reproduces the dashboard's command pattern. A real key supplied that way can appear in shell history or process arguments. For recurring operation, use the key file described below. Avoid recording the process of copying a secret during a screen share.
The dashboard download does not verify the agent script's signature or checksum.
The first scan
Watch the entire first run. The script checks dependencies, identifies the system, makes Trivy available, scans and uploads the result. Failures at those stages have different causes. Note which stage completed before changing configuration or rerunning the command.
For repeatable operation, put the reviewed script in a stable location such as /opt/secvalis.sh and make it executable. The following example assumes that path. In a root-only /etc/secvalis directory, prepare a root-owned key file with mode 0600 containing:
SYSDEVOPS_KEY=YOUR_API_KEY
Insert the real key through an approved editor or secret delivery mechanism. Check any existing file before replacing it. With the file prepared, a manual launch can use:
sudo bash -c 'set -a; . /etc/secvalis/key; exec /opt/secvalis.sh --low-priority'
The script reads SYSDEVOPS_KEY when no positional key is supplied. The secret is then absent from the literal command arguments. The file still needs protection and should not be published with the configuration. --low-priority reduces the scanner's priority; it does not promise zero production impact. Arrange an appropriate time for the first run.
Test this example on one server first. Other machines may have different container workloads, less free memory or restricted repository access. A successful run on the first host does not test those differences for you. Keep the initial acceptance check small enough that you can explain what was actually scanned.
Recognising a complete result
A successful HTTP upload means the request was accepted. It does not mean every scan target succeeded. The agent distinguishes ok, partial and failed. Partial or failed scans do not close vulnerabilities in the ledger. Another safeguard blocks closures when it detects a sharp drop in finding count.
After the upload message, read any further warnings and check the process exit status. The current script exits with code 2 for an incomplete scan even if it uploaded data. Run echo $? immediately after the agent to inspect the status. Running another command first replaces that value.
Open the correct machine and its scan history in the dashboard. Compare the time with the run you just performed and assess the visible counts against the expected scope. History lists dates, CVE counts by severity and changes from the previous result. Check the technical scan status in the agent output as well; a machine status badge is not a substitute for it.
A message saying findings are unchanged means the result matches the preceding scan. It does not mean there are no vulnerabilities. Likewise, an empty result without a permissions and scope check is insufficient evidence of a completed assessment. Accept the first deployment using both the local run and the result visible in the dashboard.
Scheduling is a separate step
The agent runs once. It prints scheduling examples with:
bash /opt/secvalis.sh --schedule-help
This displays key file instructions, a cron option and systemd service and timer units. It installs none of them. The service example uses Type=oneshot, reads EnvironmentFile=/etc/secvalis/key and points ExecStart at the script. The timer uses OnCalendar=daily, RandomizedDelaySec=1h and Persistent=true.
Check the generated ExecStart path. The help derives it from the location of the script you ran. If you move the script afterwards, update the unit. Preserve the chosen label and required options too. A timer executes its stored command, not the last command from your interactive session.
Only after saving and reviewing the unit files should you activate them:
sudo systemctl daemon-reload
sudo systemctl enable --now secvalis.timer
sudo systemctl start secvalis.service
sudo systemctl list-timers secvalis.timer
sudo journalctl -u secvalis.service
Choose a frequency that fits your process. A daily example is not a universal legal requirement. When replacing an old cron job, disable the old schedule to avoid duplicate scans. Check for a new result after a real timer invocation as well. A manual success does not prove that the service environment is correct.
Diagnosing errors
| Symptom | First check |
|---|---|
Missing curl or jq |
Dependencies on this particular host |
| Trivy or database download fails | Network access and the failing download stage |
| HTTP 401 | API key validity |
| HTTP 403 | Permission to run the scan |
| HTTP 413 | Upload size and rejection message |
| HTTP 429 | Wait before retrying rather than creating a retry loop |
partial, failed or exit code 2 |
Earlier scanner warnings, access, memory and scope |
| Manual run works, timer does not | Service journal, key file and ExecStart path |
For a support request, record the stage, time and error without secrets. Do not forward an entire terminal history without reviewing it. A short, accurate description helps distinguish download failures, scanner problems and API acceptance errors.
What this does not cover
A first scan does not install patches. Secvalis supports Linux vulnerability management and evidence preparation; update decisions, testing and maintenance windows remain with your team. It does not cover Windows, OT, PLCs or SCADA, and it does not discover unreported devices.
Deployment alone does not establish NIS2 compliance or ISO 27001 certification. The practical goal here is a verified path from server to dashboard and a schedule that has actually run. Record those outcomes when accepting the first machine, rather than marking the whole vulnerability management process complete.
Need help with deployment? Write to me: https://sysdevops.eu/kontakt. We will agree the scope, confidentiality and formalities individually.
Weekly CVE digest
One email a week with newly published vulnerabilities worth knowing about. No account needed.
This digest covers new vulnerabilities in general, not your servers. If you want to know which of them actually run in your infrastructure, that is what Secvalis does: it scans your machines and reports only what concerns them.

