Skip to content

Add: Opt-in endpoint hardening (auth, health IP allow-list, declined-response headers)#2249

Open
mde-gb wants to merge 3 commits into
mainfrom
auth-notus-vts-health-allowlist
Open

Add: Opt-in endpoint hardening (auth, health IP allow-list, declined-response headers)#2249
mde-gb wants to merge 3 commits into
mainfrom
auth-notus-vts-health-allowlist

Conversation

@mde-gb

@mde-gb mde-gb commented Jun 17, 2026

Copy link
Copy Markdown

What

Adds three opt-in [endpoints] settings to openvasd, all defaulting to off so
existing deployments are unaffected:

  • require_authentication — require the configured auth (mTLS or API key) for
    /notus, /notus/{os}, and /vts (previously always unauthenticated).
  • health_ip_allowlist — restrict the implemented health probe routes
    (GET/HEAD on /health/alive, /health/ready, /health/started) to direct
    TCP peer IPs or CIDR networks. X-Forwarded-For is intentionally ignored.
  • hide_declined_response_headers — omit the authentication, api-version, and
    feed-version metadata headers on 401 and 403 responses.

Each is configurable via TOML, CLI flag, and environment variable. Startup fails
fast if require_authentication is set without an API key or complete mTLS config.
OpenAPI, README, example configs, the default config snapshot, and tests are updated.

Why

Today openvasd serves the Notus and VT endpoints without authentication and
answers health probes for any caller. That is acceptable behind a trusted gateway,
but risky for any instance that is — intentionally or accidentally — reachable from
an untrusted network. This change lets operators harden such deployments without
breaking the default behavior.

Concrete risks on a publicly reachable instance:

  • Unauthenticated Notus/VT endpoints disclose which OS advisories and
    vulnerability tests the scanner knows about. An attacker can fingerprint the
    feed and OS coverage to infer what the operator can (and cannot) detect, and use
    that to plan evasion. These endpoints are also comparatively expensive, so open
    access invites resource abuse and denial-of-service amplification.
  • Open health endpoints (/health/alive, /health/ready, /health/started)
    leak liveness and readiness state. That confirms a live service to scanners and
    helps an attacker time activity (e.g., probe while the service is starting or
    not ready) and map infrastructure during reconnaissance.
  • Metadata headers on declined requests. Returning authentication,
    api-version, and feed-version on 401/403 responses hands version and
    capability details to callers who have not authenticated. This is information
    disclosure / version fingerprinting — OWASP A02:2025 Security Misconfiguration —
    and contradicts the least-information and defense-in-depth principles. Precise
    api-version/feed-version values let an attacker correlate the instance with
    known issues in specific versions (cf. OWASP WSTG information-gathering / version
    disclosure). Suppressing them on declined responses reduces the pre-auth
    attack surface while keeping the headers available to authenticated clients.

Because every option defaults to off, current setups are unchanged; operators opt
in only where the threat model requires it.

How

  • New EndpointPolicy in greenbone-scanner-framework holds the allow-list and the
    hide-headers flag. allows_health_peer matches the peer IP against the CIDR set;
    is_health_probe_route gates only the implemented health routes; metadata-header
    suppression is centralized in should_hide_metadata_headers.
  • The accept loop now forwards the peer SocketAddr through make_service into the
    entry point so the allow-list can be enforced per connection.
  • Request handlers (GetVTsHandler, Notus handlers) gain a require_authentication
    flag threaded through RuntimeBuilder (new api_key, endpoint_policy, and
    require_authentication builder methods).
  • Config parsing validates allow-list entries (IpInet) and rejects invalid values
    for both TOML and CLI input.

Contribution checklist

  • Conventional commit tag (Add: → minor release)
  • AI use disclosed (Co-authored-by: AI (codex/partial) and
    Co-authored-by: AI (copilot/partial))
  • RELICENSE: not required — contributor is a Greenbone member; if a RELICENSE
    file is nonetheless required, it is covered by Add: Exact client certificate pinning for openvasd mTLS #2248.

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA bf7b352.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

  • rust/Cargo.toml

@github-actions github-actions Bot added the minor_release creates a minor release label Jun 17, 2026
@mde-gb mde-gb requested a review from Copilot June 17, 2026 11:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds opt-in hardening controls for openvasd endpoints: optional authentication enforcement for Notus/VT routes, optional IP allow-listing for health probes based on direct TCP peer address, and optional suppression of metadata headers on declined (401/403) responses.

