> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Resource kinds

> Learn about the resource kinds in the Endor Labs data model.

export const YamlTable = ({children, data: propData, content}) => {
  const KV_RE = /^([A-Za-z][A-Za-z0-9_()/#\s-]+?):\s*(.+)$/;
  const INLINE_MD_RE = /(\[([^\]]+)\]\(([^)]+)\))|(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)/g;
  const YES_RE = /^-yes-$/i;
  const NO_RE = /^-no-$/i;
  const LIMITED_RE = /^-(limited|partial)-$/i;
  const NA_RE = /^-(na|none)-$/i;
  const NA2_RE = /^-na2-$/i;
  const SIMPLE_TAG_RE = /(<br\s*\/?>)|(<p\s*\/?>)|(-note-)|(-warning-)/gi;
  const tryParseKV = trimmed => {
    const m = KV_RE.exec(trimmed);
    return m ? {
      key: m[1],
      value: m[2].trim()
    } : null;
  };
  const registerKey = (key, seenKeys, orderedKeys) => {
    if (!seenKeys.has(key)) {
      orderedKeys.push(key);
      seenKeys.add(key);
    }
  };
  const flushEntry = (currentEntry, entries) => {
    if (Object.keys(currentEntry).length > 0) entries.push(currentEntry);
  };
  const parseDashPrefixed = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('- ')) {
        if (inEntry) entries.push(currentEntry);
        currentEntry = {};
        inEntry = true;
        const kv = tryParseKV(trimmed.substring(2).trim());
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      } else if (inEntry && trimmed !== '') {
        const kv = tryParseKV(trimmed);
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      }
    }
    flushEntry(currentEntry, entries);
  };
  const parseBlankSeparated = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed === '') {
        if (inEntry) {
          flushEntry(currentEntry, entries);
          currentEntry = {};
          inEntry = false;
        }
        continue;
      }
      const kv = tryParseKV(trimmed);
      if (!kv) continue;
      const isNewEntry = !line.startsWith(' ') && !line.startsWith('\t');
      if (isNewEntry && inEntry && Object.keys(currentEntry).length > 0) {
        entries.push(currentEntry);
        currentEntry = {};
      }
      registerKey(kv.key, seenKeys, orderedKeys);
      currentEntry[kv.key] = kv.value;
      inEntry = true;
    }
    flushEntry(currentEntry, entries);
  };
  const normalizeEntries = (entries, orderedKeys) => entries.map(entry => {
    const filled = {};
    for (const key of orderedKeys) filled[key] = entry[key] || '';
    return filled;
  });
  const parseYamlTableContent = contentStr => {
    if (!contentStr) return [];
    const entries = [];
    const orderedKeys = [];
    const seenKeys = new Set();
    const lines = contentStr.split('\n');
    if (lines.some(line => line.trim().startsWith('- '))) {
      parseDashPrefixed(lines, entries, orderedKeys, seenKeys);
    } else {
      parseBlankSeparated(lines, entries, orderedKeys, seenKeys);
    }
    return normalizeEntries(entries, orderedKeys);
  };
  const processText = text => {
    if (!text) return text;
    const parts = [];
    let keyIndex = 0;
    let lastIndex = 0;
    let match;
    while ((match = INLINE_MD_RE.exec(text)) !== null) {
      if (match.index > lastIndex) parts.push(text.slice(lastIndex, match.index));
      if (match[1]) {
        parts.push(<a key={keyIndex++} href={match[3]}>{match[2]}</a>);
      } else if (match[4]) {
        parts.push(<code key={keyIndex++}>{match[5]}</code>);
      } else if (match[6]) {
        parts.push(<strong key={keyIndex++}>{match[7]}</strong>);
      } else if (match[8]) {
        parts.push(<em key={keyIndex++}>{match[9]}</em>);
      }
      lastIndex = match.index + match[0].length;
    }
    if (lastIndex < text.length) parts.push(text.slice(lastIndex));
    if (parts.length === 0) return text;
    const keyRef = {
      current: keyIndex
    };
    return expandHtmlTags(parts, keyRef);
  };
  const processBadges = text => {
    if (!text || typeof text !== 'string') return text;
    if (YES_RE.test(text)) return <span className="yt-badge-yes" role="img" aria-label="Supported" title="Supported">✓</span>;
    if (NO_RE.test(text)) return <span className="yt-badge-no" role="img" aria-label="Not supported" title="Not supported">✗</span>;
    if (LIMITED_RE.test(text)) return <span className="yt-badge-limited" role="img" aria-label="Partially supported" title="Partially supported">◐</span>;
    if (NA_RE.test(text) || NA2_RE.test(text)) return <span className="yt-sr-only" title="Not applicable">Not applicable</span>;
    return processText(text);
  };
  const cellClassName = text => {
    if (!text || typeof text !== 'string') return undefined;
    if (NA_RE.test(text)) return 'yt-cell-na';
    if (NA2_RE.test(text)) return 'yt-cell-na2';
    return undefined;
  };
  const expandSimpleTags = (str, keyRef) => {
    const result = [];
    let last = 0;
    SIMPLE_TAG_RE.lastIndex = 0;
    let m;
    while ((m = SIMPLE_TAG_RE.exec(str)) !== null) {
      if (m.index > last) result.push(str.slice(last, m.index));
      if (m[1]) {
        result.push(<br key={keyRef.current++} />);
      } else if (m[2]) {
        result.push(<br key={keyRef.current++} />, <br key={keyRef.current++} />);
      } else if (m[3]) {
        result.push(<span key={keyRef.current++} className="yt-badge-note" style={{
          fontWeight: 600
        }}>Note: </span>);
      } else if (m[4]) {
        result.push(<span key={keyRef.current++} className="yt-badge-warning" style={{
          fontWeight: 600
        }}>Warning: </span>);
      }
      last = m.index + m[0].length;
    }
    if (last < str.length) result.push(str.slice(last));
    return result;
  };
  const expandHtmlTags = (chunks, keyRef) => {
    const out = [];
    for (const chunk of chunks) {
      if (typeof chunk === 'string') {
        out.push(...expandSimpleTags(chunk, keyRef));
      } else {
        out.push(chunk);
      }
    }
    return out;
  };
  const extractText = node => {
    if (node === null || node === undefined) return '';
    if (typeof node === 'string') return node;
    if (typeof node === 'number') return String(node);
    if (typeof node === 'boolean') return '';
    if (Array.isArray(node)) return node.map(extractText).join('');
    if (node && typeof node === 'object' && node.type) {
      const props = node.props || ({});
      if (typeof props.children === 'string') return props.children;
      if (props.children) return extractText(props.children);
      return '';
    }
    return String(node || '');
  };
  const [mounted, setMounted] = useState(false);
  useEffect(() => {
    setMounted(true);
  }, []);
  const data = useMemo(() => {
    if (propData) return propData;
    if (content && typeof content === 'string') return parseYamlTableContent(content);
    if (!children) return [];
    if (typeof children === 'string') return parseYamlTableContent(children);
    const childrenArray = Array.isArray(children) ? children : [children];
    return parseYamlTableContent(childrenArray.map(extractText).join('').trim());
  }, [children, propData, content]);
  const columns = useMemo(() => {
    if (!data || data.length === 0) return [];
    const firstRow = data[0];
    if (!firstRow || typeof firstRow !== 'object') return [];
    return Object.keys(firstRow);
  }, [data]);
  if (!mounted) return null;
  if (!data || data.length === 0) return null;
  const rowKey = row => columns.map(c => row[c] || '').join('|');
  return <table>
      <thead>
        <tr>
          {columns.map(col => <th key={col}>{col.replaceAll('_', ' ')}</th>)}
        </tr>
      </thead>
      <tbody>
        {data.map(row => <tr key={rowKey(row)}>
            {columns.map(col => <td key={col} className={cellClassName(row[col])}>{processBadges(row[col])}</td>)}
          </tr>)}
      </tbody>
    </table>;
};

