> ## 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.

# Configure build tools

> Learn about build tools to build repeatable patterns in your scan environment.

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 renderSuccessIcon = () => <svg viewBox="0 0 24 24" width="100%" height="100%" aria-hidden="true">
      <path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z" fill="currentColor" />
    </svg>;
  const renderFailureIcon = () => <svg viewBox="0 0 24 24" width="100%" height="100%" aria-hidden="true">
      <path fillRule="evenodd" clipRule="evenodd" d="M11.9902 1.98633C12.5208 1.9864 13.0426 2.12743 13.501 2.39453C13.9581 2.66107 14.3372 3.04388 14.5986 3.50391L22.5967 17.5L22.6895 17.6738C22.8921 18.0851 22.9979 18.5387 22.9981 18.999C22.9981 19.5253 22.8605 20.0431 22.5977 20.499C22.3348 20.9549 21.9555 21.3332 21.5 21.5967C21.0445 21.8601 20.5272 21.9994 20.001 22H4.00001C3.47453 22.0031 2.95699 21.868 2.50001 21.6084C2.04032 21.3471 1.65712 20.9684 1.39063 20.5117C1.12431 20.055 0.983643 19.5355 0.982429 19.0068C0.981281 18.4793 1.11967 17.9611 1.38282 17.5039L9.38184 3.50391C9.64344 3.04359 10.023 2.66111 10.4805 2.39453C10.9388 2.12755 11.4598 1.98636 11.9902 1.98633ZM12 16.9004C11.3925 16.9004 10.9004 17.3925 10.9004 18C10.9004 18.6075 11.3925 19.0996 12 19.0996H12.0098C12.6173 19.0996 13.1104 18.6075 13.1104 18C13.1104 17.3925 12.6173 16.9004 12.0098 16.9004H12ZM12 5.90039C11.3925 5.9004 10.9004 6.39249 10.9004 7V13C10.9004 13.6075 11.3925 14.0996 12 14.0996C12.6075 14.0996 13.0996 13.6075 13.0996 13V7C13.0996 6.39249 12.6075 5.90039 12 5.90039Z" fill="currentColor" />
    </svg>;
  const renderPartialSuccessIcon = () => <svg viewBox="0 0 24 24" width="100%" height="100%" aria-hidden="true">
      <path d="M12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1ZM12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3ZM12 5C13.8565 5 15.6374 5.73705 16.9502 7.0498C18.263 8.36256 19 10.1435 19 12C19 13.8565 18.263 15.6374 16.9502 16.9502C15.6374 18.263 13.8565 19 12 19C11.4477 19 11 18.5523 11 18V6C11 5.73478 11.1054 5.4805 11.293 5.29297C11.4805 5.10543 11.7348 5 12 5Z" fill="currentColor" />
    </svg>;
  const renderPendingIcon = () => <svg viewBox="0 0 24 24" width="100%" height="100%" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true">
      <path d="M10.1 2.182a10 10 0 0 1 3.8 0" />
      <path d="M13.9 21.818a10 10 0 0 1-3.8 0" />
      <path d="M17.609 3.721a10 10 0 0 1 2.69 2.7" />
      <path d="M2.182 13.9a10 10 0 0 1 0-3.8" />
      <path d="M20.279 17.609a10 10 0 0 1-2.7 2.69" />
      <path d="M21.818 10.1a10 10 0 0 1 0 3.8" />
      <path d="M3.721 6.391a10 10 0 0 1 2.7-2.69" />
      <path d="M6.391 20.279a10 10 0 0 1-2.69-2.7" />
    </svg>;
  const renderRunningIcon = () => <svg className="yt-status-running-svg" viewBox="22 22 44 44" width="100%" height="100%" aria-hidden="true">
      <circle className="yt-status-running-circle" cx="44" cy="44" r="20.2" fill="none" stroke="currentColor" strokeWidth="3.6" />
    </svg>;
  const renderSkippedIcon = () => <svg viewBox="0 0 24 24" width="100%" height="100%" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <circle cx="12" cy="12" r="10" />
      <path d="M8 12h8" />
    </svg>;
  const STATUS_ICON_DEFS = [{
    re: /^-status-success-$/i,
    colorClass: 'yt-status-color-success',
    label: 'Success',
    render: renderSuccessIcon
  }, {
    re: /^-status-failure-$/i,
    colorClass: 'yt-status-color-failure',
    label: 'Failure',
    render: renderFailureIcon
  }, {
    re: /^-status-partial-success-$/i,
    colorClass: 'yt-status-color-partial',
    label: 'Partial success',
    render: renderPartialSuccessIcon
  }, {
    re: /^-status-pending-$/i,
    colorClass: 'yt-status-color-neutral',
    label: 'Pending',
    render: renderPendingIcon
  }, {
    re: /^-status-running-$/i,
    colorClass: 'yt-status-color-neutral',
    label: 'Running',
    render: renderRunningIcon
  }, {
    re: /^-status-skipped-$/i,
    colorClass: 'yt-status-color-neutral',
    label: 'Skipped',
    render: renderSkippedIcon
  }];
  const renderStatusBadge = def => <span className={['yt-status-icon', def.colorClass].join(' ')} role="img" aria-label={def.label} title={def.label}>
      {def.render()}
    </span>;
  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>;
    const statusBadge = STATUS_ICON_DEFS.find(def => def.re.test(text));
    if (statusBadge) return renderStatusBadge(statusBadge);
    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);
  const scrollWrapRef = useRef(null);
  const [isScrollable, setIsScrollable] = 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]);
  useEffect(() => {
    const wrap = scrollWrapRef.current;
    if (!wrap) return undefined;
    const updateScrollable = () => {
      setIsScrollable(wrap.scrollWidth > wrap.clientWidth);
    };
    updateScrollable();
    const observer = new ResizeObserver(updateScrollable);
    observer.observe(wrap);
    return () => observer.disconnect();
  }, [mounted, data]);
  if (!mounted) return null;
  if (!data || data.length === 0) return null;
  const rowKey = row => columns.map(c => row[c] || '').join('|');
  return <div ref={scrollWrapRef} style={{
    overflowX: 'auto',
    margin: '1.75rem 0'
  }} role={isScrollable ? 'region' : undefined} aria-label={isScrollable ? 'Scrollable table' : undefined} tabIndex={isScrollable ? 0 : undefined}>
      <table style={{
    display: 'table',
    width: '100%',
    minWidth: '100%',
    margin: 0
  }}>
        <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>
    </div>;
};

Endor Labs uses build tools to scan projects, generate reliable Software Bill of Materials (SBOM), and detect security or operational risks. For languages like Java, Python, and .NET that depend on the build environment, it relies on specific runtime or package manager versions to ensure precise results. When tools are missing, you can define and install them in the CLI, and Endor Labs sets them up in an isolated sandbox during the scan. This feature is supported on Linux and macOS.

You need to [install and initialize](/developers-api/cli/install-and-configure) endorctl before configuring the build toolchains in a scan profile.

## Toolchain priority in monitoring scans

Endor Labs [SCM integrations](/setup-deployment/scm-integrations) continuously monitor your projects for security and operational risks. Each app monitors the projects in your organization and runs a scan once every 24 hours.

For performing scans, the SCM apps check the toolchain specifications in the following order:

1. Scan workflow, if present.
2. Toolchain configuration specified through endorctl API.
3. Toolchain configuration specified in `scanprofile.yaml` file.
4. Enable auto detection to automatically detect the toolchains from your manifest files.
5. Uses the system defaults.

## Configure build tools for endorctl scans

After [installing and initializing](/developers-api/cli/install-and-configure) endorctl, run the endorctl scan with the `--install-build-tools` flag to automatically download and install any missing toolchains in an isolated sandbox to properly execute language-specific scans and dependency resolution.

1. For the first time, run the endorctl scan to create a project with Endor Labs.

   ```bash theme={null}
   endorctl scan
   ```

2. Run the following command to automatically download and install build tools as part of your scan.

   ```bash theme={null}
   endorctl scan --install-build-tools
   ```

3. The system checks for the required toolchain specifications in the following order before installing them in the sandbox.

   * [Configure scan workflow through endorctl API](/scan/scan-profiles/configure-scan-workflow-through-api)
   * [Configure toolchain profile through endorctl API](/scan/scan-profiles/configure-scanprofile-api)
   * [Configure toolchain profile in the profile.yaml file](/scan/scan-profiles/configure-scanprofile-yaml)
   * [Automatically detect toolchain profiles](/scan/scan-profiles/auto-detect-toolchains)
   * [Uses the system defaults](#system-default-toolchain-versions)

## Scan with a preconfigured build environment

If your build tools are already installed in your scan environment, use `--use-scan-profile` to apply the project's scan profile configuration without downloading and installing tools in a new sandbox. Endor Labs fetches the scan profile associated with the project and applies its automated scan parameters, including custom paths, environment variables, and any custom scripts, using the tools already available on the machine.

This approach is useful when you have a container or CI runner with the required tools already installed and you want the scan profile to control scan behavior.

Before you run the scan:

1. Verify that the project already exists in Endor Labs. If it does not, run `endorctl scan` first to create it.
2. Configure a scan profile for the project. See [Configure scan profile through the Endor Labs user interface](/scan/scan-profiles/configure-scanprofile-ui), [through the API](/scan/scan-profiles/configure-scanprofile-api), or [through a YAML file](/scan/scan-profiles/configure-scanprofile-yaml).
3. Verify that the required build tools are installed on the machine.

To scan using the project's scan profile, run:

```bash theme={null}
endorctl scan --use-scan-profile
```

<Note>
  `--use-scan-profile` and `--install-build-tools` cannot be used at the same time. Use `--install-build-tools` if you want to download and install build tools rather than using pre-installed ones.
</Note>

## System default toolchain versions

If you do not provide a tool profile, the default toolchains are installed in the sandbox while performing the endorctl scan with the `install-build-tools` flag. See [Toolchain support matrix](#toolchain-support-matrix) for details on default versions.

### Toolchain support matrix

The following table outlines the toolchain profile support details across different languages and platforms.

<YamlTable>
  {`


    - Dependencies: **Java**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Java 8, 11, 17, 21, 25
    Default_Version: Java 17
    Platform: Linux, Darwin
    - Dependencies: **Maven**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Maven 3.8.8, 3.9.4, 3.9.5, 3.9.6, 3.9.7, 3.9.8, 3.9.9, 3.9.10, 3.9.11, 3.9.15, 3.9.16
    Default_Version: Maven 3.9.4
    Platform: Linux, Darwin
    - Dependencies: **Gradle**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Gradle 6.9.4, 7.6.4, 8.4, 9.0.0
    Default_Version: Gradle 8.4
    Platform: Linux, Darwin
    - Dependencies: **Python**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13
    Default_Version: Python 3.10
    Platform: Linux, Darwin
    - Dependencies: **NodeJS**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Node.js 16.20, 18.20, 20.10, 20.15, 20.19, 22.18, 24.6, 24.7, 24.8, 24.12, 25.4, 26.0
    Default_Version: Node.js 20.10.0
    Platform: Linux, Darwin
    - Dependencies: **Yarn**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Yarn 1.22, 2, 3, 4.9.1, 4.13.0
    Default_Version: Yarn 1.22.19
    Platform: Linux, Darwin
    - Dependencies: **pnpm**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: pnpm 6.35, 7.33, 8.10, 8.15, 9.15, 10.14, 10.15, 10.16, 11.9, 11.20, 11.21, 11.22, 11.25
    Default_Version: pnpm 8.10.2
    Platform: Linux, Darwin
    - Dependencies: **Golang**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Golang 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.21, 1.22, 1.23, 1.24, 1.25, 1.26
    Default_Version: Golang 1.24.6
    Platform: Linux, Darwin
    - Dependencies: **.NET**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: .NET 6, 7, 8, 9, 10
    Default_Version: .NET 7.0.401
    Platform: Linux, Darwin
    - Dependencies: **Scala**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Scala 1.9.0, 1.10.0, 1.11.0
    Default_Version: Scala 1.9.0
    Platform: Linux, Darwin
    - Dependencies: **Rust**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Rust 1.77.0, 1.89.0, 1.97.0, 1.98.1
    Default_Version: Rust 1.89.0
    Platform: Linux, Darwin
    - Dependencies: **Kotlin**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection:
    Default_Version: Java 17
    Platform: Linux, Darwin
    - Dependencies: **Typescript**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: 16.20, 18.20, 20.10, 20.15, 20.19, 22.18, 24.6, 24.7, 24.8, 24.12, 25.4, 26.0
    Default_Version: Node.js 20.10.0
    Platform: Linux, Darwin
    - Dependencies: **Android**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection:
    Default_Version: platform-tools
    Platform: Linux, Darwin
    - Dependencies: **PHP**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection:
    Default_Version: 8.2
    Platform: Linux
    - Dependencies: **Composer**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection:
    Default_Version: Composer 2.6
    Platform: Linux
    - Dependencies: **Ruby**
    Support_for_API: Supported
    Support_for_profile_yaml: Supported
    Support_for_Auto_detection: Ruby 3.2.1, 3.2.9, 3.3.9, 3.4.5, 3.4.10
    Default_Version: Ruby 3.2.9
    Platform: Linux


    `}
</YamlTable>

<Note>
  .NET 5 and earlier versions are not supported for auto detection or manual configuration.
</Note>

<Note>
  If a project uses Java 8, Endor Labs installs both Java 8 and Java 17.0.11. It builds the project with Java 8 and scans it with Java 17.
</Note>

## Configure automated scan parameters

Automated scan parameters are endorctl parameters and environment variables that you define in a scan profile. They apply to projects linked to that profile and help customize scan behavior during cloud scans.

You can define the following parameters in your scan profile:

* **included\_paths**: Enable to specify a list of paths to include in the scan.

* **excluded\_paths**: Enable to specify a list of paths to exclude from the scan. Excluded paths do not apply to secrets scanning. Secrets detection always scans the full repository. To filter or suppress secret findings, use policies or a `.gitleaksignore` file instead.

* **languages**: Enable to specify a list of languages to scan. If empty, default values are used.

* **call\_graph\_languages**: Enable to specify a list of languages to use for generating call graphs. If empty, default values are used.

* **segment\_match\_languages**: Enable to specify a list of languages to scan using segment-based analysis.

* **additional\_environment\_variables**: Enable to specify additional environment variables to set during the scan. Only the environment variables starting with `ENDOR_` are passed to the scan, all others are ignored. See [Global flags and environment variables](/developers-api/cli/environment-variables) for a complete list of available environment variables.

* **enable\_automated\_pr\_scans**: Enables automatic scanning of pull request changes.

* **enable\_pr\_comments**: Enables adding scan results as comments in pull requests.

* **enable\_sast\_scan**: Enables SAST during the scanning process.

* **disable\_code\_snippet\_storage**: Disables the storage of code snippets.

If you are using Bazel in your build, you can further configure:

* **bazel\_configuration**: Enable to specify configuration settings for Bazel scans. See [Bazel flags](/developers-api/cli/commands/scan#bazel-flags) for more details.

* **bazel\_show\_internal\_targets**: Enable to include internal build targets in the dependency analysis.

* **bazel\_workspace\_path**: Enable to specify the path to the Bazel workspace.

* **bazel\_include\_targets**: Enable to specify Bazel targets to include in the scan.

* **bazel\_exclude\_target**: Enable to specify Bazel targets to exclude from the scan.

The following toolchain profile shows a yaml definition with configured automated scan parameters:

```yaml expandable theme={null}
kind: AutomatedScanParameters
spec:
  automated_scan_parameters:
    included_paths:
      - python/**
    excluded_paths:
      - java/**
    languages:
      - python
    call_graph_languages:
      - python
    additional_environment_variables:
      - ENDOR_LOG_VERBOSE=true
      - ENDOR_LOG_LEVEL=debug
    enable_automated_pr_scans: true
    enable_pr_comments: true
    enable_sast_scan: true
    disable_code_snippet_storage: true
    bazel_configuration:
      bazel_show_internal_targets: true
      bazel_workspace_path: "go-bazel-repo/"
      bazel_include_targets:
      bazel_abs:
        - "//cmd:cmd"
```