Changes:

  • Introduces [endpoints] settings and corresponding CLI/env/config plumbing for require_authentication, health_ip_allowlist, and hide_declined_response_headers.
  • Threads peer SocketAddr into request handling to enforce health allow-listing and centralizes “hide declined headers” logic in the framework entry point.
  • Updates OpenAPI, README, example configs, config snapshots, and adds tests for the new behaviors.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
rust/src/openvasd/README.md Documents new endpoint hardening options and CLI flags.
rust/src/openvasd/notus/mod.rs Makes Notus handlers optionally require authentication and adds tests.
rust/src/openvasd/main.rs Wires new endpoint policy/auth settings into runtime initialization and adds fail-fast validation.
rust/src/openvasd/config/snapshots/openvasd__config__tests__defaults.snap Updates default config snapshot for new fields.
rust/src/openvasd/config/mod.rs Adds new endpoints config fields, TOML validation/serde for allow-list, CLI/env flags, and tests.
rust/examples/openvasd/config.example.toml Documents new [endpoints] options in example config.
rust/examples/openvasd/config.example_v1.toml Documents new [endpoints] options in example v1 config.
rust/crates/greenbone-scanner-framework/src/lib.rs Adds endpoint policy plumbing, peer forwarding into services, and threads “require auth” into VT handler registration.
rust/crates/greenbone-scanner-framework/src/get_vts.rs Adds optional authentication requirement to /vts handler and tests.
rust/crates/greenbone-scanner-framework/src/entry/mod.rs Implements EndpointPolicy (health allow-list + hide headers), enforces allow-list for health routes, and hides metadata headers on 401/403 when configured.
rust/crates/greenbone-scanner-framework/Cargo.toml Adds cidr dependency for allow-list CIDR matching.
rust/Cargo.toml Moves cidr to workspace dependency and consumes it via workspace.
rust/Cargo.lock Updates lockfile for dependency graph changes.
rust/api/openapi.yml Updates health paths and documents new 401/403 behaviors for affected routes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rust/src/openvasd/config/mod.rs
Comment thread rust/src/openvasd/config/mod.rs Outdated
Comment thread rust/src/openvasd/notus/mod.rs Outdated
Comment thread rust/api/openapi.yml
Comment thread rust/api/openapi.yml
Comment thread rust/api/openapi.yml
Address PR review feedback on the unreleased endpoint-auth/health-allowlist
feature. No user-visible behavior change, so this stays a non-escalating
Refactor (the PR's Add: merge already covers the feature).

- config: validate --health-ip-allowlist via clap value_parser!(IpInet)
  instead of panicking at parse time; collect parsed values directly.
- config: keep serialize signature as &[IpInet] and add #[serde(default)]
  on Endpoints.enable_get_scans.
- framework: fix clippy::op_ref in is_health_probe_route.
- notus: rename internal Get/PostOSIcnomingRequest -> ...IncomingRequest typo.
- openapi: document 503 Service Unavailable on the HEAD health probes.

Co-authored-by: AI (copilot/partial)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Comment thread rust/src/openvasd/config/mod.rs
Comment thread rust/src/openvasd/config/mod.rs Outdated
Comment thread rust/src/openvasd/notus/mod.rs Outdated
@mde-gb mde-gb requested a review from Copilot June 17, 2026 12:23
@github-actions github-actions Bot added minor_release creates a minor release and removed minor_release creates a minor release labels Jun 17, 2026
@mde-gb mde-gb changed the title Add: Optional endpoint authentication and health IP allow-listing Add: Opt-in endpoint hardening (auth, health IP allow-list, declined-response headers) Jun 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Comment thread rust/api/openapi.yml
Comment thread rust/api/openapi.yml
Comment thread rust/src/openvasd/README.md Outdated
Document that openvasd refuses to start when require_authentication is
enabled without an API key or complete mTLS configuration, and describe the
current declined-response header behaviour instead of changes over time.

Co-authored-by: AI (copilot/full)
@github-actions github-actions Bot added minor_release creates a minor release and removed minor_release creates a minor release labels Jun 17, 2026
@mde-gb mde-gb marked this pull request as ready for review June 18, 2026 12:10
@mde-gb mde-gb requested a review from a team as a code owner June 18, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor_release creates a minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants