Skip to content

About

This repo contains the source for the CVE Search API

Resources

Stars

0 stars

Watchers

4 watching

Forks

Repository files navigation

CVE Search API

Table of Contents

The CVE Search API Project

This repository provides an API for searching CVE Records in an existing OpenSearch index. It supports the CVE Program's mission to identify, define, and catalog publicly disclosed cybersecurity vulnerabilities by making CVE Records searchable through structured filters and a raw-query endpoint.

License

The project's license is CC0 1.0 Universal.

Running the API locally

Copy .env.example to an untracked .env and replace or check the following values. Keep the tracked example in place.

  • PORT - port used for the search API, defaulted to 3000 for development
  • OpenSearchCveIndex - existing CVE index name in your OpenSearch deployment
  • OpenSearchAllowUnknownSslCerts - set to true only for local development against self-signed certificates
  • OpenSearchDomainEndpoint - absolute URL to an existing OpenSearch deployment. This API does not create or manage the OpenSearch index or mapping.
  • SearchOpenSearchRequestTimeoutMs - optional timeout for each OpenSearch request, default 20000
  • SearchRequestDeadlineMs - optional overall /search processing deadline, default 30000
  • SearchReadinessTimeoutMs - optional timeout for the OpenSearch index readiness check, default 5000
  • RequestLogSuccessSampleRate - optional fraction of successful access logs to retain, default 0.1; includes health checks when they are enabled for logging
  • RequestLogHealthChecks - optional flag to include successful health checks in access-log sampling, default false
  • WebSearchEnabled - optional /webSearch availability flag, default true
  • NPM_CA_CERT - optional absolute host path to a corporate or self-signed CA certificate bundle used only during local Docker Compose builds

The three timeout settings (SearchOpenSearchRequestTimeoutMs, SearchRequestDeadlineMs, and SearchReadinessTimeoutMs) accept integer milliseconds from 1 through 2147483647. Invalid or out-of-range settings fall back to the defaults listed above; they do not disable timeouts. This upper bound prevents Node.js timer overflow from turning a large configured duration into a 1 ms timeout.

cp .env.example .env

Docker API Only

Use docker-compose.yaml when OpenSearch 3.5 is already running on the external Docker network opensearch-35_opensearch-net.

  1. Set OpenSearchDomainEndpoint in .env:
OpenSearchDomainEndpoint=https://opensearch-node-350:9200

If the target OpenSearch deployment requires credentials, provide them through untracked local environment configuration or deployment-managed secrets. Do not commit credential-bearing endpoint values.

  1. If npm needs a corporate or self-signed CA certificate during local Docker Compose builds, set NPM_CA_CERT to the absolute path on the host. The compose file uses Dockerfile.local, which mounts this certificate only for the npm install layer:
NPM_CA_CERT=/path/to/ca.crt
  1. Start only the API server:
docker compose -f docker-compose.yaml up --build

The compose file runs only the Search API with NODE_ENV=production and NODE_CONFIG_ENV=prod.

Deploying with npm

Use Node.js 24 for the repository's current runtime and development tooling. CI and the Docker dependency-build stage use Node.js 24.14.1; the final runtime image uses Distroless Node.js 24.

Upstream compatibility caveat: The locked cve-core package still declares Node.js >= 16.20.2 < 22. That metadata conflicts with this repository's Node.js 24 baseline and can cause installation warnings or failures when strict engine checks are enabled. Resolving the declaration requires coordination with the cve-core maintainers; it is not a recommendation to use Node.js 16 or 18 with this repository's current development tooling.

  1. Set OpenSearchDomainEndpoint in .env to an existing OpenSearch deployment:
OpenSearchDomainEndpoint=https://search.example.com
  1. Install dependencies:
npm ci
  1. Run the CVE Search API in development mode:
npm run dev

npm run dev regenerates api-docs/openapi.json and starts the API with nodemon. To run the production server entrypoint locally, use:

npm start

The Search API uses PORT, defaulting to http://localhost:3000. The tracked Postman environment defaults to port 4000; either set PORT=4000 before starting the API or change Postman's baseUrl to match the running server.

Health Checks

GET /api/health-check is a process liveness check. It returns HTTP 200 when the Node.js process is running and deliberately does not contact OpenSearch. Use it where a dependency outage should not restart otherwise healthy API tasks.

GET /api/ready-check first verifies that the configured CVE index exposes compatible field capabilities for each logical /search feature, then sends a minimal zero-result search. CNA, ADP, legacy, and CVSS-version fields that implement the same feature are treated as alternatives, while mapped fields must still use compatible searchable types. This checks mappings, connectivity, index availability, and the same search permission used by the API without retrieving CVE records or counting all matches. It returns HTTP 200 when these checks pass; it does not prove data completeness or capacity for every search. Configuration errors, connection failures, timeouts, incompatible cve-core SearchReader contracts, missing logical capabilities, incompatible mapped fields, and a missing index return a sanitized HTTP 503 SEARCH_NOT_READY response with Retry-After: 5. SearchReadinessTimeoutMs defaults to five seconds for the overall readiness check, covering both field-capability and search operations. Each individual operation also uses that value as its transport timeout, and the overall deadline can abort it earlier.

An AWS load balancer can use /api/ready-check to stop routing search traffic to an unready task while the container orchestrator continues using /api/health-check for process liveness. Coordinate that probe selection with the infrastructure team before changing deployed health-check behavior.

When the configured index is an alias spanning multiple indices, every reported mapped type of each required field must be compatible and searchable. CVE ID sorting also requires aggregation support. One compatible type cannot conceal a conflicting type in another index; readiness returns HTTP 503 rather than advertising that configuration as ready.

API Input Validation

JSON request bodies for both search endpoints are limited to 100 KiB (102,400 bytes, measured after decompression). Larger bodies return HTTP 413 REQUEST_BODY_TOO_LARGE. Parser errors return sanitized JSON rather than HTML or stack traces: malformed JSON returns HTTP 400 MALFORMED_JSON, other unreadable bodies return HTTP 400 INVALID_REQUEST, and unsupported encoding returns HTTP 415 (SEARCH_CONTENT_TYPE for /search, REQUEST_ENCODING_UNSUPPORTED for /webSearch). Unexpected server errors return a generic INTERNAL_SERVER_ERROR response without exception details, including outside production mode.

POST /search accepts an optional JSON object request body and validates supported fields, boolean parameters, pagination values, CVSS severity values, required parameter combinations, CPE Name requirements, and date-time formats. Enum-valued fields are accepted case-insensitively and normalized to their documented canonical values. A non-empty body must use the application/json media type with UTF-8 encoding; unsupported media types or encodings return HTTP 415, and malformed JSON returns HTTP 400. If OpenSearch is unavailable, the endpoint returns HTTP 503 with a Retry-After header.

Successful /search responses use an API-owned response structure rather than exposing search-backend response objects. The top-level fields are apiVersion, status, warnings, pagination, and records, in that order. records contains complete CVE Records directly, without search-backend hit wrappers or infrastructure metadata. pagination contains page, pageSize, resultsReturned, totalResults, totalPages, and totalIsExact. Non-fatal conditions are reported in warnings before the potentially long records array.

CVE Records do not exist for years before 1999. A syntactically valid pre-1999 value in cveIds is therefore a valid search that contributes no matches rather than a request error. The response includes a CVE_IDS_NOT_RETURNED warning listing those IDs. When pre-1999 and supported-year IDs are requested together, matching supported-year records are still returned.

Use the optional scope field to control which parts of each record participate in matching. Values are case-insensitive: FULL (the default) searches base record fields, CNA data, and every ADP provider; CNA_ONLY searches base record fields and CNA data; and ADP_ONLY searches base record fields and every ADP provider. Scope changes matching only, so successful responses always contain the complete CVE record. CPE applicability filters use CNA data and return HTTP 400 when combined with ADP_ONLY.

Date filters use the API's full UTC timestamp format and inclusive boundaries. When both boundaries for publication, modification, SSVC timestamp, or KEV date-added filters are supplied, the start must be before or equal to the end.

Scope applies to filter matching as follows:

Filters Data used for matching
cveIds, pubStartDate, pubEndDate, lastModStartDate, lastModEndDate Base record metadata in every scope
noRejected Base record state in every scope, plus the legacy CNA state when CNA data is selected
keywordSearch, keywordExactMatch Description text in the selected CNA and/or ADP containers
cweId, all CVSS severity and metric filters Problem types or metrics in the selected CNA and/or ADP containers
All SSVC filters, knownExploited, KEV date filters, referenceURL, disputed Structured metrics, references, or tags in the selected CNA and/or ADP containers
cpeName, isVulnerable, virtualMatchString, and version range filters CNA CPE applicability data; incompatible with ADP_ONLY
resultsPerPage, pageNumber Response controls; they do not select record data

Missing data in selected containers does not make an otherwise compatible request invalid. A positive filter cannot match a record that lacks the requested data. Exclusion filters behave differently: knownExploited: false and disputed: false can match records with no selected KEV metric or disputed tag, including records without a selected container. Other supplied filters must still match. The API does not remove unselected containers from a returned record.

keywordSearch searches only description text selected by scope. By default, the API escapes caller-supplied query syntax, adds a trailing prefix wildcard to each whitespace-delimited term, and combines terms with AND using simple_query_string. For example, remote code searches for remote* AND code*. With keywordExactMatch: true, it instead uses an analyzed phrase query in the selected description fields. Phrase matching follows the index's text analyzer; it is not a case-sensitive, character-for-character substring comparison.

SSVC metrics can be filtered with ssvcExploitation (NONE, POC, or ACTIVE), ssvcAutomatable (YES or NO), ssvcTechnicalImpact (PARTIAL or TOTAL), ssvcRole, ssvcTimestampStartDate, and ssvcTimestampEndDate. Enum and role comparisons are case-insensitive, timestamps use the API's full UTC timestamp format with inclusive boundaries, and all supplied SSVC conditions must match the same structured SSVC metric entry in a container selected by scope.

Use knownExploited to include or exclude records with a structured KEV metric in containers selected by scope. The optional kevDateAddedStartDate and kevDateAddedEndDate boundaries are inclusive, require knownExploited: true, and use the API's full UTC timestamp format. Stored KEV dateAdded values are interpreted as midnight UTC.

Use referenceURL for a case-insensitive literal substring search over reference URLs in containers selected by scope. The filter accepts one string of at least three characters; user-supplied wildcard syntax is treated literally.

Use the strict boolean disputed filter to require (true) or exclude (false) the exact disputed tag in containers selected by scope. This does not provide a general-purpose record tag filter.

String inputs are bounded before query construction:

Field Limit
keywordSearch 512 characters and 64 whitespace-delimited terms
cveIds 4,096 characters overall, 100 IDs, and 64 characters per ID
cweId 32 characters
cpeName 2,048 characters
virtualMatchString 2,048 characters
versionStart, versionEnd 256 characters each
ssvcRole 256 characters
referenceURL 3 through 2,048 characters
CVSS metric fields 256 characters, 32 slash-delimited tokens, and 32 characters per token

Requests that exceed a limit return HTTP 400 before contacting OpenSearch. These bounds limit input size and query complexity without changing the documented CPE matching semantics.

Use cveIds to request up to 100 CVE records by comma-separated CVE ID.

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"cveIds":"CVE-2024-0001,CVE-2024-0002"}'

Set noRejected to true to exclude CVE records with rejected status values.

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"noRejected":true}'

When filtering with cpeName, provide a CPE 2.3 name beginning with cpe:2.3 and containing concrete part, vendor, product, and version components; part must be a, h, or o. Empty components, malformed escaping, and unsupported part values return HTTP 400. The API compares the provided CPE Name against CPE Match Criteria, including exact match strings and version range match strings when the indexed CVE data includes range fields. Use virtualMatchString when you intentionally need to search for partial CPE Match String values without those required components.

CPE Name Search

Use cpeName when a user has a concrete asset CPE Name and needs CVE records whose CPE Match Criteria apply to that asset version. The part, vendor, product, and version components must all be concrete values. Unescaped * or ? characters anywhere in those required components return HTTP 400 (INVALID_CPE_NAME), including versions such as 2.6.*, 2.6*, 2.*, and *.*. Backslash-escaped literal characters remain allowed. Optional components can still be * or omitted.

Valid cpeName example:

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"cpeName":"cpe:2.3:a:freetype:freetype:2.8.1:*:*:*:*:*:*:*"}'

Invalid cpeName example because the version component is *:

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"cpeName":"cpe:2.3:a:freetype:freetype:*:*:*:*:*:*:*:*"}'

The valid query can match stored CPE Match Criteria that use either a concrete version or a wildcard version plus range fields such as versionStartIncluding, versionStartExcluding, versionEndIncluding, or versionEndExcluding. In accordance with the CPE 2.3 Name Matching specification, CPE string literal comparisons are insensitive to lexical case, so an input component such as macos matches stored criteria containing macOS. Every concrete non-version component in the input, such as edition, language, target software, or target hardware, must be compatible with the same CPE Match Criteria entry that satisfies the version and vulnerability checks. Optional input components set to * remain broad matches. Use virtualMatchString instead of cpeName when searching for partial CPE Match String values such as all versions of a product.

The requested version does not need to appear literally in a returned record when it falls within a stored range. The API evaluates those criteria; it does not verify that a software version actually exists. An open-ended range can therefore match a hypothetical version such as 1001.1.

For a version interval, use virtualMatchString without a version component and supply explicit version boundaries. For example, to search for criteria overlapping Linux versions from 2.6 inclusive to 2.7 exclusive:

{
    "virtualMatchString": "cpe:2.3:o:linux:linux_kernel",
    "versionStart": "2.6",
    "versionStartType": "including",
    "versionEnd": "2.7",
    "versionEndType": "excluding"
}

An embedded wildcard such as 2.6.* is not a supported cpeName version-family search. A literal version ending in punctuation, such as 2.6., is still accepted but is not a version-prefix search either.

The version component - is the CPE logical value NA, meaning that no meaningful version applies, not that the version is unknown or unrestricted. Numeric version range boundaries on wildcard-version criteria do not exclude an asset whose version is -; an exact concrete criteria version still does not match -, and an exclusive - boundary still excludes it. The CPE specification defines NA; this treatment of numeric range boundaries is an API matching policy. This rule can produce different range behavior than a literal reading of source CVE Record applicability fields. Do not substitute - for * to search all versions; use virtualMatchString with an omitted version or a whole-component * instead.

Set isVulnerable to true with cpeName to require the matching CPE Match Criteria entry itself to be marked vulnerable. A vulnerable flag on an unrelated CPE entry does not satisfy the request. Omitting isVulnerable, or setting it to false, does not apply a vulnerability restriction.

Virtual Match String Search

Use virtualMatchString when a user needs CPE Match Criteria compatibility matching instead of concrete asset matching. It must begin with cpe:2.3 and include at least a valid part component: a, h, o, *, or -. A bare cpe:2.3 prefix, empty components, malformed escaping, and unsupported part values return HTTP 400. String literal components are compared without regard to lexical case. Omitted trailing components and * components act as broad matches.

Successful searches can include CPE interpretation warnings before the records array. CPE_COMPONENTS_DEFAULTED identifies trailing cpeName components that were omitted and treated as wildcards. BROAD_VIRTUAL_MATCH_STRING identifies wildcard or omitted leading virtualMatchString components that broadened the search. Invalid CPE strings are rejected rather than converted into warnings.

Partial product example:

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"virtualMatchString":"cpe:2.3:o:microsoft:windows_10_1809"}'

Full match string example:

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"virtualMatchString":"cpe:2.3:o:microsoft:windows_10_1809:*:*:*:*:*:*:x86:*"}'

Virtual Match String Version Ranges

Use versionStart, versionStartType, versionEnd, and versionEndType with virtualMatchString to search CPE Match String ranges. Each provided version bound must include its matching type, and the virtualMatchString must be a partial CPE 2.3 match string without a version component. Negative numeric values and the standalone CPE logical NA value (-) are not accepted as ordered range boundaries. When both bounds are provided, versionStart must be less than versionEnd; equal values are valid only when both bounds are including.

curl -X POST "http://localhost:3000/search" \
  -H "Content-Type: application/json" \
  -d '{"virtualMatchString":"cpe:2.3:o:linux:linux_kernel","versionStart":"2.2","versionStartType":"including","versionEnd":"2.6","versionEndType":"excluding"}'

Version ranges use overlap semantics. A stored wildcard-version CPE Match Criteria entry such as cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* with versionEndExcluding=6.9 matches requested ranges that overlap versions before 6.9, and does not match a requested range that starts at 6.9. Stored intervals with a start after their end, or equal boundaries where either boundary is exclusive, are empty and do not match range searches.