Here is an overview diagram of the Endor Labs data model for the most commonly used resource kinds. Lighter shading identifies the objects that are re-computed on every scan.

<img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/developers-api/rest-api/data-model.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=25cce4b25e97f870c2a7b0f10b3b553e" alt="data model" width="1315" height="700" data-path="images/developers-api/rest-api/data-model.webp" />

This section describes the most commonly used resource kinds. For a complete list of supported resource kinds, see the [Endor Labs OpenAPI documentation](/api-reference/).

All objects contain a reference to the project UUID, either as the parent object (`meta.parent_uuid`) or a specific field in the object-specific data if the project is not the direct parent (`spec.project_uuid` if not specified otherwise).

Use the following command to get a list of all objects of a given resource kind in your tenant.

Here are a few useful options:

* `--count`
* `--page-size=1`
* `--list-all`
* `--filter="meta.parent_uuid==<uuid>"`
* `--filter="spec.project_uuid==<uuid>"`

```bash theme={null}
endorctl api list -r <resource-kind>
```

## Project

* This is the logical root of all the other information for a given project.
* Contains information about the source code location of a project, such as a Git repository, or a package manager package name.
* Does not have a parent and is not associated with a context.
* The object name is the HTTP clone URL, for example: `"https://github.com/definitelytyped/definitelytyped.git"`.

For more information, see the [ProjectService REST API documentation](/api-reference/projectservice/listprojects).

## Repository

* Contains information about the source code for a project.
* Child of a Project and, just like the Project, does not belong to a context.
* There is at most one Repository per Project, but a Project may not have a Repository if there is no source code.
* The object name is the same as the Project.

For more information, see the [RepositoryService REST API documentation](/api-reference/repositoryservice/listrepositories).

## RepositoryVersion

* Contains information about a specific version of a Repository.
* Has the Project as the parent.
* There are often multiple RepositoryVersions per project.
* Each RepositoryVersion is associated with a [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context).
* The object name is the corresponding branch name, tag, or SHA, for example: `"main"`.

For more information, see the [RepositoryVersionService REST API documentation](/api-reference/repositoryversionservice/listrepositoryversions).

## PackageVersion

