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

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.endorlabs.com/feedback

```json
{
  "path": "/platform-administration/policies/finding-policies/managing-scm-configuration/index",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# RSPM policies

> Learn about the out-of-the-box finding policies for repository security posture management (RSPM).

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 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>;
    return processText(text);
  };
  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}>{processBadges(row[col])}</td>)}
          </tr>)}
      </tbody>
    </table>;
};

Strong information security practices are necessary to secure your open source code used in your development and delivery infrastructure.

## Policies for repository security posture management

Endor Labs comes with the following out-of-the-box policies that help you determine the effectiveness of your security practices.
See [Finding Policies](/platform-administration/policies/finding-policies/managing-scm-configuration/..) for details on how to **enable**, **disable**, or **edit** out-of-the-box policies.

<YamlTable>
  {`


    - Policy: Archive inactive repositories
    Description: Repositories that are not actively maintained are vulnerable to security breaches. Archiving such repositories helps maintain a cleaner and more organized GitHub environment. Archiving ensures repositories become read-only, thus preventing unauthorized modifications. Raise findings for repositories that have been inactive beyond the duration specified by the user, defaulting to 6 months if not specified.
    Severity: High

    - Policy: At least two administrators should be configured for a repository
    Description: Having fewer than two administrators for a repository may cause problems when the administrator is unavailable. A minimum of two administrators must be configured to meet this requirement.
    Severity: Medium

    - Policy: Authorization to push or merge to protected branches should be limited
    Description: Limiting the authorization to push or merge code to protected branches is a best practice in software development workflows. By restricting access to protected branches, you maintain control over code changes and ensure that only authorized individuals can make modifications. Raises findings for repositories that do not enforce rules around merging code to protected branches.
    Severity: Medium

    - Policy: Branch protection rules should be enforced on administrators
    Description: Enforcing branch protection rules on administrators is a best practice in software development workflows. By applying branch protection rules to administrators, you ensure that even privileged individuals follow the established processes and adhere to the same standards as other team members. Raises findings for repositories that do not enforce branch protection rules.
    Severity: Medium

    - Policy: Branches should be up-to-date before merging
    Description: Ensuring that branches are up-to-date before merging is a best practice in software development. It avoids conflicts, helps in the early detection of issues, and maintains code coherence. Raise findings for repositories that do not enforce rules on branches to be up-to-date before merging.
    Severity: Medium

    - Policy: Code owner review is required when a change affects owned code
    Description: Code owner review is a practice in software development where specific individuals or teams are designated as code owners for certain parts of the codebase. When a change is proposed that affects code owned by a particular individual or team, a code owner review is required before the change can be merged into the main codebase.
    Severity: Low

    - Policy: Code owner should be configured for sensitive code
    Description: Code owner review is a best practice in software development workflows where specific individuals or teams are designated as code owners for certain parts of the codebase. When a change is proposed that affects code owned by a particular individual or team, a code owner review is required before the change can be merged into the main codebase. Raises findings for repositories that do not enforce code owner reviews.
    Severity: Low

    - Policy: Comments should be resolved before merging
    Description: Resolving comments ensures that all feedback, questions, and issues raised during the code review process have been addressed satisfactorily before the code is considered ready for integration. Raises findings for repositories that do not resolve comments before merging.
    Severity: Low

    - Policy: Commits should be signed for new changes
    Description: Requiring commits to be signed for new changes is a best practice in software development workflows. Commit signing involves using digital signatures to verify the authenticity and integrity of the commit. Raises findings for repositories that do not enforce signed commits.
    Severity: Medium

    - Policy: Contributors should not approve their own changes
    Description: Robust code reviews are essential and contributors should not approve their own changes in a collaborative software development environment. Raises findings for repositories that do not enforce code reviews.
    Severity: High

    - Policy: Default member permissions should be restricted
    Description: As a best practice, set the base permissions for members in an organization to either "read" or "none" on GitHub. Restricting member permissions controls the access over repositories and prevents misuse.
    Severity: Medium

    - Policy: Dismissing Code Change Reviews should be restricted
    Description: Restricting the ability to dismiss code change reviews is a best practice in software development workflows. Dismissing code change reviews should be limited to specific cases and authorized individuals to ensure accountability, maintain code quality, and promote a collaborative and transparent review process. Raises findings for repositories that do not enforce rules around dismissing code reviews.
    Severity: Medium

    - Policy: Ensure branch protection is enforced for the default branch
    Description: Branch protection rules allow you to set controls over your software development processes. The default branch for this repository has no branch protection rules and should be protected.
    Severity: High

    - Policy: Force pushing code to protected branches should be restricted
    Description: Restricting the ability to force push code to protected branches is a best practice in software development workflows. Restricting this action helps maintain code integrity, accountability, and collaboration. Raises findings for repositories that do not enforce rules around pushing code to protected branches.
    Severity: Medium

    - Policy: Linear commit history should be required
    Description: Linear commit history indicates a chronological sequence of commits made to a code repository. It provides a clear and chronological view of the code changes made to a repository, aiding in code navigation, collaboration, and bug tracking. Raises findings for repositories that do not have linear commit history.
    Severity: Low

    - Policy: Missing Source Code
    Description: If you cannot audit the source code associated with a software component, there is limited visibility that can result in operational and security risks. Raises findings for packages with missing source code.
    Severity: Low

    - Policy: Multi-Factor Authentication (MFA) should be required for external contributors
    Description: Multi-Factor Authentication adds an additional layer of security to access accounts or systems and prevents unauthorized access to code repositories. Raises findings for repositories that do not enforce MFA for external contributors.
    Severity: High

    - Policy: Multi-Factor Authentication (MFA) should be required for organization members
    Description: Multi-Factor Authentication adds an additional layer of security to access accounts or systems and prevents unauthorized access to code repositories. Raises findings for repositories that do not enforce MFA for members in their organization.
    Severity: High

    - Policy: Organization webhooks must be configured with a secret
    Description: The authenticity of a webhook payload cannot be verified when it is set up without a secret key. Anyone could send forged payloads to the organization's webhook endpoints leading to security issues.
    Severity: Medium

    - Policy: Organization webhooks should use HTTPS
    Description: A webhook URL is used to send notifications, along with a payload, to designated internet endpoints. Given that the payload contains sensitive information, all webhooks must be directed toward endpoints secured by HTTPS.
    Severity: Medium

    - Policy: Organization webhooks should use SSL verification
    Description: When Organization webhook SSL verification is disabled, GitHub is explicitly instructed not to verify the identity of the remote server it is sending information to. This configuration bypasses standard security controls in the HTTP protocol, which are designed to prevent attackers from executing man-in-the-middle attacks.
    Severity: Low

    - Policy: Organizations should be verified
    Description: The Organization Verified badge on GitHub is a visual indicator that signifies an organization's authenticity and official status. It helps users identify legitimate and trusted organizations on the GitHub platform. Raise findings for organizations that are not verified.
    Severity: Low

    - Policy: Organizations should have fewer than three owners
    Description: Organization administrators have the highest level of permissions, including the ability to add/remove collaborators, create or delete repositories, change branch protection policy, and convert to a publicly accessible repository. Due to the permissive access granted to an organization administrator, it is highly recommended to have at most three administrator accounts.
    Severity: Medium

    - Policy: Private repositories should not permit forking
    Description: Allowing forking in repositories within an organization can compromise data security, potentially exposing sensitive information to unauthorized parties. It exposes vulnerabilities in the codebase, making it more susceptible to exploitation. Additionally, tracking changes across multiple forks becomes complicated.
    Severity: Low

    - Policy: Protected Branch Deletion should be blocked
    Description: Protecting branch deletion, especially for critical branches, is a best practice in software development workflows. Raises findings for repositories that do not enforce rules around protected branch deletion.
    Severity: Medium

    - Policy: Repository webhooks must be configured with a secret
    Description: The authenticity of a webhook payload cannot be verified when it is set up without a secret key. Anyone could send forged payloads to the repository's webhook endpoints leading to security issues.
    Severity: Medium

    - Policy: Repository webhooks should use HTTPS
    Description: A webhook URL is used to send notifications, along with a payload, to designated internet endpoints. Given that the payload contains sensitive information, all webhooks must be directed toward endpoints secured by HTTPS.
    Severity: Medium

    - Policy: Repository webhooks should use SSL verification
    Description: When repository webhook SSL verification is disabled, GitHub is explicitly instructed not to verify the identity of the remote server it is sending information to. This configuration bypasses standard security controls in the HTTP protocol, which are designed to prevent attackers from executing man-in-the-middle attacks.
    Severity: Low

    - Policy: Require a SECURITY.md file
    Description: A SECURITY.md outlines security practices, reporting procedures, and guidelines for handling security-related issues within a project. It is included in the root directory of software repositories. Raise findings for repositories that do not include a SECURITY.md file.
    Severity: Low

    - Policy: Restrict general action permissions to organization members
    Description: Setting general action permissions for the organization to "all" can pose security risks by allowing unrestricted access to repositories to use GitHub Actions. This ensures that actions within the organization are confined to local resources, mitigating the risk of unauthorized access or unintended actions on external resources.
    Severity: High

    - Policy: Restrict the creation of repositories to trusted members
    Description: Limiting repository creation to trusted users and teams is advisable for maintaining organizational structure, reducing tracking workload, preventing impersonation, and avoiding overloading the version-control system.
    Severity: Medium

    - Policy: Stale approvals should be dismissed
    Description: To prevent malicious code from being introduced into a codebase, it is important to have a robust approval process for code changes. When changes are made to a proposal, outdated approvals must be declined, and previously accepted code changes must be re-evaluated. The approval process should involve multiple reviewers, and organizations should also consider implementing automated code analysis and security testing.
    Severity: Medium

    - Policy: Status checks should pass before merging new code
    Description: Ensuring that status checks pass before merging new code is a best practice in software development workflows. Status checks serve as automated checks or validations that assess the quality, integrity, and readiness of the code changes before they are merged into the main codebase. Raises findings for repositories that do not enforce status checks before merging new code.
    Severity: Medium

    - Policy: Two informed reviews should be required for code changes
    Description: Requiring two informed reviews for code changes is a best practice in software development. It helps ensure that code changes are thoroughly examined, promotes collaboration, and increases the overall quality of the codebase. Raises findings for repositories that do not enforce two reviews for code changes.
    Severity: Medium

    - Policy: Workflows should not be allowed to create and approve pull requests
    Description: Allowing workflows to create and approve pull requests within an organization can enable users to evade code-review protocols. Attackers could exploit this by establishing workflows that autonomously approve their pull requests and merge them discreetly. Consequently, they can introduce potentially harmful code into the production system.
    Severity: High


    `}
</YamlTable>
