Skip to content

Session Management

After a scan completes, its session directory can be uploaded to the Bullium Consulting consultation portal, pushed with a shareable report link, or re-uploaded after a report-template change. Three CLIs cover these flows: upload_session.sh, push_session.sh, and refresh_reports.sh. All three share the multipart uploader in submit_session.sh.

For the wire format and portal endpoints, see the API Contract.

Credentials

Every uploader reads portal credentials from a config file (the -c flag) or from direct URL and key flags. In config files, NV_API_KEY takes precedence over the legacy CONSULTATION_API_KEY alias, and both are accepted for backward compatibility. See Report Configuration and Secrets Management for where these live and how to rotate them.

Session Upload

scripts/upload_session.sh uploads a completed session using a config file for credentials. It defaults to the most recent session.

upload_session.sh -c <config> [options]

Required:
  -c <file>           Report config file (CONSULTATION_API_URL + NV_API_KEY)

Session Selection (pick one, defaults to --latest):
  -s <session_dir>    Path to a session directory
  -i <session_id>     Session ID, for example 20260224_120000
  --latest            Use the most recent session (default)

Options:
  -r <file>           HTML report file (overrides auto-detection from the session dir)
  -e <file>           Executive summary HTML (auto-detected from the session dir)
  --dry-run           Show what would be uploaded without sending
  -h, --help          Show help
bash
# Upload the most recent session (default)
./scripts/upload_session.sh -c ~/netvuln-tool/configs/acme.conf

# Upload a specific session by ID
./scripts/upload_session.sh -c ~/netvuln-tool/configs/acme.conf -i 20260224_120000

# Upload a specific session by path
./scripts/upload_session.sh -c ~/netvuln-tool/configs/acme.conf -s ~/netvuln-tool/sessions/20260224_120000

# Preview without sending
./scripts/upload_session.sh -c ~/netvuln-tool/configs/acme.conf --dry-run

Upload is also available as option 9 in the interactive menu (vulnscan_menu.sh).

Automatic push after a scan

You rarely need to run the uploader by hand. When the config passed to the recon pipeline with -c defines both CONSULTATION_API_URL and NV_API_KEY (or CONSULTATION_API_KEY), the session is submitted automatically once the pipeline finishes, and a shareable report link is returned on success. The manual uploaders exist for re-pushing older sessions or for hosts where the scan and the upload happen separately.

Session Push

scripts/push_session.sh submits a previously completed session and reports the portal session ID and shareable link that come back in the response. It can auto-discover artifacts from a session directory or take a JSON path directly.

push_session.sh (-d <dir> | -j <file>) [options]

Required (one of):
  -d <dir>            Session directory (auto-discovers JSON, log, report, exec summary)
  -j <file>           Path to session_results.json directly

Optional:
  -R <file>           Path to the HTML report file
  -e <file>           Path to the executive summary HTML (auto-detected from the session dir)
  -c <file>           Config file (for CONSULTATION_API_URL and NV_API_KEY)
  -u <url>            API URL (overrides the config file)
  -k <key>            API key (overrides the config file)
  -h, --help          Show help
bash
# Push a session directory using a config file
./scripts/push_session.sh -d ~/netvuln-tool/sessions/20260224_120000 \
    -c ~/netvuln-tool/configs/acme_corp.conf

# Push with an explicit URL and key
./scripts/push_session.sh -d ~/netvuln-tool/sessions/20260224_120000 \
    -u https://portal.netvulntool.com/api/upload -k nvt_pro_<hex>

# Push a specific JSON alongside its report
./scripts/push_session.sh -j /path/to/session_results.json \
    -R /path/to/report.html -c config.conf

On a successful upload the tool prints the returned session ID and, when the portal issues one, a shareable report link of the form:

https://<your-portal>/share/?token=<64-hex-chars>

That link requires no login. The long random token is the credential, so treat the URL as sensitive.

Remote agents

For agents managed through Command and Control, pushing is handled remotely. Dispatch a run_scan command with upload: true to auto-push the resulting session, or send a push_session command (optionally with a specific session_id, defaulting to the latest) to push an already-completed session. Both report the portal session ID back through the agent's heartbeat.

Report Refresh

When the report template (report_template.sh) changes (cosmetic fixes, new features, bug fixes), you can regenerate and re-upload reports for existing portal sessions without re-running the scan. scripts/refresh_reports.sh drives the PUT /api/refresh endpoint, which replaces report artifacts in place.

refresh_reports.sh [options] SESSION_ID [SESSION_ID ...]

Required (one of):
  -c <config.conf>     Config file with NV_API_URL and NV_API_KEY
  -u <url> -k <key>    API URL and key directly

Options:
  --all                Refresh every session on the portal. Listing them uses
                       the Identity-authenticated endpoint, so this needs a
                       JWT in NV_JWT (or CONSULTATION_JWT) as well as the API
                       key used to refresh.
  --dry-run            Regenerate locally without uploading
  -h, --help           Show help
bash
# Refresh a specific session
./scripts/refresh_reports.sh -u https://portal.netvulntool.com/api \
    -k nvt_pro_<hex> 20260318_103739

# Refresh several sessions
./scripts/refresh_reports.sh -u https://portal.netvulntool.com/api \
    -k nvt_pro_<hex> 20260318_103739 20260220_091500

# Dry run: regenerate locally, upload nothing
./scripts/refresh_reports.sh -u https://portal.netvulntool.com/api \
    -k nvt_pro_<hex> --dry-run 20260318_103739

# Refresh every session on the portal. Export the JWT rather than passing it
# as a flag, so the token stays out of ps output and shell history.
export NV_JWT='<identity-jwt>'
./scripts/refresh_reports.sh -u https://portal.netvulntool.com/api \
    -k nvt_pro_<hex> --all --dry-run

--all needs two credentials

Refreshing and downloading authenticate with the API key, but listing sessions is gated on a Netlify Identity JWT, and neither credential derives from the other. Without NV_JWT (or CONSULTATION_JWT) exported, --all stops before touching anything and tells you which variable to set.

The tool sends that token in the X-Identity-Token header, never in Authorization. You do not have to do anything about this, but it matters if you are scripting the same call by hand: the portal's edge terminates any request carrying a validly-signed Identity JWT in Authorization before the handler runs, and an invalid token returns the same clean 401 under either header, so a test credential will not reveal the difference.

Run it with --dry-run first. The summary reports how many sessions would be touched, and if any of them fail, it lists the failing session IDs so you can retry just those rather than the whole account.

Refresh, not re-push

push_session.sh cannot re-upload to a session that already exists on the portal (it returns an HTTP 500 duplicate error). Use refresh_reports.sh for that. The refresh endpoint accepts only report.html and exec_summary.html; it cannot update session JSON or pipeline logs. Share-page links stay the same after a refresh, because the share token is permanent.

refresh_reports.sh expects the NV_API_URL and NV_API_KEY variable names in a config file. If your config uses CONSULTATION_API_URL / CONSULTATION_API_KEY, pass credentials directly with -u and -k instead.

Under the Hood

Both upload_session.sh and push_session.sh delegate the actual transfer to submit_session.sh, a shared library that performs the multipart upload (25 MB maximum). It sends the session JSON plus, when present, the pipeline log, the report HTML, and the executive-summary HTML, and it exposes the portal's session ID and share token to the calling script on success.

Apache-2.0 licensed (appliance subtree proprietary)