* Contains information about a specific version of a package and its dependencies.
* Does not have a parent (for historical reasons), but is associated with a [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) and connected to the Project through `spec.project_uuid`.
* The object name is the corresponding package version name in the format `<ecosystem>://<package-name>@<version>`, for example: `"mvn://org.webjars.npm:types__json-schema@1.2.3"`.

For more information, see the [PackageVersionService REST API documentation](/api-reference/packageversionservice/listpackageversions).

### Resolution errors

Details about any dependency resolution or call graph generation errors for a package version are stored in `spec.resolution_errors`. There are three categories of resolution errors, each with a separate field that can contain up to one resolution error:

1. **Unresolved** - Details in `spec.resolution_errors.unresolved` if there was an error computing the unresolved dependencies.
2. **Resolved** - Details in `spec.resolution_errors.resolved` if there was an error resolving the dependency versions.
3. **Call graph** - Details in `spec.resolution_errors.call_graph` if there was an error generating the call graph.

Each resolution error has a `status_error` field and may also contain details about the `target`, the `operation` that failed, and a `description` of the error. The following status errors are supported:

<YamlTable>
  {`


    - Status_Error: STATUS_ERROR_BUILD
    Description: Indicates that the plugin failed to build the package version. This status error is only used for unresolved dependencies.
    - Status_Error: STATUS_ERROR_CALL_GRAPH
    Description: Indicates that the system failed to create the call graph. This status error is only used for call graph computation.
    - Status_Error: STATUS_ERROR_DEPENDENCY
    Description: Indicates that the system failed to resolve a dependency. In most cases, this happens when a manifest contains bad associations of dependencies and versions. This status error is only used for resolved dependencies.
    - Status_Error: STATUS_ERROR_INTERNAL
    Description: Indicates that there was an internal system failure such as a data stream error.
    - Status_Error: STATUS_ERROR_MANIFEST_LOAD
    Description: Indicates that the system is unable to find the manifest of the language (pom.xml, packages.json, etc). This status error is only used for unresolved dependencies.
    - Status_Error: STATUS_ERROR_MANIFEST_PARSE
    Description: Indicates that the system failed to parse the manifest. This status error is only used for unresolved dependencies.
    - Status_Error: STATUS_ERROR_MISSING_ARTIFACT
    Description: Indicates that the system failed to compute the call graph because the package is not built. This status error is only used for call graph computation.
    - Status_Error: STATUS_ERROR_NO_CODE_ARTIFACT
    Description: Indicates that the package version does not have any source code. This status error is only used for call graphs.
    - Status_Error: STATUS_ERROR_PACKAGE_VERSION_UNAVAILABLE
    Description: Indicates that the package version is not available from the package manager. This status error is only used for unresolved dependencies.
    - Status_Error: STATUS_ERROR_UNSUPPORTED
    Description: Indicates that a package version with an unsupported language was scanned.
    - Status_Error: STATUS_ERROR_VENV
    Description: Indicates that the system failed to create the virtual environment required to generate the call graph. This status error is only applicable to Python projects.

    `}
</YamlTable>

Below is an example resolution error in the **Resolved** category:

```json theme={null}
{
  "spec": {
    "resolution_errors": {
      "resolved": {
        "description": "failed to discover dependency: unable to resolve dependencies for 'requirements': unable to get direct dependencies: unable to install modules to extract dependencies: unable to resolve package version: ResolveModuleVersion: error in pypi json api for: torch, exact version: 1.9.0+cpu, err: package not found in the repository: unable to resolve dependency version: unable to discover dependencies, unable to discover dependencies",
        "operation": "python:resolvedDependencies:discover",
        "status_error": "STATUS_ERROR_DEPENDENCY",
        "target": "pypi://requirements@main"
      }
    }
  }
}
```

## DependencyMetadata

* Different from other common resource kinds as it represents the *relationship* between two PackageVersions: The **importer** and the **dependency**.
* There is one DependencyMetadata object for every dependency for every PackageVersion.
* Has the **importer** PackageVersion as the parent and exists in the same [Namespace](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#tenantmeta) and [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) as the parent.
* The object name is the same as the **dependency** PackageVersion.
* Combine the object name (`meta.name`) and the parent UUID (`meta.parent_uuid`) to get a unique key.
* Connected to the Project through `spec.importer_data.project_uuid`.
* Details about the relationship are stored in `spec.dependency_data`.
  For example:

  * `spec.dependency_data.direct`
  * `spec.dependency_data.reachable`
  * `spec.dependency_data.scope`

For more information, see the [DependencyMetadataService REST API documentation](/api-reference/dependencymetadataservice/listdependencymetadata).

## LinterResult

* Contains the results of scans using third-party programs such as Gitleaks or Semgrep.
* Has a RepositoryVersion or PackageVersion as the parent.
* Belongs to the same [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) as the parent.
* Connected to the Project through `spec.project_uuid`.
* The object name is the name of the rule that created the result, for example: `"gen-shady-links"`.
* The result origin is stored in `spec.origin`, for example: `"LINTER_RESULT_ORIGIN_SECRETS_SCANNER"`.

For more information, see the [LinterResultService REST API documentation](/api-reference/linterresultservice/listlinterresults).

## Metric

* Contains the output of the analytics processing.
* Has a PackageVersion, RepositoryVersion, or Repository as the parent.
* Belongs to the same [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) as the parent.
* Connected to the Project through `spec.project_uuid`.
* The object name is the name of the analytic that created the metric, for example: `"package_version_scorecard"`.

For more information, see the [MetricService REST API documentation](/api-reference/metricservice/listmetrics).

### Metric types

There are many different types of Metrics. The specifics are stored under `spec.metric_values.<key>.<value>`, for example: `spec.metric_values.scorefactor.score_factor_list`. Some Metrics have more than one key-value field under `spec.metric_values`. The following table lists all supported Metric types along with the corresponding paths to the Metric specific data under `spec.metric_values`.

<YamlTable>
  {`


    - Metric_Name: \`github_workflow_posture\`
    Metric_Values_Paths: \`GHWorkflowPosture.github_workflows\`
    Description: Posture management of GitHub Actions workflow yaml files for a repository version.
    - Metric_Name: \`model_scorecard\`
    Metric_Values_Paths: \`scorecard.score_card\`, \`scorefactor.score_factor_list\`
    Description: Scorecard for a model repository.
    - Metric_Name: \`package_version_scorecard\`
    Metric_Values_Paths: \`scorecard.score_card\`, \`scorefactor.score_factor_list\`
    Description: Scorecard for a package version.
    - Metric_Name: \`pkg_version_info_for_license\`
    Metric_Values_Paths: \`licenseInfoType.license_info\`
    Description: License information for a package version.
    - Metric_Name: \`pkg_version_stats_for_dependency\`
    Metric_Values_Paths: \`dependencyStatsType.dependency_stats\`
    Description: Dependency related statistics for a package version.
    - Metric_Name: \`pkg_version_stats_for_linter\`
    Metric_Values_Paths: \`linterStats.linter_stats\`
    Description: Linter related statistics for a package version.
    - Metric_Name: \`pkg_version_stats_for_secret\`
    Metric_Values_Paths: \`secretStats.secret_stats\`
    Description: Secret related statistics for a package version.
    - Metric_Name: \`pkg_version_stats_for_vuln\`
    Metric_Values_Paths: \`vulnerabilityStatsType.vulnerability_stats\`, \`publishedVulnerabilitiesStatsType.time_tracker\`
    Description: Vulnerability related statistics for a package version.
    - Metric_Name: \`repo_activity_for_commit\`
    Metric_Values_Paths: \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: Commit activity for a repository.
    - Metric_Name: \`repo_activity_for_issue\`
    Metric_Values_Paths: \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: Issue activity for a repository.
    - Metric_Name: \`repo_activity_for_pr\`
    Metric_Values_Paths: \`allActivityTrackerType.time_tracker\`, \`accountActivityTrackerType.time_tracker\`, \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: PR activity for a repository.
    - Metric_Name: \`repo_scorecard\`
    Metric_Values_Paths: \`scorecard.score_card\`, \`scorefactor.score_factor_list\`
    Description: Scorecard for a repository.
    - Metric_Name: \`repo_scpm_data\`
    Metric_Values_Paths: \`ScpmDataType.scpm_data\`
    Description: RSPM data for a repository.
    - Metric_Name: \`repo_stats_for_dependency\`
    Metric_Values_Paths: \`dependencyStatsType.dependency_stats\`
    Description: Dependency related statistics for a repository version.
    - Metric_Name: \`repo_stats_for_file\`
    Metric_Values_Paths: \`fileStats.file_stats\`
    Description: File related statistics for a repository version.
    - Metric_Name: \`version_activity_for_commit\`
    Metric_Values_Paths: \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: Commit activity of a repository version.
    - Metric_Name: \`version_activity_for_issue\`
    Metric_Values_Paths: \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: Issue activity of a repository version.
    - Metric_Name: \`version_activity_for_pr\`
    Metric_Values_Paths: \`allActivityTrackerType.time_tracker\`, \`accountActivityTrackerType.time_tracker\`, \`locationActivityTrackerType.time_tracker\`, \`locationActivityCountType.tag_counts\`
    Description: PR activity of a repository version.
    - Metric_Name: \`version_cicd_tools\`
    Metric_Values_Paths: \`CiCdTools.ci_cd_tools\`
    Description: List of CI/CD Tools for a repository version.
    - Metric_Name: \`version_scorecard\`
    Metric_Values_Paths: \`scorecard.score_card\`, \`scorefactor.score_factor_list\`
    Description: Scorecard for a repository version.
    - Metric_Name: \`version_stats_for_dependency\`
    Metric_Values_Paths: \`dependencyStatsType.dependency_stats\`
    Description: Dependency related statistics for a repository version.
    - Metric_Name: \`version_stats_for_file\`
    Metric_Values_Paths: \`fileStats.file_stats\`
    Description: File related statistics for a repository version.
    - Metric_Name: \`version_stats_for_vuln\`
    Metric_Values_Paths: \`vulnerabilityStatsType.vulnerability_stats\`, \`publishedVulnerabilitiesStatsType.time_tracker\`
    Description: Vulnerability related statistics for a package version.

    `}
</YamlTable>

## Finding

* Contains details of a problem that needs to be fixed.
* Has a PackageVersion, RepositoryVersion, or Repository as the parent.
* Belongs to the same [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) as the parent.
* Connected to the Project through `spec.project_uuid`.
* There are many different types of Findings and new types can be created by custom [Finding Policies](/platform-administration/policies/finding-policies).
* The object name is the Finding type, for example: `"outdated_release"`. For more information, see [Finding names and metadata](#finding-names-and-metadata) below.
* The object description contains a more specific description of the Finding, for example: `"Outdated Dependency @babel/plugin-syntax-async-generators@7.8.4"`.
* Additional finding type specific data is stored in `spec.finding_metadata`, for example: `spec.finding_metadata.vulnerability`.
* PackageVersion Findings often involve both the root PackageVersion and a dependency PackageVersion. The following details about the dependency PackageVersion are available directly in the Finding object:
  * `spec.target_dependency_name`, for example: `"@babel/plugin-syntax-async-generators"`
  * `spec.target_dependency_package_name`, for example: `"npm://@babel/plugin-syntax-async-generators@7.8.4"`
  * `spec.target_dependency_version`, for example: `"7.8.4"`
  * `spec.finding_metadata.dependency_package_version_metadata`
* The UUID of the DependencyMetadata for the dependency is stored in `spec.target_uuid`.
* There is one Finding object for every PackageVersion that includes a dependency with a given problem. If 10 PackageVersions include a dependency with a vulnerability then there will be 10 findings for the vulnerability.

For more information, see the [FindingService REST API documentation](/api-reference/findingservice/listfindings).

### Finding names and metadata

The following table lists all supported values for the Finding `meta.name` field along with an example value for the corresponding `meta.description` and an explanation.

<YamlTable>
  {`


    - Finding_Name: \`archived_source_code_repo\`
    Example_Description: \`Unmaintained Dependency derive-error-chain@0.10.1\`
    Explanation: The source code repository for this package is archived. There is no additional metadata for this finding type.
    - Finding_Name: \`bad_license\`
    Example_Description: \`License Risk in Dependency org.codehaus.plexus:plexus-io@2.0.3\`
    Explanation: The repository for this package is either missing a license or the license found is problematic. There is no additional metadata for this finding type.
    - Finding_Name: \`dependency_with_critical_vulnerabilities\`
    Example_Description: \`GHSA-65fg-84f6-3jq3: SQL Injection in Log4j 1.2.x\`
    Explanation: A critical severity known vulnerability has been assessed against this version of the software package according to the information in \`OSV.dev\`. Additional information about the vulnerability is stored in \`spec.finding_metadata.vulnerability\`.
    - Finding_Name: \`dependency_with_high_severity_vulnerabilities\`
    Example_Description: \`GHSA-w9p3-5cr8-m3jj: Deserialization of Untrusted Data in Log4j 1.x\`
    Explanation: This package version contains a vulnerability that has been marked as high severity according to the information in \`OSV.dev\`. Additional information about the vulnerability is stored in \`spec.finding_metadata.vulnerability\`.
    - Finding_Name: \`dependency_with_low_activity_score\`
    Example_Description: \`Dependency tempdir@0.3.7 With Low Activity Score\`
    Explanation: This package may be unmaintained, as determined by multiple factors contributing to a low activity score. Reliance on packages that are no longer maintained can make it costly or unreasonable to fix significant security risks, or quality issues. This may render the package obsolete over time. By relying on an unmaintained software package, organizations may assume the cost of maintenance and have a longer lead time for fixes on any security issues, if they are fixed at all. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_low_popularity_score\`
    Example_Description: \`Dependency unicode-canonical-property-names-ecmascript@2.0.0 With Low Popularity Score\`
    Explanation: Popularity is a social proxy for quality. Popular packages are more likely to remain maintained and thoroughly tested. Relying on lesser known packages for critical functions may increase operational risk. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_low_quality_score\`
    Example_Description: \`Dependency org.slf4j:slf4j-api@1.7.6 With Low Quality Score\`
    Explanation: This package may have an increased risk of bugs and quality issues as determined by multiple factors contributing to a low-quality score. A low quality score indicates a project may have an immature software development practice. Relying on packages that do not follow code development best practices can result in an increased risk of security and operational problems. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_low_severity_vulnerabilities\`
    Example_Description: \`GHSA-5mg8-w23w-74h3: Information Disclosure in Guava\`
    Explanation: This package version contains a vulnerability that has been marked as low severity according to the information in \`OSV.dev\`. Additional information about the vulnerability is stored in \`spec.finding_metadata.vulnerability\`.
    - Finding_Name: \`dependency_with_malicious_package\`
    Example_Description: \`MAL-2023-462: Malicious code in fsevents (npm)\`
    Explanation: This version of the software package is considered malware according to \`OSV.dev\`. Additional information about the malware advisory is stored in \`spec.finding_metadata.vulnerability\`.
    - Finding_Name: \`dependency_with_medium_severity_vulnerabilities\`
    Example_Description: \`GHSA-269g-pwp5-87pp: TemporaryFolder on unix-like systems does not limit access to created files\`
    Explanation: This package version contains a vulnerability that has been marked as medium severity according to the information in \`OSV.dev\`. Additional information about the vulnerability is stored in \`spec.finding_metadata.vulnerability\`.
    - Finding_Name: \`dependency_with_multiple_low_scores\`
    Example_Description: \`Dependency esformatter-remove-trailing-commas@1.0.1 With Multiple Low Scores\`
    Explanation: This package version has received low scores across more than one categories. This is stronger indication that the package may be problematic and presents an increased risk for security and operational problems. Additional information about the scores is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_very_low_activity_score\`
    Example_Description: \`Dependency is-finite@1.1.0 With Very Low Activity Score\`
    Explanation: This package is very likely to be unmaintained, as determined by multiple factors contributing to a very low activity score. Reliance on packages that are no longer maintained can make it costly or unreasonable to fix significant security risks, or quality issues. This may render the dependency obsolete over time. By relying on an unmaintained software package, organizations may assume the cost of maintenance and have a longer lead time for fixes on any security issues, if they are fixed at all. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_very_low_popularity_score\`
    Example_Description: \`Dependency http-range-header@0.3.0 With Very Low Popularity Score\`
    Explanation: Popularity is a social proxy for quality. Popular packages are more likely to remain maintained and thoroughly tested. Relying on lesser known packages for critical functions may increase operational risk. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`dependency_with_very_low_quality_score\`
    Example_Description: \`Dependency org.apache.sis.core:sis-utility@1.1 With Very Low Quality Score\`
    Explanation: This package is likely to have an increased risk of bugs and quality issues as determined by multiple factors contributing to a very low-quality score. A low quality score indicates a project may have an immature software development practice. Relying on packages that do not follow code development best practices can result in an increased risk of security and operational problems. Additional information about the score is stored in \`spec.finding_metadata.dependency_score_card\` and \`spec.finding_metadata.dependency_score_factor_list\`.
    - Finding_Name: \`missing_source_code\`
    Example_Description: \`Missing Source Code Repository for Dependency commons-dbcp:commons-dbcp@1.4\`
    Explanation: The package versions source code reference is not currently available. As a result, automated analysis of the package's activity, popularity, code quality and security have not been performed. Manual assessment is required to assess the operational and security risk of this package. There is no additional metadata for this finding type.
    - Finding_Name: \`outdated_release\`
    Example_Description: \`Outdated Dependency @babel/plugin-syntax-async-generators@7.8.4\`
    Explanation: This package has had multiple later releases or a significant period of time has passed since the release of the version currently in use. Relying on outdated dependencies can result in missing important bug fixes or security patches and make upgrades more difficult. There is no additional metadata for this finding type. A dependency is considered outdated if it is older than 10 months and at least 5 releases behind the latest release.
    - Finding_Name: \`policy_finding\`
    Example_Description: \`Code owner approval is not required\`
    Explanation: The finding was created by a [Rego policy](/platform-administration/policies/finding-policies). The policy UUID is stored in \`spec.finding_metadata.source_policy_info.uuid\`.
    - Finding_Name: \`recently_released_dependency\`
    Example_Description: \`Recently Released Dependency chalk@5.6.1\`.
    Explanation: This package version is using a recent release of a dependency. Recently released versions of dependencies are more likely to introduce supply chain risk and breaking changes.
    - Finding_Name: \`typosquatted_dependency\`
    Example_Description: \`Dependency serverles@3.27.1 is a Potential Typosquat\`
    Explanation: The name of the dependency is very similar to another package which is more popular and widely used. It is possible that this is a malicious package in the package manager with malware inserted. Additional information about the typosquatted dependency is stored in \`spec.finding_metadata.typosquatted_dependency_version_metadata\`.
    - Finding_Name: \`unpinned_direct_dependency\`
    Example_Description: \`Unpinned Direct Dependency num-integer@0.1.45\`
    Explanation: This package version has not pinned one of its direct dependencies. Dependencies that are not pinned to a specified version decrease the likelihood of build reproducibility and can be unexpectedly updated, which may introduce operational or security issues into your application. Unpinned dependencies expose organizations to the risk of software supply chain attacks where attackers compromise the upstream software dependency and publish a malicious version of the code. There is no additional metadata for this finding type.
    - Finding_Name: \`unreachable_direct_dependency\`
    Example_Description: \`Unused Direct Dependency org.typelevel:macro-compat_2.11@1.1.1\`
    Explanation: Static analysis of this software package indicates that this direct dependency is unused. Unused direct dependencies unnecessarily increase the size of executables, application resource utilization and, increase build time and as a result may decrease developer productivity and application performance. There is no additional metadata for this finding type.

    `}
</YamlTable>

### Finding categories

The following finding categories are supported as possible values in the `spec.finding_categories` list. All findings must have at least one category.

<YamlTable>
  {`


    - Finding_Category: \`FINDING_CATEGORY_AI_MODELS\`
    UI_Category: AI Models
    Description: AI model findings
    - Finding_Category: \`FINDING_CATEGORY_CICD\`
    UI_Category: CI/CD
    Description: CI/CD pipeline findings
    - Finding_Category: \`FINDING_CATEGORY_CONTAINER\`
    UI_Category: Container
    Description: Container findings
    - Finding_Category: \`FINDING_CATEGORY_GHACTIONS\`
    UI_Category: GitHub Actions
    Description: GitHub action findings
    - Finding_Category: \`FINDING_CATEGORY_LICENSE_RISK\`
    UI_Category: License Risk
    Description: License issues
    - Finding_Category: \`FINDING_CATEGORY_MALWARE\`
    UI_Category: Malware
    Description: Malware findings
    - Finding_Category: \`FINDING_CATEGORY_OPERATIONAL\`
    UI_Category: Operational
    Description: Operational issues
    - Finding_Category: \`FINDING_CATEGORY_SAST\`
    UI_Category: SAST
    Description: SAST findings
    - Finding_Category: \`FINDING_CATEGORY_SCA\`
    UI_Category: SCA
    Description: Software Composition Analysis issues
    - Finding_Category: \`FINDING_CATEGORY_SCPM\`
    UI_Category: RSPM
    Description: Repository security posture management issues
    - Finding_Category: \`FINDING_CATEGORY_SECRETS\`
    UI_Category: Secrets
    Description: Exposed secrets
    - Finding_Category: \`FINDING_CATEGORY_SECURITY\`
    UI_Category: Security
    Description: Security issues
    - Finding_Category: \`FINDING_CATEGORY_SUPPLY_CHAIN\`
    UI_Category: Supply Chain
    Description: Supply chain specific problems (malicious packages, typosquats)
    - Finding_Category: \`FINDING_CATEGORY_TOOLS\`
    UI_Category: Tools
    Description: Tool-related findings
    - Finding_Category: \`FINDING_CATEGORY_VULNERABILITY\`
    UI_Category: Vulnerability
    Description: Vulnerability findings

    `}
</YamlTable>

### Finding tags

The following system defined finding tags are supported as possible values in the `spec.finding_tags` list and referred to as "attributes" in the Endor Labs user interface. These are different from the free-form custom tags that are stored in the [Meta](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#meta) field.

<YamlTable>
  {`


    - Finding_Tag: \`FINDING_TAGS_CI_BLOCKER\`
    UI_Attribute: Blocker
    Description: Finding was marked as blocking by one or more action policies. The policy UUIDs are stored in \`spec.actions.policy_uuids\`.
    - Finding_Tag: \`FINDING_TAGS_CI_WARNING\`
    UI_Attribute: Warning
    Description: Finding triggered a warning based on one or more action policies. The policy UUIDs are stored in \`spec.actions.policy_uuids\`.
    - Finding_Tag: \`FINDING_TAGS_DIRECT\`
    UI_Attribute: Direct
    Description: Finding applies to a direct dependency.
    - Finding_Tag: \`FINDING_TAGS_DISPUTED\`
    UI_Attribute: Disputed
    Description: The CVE reported in this finding has been marked as 'disputed'.
    - Finding_Tag: \`FINDING_TAGS_EXCEPTION\`
    UI_Attribute: Exception
    Description: Finding was marked as exempt from action policies by one or more exception policies. The policy UUIDs are stored in \`spec.exceptions.policy_uuids\`.
    - Finding_Tag: \`FINDING_TAGS_EXPLOITED\`
    UI_Attribute: Exploited
    Description: The CVE reported in this finding is actively exploited and is listed in the Known Exploited Vulnerabilities (KEV) database.
    - Finding_Tag: \`FINDING_TAGS_FIX_AVAILABLE\`
    UI_Attribute: Fix Available
    Description: There is a fix available for the CVE reported in this finding.
    - Finding_Tag: \`FINDING_TAGS_INVALID_SECRET\`
    UI_Attribute: Invalid Secret
    Description: Finding applies to an invalid secret.
    - Finding_Tag: \`FINDING_TAGS_MALWARE\`
    UI_Attribute: Malware
    Description: Finding applies to a malicious package.
    - Finding_Tag: \`FINDING_TAGS_NAMESPACE_INTERNAL\`
    UI_Attribute: First Party
    Description: Finding applies to a dependency that belongs to the same namespace.
    - Finding_Tag: \`FINDING_TAGS_NORMAL\`
    UI_Attribute: Normal
    Description: Finding applies to a normal, non-test, dependency.
    - Finding_Tag: \`FINDING_TAGS_NOTIFICATION\`
    UI_Attribute: Notification
    Description: Finding triggered a notification based on one or more action policies. The policy UUIDs are stored in \`spec.actions.policy_uuids\`.
    - Finding_Tag: \`FINDING_TAGS_PATH_EXTERNAL\`
    UI_Attribute: External Path Only
    Description: Finding applies to a transitive dependency that can only be reached through external, non-OSS, project paths.
    - Finding_Tag: \`FINDING_TAGS_PHANTOM\`
    UI_Attribute: Phantom
    Description: Finding applies to a phantom dependency.
    - Finding_Tag: \`FINDING_TAGS_SEGMENT_MATCH\`
    UI_Attribute: Segment Match
    Description: Finding applies to a dependency discovered through segment-matching.
    - Finding_Tag: \`FINDING_TAGS_POTENTIALLY_REACHABLE_DEPENDENCY\`
    UI_Attribute: Potentially Reachable Dependency
    Description: Finding applies to a potentially reachable dependency.
    - Finding_Tag: \`FINDING_TAGS_POTENTIALLY_REACHABLE_FUNCTION\`
    UI_Attribute: Potentially Reachable Function
    Description: Finding applies to a potentially reachable function.
    - Finding_Tag: \`FINDING_TAGS_PROJECT_INTERNAL\`
    UI_Attribute: Same Repository
    Description: Finding applies to a dependency that belongs to the same project.
    - Finding_Tag: \`FINDING_TAGS_REACHABLE_DEPENDENCY\`
    UI_Attribute: Reachable Dependency
    Description: Finding applies to a reachable dependency.
    - Finding_Tag: \`FINDING_TAGS_REACHABLE_FUNCTION\`
    UI_Attribute: Reachable Function
    Description: Finding applies to a reachable function.
    - Finding_Tag: \`FINDING_TAGS_SELF\`
    UI_Attribute: Self
    Description: Finding applies only to the analyzed package version, there is no dependency involved.
    - Finding_Tag: \`FINDING_TAGS_SNOOZED\`
    UI_Attribute: Snoozed
    Description: Finding has been manually snoozed. The details are stored in \`spec.snooze\` and \`spec.dismiss\` is set to \`true\`.
    - Finding_Tag: \`FINDING_TAGS_TEST\`
    UI_Attribute: Test
    Description: Finding applies to a dependency that is not in production code.
    - Finding_Tag: \`FINDING_TAGS_TRANSITIVE\`
    UI_Attribute: Transitive
    Description: Finding applies to a transitive (indirect) dependency.
    - Finding_Tag: \`FINDING_TAGS_UNDER_REVIEW\`
    UI_Attribute: Under Review
    Description: Finding applies to suspicious package under review.
    - Finding_Tag: \`FINDING_TAGS_UNFIXABLE\`
    UI_Attribute: Unfixable
    Description: There is no fix available for the CVE reported in this finding.
    - Finding_Tag: \`FINDING_TAGS_UNREACHABLE_DEPENDENCY\`
    UI_Attribute: Unreachable Dependency
    Description: Finding applies to an unreachable dependency.
    - Finding_Tag: \`FINDING_TAGS_UNREACHABLE_FUNCTION\`
    UI_Attribute: Unreachable Function
    Description: Finding applies to an unreachable function.
    - Finding_Tag: \`FINDING_TAGS_VALID_SECRET\`
    UI_Attribute: Valid Secret
    Description: Finding applies to a valid secret.
    - Finding_Tag: \`FINDING_TAGS_WITHDRAWN\`
    UI_Attribute: Withdrawn
    Description: The CVE reported in this finding has been marked as 'withdrawn'.

    `}
</YamlTable>

### Exceptions

A finding can be exempt from triggering action policies (such as admission and notification policies)
if it is matched and marked as dismissed by an exception policy.

[Exception policies](/platform-administration/policies/exception-policies) allow you to set any criteria
you want to mark findings as dismissed. You can apply an exception policy across all projects, a sub-set of projects,
or a specific project, within a tenant.
Based on the criteria you set, the exception can persist across multiple package versions.

Findings dismissed by one or more exception policies have the `spec.dismiss` field set to `true` and
the corresponding policy object UUIDs are listed under the `spec.exceptions.policy_uuids` field.
They also carry the `FINDING_TAGS_EXCEPTION` tag.

### Action policies

Findings matched by one or more action policies (a.k.a. admission and notification policies)
contain the corresponding policy object UUIDs in `spec.actions.policy_uuids`.
They also carry a tag corresponding to the specific action, for example, `FINDING_TAGS_CI_WARNING`,
`FINDING_TAGS_CI_BLOCKER`, or `FINDING_TAGS_NOTIFICATION`.

## ScanResult

* Contains details of a scan such as:
  * Configuration
  * Host environment details
  * Runtime statistics
  * Findings
  * Policies triggered
  * Error logs
  * [Exit code](/best-practices/troubleshooting/endorctl-exitcodes)
  * [Scan status](#scan-status)
* Has the Project as the parent.
* Belongs to the same [Context](/developers-api/rest-api/using-the-rest-api/data-model/common-fields#context) as the scan.

For more information, see the [ScanResultService REST API documentation](/api-reference/scanresultservice/listscanresults).

### Scan status

The following scan statuses are supported:

<YamlTable>
  {`

    - Status: \`STATUS_SUCCESS\`
    Description: Scan completed successfully.
    - Status: \`STATUS_PARTIAL_SUCCESS\`
    Description: Scan completed, but with critical warnings or errors. See \`spec.logs\` for more information.
    - Status: \`STATUS_FAILURE\`
    Description: Scan failed. See \`spec.exit_code\` and the [exit code documentation](/best-practices/troubleshooting/endorctl-exitcodes) for more information.
    - Status: \`STATUS_RUNNING\`
    Description: Scan is running.

    `}
</YamlTable>