CPE version comparisons used by both cpeName applicability and virtualMatchString version ranges use Maven-style qualifier precedence: alpha/a < beta/b < milestone/m < rc/cr < snapshot < an unqualified release/ga/final/release < sp < unknown qualifiers. Unknown qualifiers, including hf, sort after known qualifiers in case-insensitive lexical order. This means a range beginning at 1.0.0-rc1 includes 1.0.0, while a range ending before 1.0.0 can include prerelease versions.

Numeric segments used in version range comparisons ignore leading zeros. A stored exclusive upper bound of 10.05.1 therefore includes 10.5.0, and CVE-2026-33280's exclusive 6.02 upper bound includes 6.1 but excludes 6.2. This normalization applies only to range comparison. Exact CPE Match Criteria preserve leading zeros, so the CVE-2025-9392 versions 1.0.04.001 and 1.0.4.1 are not equivalent. This comparison rule is not a universal firmware-versioning rule and can differ from a vendor's actual release sequence.

Future recommendation: broad virtualMatchString values can be expensive because they may require large candidate scans plus semantic CPE post-filtering. Requiring a concrete part and vendor for normal searches and a concrete part, vendor, and product for version range searches would reduce the most expensive public search shapes. Narrowing the accepted searches beyond the current valid-part requirement should be handled as a policy decision before implementation.

Raw Query Endpoint

POST /webSearch is a supported raw-query endpoint. It is enabled by default and can be disabled without a code change by setting WebSearchEnabled=false and restarting the service. When disabled, it returns HTTP 410 with the stable error code WEB_SEARCH_DISABLED before validating the request or contacting OpenSearch.

While enabled, POST /webSearch requires a non-empty JSON query string. It also accepts optional sort, from, and size fields:

{
    "query": "apache",
    "sort": {
        "property": "cveId",
        "order": "asc"
    },
    "from": 0,
    "size": 10
}
  • sort.property is required when sort is supplied and may be cveId or relevancy
  • sort.order may be asc or desc; when omitted, the chosen property is sorted descending
  • from must be an integer greater than or equal to 0
  • size must be an integer from 1 to 500

The controller validates successful BasicSearchManager responses before returning HTTP 200. A response without the expected status metadata, total-hit count, or hit array is treated as an invalid upstream response and returns a sanitized HTTP 502.

Swagger API docs

Swagger API docs are regenerated by npm run dev and can be regenerated manually using:

npm run swagger-autogen

Docker builds copy the committed api-docs/openapi.json into the runtime image; they do not regenerate it. Regenerate and commit that file whenever the route or request schema changes.

The Swagger API docs will be served at http://localhost:3000/api-docs while the CVE Search API is running via Docker or npm with the default port.

Testing

Unit, route, OpenAPI, runtime config, and error helper tests can be run with npm:

npm test

Linting, formatting, and coverage checks can be run with npm. npm run quality runs all three, and the coverage command executes the test suite:

npm run lint
npm run format:check
npm run coverage
npm run quality

An importable Postman collection for manual /search contract and filter testing is documented in test/postman/README.md. The complete collection targets a fully populated index like those used by shared managed environments; data-dependent positive assertions may fail against an incomplete local index even when the API is operating correctly.

Operational Logging

Every request receives an X-Request-ID response header. A caller-provided X-Request-ID is preserved when it contains only letters, numbers, ., _, :, or - and is no longer than 128 characters; otherwise the API generates a UUID. The same value appears as request-id in access logs.

Access logs omit query strings and request bodies. By default, the API retains 10% of successful non-health-check access logs, suppresses successful /api/health-check and /api/ready-check access logs, and retains every HTTP 4xx or 5xx access log. Set RequestLogSuccessSampleRate from 0 through 1 to change successful-request sampling. RequestLogHealthChecks=true includes successful health checks in that same sample; it does not bypass sampling. To retain every successful health check, enable that flag and set RequestLogSuccessSampleRate=1, which also retains all other successful access logs.

Each /search request owns a lifecycle cancellation signal. When its overall deadline expires, the API aborts the active OpenSearch transport request before returning HTTP 504. When the caller disconnects, the API aborts work that is needed only by that caller and does not attempt to write a response. This prevents timed-out or abandoned standard searches from continuing until the transport timeout.

