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

# ignore

> Use the ignore command to add findings to the ignore file.

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>;
};

Use the `ignore` command to add findings or vulnerability IDs to the ignore file, which dismisses findings during scans. This allows developers to request exceptions directly in their pull requests and provides teams with the option to manage exceptions directly in the source code.

<Note>You must [enable ignore file support](/platform-administration/configure-system-settings#allow-ignore-files-to-dismiss-findings) in **Settings** > **SYSTEM SETTINGS** > **Developer Workflows** for ignore files to be processed during scans. </Note>

## Usage

The syntax of the `endorctl ignore` command is:

```bash theme={null}
endorctl ignore [--finding-uuid <uuid> | --vuln-id <vuln-id>] [-i] [flags]
```

You must provide `--finding-uuid`, `--vuln-id`, or `--interactive`. If you provide a
finding UUID, you must also provide `--namespace`.

The more fields you provide, the more specific the ignore entry. For example, if you provide the finding name and multiple findings share that name in the same repository version, the command applies the ignore entry to all such findings.

## Options

The command `endorctl ignore` uses the following flags and environment variables:

<YamlTable>
  {`


    - Flag: \`comments\`
    Environment_Variable: \`ENDOR_IGNORE_COMMENTS\`
    Type: string
    Description: Optional comments to add to the ignore entry.

    - Flag: \`expiration-date\`
    Environment_Variable: \`ENDOR_IGNORE_EXPIRATION_DATE\`
    Type: string
    Description: Stop ignoring the finding on this date (format: YYYY-MM-DD).

    - Flag: \`expire-if-fix-available\`
    Environment_Variable: \`ENDOR_IGNORE_EXPIRE_IF_FIX_AVAILABLE\`
    Type: boolean
    Description: Stop ignoring the finding if a fix becomes available.

    - Flag: \`finding-uuid\`
    Environment_Variable: \`ENDOR_IGNORE_FINDING_UUID\`
    Type: comma-separated string
    Description: UUID of finding to ignore.

    - Flag: \`interactive\`
    Environment_Variable: \`ENDOR_IGNORE_INTERACTIVE\`
    Type: boolean
    Description: Enter finding and/or ignore entry details interactively.

    - Flag: \`path\`
    Environment_Variable: \`ENDOR_IGNORE_PATH\`
    Type: string
    Description: Path to the repository or file to add the ignore entry to (default \`.endorignore.yaml\`).

    - Flag: \`prefix\`
    Environment_Variable: \`ENDOR_IGNORE_PREFIX\`
    Type: string
    Description: Override the default prefix for the ignore entry ID (default \`endorignore-\`, or project name if added by finding UUID).

    - Flag: \`reason\`
    Environment_Variable: \`ENDOR_IGNORE_REASON\`
    Type: string
    Description: Reason for ignoring the finding. Valid values: \`false-positive\`, \`risk-accepted\`, \`in-triage\`, \`resolved\`, \`other\` (default \`risk-accepted\`).

    - Flag: \`username\`
    Environment_Variable: \`ENDOR_IGNORE_USERNAME\`
    Type: string
    Description: Override the username associated with the ignore entry.

    - Flag: \`vuln-id\`
    Environment_Variable: \`ENDOR_IGNORE_VULN_ID\`
    Type: comma-separated string
    Description: Vulnerability ID to ignore, such as CVE or GHSA identifiers.


    `}
</YamlTable>

## Examples

### Ignore a finding based on UUID

Ignore a specific finding based on the UUID and enter details such as reason and expiration-date interactively:

```bash theme={null}
endorctl ignore --finding-uuid $FINDING_UUID --namespace $NAMESPACE -i
```

<img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/developers-api/cli/ignore_interactive_with_uuid.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=5fd49653c50ca6d063af95825fc7389e" alt="Ignore finding UUID interactive" width="652" height="392" data-path="images/developers-api/cli/ignore_interactive_with_uuid.webp" />

#### Ignore entry based on finding UUID and interactive input

Here the user entered the reason, expiration date, and comments interactively. The rest was automatically populated based on the finding UUID. The default prefix is the finding project name.

```yaml theme={null}
 version: 1.0.0
 ignore:
   - id: endorlabs/app-java-demo-1
     username: bob@corp.com@google
     update_time: 2026-02-09 22:35:04 UTC
     finding_name: Unmaintained Dependency org.webjars.bowergithub.webcomponents:shadycss@1.9.1
     parent_name: mvn://com.endor.webapp:endor-java-webapp-demo@4.0-SNAPSHOT
     dependency_name: mvn://org.webjars.bowergithub.webcomponents:shadycss@1.9.1
     extra_key: mvn://org.webjars.bowergithub.webcomponents:shadycss@1.9.1
     reason: other
     expiration_date: 2026-03-01
     comments: Will change to a better dependency in a separate commit
```

### Enter all details interactively

Enter all details about which findings to ignore interactively, without the UUID:

```bash theme={null}
endorctl ignore -i
```

<img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/developers-api/cli/ignore_interactive_full.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=c442ac65d03624d833a19ac98f0562e3" alt="Ignore interactive" width="651" height="606" data-path="images/developers-api/cli/ignore_interactive_full.webp" />

#### Ignore entry based on interactive input only

Here the user entered the finding name, reason, expiration date, and comments interactively. The default prefix is `endorignore-`.

```yaml theme={null}
 version: 1.0.0
 ignore:
   - id: endorignore-1
     username: bob@corp.com@google
     update_time: 2026-02-09 22:36:01 UTC
     finding_name: Unmaintained Dependency org.webjars.bowergithub.webcomponents:shadycss@1.9.1
     reason: other
     expiration_date: 2026-03-01
     comments: Will change to a better dependency in a separate commit
```

### Automation

Use command in a script to ignore findings based on UUID with a custom prefix:

```bash theme={null}
endorctl ignore \
  --path=$PATH_TO_IGNORE_FILE \
  --prefix=$CUSTOM_PREFIX \
  --namespace=$NAMESPACE \
  --finding-uuid=$FINDING_UUID \
  --username=$USERNAME \
  --reason=$REASON \
  --comments=$COMMENTS \
  --expiration-date=$EXPIRATON_DATE \
  --expire-if-fix-available=$EXPIRE_IF_FIX_AVAILABLE
```