Deadline checks also compare elapsed monotonic time, so they do not depend on the timeout callback running first. Semantic filtering checks cancellation between candidates and after the final candidate, and yields to the event loop every 100 candidates. An expired search cannot start its page fetch or return a successful empty result merely because filtering delayed the timer. Cancellation is cooperative; it does not interrupt an individual synchronous operation in progress.

Semantic Post-Filtering

Two separate 10,000-record controls apply to /search:

  • Every requested page must fall within the first 10,000 results. Direct OpenSearch filters still report an exact total that can exceed 10,000, but pages beyond that window are rejected.
  • Filters that require semantic post-filtering inspect at most 10,000 search candidates. Their reported total and pagination describe only matches found within that candidate set.

CVSS vector filters, SSVC filters, date-bounded positive knownExploited searches, cpeName, and virtualMatchString searches use semantic post-filtering where OpenSearch cannot guarantee the required same-entry or version-comparison behavior. These searches retrieve up to 10,000 lightweight candidates, apply semantic checks in Node.js, paginate the matching CVE IDs, and fetch the requested page as complete CVE records. Every slash-delimited token supplied to one CVSS vector filter must match a complete token in the same eligible vector; a base token such as AV:N does not match a modified token such as MAV:N.

The reported total and pagination are complete only within that bounded candidate set; qualifying records beyond the first 10,000 search candidates may not be represented. When a semantic search reaches that limit, the response sets pagination.totalIsExact to false and includes a SEMANTIC_CANDIDATE_LIMIT_REACHED warning. Semantic searches that remain below the limit and direct searches set totalIsExact to true. This preserves the existing bounded post-filter behavior until PIT-based pagination is implemented. A knownExploited filter without date boundaries uses a direct query and retains ordinary exact-total behavior.

/search orders search results by CVE ID so repeated shallow-page requests use a deterministic sort. The response pagination.pageSize preserves the requested resultsPerPage value, while pagination.resultsReturned reports the number of records actually returned and may be smaller for a partial or out-of-range page. Current searches do not use a point-in-time snapshot, so index updates between separate page requests can shift results. Request-scoped PIT traversal would improve consistency within one request, but consistency across separate page requests would additionally require reusing the same snapshot.

The API does not cache, coalesce, queue, rate-limit, or aggregate performance telemetry in process. Each request executes its own required OpenSearch operations. Public rate enforcement, admission control, shared caching, and durable metrics collection must be supplied by the deployment infrastructure.

OpenSearch operations use one attempt and return a sanitized HTTP 504 SEARCH_TIMEOUT response when they exceed the 20-second default timeout. The same response is returned when a /search request exceeds the 30-second default overall deadline, and the active OpenSearch request is aborted.

Docker Runtime Checks

Docker runtime smoke checks can be run after building the image. The default Dockerfile avoids BuildKit RUN --mount syntax for AWS builders that do not support it. The example below checks packaging and process liveness only; replace the placeholder endpoint/index and check /api/ready-check separately to verify an actual OpenSearch dependency:

docker build -t cve-search-api:runtime-smoke .
docker run --rm -d --name cve-search-api-runtime-smoke -p 4100:3000 \
  -e OpenSearchDomainEndpoint=https://search.example.com \
  -e OpenSearchCveIndex=cves \
  cve-search-api:runtime-smoke
curl -fsS http://127.0.0.1:4100/api/health-check
docker rm -f cve-search-api-runtime-smoke
docker image inspect cve-search-api:runtime-smoke --format 'User={{.Config.User}} Entrypoint={{json .Config.Entrypoint}} Cmd={{json .Config.Cmd}}'

When building locally on a network that requires a corporate or self-signed CA bundle for npm, use Dockerfile.local with the npm CA secret:

docker build -f Dockerfile.local --secret id=npm_ca,src=/path/to/ca.crt -t cve-search-api:runtime-smoke .

The final runtime image uses Google Distroless Node, so it does not include a shell, package manager, or command lookup tools.

About

This repo contains the source for the CVE Search API

Resources

Stars

0 stars

Watchers

4 watching

Forks

Releases

Used by

Contributors

Languages