diff --git a/content/code-security/concepts/secret-security/about-push-protection.md b/content/code-security/concepts/secret-security/about-push-protection.md index c98d4e02f38c..c6ba63c9562a 100644 --- a/content/code-security/concepts/secret-security/about-push-protection.md +++ b/content/code-security/concepts/secret-security/about-push-protection.md @@ -28,7 +28,6 @@ Push protection blocks secrets detected in: * Commits made in the {% data variables.product.prodname_dotcom %} UI{% ifversion push-protection-delegated-bypass-file-upload-support %} * File uploads to a repository on {% data variables.product.github %}{% endif %}{% ifversion secret-scanning-push-protection-content-endpoints %} * Requests to the REST API{% endif %} -* Interactions with the {% data variables.product.github %} MCP server (public repositories only) When push protection detects a potential secret during a push attempt, it will block the push and provide a detailed message explaining the reason for the block. You will need to review the code in question, remove any sensitive information, and reattempt the push. diff --git a/content/code-security/concepts/secret-security/working-with-push-protection-and-the-github-mcp-server.md b/content/code-security/concepts/secret-security/working-with-push-protection-and-the-github-mcp-server.md index c2d49b01a670..8359af90b8fa 100644 --- a/content/code-security/concepts/secret-security/working-with-push-protection-and-the-github-mcp-server.md +++ b/content/code-security/concepts/secret-security/working-with-push-protection-and-the-github-mcp-server.md @@ -32,3 +32,4 @@ To resolve the block, you can either: * [AUTOTITLE](/code-security/secret-scanning/introduction/about-push-protection) * [About the {% data variables.product.github %} MCP server](/copilot/concepts/about-mcp#about-the-github-mcp-server) +* [AUTOTITLE](/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server) diff --git a/content/code-security/how-tos/index.md b/content/code-security/how-tos/index.md index 241674135bf6..042529580df4 100644 --- a/content/code-security/how-tos/index.md +++ b/content/code-security/how-tos/index.md @@ -15,6 +15,7 @@ children: - manage-security-alerts - /maintain-quality-code - /report-and-fix-vulnerabilities + - /use-ghas-with-ai-coding-agents - /view-and-interpret-data --- diff --git a/content/code-security/how-tos/use-ghas-with-ai-coding-agents/index.md b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/index.md new file mode 100644 index 000000000000..934f4ba6ce41 --- /dev/null +++ b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/index.md @@ -0,0 +1,11 @@ +--- +title: Use GitHub Advanced Security with AI coding agents +shortTitle: Advanced Security with AI agents +intro: 'Catch secrets, vulnerabilities, and insecure dependencies while you code, directly from {% data variables.product.prodname_copilot %} agent mode and other MCP-compatible tools.' +versions: + fpt: '*' + ghec: '*' +contentType: how-tos +children: + - /scan-for-secrets-with-github-mcp-server +--- \ No newline at end of file diff --git a/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md new file mode 100644 index 000000000000..e10b1741e86d --- /dev/null +++ b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md @@ -0,0 +1,152 @@ +--- +title: Scanning for secrets with the GitHub MCP server +shortTitle: Scan for secrets with MCP +allowTitleToDifferFromFilename: true +intro: 'Detect exposed secrets in real time from your AI coding agent, before they ever reach your repository.' +versions: + feature: copilot +permissions: 'People with write access to a repository.' +contentType: how-tos +category: + - Protect your secrets +--- + +The {% data variables.product.github %} Model Context Protocol (MCP) server lets you run {% data variables.product.prodname_secret_scanning %} directly from {% data variables.product.prodname_copilot %} agent mode, {% data variables.copilot.copilot_cli %}, and other MCP-compatible tools. Scan your code for exposed keys, tokens, and credentials as you work, and fix them before you push. + +The secret scanning tools are only available via the {% data variables.product.github %} remote MCP server. **Local MCP server configurations are not supported**. + +This works with any MCP-compatible agent or IDE, including {% data variables.product.prodname_vscode %}, JetBrains, Claude Code, Cursor, and Windsurf. The experience varies across clients. + +> [!NOTE] Findings returned by MCP-invoked scans are **ephemeral**. They are surfaced in your agent's chat for the current session only and are not persisted as alerts on {% data variables.product.github %}. This means these findings won't appear in the Security tab, in the {% data variables.product.prodname_secret_scanning %} alerts list, or in the REST/GraphQL APIs for alerts. MCP scans should be treated as a pre-commit safety check, not as a system of record. Remediate findings before they are pushed to the repository and persisted in Git history. + +## Prerequisites + +* **{% data variables.product.prodname_GH_secret_protection %}** is enabled for the repository. +* **{% data variables.product.github %} MCP server** is connected in your IDE or agent. See [AUTOTITLE](/copilot/how-tos/provide-context/use-mcp/set-up-the-github-mcp-server). +* Your organization's **security configuration** determines which secret types are detected and whether push protection is enforced. The MCP tools respect your organization's push protection configuration (repository-level push protection settings are not used). + +## Step 1: Install and configure tools + +### Enable the `secret_protection` toolset + +Enable the `secret_protection` toolset to make the scanning tools available to your agent. The default toolsets do not include it. + +The `run_secret_scanning` tool is currently attached to the `copilot` toolset rather than `secret_protection`. You must explicitly include `run_secret_scanning` as an additional tool alongside the `secret_protection` toolset in your MCP configuration. + +{% cli %} + +{% data variables.copilot.copilot_cli %} has the {% data variables.product.github %} MCP server built in: + +```shell +copilot mcp --toolsets=secret_protection --tools=run_secret_scanning +``` + +{% endcli %} + +{% vscode %} + +Add the `secret_protection` toolset and the `run_secret_scanning tool` to your MCP configuration: + +```json copy +{ + "servers": { + "github": { + "url": "https://api.githubcopilot.com/mcp/", + "headers": { + "X-MCP-Toolsets": "secret_protection", + "X-MCP-Tools": "run_secret_scanning" + } + } + } +} +``` + +{% endvscode %} + +{% jetbrains %} + +In your JetBrains IDE, edit your MCP server configuration to include the `secret_protection` toolset and `run_secret_scanning` tool headers. For more information on configuring MCP servers in JetBrains, see [MCP Server](https://www.jetbrains.com/help/idea/mcp-server.html) in the JetBrains documentation. + +```json copy +{ + "servers": { + "github": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/", + "headers": { + "GitHub-MCP-Toolsets": "secret_protection", + "GitHub-MCP-Tools": "run_secret_scanning" + } + } + } +} +``` + +{% endjetbrains %} + +### (Optional) Install the {% data variables.product.prodname_AS %} plugin + +The [{% data variables.product.prodname_AS %} plugin](https://github.com/github/copilot-plugins/tree/main/plugins/advanced-security) gives you a `/secret-scanning` slash command for a streamlined scanning experience in {% data variables.copilot.copilot_cli %} and {% data variables.product.prodname_vscode %}. +The plugin uses the MCP tools under the hood, so you'll still need to enable the `secret_protection` toolset. + +Instructions for installing the plugin: +* For **{% data variables.copilot.copilot_cli %}**, see [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/plugins-finding-installing#installing-plugins). +* For **{% data variables.product.prodname_vscode %}**, see [Discover and install plugins](https://code.visualstudio.com/docs/copilot/customization/agent-plugins#_discover-and-install-plugins) in the {% data variables.product.prodname_vscode %} documentation. + +## Step 2: Scan your code + +Once the toolset is enabled, you can trigger a scan in several ways depending on your client. + +**Natural-language prompt**. In any MCP-compatible agent, you can ask: + +> "Scan my current changes for exposed secrets and show me the files and lines I should update before I commit." + +> "Run {% data variables.product.prodname_secret_scanning %} on the files I've changed since my last commit and summarize any high-confidence findings." + +**Slash command (requires the {% data variables.product.prodname_AS %} plugin)**. If you installed the optional plugin in Step 1, you can also use: + +>"/secret-scanning Review the staged diff for credentials, keys, or tokens and propose replacements using environment variables." + +**Direct tool invocation:** You can also invoke the scanning tool directly from your client. + +{% cli %} + +Run `copilot --add-github-mcp-tool run_secret_scanning`. + +{% endcli %} + +{% vscode %} + +Type `/secret-scanning` in {% data variables.copilot.copilot_chat_short %}. + +{% endvscode %} + +{% jetbrains %} + +1. In your IDE, open {% data variables.copilot.copilot_chat_short %} +1. Click the **Agent** tab +1. Use a prompt like: "Scan my recent changes for exposed secrets before I commit." You can also click the tools icon in the chat box to browse available `secret_protection` tools directly. + +{% endjetbrains %} + +The agent returns: + +* The **type** of secret found +* The **file and line** where it was detected +* **Remediation steps**, such as removing or rotating the credential + +If push protection is enabled, the MCP server also blocks secrets from being included in any actions it takes on your behalf, such as commits, pull requests, or the creation of files. See [AUTOTITLE](/code-security/concepts/secret-security/working-with-push-protection-and-the-github-mcp-server). + +## Troubleshooting + +| Problem | Check | +|---|---| +| Scanning returns no results | Verify the `secret_protection` toolset is enabled in your MCP configuration. | +| Repository not eligible |{% data variables.product.prodname_secret_scanning_caps %} via MCP is available to public repositories and requires {% data variables.product.prodname_GH_secret_protection %} to be enabled for private and internal repositories. | +| Agent doesn't recognize the tool | Confirm your IDE or agent supports MCP. See [AUTOTITLE](/copilot/concepts/context/mcp#availability). | +| Unexpected detection results | Your organization's security configuration controls which patterns are scanned. Check your repository security settings. | +| Tool works in one client but not another | The experience varies across MCP-compatible clients. Check your client's MCP documentation for supported features. | + +## Further reading + +* [AUTOTITLE](/copilot/how-tos/provide-context/use-mcp-in-your-ide/configure-toolsets) \ No newline at end of file diff --git a/content/code-security/reference/index.md b/content/code-security/reference/index.md index 8154e41437d0..3bbaa23578f4 100644 --- a/content/code-security/reference/index.md +++ b/content/code-security/reference/index.md @@ -14,4 +14,5 @@ children: - /supply-chain-security - /code-quality - /permissions + - /security-incident-response --- diff --git a/content/code-security/reference/secret-security/understanding-github-secret-types.md b/content/code-security/reference/secret-security/understanding-github-secret-types.md index 76523628c5c9..e494de833ff5 100644 --- a/content/code-security/reference/secret-security/understanding-github-secret-types.md +++ b/content/code-security/reference/secret-security/understanding-github-secret-types.md @@ -5,7 +5,7 @@ versions: fpt: '*' ghes: '*' ghec: '*' -shortTitle: GitHub secret types +shortTitle: Understand secret types redirect_from: - /code-security/getting-started/understanding-github-secret-types contentType: reference diff --git a/content/code-security/reference/security-incident-response/index.md b/content/code-security/reference/security-incident-response/index.md new file mode 100644 index 000000000000..45ae587dea20 --- /dev/null +++ b/content/code-security/reference/security-incident-response/index.md @@ -0,0 +1,13 @@ +--- +title: Reference for security incident response +shortTitle: Incident response +intro: Find reference information to support your investigation and response to security incidents. +versions: + fpt: '*' + ghec: '*' + ghes: '*' +contentType: reference +children: + - /investigation-tools + - /investigation-areas +--- diff --git a/content/code-security/reference/security-incident-response/investigation-areas.md b/content/code-security/reference/security-incident-response/investigation-areas.md new file mode 100644 index 000000000000..026121d19c63 --- /dev/null +++ b/content/code-security/reference/security-incident-response/investigation-areas.md @@ -0,0 +1,165 @@ +--- +title: Common security incident investigation areas +shortTitle: Investigation areas +allowTitleToDifferFromFilename: true +intro: 'Reference for investigating security incidents across multiple attack vectors, including the key surfaces and tools to check on {% data variables.product.github %}.' +versions: + fpt: '*' + ghec: '*' + ghes: '*' +contentType: reference +--- + +This reference article shows you which {% data variables.product.github %} tools to use and which {% data variables.product.github %} surfaces to check when you're responding to a security incident. Use this article to guide your investigation across major threat categories. + +For full guidance on how to respond to a security incident, including **containment strategies**, see [AUTOTITLE](/code-security/tutorials/secure-your-organization/responding-to-security-incidents). + +> [!IMPORTANT] +> The availability of each tool (and the data it provides) varies by {% data variables.product.github %} plan, role, permissions, feature enablement, and pre-incident configuration (for example, audit log streaming and IP address disclosure require prior set up). For more information, see [AUTOTITLE](/code-security/reference/security-incident-response/investigation-tools). +> +> Be aware that real-world security incidents rarely involve a single attack vector. A credential compromise may lead to malicious code injection, which may enable data exfiltration. As you investigate a threat signal, be prepared to move into other investigation areas, and to loop through containment, deeper investigation and remediation as you uncover new indicators of compromise and as your understanding of the threat model evolves. + +## Exposed or compromised credentials + +This section may apply when: + +You suspect a token or key has been stolen or exploited, received a {% data variables.product.prodname_secret_scanning %} alert, or found credentials exposed in code, logs or a public repository. + +### What to check + +* Search the audit log for: + * Actions taken by the compromised token, by searching for all events associated with that token. See [AUTOTITLE](/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/identifying-audit-log-events-performed-by-an-access-token). + * Actions taken by unexpected actors or unknown IP addresses (if IP address disclosure is enabled). +* Review {% data variables.product.prodname_secret_scanning %} alerts for relevant findings to assess a leaked secret's location, exposure and validity. +* Use security overview for your enterprise or organization to identify trends or activity across repositories. +* Use {% data variables.product.github %} code search to check for secrets exposed in code, `.env` files, or configuration files across repositories. + +### Key tools + +| Tool | Purpose | +| --- | --- | +| [Audit log](/code-security/reference/security-incident-response/investigation-tools#audit-logs) | Trace token usage | +| [Security overview](/code-security/reference/security-incident-response/investigation-tools#security-overview) | View organization- or enterprise-level security alerts and activity, particularly {% data variables.product.prodname_secret_scanning %} alerts | +| [{% data variables.product.github %} code search](/code-security/reference/security-incident-response/investigation-tools#github-code-search) | Search for exposed credentials in code | + +### Key resources + +* [Containment actions](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat){% ifversion ghec %} +* [AUTOTITLE](/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/identifying-audit-log-events-performed-by-an-access-token) (organizations) +* [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/identifying-audit-log-events-performed-by-an-access-token) (enterprises){% endif %} +* [AUTOTITLE](/code-security/tutorials/remediate-leaked-secrets/remediating-a-leaked-secret) + +## Unauthorized access and account compromise + +This section may apply when: + +You noticed unusual login activity, saw unexpected commits or changes, or detected suspicious account behavior. + +### What to check + +* Search the audit log for **member access, permissions, or role changes**. For example, look for events such as `org.add_member`, `repo.add_member`, `org.add_outside_collaborator`, `org.update_member`, `repo.update_member`, `role.create`, `role.update`. +* For any suspicious events in the audit log, **identify the actor**. Check if the actor is an unknown user, a potentially compromised account, or an unrecognized app. +* If you have IP address visibility enabled, **check if the IP address** associated with unusual events or suspicious activity is recognized. +* Search the audit log for events relating to **newly created deploy keys or apps,** for example `public_key.create`, `integration_installation.create`. +* Review the audit log for **unexpected repository changes**, such as new public repositories or repository visibility changes (private to public), for example `repo.create`, `repo.access`. +* Use the activity view (repository-level) to **build a timeline of recent pushes**. Look for pushes from unexpected actors, force pushes, or unusual branch names. + +### Key tools + +| Tool | Purpose | +| --- | --- | +| [Audit logs](/code-security/reference/security-incident-response/investigation-tools#audit-logs) | Search and cross-check actions, actors and IP addresses | +| [Activity view](/code-security/reference/security-incident-response/investigation-tools#activity-view) | Review activity for specific repositories | + +### Key resources + +* [Containment actions](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat) + +## Data exfiltration + +This section may apply when: + +You detected large downloads, unusual API activity, or received reports of your data appearing externally. + +### What to check + +* Search audit logs for high-volume git operations (`git.clone`, `git.fetch`) or API requests, particularly from an unfamiliar actor (`actor`) or IP address (if IP address visibility is enabled), that indicate bulk data collection. + * Note that Git events in the audit log have special access requirements and retention policies that differ from other audit log events. For {% data variables.product.prodname_ghe_cloud %}, you can access Git events via the REST API and data is retained for seven days, unless you are streaming the audit log. For {% data variables.product.prodname_ghe_server %}, Git events must be enabled in the audit log configuration and are not included in search results. + * Similarly, capturing API activity in the audit logs requires prior configuration and is not available by default. +* Check the audit logs for repository replication or exposure events, for example, repository visibility changes (from private to public), unexpected new repositories being created (such as new public repositories) or repositories being renamed or transferred (`repo.create`, `repo.access` (visibility changes), `repo.rename`, `repo.transfer`). +* Check for outbound mechanisms, for example webhooks being created or updated (`hook.create` or similar events in the audit logs), and check if any webhook points to an unrecognized domain. + +### Key tools + +| Tool | Purpose | +| --- | --- | +| [Audit logs](/code-security/reference/security-incident-response/investigation-tools#audit-logs) | Search for relevant actions | + +### Key resources + +* [Containment actions](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat) + +## Malicious code and workflow changes + +This section may apply when: + +You found suspicious code in your repository, a security researcher reported an issue, or you noticed unexpected workflow behavior. + +### What to check + +* Review the **Actions** tab for unexpected workflow runs, especially those triggered by unfamiliar users or at unusual times. +* Inspect workflow run logs for suspicious output. +* Use {% data variables.product.github %} code search to find suspicious files or code additions, particularly in workflow files (`.github/workflows/`), shell scripts, or configuration files. +* Use the Activity view to check for pushes to unusual branch names, force pushes, pushes from unexpected actors. +* Check the audit logs for changes to security settings or disablement actions (look for events like `repository_ruleset.destroy`, `repository_secret_scanning_push_protection.disable`, or other `.delete`, `.disable`, `.destroy` events). +* Check the audit logs for events relating to new self-hosted runners being added (for example, `org.register_self_hosted_runner`, `repo.register_self_hosted_runner` events). +* Check for {% data variables.product.prodname_dependabot_alerts %} or the [{% data variables.product.prodname_advisory_database %}](https://github.com/advisories) for advisories related to {% data variables.product.prodname_actions %} used in your workflows. + +### Key tools + +| Tool | Purpose | +| --- | --- | +| [Workflow runs and logs](/code-security/reference/security-incident-response/investigation-tools#workflow-runs-and-logs) | Review workflow execution and inspect log output | +| [Activity view](/code-security/reference/security-incident-response/investigation-tools#activity-view) | Identify unexpected pushes, force pushes, or pushes from unfamiliar actors | +| [{% data variables.product.github %} code search](/code-security/reference/security-incident-response/investigation-tools#github-code-search) | Search for suspicious code patterns | +| [Audit logs](/code-security/reference/security-incident-response/investigation-tools#audit-logs) | Filter by action to find security setting changes | + +### Key resources + +* [Containment actions](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat) + +## Malware and supply chain attacks + +This section may apply when: + +You received a malware or dependency alert, suspect a malicious package, or noticed unexpected dependencies in your projects. + +### What to check + +* Check for a {% data variables.product.prodname_dependabot %} malware alert, which can tell you details about the malicious package (such package name, affected versions, and the patched version), as well as remediation steps. Currently supported for packages in the `npm` ecosystem only. +* Search the [{% data variables.product.prodname_advisory_database %}](https://github.com/advisories) to see if {% data variables.product.github %} is reporting advisories for dependencies (or dependency versions) that your projects are using. For malware specifically, search `type:malware` in the advisory database. +* Use {% data variables.product.github %} code search to search for references to the suspected package or action across your organization. +* Review the dependency graph for your repositories to identify any new or unexpected dependencies. +* Use activity view and check commit history to review recent changes to dependency manifests or lockfiles (for example, `package.json`, `package-lock.json`, `Gemfile.lock`). Check blame views and pull requests to identify who introduced the changes and whether they were reviewed. +* Review recently created security alerts in your organization's security overview. + +### Key tools + +| Tool | Purpose | +| --- | --- | +| [{% data variables.product.github %} code search](/code-security/reference/security-incident-response/investigation-tools#github-code-search)| Search for references to the suspected package or Action | +| [Dependency graph](/code-security/reference/security-incident-response/investigation-tools#dependency-graph) | Visualize and review dependencies | +| [{% data variables.product.prodname_dependabot %} alerts](/code-security/how-tos/manage-security-alerts/manage-dependabot-alerts/viewing-and-updating-dependabot-alerts) | Review for alerts relating to vulnerable dependencies | +| [{% data variables.product.prodname_advisory_database %}](https://github.com/advisories)| Search for `type:malware` | +| [Activity view](/code-security/reference/security-incident-response/investigation-tools#activity-view) | Review recent pushes to repositories | +| [Security overview](/code-security/reference/security-incident-response/investigation-tools#security-overview) | Review recent security alerts across an organization or enterprise | + +### Key resources + +* [Containment actions](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat) + +## Further reading + +* [AUTOTITLE](/code-security/tutorials/secure-your-organization/responding-to-security-incidents) +* [AUTOTITLE](/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/reviewing-the-audit-log-for-your-organization) +* [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/about-the-audit-log-for-your-enterprise) \ No newline at end of file diff --git a/content/code-security/reference/security-incident-response/investigation-tools.md b/content/code-security/reference/security-incident-response/investigation-tools.md new file mode 100644 index 000000000000..a9534d1c1acd --- /dev/null +++ b/content/code-security/reference/security-incident-response/investigation-tools.md @@ -0,0 +1,173 @@ +--- +title: Investigation tools for security incidents +shortTitle: Investigation tools +allowTitleToDifferFromFilename: true +intro: 'The core {% data variables.product.github %} tools you can use to investigate security incidents, what each tool is best used for, and common considerations that affect what data is available.' +versions: + fpt: '*' + ghec: '*' + ghes: '*' +contentType: reference +--- + +Use this reference to decide which {% data variables.product.github %} tools to use during a security investigation, what questions each tool can answer, and what factors may affect the data you can see. + +> [!NOTE] +> The availability of each tool (and the data it provides) varies by {% data variables.product.github %} plan, your role and permissions, feature enablement, and pre-incident configuration (for example, audit log streaming and IP address disclosure require prior set up). + +## Activity view + +### Use + +* Get an **overview of activity** in a specific repository, including merges, pushes, force pushes, branch creations and deletions, attributed to specific actors over a defined period. +* Correlate suspicious code appearances with **related pushes or merges**. +* Answer questions about **when** a change was made, **who** made it, **in which branch**, and explore the diff or commit history. + +#### Permissions + +Read access to the repository. + +### Key resources + +* [AUTOTITLE](/repositories/viewing-activity-and-data-for-your-repository/using-the-activity-view-to-see-changes-to-a-repository) + +### Notes and limitations + +* Activity view is best used as an initial navigation and correlation surface; it doesn't have the same completeness or query power as raw audit log exports. +* Some incidents require correlation across repositories or organizations, which may be easier in the audit log. + +## Audit logs + +### Use + +* Answer questions about **what's changed**, **when**, and **by whom** across an enterprise or organization. +* Investigate events that may have enabled compromise, or indicate it, such as changes to membership, roles, permissions, or the generation or use of access tokens, etc. +* Attribute security-relevant actions to an actor (user or integration) and build an investigation timeline. +* Filter by actor, action, IP address (if enabled), or token, to identify suspicious activity or trace token usage. +* Correlate activity across multiple repositories or organizations. + +#### Permissions + +* To view the organization audit log, you need to be an organization owner. +* To view the enterprise audit log, you need to be an enterprise administrator. +* To view the security log (personal account), you need to be the account owner. +* To view audit log data exported to an external Security Information and Event Management (SIEM) system, log management system or other tools and services, you need access to that system. + +### Key resources + +* [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/audit-log-events-for-your-enterprise) +* [AUTOTITLE](/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/audit-log-events-for-your-organization) +* [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/security-log-events){% ifversion ghec %} +* [AUTOTITLE](/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/identifying-audit-log-events-performed-by-an-access-token){% endif %} + +### Notes and limitations + +* {% data variables.product.github %} provides three audit logs: **enterprise**, **organization**, and user **security logs**. +* The {% data variables.product.github %} audit log UI has **limited filtering and search** capabilities. For this reason, we recommend that enterprises **stream** the enterprise audit log to an external SIEM or log management system for more advanced querying. + * Audit log streaming to an external SIEM or log management system requires prior configuration. See [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise). + * Without audit log streaming, you won't be able to run more complex queries, such as correlating events across organizations or repositories, or pivoting from a specific token to all related events. + * Git events data are included in the stream. +* We recommend streaming **API request events**; this requires prior configuration. See [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#enabling-audit-log-streaming-of-api-requests). +* For enterprises on {% data variables.product.prodname_ghe_cloud %}, we recommend displaying **IP addresses** in the audit logs; this requires prior configuration. See [AUTOTITLE](/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/displaying-ip-addresses-in-the-audit-log-for-your-enterprise). +* Different {% data variables.product.github %} plans have different data availability and data retention offerings: + * {% data variables.product.prodname_free_team %} and {% data variables.product.prodname_team %} plans can't view API activity or Git events at all. + * Standalone organizations (organizations that are not part of an enterprise) can't stream the audit logs, can't view API request events, and are limited to 7 days for Git event data. + * For enterprises on {% data variables.product.prodname_ghe_cloud %}: + * If your enterprise uses **{% data variables.product.prodname_emus %}**, then the audit log also includes user **security logs** (events related to user accounts, such as login activity and token usage). + * If your enterprise _doesn't use_ {% data variables.product.prodname_emus %}, then the {% data variables.product.github %} audit log only includes events related to the enterprise account and the organizations within it. +* The audit logs **don't** include page view or repository browsing telemetry. + +## Dependency graph + +### Use + +* Check whether a repository depends on a **vulnerable or compromised package** (or version). +* Review for **new or suspicious dependencies** that may have been introduced during an incident. +* Filter and explore dependencies by ecosystem or relationship (direct or transitive). +* Export a software bill of materials (SBOM) for auditing purposes, or to preserve evidence. + +#### Permissions + +* Write or maintain access to the repository. + +### Key resources + +* [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/exploring-the-dependencies-of-a-repository) +* [AUTOTITLE](/code-security/reference/supply-chain-security/dependency-graph-supported-package-ecosystems) +* [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/exporting-a-software-bill-of-materials-for-your-repository) + +### Notes and limitations + +* The dependency graph is generated from supported manifest/lock files (and optional build-time submissions), so it can be incomplete or differ from what was actually built and deployed. To get the most accurate view, especially for dependencies resolved during CI/build, you should be supplementing the dependency graph with build-time dependency submission (or other build provenance such as SBOMs). + +## {% data variables.product.github %} code search + +### Use + +* Search for Indicators of Compromise (IoCs) across repositories, such as known malicious workflows or package names. +* Quickly scope the potential blast radius by checking if suspicious code patterns, such as a leaked secret or malicious code snippet, appear in other repositories across the organization or enterprise. +* Scope the search by various different qualifiers that may be useful during an incident, for example: + * Search within a specific repository, organization, or enterprise (using the `repo:`, `org:`, `enterprise:` qualifiers). + * Search within specific file paths (`path:.github/workflows repo:ORG-NAME/REPO-NAME`). + +#### Permissions required + +* To search across public repositories, you must be signed into your {% data variables.product.github %} account. +* To search across private repositories, you must have read access to those repositories. + +### Key resources + +{% ifversion fpt or ghec %} +* [AUTOTITLE](/search-github/github-code-search/using-github-code-search) +* [AUTOTITLE](/search-github/github-code-search/understanding-github-code-search-syntax){% elsif ghes %} +* [AUTOTITLE](/search-github/searching-on-github/searching-code){% endif %} + +### Notes and limitations + +* Supports regex search. +* Searches across the default branch of a repository only. If the suspicious code was introduced in a non-default branch and hasn't been merged, it won't be found by code search. +* You can use code search to determine if a pattern or IoC is present, but it doesn't provide context such as when the code was added or by whom. You should use code search in conjunction with other tools, such as audit logs, activity view, or checking the blame view, commit history and pull request history of a repository. + +## Security overview and security alerts + +### Use + +* See a high-level view of all security alerts ({% data variables.product.prodname_secret_scanning %}, {% data variables.product.prodname_code_scanning %}, and {% data variables.product.prodname_dependabot %} alerts) across repositories in an organization or enterprise. +* Triage what {% data variables.product.github %} has already detected and identify which repositories are affected. +* Track new alerts created during an incident (which can indicate active exploitation or spread). + +#### Permissions required + +* To see data for organizations at the enterprise-level, an enterprise administrator must have the organization owner or security manager role in the relevant organizations. +* To see data for repositories at the organization-level, the organization owner or security manager role is required. + +### Key resources + +* [AUTOTITLE](/code-security/concepts/security-at-scale/about-security-overview) +* [AUTOTITLE](/code-security/how-tos/view-and-interpret-data/analyze-organization-data/viewing-security-insights#viewing-the-security-overview-dashboard-for-your-organization) + +### Notes and limitations + +* Alerts for leaked secrets, vulnerable code, vulnerable dependencies and malware are only visible if the relevant features were enabled and configured prior to the incident. + +## Workflow runs and logs + +### Use + +* Confirm what executed in CI/CD at a given time (such as the commands executed, or the dependency installed). +* Investigate suspicious workflow runs, such as those triggered by an unfamiliar user or at an unusual time, to see what actions were performed, which secrets were accessed, and what code was executed. +* Determine whether a workflow had access to any secrets. + +#### Permissions required + +* Read access to the repository. + +### Key resources + +* [AUTOTITLE](/actions/how-tos/monitor-workflows/view-workflow-run-history) +* [AUTOTITLE](/actions/how-tos/monitor-workflows/use-workflow-run-logs) + +### Notes and limitations + +* {% data variables.product.github %} automatically redacts secrets from workflow logs. +* By default, workflow logs are retained by {% data variables.product.github %} for 90 days, but you can configure this retention period to be longer (up to 400 days for private repositories). diff --git a/content/code-security/tutorials/secure-your-organization/index.md b/content/code-security/tutorials/secure-your-organization/index.md index d6d31d879460..cb0c0cf21a3b 100644 --- a/content/code-security/tutorials/secure-your-organization/index.md +++ b/content/code-security/tutorials/secure-your-organization/index.md @@ -14,4 +14,7 @@ children: - /interpreting-secret-risk-assessment-results - /interpreting-code-security-risk-assessment-results - /organizing-remediation-efforts-for-leaked-secrets + - /protect-against-threats + - /preparing-for-security-incidents + - /responding-to-security-incidents --- diff --git a/content/code-security/tutorials/secure-your-organization/preparing-for-security-incidents.md b/content/code-security/tutorials/secure-your-organization/preparing-for-security-incidents.md new file mode 100644 index 000000000000..f7c6a6e52cfb --- /dev/null +++ b/content/code-security/tutorials/secure-your-organization/preparing-for-security-incidents.md @@ -0,0 +1,91 @@ +--- +title: Preparing for a security incident +shortTitle: Prepare for a security incident +allowTitleToDifferFromFilename: true +intro: Ensure you have the tools and processes in place to respond effectively to a security incident. +versions: + fpt: '*' + ghec: '*' + ghes: '*' +contentType: tutorials +--- + +The guidance in this article is aimed at enterprise owners, organization owners, security managers and security teams. However, you will need to have the enterprise owner role to enable several of the features referenced in this article. + +## Introduction + +When a security incident occurs, the ability to investigate what happened, understand the scope of impact, and contain the threat depends on having the right tools and processes already in place. This article brings together the key actions you should take **before** an incident occurs so that your team is equipped to respond quickly and effectively. + +## Set up critical tools in advance + +The following investigative tooling is not available by default when you set up your {% data variables.product.github %} enterprise. We strongly recommend enabling these features before any incident occurs. + +These controls are critical for incident response, compliance, and operational transparency. Without them, your team can have major visibility gaps during an investigation, especially for API activity, Git activity, and long-running incidents where you need historical data. + +### Audit log streaming + +You should stream the enterprise audit logs to a Security Information and Event Management (SIEM) system. This keeps a copy of your audit log data (including both audit events and Git events) in a system where you can run complex queries across large volumes of data and retain data beyond default retention periods. + +This is critical in an incident because some high-value events are not visible in the {% data variables.product.github %} audit log web UI, and logs are only available for a limited time unless you export and retain them externally. + +With streamed logs, enterprise and organization owners can independently investigate activity from users, apps, tokens, and SSH keys, instead of depending on ad hoc data collection during an active response. + +To set up audit log streaming, see [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise). + +### Stream API request events + +By default, the audit log stream won't include API request events. Enable API request streaming so that you can detect and investigate unauthorized API access or data exfiltration by compromised tokens or apps. + +See [Enabling audit log streaming of API requests](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#enabling-audit-log-streaming-of-api-requests). + +### Display IP addresses + +By default, {% data variables.product.github %} doesn't show source IP addresses in the enterprise audit log. During an investigation, source IPs help you verify whether activity from an actor (a user or app) came from a trusted or unfamiliar address. + +Enterprises on {% data variables.product.prodname_ghe_cloud %} can enable IP address disclosure, see [AUTOTITLE](/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/displaying-ip-addresses-in-the-audit-log-for-your-enterprise). + +### Retain identity provider logs + +If your enterprise uses SAML or OIDC authentication, adopt a similar retention strategy for your IdP logs. + +Retained IdP logs help you investigate authentication activity and review provisioning and deprovisioning events over longer time windows, including incidents that unfold over months. + +## Familiarize yourself with tooling, limitations and common investigation areas + +Before an incident occurs, review the {% data variables.product.github %} tools and surfaces you can use during an investigation, and understand each tool's capabilities and limitations. + +Familiarize yourself with: + +* {% data variables.product.github %} tools and surfaces for investigations, including their limitations. See [AUTOTITLE](/code-security/reference/security-incident-response/investigation-tools). +* Key procedures for using the audit log during a security threat, such as [AUTOTITLE](/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/identifying-audit-log-events-performed-by-an-access-token). +* Common investigation areas and the checks you can perform for specific threat signals. See [AUTOTITLE](/code-security/reference/security-incident-response/investigation-areas). + +## Familiarize yourself with containment strategies + +Before an incident occurs, review the immediate containment actions you might need. Planning these actions in advance with your security and operations teams helps you respond quickly, and means you can include clear guidance in your Security Incident Response Plan (SIRP). + +Familiarize yourself with: + +* Common containment actions on {% data variables.product.github %}, such as revoking credentials, enabling an IP allow list, suspending users, and other access disablement actions. See [Contain the threat](/code-security/tutorials/secure-your-organization/responding-to-security-incidents#step-2-contain-the-threat). +* Revocation options for each type of credential that can programmatically access {% data variables.product.github %}. See [AUTOTITLE](/organizations/managing-programmatic-access-to-your-organization/github-credential-types). +* For enterprises on {% data variables.product.prodname_ghe_cloud %}: the bulk emergency actions available to enterprise owners in a major incident, such as locking down SSO and deleting all user tokens and keys. See [AUTOTITLE](/enterprise-cloud@latest/admin/managing-iam/respond-to-incidents). + +## Prepare a Security Incident Response Plan (SIRP) + +Create and maintain an up-to-date Security Incident Response Plan (SIRP) for your enterprise. + +Your plan should define: + +* Roles and responsibilities +* Escalation paths +* Communication protocols +* Severity classification criteria +* Step-by-step response procedures for common threat types + +{% data variables.product.prodname_copilot_short %} can help you draft and refine this plan based on your team's needs and resources. + +For guidance, see [What is incident response](https://github.com/resources/articles/what-is-incident-response#what-is-incident-response). + +## Next steps + +* [AUTOTITLE](/code-security/tutorials/secure-your-organization/responding-to-security-incidents) \ No newline at end of file diff --git a/content/code-security/tutorials/secure-your-organization/protect-against-threats.md b/content/code-security/tutorials/secure-your-organization/protect-against-threats.md new file mode 100644 index 000000000000..25515fcce2b1 --- /dev/null +++ b/content/code-security/tutorials/secure-your-organization/protect-against-threats.md @@ -0,0 +1,188 @@ +--- +title: Protecting against security threats +shortTitle: Protect against threats +intro: 'What steps should I take now, in the near future, and on an ongoing basis + to reduce exposure to security threats across my organizations on {% data variables.product.github %}?' +versions: + fpt: '*' + ghes: '*' + ghec: '*' +allowTitleToDifferFromFilename: true +contentType: tutorials +--- + +## Introduction + +Preventing security incidents is less costly and less disruptive than responding +to them. By proactively hardening your environment on {% data variables.product.github %}, you reduce your exposure to threats such as exploited credentials, unauthorized access, and supply chain attacks. + +This guide primarily focuses on the protective measures you can apply across organizations that are part of an enterprise on {% data variables.product.prodname_ghe_cloud %}. To trial {% data variables.product.prodname_ghe_cloud %}, see [AUTOTITLE](/enterprise-cloud@latest/admin/overview/setting-up-a-trial-of-github-enterprise-cloud). + +Many of {% data variables.product.github %}'s security features mentioned here, such as security configurations, branch rulesets and access controls, can be configured at both the organization level or enterprise level. + +## Immediate actions + +These are high-impact actions you can take right now to establish a security baseline across an organization. + +* [Establish security coverage](#establish-security-coverage) +* [Tighten controls](#tighten-controls) +* [Review and restrict access](#review-and-restrict-access) +* [Run a secret risk assessment](#run-a-secret-risk-assessment) + +### Establish security coverage + +Ensure that {% data variables.product.github %}'s {% data variables.product.prodname_GHAS %} tools are active across all repositories. Rather than enabling tools one by one, you can create and apply a **security configuration**, which is a collection of security settings that can be applied to repositories across your organization or enterprise in a single action. + +A strong configuration might include: + +* **{% data variables.product.prodname_secret_scanning_caps %}** and **push protection** to detect secrets that have already been committed to your codebase, and prevent new secrets from being pushed. Leaked credentials are one of the most common causes of security breaches. +* **{% data variables.product.prodname_code_scanning_caps %}** to identify vulnerabilities and coding errors in your source code before they reach production. +* **{% data variables.product.prodname_dependabot_alerts %}** and **{% data variables.product.prodname_dependabot_security_updates %}** to notify you of known vulnerabilities and malware in your dependencies and automatically open pull requests to update vulnerable dependencies. + +See [AUTOTITLE](/enterprise-cloud@latest/code-security/how-tos/secure-at-scale/configure-organization-security/establish-complete-coverage/creating-a-custom-security-configuration) (organizations) and [AUTOTITLE](/enterprise-cloud@latest/code-security/how-tos/secure-at-scale/configure-enterprise-security/establish-complete-coverage/creating-a-custom-security-configuration-for-your-enterprise) (enterprises). + +### Tighten controls + +{% data variables.product.github %} gives you a range of controls that govern what can happen in your repositories and organization. Ensuring these controls are configured appropriately is essential for reducing risk. + +#### Protect critical branches with rulesets + +Rulesets let you define protection rules for branches and tags across one or more repositories. Use them to enforce requirements such as pull request reviews and status checks (such as automated security scans). This can help prevent unauthorized changes from reaching production code, including changes from compromised accounts. + +See [AUTOTITLE](/organizations/managing-organization-settings/creating-rulesets-for-repositories-in-your-organization) (organizations) and [AUTOTITLE](/enterprise-cloud@latest/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-code-governance) (enterprises). + +#### Control who can bypass push protection + +When you enable push protection, contributors who attempt to push a detected secret are blocked but, by default, they have the option to bypass the block. **Delegated bypass** requires that bypass requests pass through a review and approval cycle, so no bypass can happen without an explicit, audited decision. + +See [AUTOTITLE](/enterprise-cloud@latest/code-security/how-tos/secure-your-secrets/manage-bypass-requests/enabling-delegated-bypass-for-push-protection). + +#### Enforce dependency review on pull requests + +The dependency review action lets you catch vulnerable dependencies before they're merged, by surfacing known vulnerabilities in a pull request's dependency changes. Like push protection for secrets, it acts as a gate rather than an after-the-fact alert. You can enforce dependency review on pull requests across your organization. + +See [AUTOTITLE](/code-security/concepts/supply-chain-security/about-dependency-review#about-the-dependency-review-action) and [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-organization-security/configure-specific-tools/enforcing-dependency-review-across-an-organization). + +### Review and restrict access + +Access that was appropriate when it was granted may no longer be necessary. Regularly reviewing who and what has access to an organization reduces the risk of unauthorized actions. + +#### Audit member access and follow the principle of least privilege + +Ensure that members of organizations have only the access they need. Remove members who no longer require access, downgrade roles where broader permissions aren't justified, and review outside collaborator access. Overly permissive access increases the blast radius of any compromised account. + +If the default roles are more permissive than an organization requires, you can create **custom roles** that grant only the specific permissions each team needs. This is especially valuable for organizations adopting a zero trust security model. + +See [AUTOTITLE](/enterprise-cloud@latest/admin/managing-accounts-and-repositories/managing-roles-in-your-enterprise/identify-role-requirements). + +#### Review authorized applications + +{% data variables.product.prodname_oauth_apps %} and {% data variables.product.prodname_github_apps %} that are installed in an organization can access data. Review the list of authorized applications and remove any that are no longer needed or no longer trusted. Stale integrations represent an often-overlooked attack surface. + +See [AUTOTITLE](/apps/using-github-apps/reviewing-and-modifying-installed-github-apps) and [AUTOTITLE](/enterprise-cloud@latest/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions). + +#### Restrict network access with IP allow lists + +For organizations on {% data variables.product.prodname_ghe_cloud %}, if your organization operates from known network ranges, configure an IP allow list to restrict access to {% data variables.product.github %} resources from those ranges only. This adds a layer of defense against compromised credentials being used from unexpected locations. + +See [AUTOTITLE](/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization) and [AUTOTITLE](/enterprise-cloud@latest/admin/configuring-settings/hardening-security-for-your-enterprise/restricting-network-traffic-to-your-enterprise-with-an-ip-allow-list). + +{% ifversion secret-risk-assessment %} + +### Run a secret risk assessment + +Run a free, on-demand scan for an organization's repositories that gives you a point-in-time view of the total number of currently exposed secrets across your organization. + +See [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-organization-security/configure-specific-tools/assess-your-secret-risk). + +{% endif %} + +## Near-term actions + +These actions are also important for your security posture, but may require more preparation and coordination before you can roll them out. + +* [Strengthen authentication](#strengthen-authentication) +* [Harden your {% data variables.product.prodname_actions %} workflows](#harden-your-github-actions-workflows) +* [Prepare for a security incident](#prepare-for-a-security-incident) + +### Strengthen authentication + +Weak or compromised authentication is one of the most common causes of account takeover. Requiring strong authentication across your organization significantly reduces this risk. + +Require two-factor authentication (2FA) for all members, which ensures that a compromised password alone is not enough to access an account. Before enforcing the requirement, communicate with your organization so members have time to set up 2FA. + +Organizations on {% data variables.product.prodname_ghe_cloud %} can go further by enforcing single sign-on (SSO), which centralizes authentication through your identity provider. + +See [AUTOTITLE](/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization) and [AUTOTITLE](/enterprise-cloud@latest/organizations/managing-saml-single-sign-on-for-your-organization/about-identity-and-access-management-with-saml-single-sign-on). + +### Harden your {% data variables.product.prodname_actions %} workflows + +{% data variables.product.prodname_actions %} workflows often have access to secrets, deployment credentials, and write permissions to your repository. Without careful configuration, a compromised or malicious action can exfiltrate data or inject malicious code. + +#### Explicitly declare workflow permissions + +By default, workflows may receive broad permissions through the `GITHUB_TOKEN`. Explicitly declare the minimum permissions each workflow needs using the `permissions` key in your workflow files. This limits the damage that a compromised workflow step can cause. + +#### Pin third-party actions to commit SHAs + +When you reference a third-party action by tag (for example, `v1`), the tag can be moved to point to different code. Pinning actions to a full commit SHA ensures you always run the exact code you reviewed and approved. This protects against supply chain attacks where a tag is hijacked. + +#### Restrict which actions can run + +Configure policies at the organization or enterprise level to control which actions are allowed to run. You can limit actions to those created by {% data variables.product.github %}, actions from verified creators, or a specific allowlist. + +For more information on all of these practices, as well as additional secure use practices for {% data variables.product.prodname_actions %} specifically, see [AUTOTITLE](/actions/reference/security/secure-use). + +## Ongoing security practices + +These practices should become part of your regular operational rhythm. + +* [Monitor your security posture with security overview](#monitor-your-security-posture-with-security-overview) +* [Run regular security campaigns to reduce security debt](#run-regular-security-campaigns-to-reduce-security-debt) +* [Continue to audit access and permissions](#continue-to-audit-access-and-permissions) +* [Keep dependencies up to date](#keep-dependencies-up-to-date) +* [Rotate secrets and enforce expiration](#rotate-secrets-and-enforce-expiration) + +### Monitor your security posture with security overview + +Security overview gives you a centralized view of an organization's and enterprise's security landscape. Use it to track which repositories have security features enabled and identify repositories with open alerts, so that emerging risks don't go unnoticed. + +See [AUTOTITLE](/enterprise-cloud@latest/code-security/concepts/security-at-scale/about-security-overview). + +### Run regular security campaigns to reduce security debt + +Over time, security alerts can accumulate. Security campaigns let you organize and prioritize remediation efforts, assign groups of alerts to developers (with the help of {% data variables.product.prodname_copilot_short %}-generated fixes), or assign alerts directly to {% data variables.product.prodname_copilot_short %}. + +Security campaigns are available to organizations on {% data variables.product.prodname_team %} or {% data variables.product.prodname_ghe_cloud %} with {% data variables.product.prodname_GH_cs_or_sp %} enabled. See [AUTOTITLE](/enterprise-cloud@latest/code-security/how-tos/manage-security-alerts/remediate-alerts-at-scale/creating-managing-security-campaigns). + +### Continue to audit access and permissions + +As people join and leave an organization, and as projects evolve, access requirements change. Schedule periodic reviews of: + +* Organization membership and roles. +* Outside collaborator access. +* Repository-level permissions and team assignments. +* Authorized OAuth and {% data variables.product.prodname_github_apps %}. + +This ensures that access remains aligned with the principle of least privilege, even as your organization changes. + +### Keep dependencies up to date + +Vulnerable dependencies are a common entry point for attackers. {% data variables.product.prodname_dependabot %} can automatically open pull requests to update dependencies with known vulnerabilities, but those pull requests still need to be reviewed and merged promptly. + +Establish a process for triaging and merging {% data variables.product.prodname_dependabot %} pull requests so that security updates don't stall. + +See [AUTOTITLE](/enterprise-cloud@latest/code-security/concepts/supply-chain-security/about-dependabot-auto-triage-rules) and [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/manage-your-dependency-security/managing-pull-requests-for-dependency-updates). + +### Rotate secrets and enforce expiration + +The longer a credential exists, the more opportunity there is for it to be exposed or stolen. Where possible: + +* Set expiration dates on {% data variables.product.pat_generic_plural %}. +* Rotate secrets on a regular schedule. + +For information on managing tokens, see [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) and [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation). + +## Next steps + +* Even with strong preventive controls in place, security incidents can still occur. There are several critical tools and response processes that you should ensure are set up in advance. See [AUTOTITLE](/code-security/tutorials/secure-your-organization/preparing-for-security-incidents). \ No newline at end of file diff --git a/content/code-security/tutorials/secure-your-organization/responding-to-security-incidents.md b/content/code-security/tutorials/secure-your-organization/responding-to-security-incidents.md new file mode 100644 index 000000000000..2e177f5971f5 --- /dev/null +++ b/content/code-security/tutorials/secure-your-organization/responding-to-security-incidents.md @@ -0,0 +1,237 @@ +--- +title: Responding to a security incident +shortTitle: Respond to a security incident +allowTitleToDifferFromFilename: true +intro: Respond strategically to a security incident affecting organizations or repositories in your {% data variables.product.github %} enterprise. +versions: + fpt: '*' + ghec: '*' + ghes: '*' +contentType: tutorials +--- + +The guidance in this article is aimed at enterprise owners, organization owners, security managers and security teams. However, you will need to have the enterprise owner role to perform several of the actions outlined in this article. Some steps may require coordination with organization owners or repository administrators. + +## Introduction + +This guide walks you through how to respond to a security incident, outlining the {% data variables.product.github %} surfaces you can use to validate and investigate a threat, and the tools you can use to contain and remediate it. + +> [!IMPORTANT] The steps here are general guidelines. Every incident is unique and may require different approaches based on the specific circumstances. +> +> While {% data variables.contact.github_support %} can assist with platform-specific questions, you are best placed to investigate and respond to a security incident affecting your systems and resources. + +### Prerequisites + +Ideally, you have **audit log streaming** and **source IP address visibility** already enabled for the enterprise (streaming the data to a security information and event management (SIEM) system) and you have access to that data. See [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise). + +### Throughout your response + +As you progress through your response, make sure that you: +* **Preserve evidence**: Take screenshots of suspicious activity, export logs or query results, and save copies of affected files or code before cleanup. +* **Keep a record**: Document your findings (for example, times, dates, Indicators of Compromise (IoCs), repositories affected) and record each decision you take. +* **Communicate**: Notify relevant stakeholders (such as security leads and engineering managers, as well as legal and privacy teams if sensitive data is at risk) and keep them updated. + +## Step 1: Assess the signal and validate quickly + +The goal is to quickly determine whether the signal you're seeing is likely to be a real and active threat. + +### 1. Identify + +Try to identify the nature of the signal you're seeing. For example, does the signal show indications of: + +* **Credential compromise** (alert for a leaked secret, reports of credentials found on an external site) +* **Unauthorized access or account compromise** (reports of suspicious logins, unfamiliar commits or changes) +* **Data exfiltration** (reports of suspicious file changes or additions, unexpected workflow runs, unusual API activity, unknown repository creations, or unexpected repository visibility changes) +* **Malicious code injection** (reports of suspicious code changes, unexpected workflow runs, new files added) +* **Supply chain attack** (reports of suspicious package versions, alerts for vulnerable dependencies) + +For help identifying these threat signals across your organization or enterprise, consult [AUTOTITLE](/code-security/reference/security-incident-response/investigation-areas). + +We suggest you don't spend too much time on deep inspection in the earlier stages of your investigation, since the initial goal is to **identify** the threat signal in order to **validate** it and strategize your response. + +### 2. Validate + +Check for evidence to validate that the potential threat is real, and whether or not it's currently active. + +The following {% data variables.product.github %} tools and surfaces can help. + +| Tool / surface | Purpose | +| --- | --- | +| [Security overview and security alerts](/code-security/reference/security-incident-response/investigation-tools#security-overview-and-security-alerts) | Review security alerts across your organization or enterprise | +| [Audit logs](/code-security/reference/security-incident-response/investigation-tools#audit-logs) | Search for events related to the signal you're investigating, such as token creation, permission changes, or repository visibility changes | +| [Activity view](/code-security/reference/security-incident-response/investigation-tools#activity-view) | View a timeline of pushes, commits, and branch activity for a specific repository | +| [{% data variables.product.github %} code search](/code-security/reference/security-incident-response/investigation-tools#github-code-search) | Search for known indicators of compromise, such as specific filenames or code patterns, across repositories | +| [Dependency graph](/code-security/reference/security-incident-response/investigation-tools#dependency-graph) | Check whether repositories depend on a specific package or package version | +| [Workflow runs and logs](/code-security/reference/security-incident-response/investigation-tools#workflow-runs-and-logs) | Review workflow execution history and inspect log output for suspicious activity | + +For details on each tool, see [AUTOTITLE](/code-security/reference/security-incident-response/investigation-tools). + +The validation phase can be **quick**: +* Aim to gather enough evidence to determine whether the signal is likely to be a **real** and **active** threat. +* If you can't quickly rule out the signal as a false positive, assume it's real. +* Deep investigation can be performed later. + +### 3. Decide + +Based on the evidence gathered, determine three things: + +1. **Is this a real threat?** If you cannot quickly and confidently rule the signal out as a false positive, treat it as real and proceed to containment. +1. **Is the threat still active?** If the attacker appears to still have access or activity is ongoing, prioritize immediate containment actions first. If the compromise appears historical, you still need to investigate and remediate, but you may have more time to plan your response. +1. **What is the potential scope?** Consider how far the compromise could reach—a single credential, a repository, an organization, or the entire enterprise. This will help you scale your response appropriately. + +If in doubt, treat the threat as real, and scale back your response as evidence allows. + +## Step 2: Contain the threat + +The next step assumes you are dealing with a real and active threat. The goal now is to **immediately reduce ongoing risk** using what you know so far. + +There are several containment actions you can choose to perform to limit the attacker's access and capabilities. + +>[!IMPORTANT] +> You should base your choice of actions on the nature of the threat, the potential scope, and the evidence you have at this point. We don't recommend taking all of these actions for every incident. Some actions are more disruptive or destructive than others, so you must weigh the risks and benefits of each action based on your assessment of the nature of the threat above. + +### Revoke compromised credentials + +For exposed or exploited credentials, the most immediate action you can take is to revoke the affected credentials to prevent further misuse. + +{% ifversion fpt or ghec or ghes > 3.17 %} +* **Revoke via the API** + + If the token is one of the following types, and the literal value of the token is known, you (or anybody) can revoke it by **submitting a request via the REST API**. See [AUTOTITLE](/rest/credentials/revoke?apiVersion=2022-11-28#revoke-a-list-of-credentials). + + * {% data variables.product.pat_v1_caps %} + * {% data variables.product.pat_v2_caps %}{% ifversion fpt or ghec or ghes > 3.20 %} + * {% data variables.product.prodname_oauth_app %} access token + * {% data variables.product.prodname_github_app %} user access token + * {% data variables.product.prodname_github_app %} refresh token{% endif %} +{% endif %} + +* **Revocation and containment options** + + There are additional options for blocking credential access. For a full list by credential type, see [AUTOTITLE](/organizations/managing-programmatic-access-to-your-organization/github-credential-types). + +* **Emergency actions (major incident)** + + Enterprise owners on {% data variables.product.prodname_ghe_cloud %} can take bulk emergency actions to lock down access across their enterprise. For enterprises with {% data variables.product.prodname_emus %}, this includes **deleting all user tokens and keys**. These are high-impact actions that will break automations and should be reserved for major incidents. See [AUTOTITLE](/enterprise-cloud@latest/admin/managing-iam/respond-to-incidents). + +### Restrict access + +To restrict access to the enterprise, organization or repository, there are several immediate actions you can take. + +* **Configure IP allowlists** + + Block unknown or suspicious IP addresses from accessing the organization or enterprise. See [AUTOTITLE](/enterprise-cloud@latest/admin/configuring-settings/hardening-security-for-your-enterprise/restricting-network-traffic-to-your-enterprise-with-an-ip-allow-list) (enterprise admins) and [AUTOTITLE](/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization) (organization owners). + +* **Remove compromised or suspicious users** + + Remove the user or suspend the account. See {% ifversion remove-enterprise-members %}[AUTOTITLE](/admin/managing-accounts-and-repositories/managing-users-in-your-enterprise/removing-a-member-from-your-enterprise) (enterprise admins) and {% endif %}[AUTOTITLE](/organizations/managing-membership-in-your-organization/removing-a-member-from-your-organization) (organization owners). + +* **Change repository visibility to private** + + Change the affected repository's visibility to private, and restrict the ability of others to make further changes. For example, if sensitive code was exposed in a public repository belonging to the organization, or if a malicious actor changed the repository's visibility setting from private to public, you can change the visibility of the repository. See [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/setting-repository-visibility) (repository administrators and organization owners) and [AUTOTITLE](/organizations/managing-organization-settings/restricting-repository-visibility-changes-in-your-organization) (organization owners). + +* **Emergency actions (major incident)** + + Enterprise owners on {% data variables.product.prodname_ghe_cloud %} can take bulk emergency actions to lock down access across their enterprise. These include **locking down SSO** to block all non-owner access and **revoking all user SSO authorizations across organizations**. These are high-impact actions that will break automations and should be reserved for major incidents. See [AUTOTITLE](/enterprise-cloud@latest/admin/managing-iam/respond-to-incidents). + +### Disable malicious artifacts and activity + +* **Stop malicious workflow runs** + + If you suspect that a {% data variables.product.prodname_actions %} workflow or runner is being used as part of an active attack, you can take the following actions: + * Cancel in-progress workflow runs for an affected repository. See [AUTOTITLE](/actions/how-tos/manage-workflow-runs/cancel-a-workflow-run). + * Disable {% data variables.product.prodname_actions %} for an affected repository in an organization, or for a specific organization. See [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization) (organization owners) and [AUTOTITLE](/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise) (enterprise administrators). + * Remove self-hosted runners. See [AUTOTITLE](/actions/how-tos/manage-runners/self-hosted-runners/remove-runners). + +* **Disable webhooks** + + If you suspect that a compromised repository or organization webhook is being used as a live data exfiltration channel, you can disable it. See [AUTOTITLE](/webhooks/using-webhooks/disabling-webhooks). + +* **Delete malicious branches** + + If you've identified branches that contain malicious code or workflows, delete them immediately to prevent execution. See [AUTOTITLE](/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository#deleting-a-branch). + +## Step 3: Investigate fully + +After immediate containment, the goal now is to understand the full scope and impact of the incident, identify all IoCs and persistence mechanisms, and gather the evidence you need to contain and fully remediate the threat. + +> [!IMPORTANT] Incident response is not a linear process. You may need to iterate between investigation, containment, and remediation as you discover new IoCs or understand more about the attack. + +1. Based on the signals you've seen and the evidence gathered so far, develop a **working hypothesis** of what has happened and decide what additional evidence you will need to prove or disprove that hypothesis. +1. Consider the different **investigation areas** outlined in [AUTOTITLE](/code-security/reference/security-incident-response/investigation-areas) to help guide your investigation. + + Don't limit your investigation to a single line of inquiry. Many attacks use a combination of techniques, such as malicious package installation combined with credential exploitation, workflow file injections, and data exfiltration. Ensure that you are investigating all potential attack vectors. +1. **Document** all known IoCs so far, searching for traces across all surfaces of {% data variables.product.github %}. +1. **Inventory** all the affected workflows, repositories, and organizations to capture the scope of the incident systematically. + * Include the repository name, what was affected (code, secrets, workflows), and the timeline of compromise. + * Create a list of all affected accounts and credentials. Note which tokens, SSH keys, or other credentials may have been exposed or misused. +1. **Validate** your working theory against the evidence. + * Review the evidence you've gathered. Does it support your initial hypothesis? + * Consider alternative explanations. Could there be a different cause for the activity you've observed? + * If your hypothesis is disproved, form a new hypothesis based on the evidence and repeat the investigation steps as needed. +1. **Circle back to containment** if you discover new IoCs or evidence of ongoing activity that requires immediate action. + +Once you have high confidence in your understanding of what's happened and the root cause, document your findings and proceed to remediation. + +## Step 4: Remediate + +The goal now is to remove all traces of compromise, fix the root cause, and restore systems to a secure state. Remediation actions will depend on the exploitation you have faced, but some good practices are as follows. + +### Rotate tokens and secrets + +Even if you're not certain a credential was compromised, rotate it if there's any possibility of exposure. + +* Generate new tokens and secrets to replace any that were revoked or may have been exposed. +* Rotate secrets stored in {% data variables.product.github %} at the repository, environment, and organization levels. +* Update any credentials in external systems that may have been accessed using compromised tokens. +* Consider enabling token expiration policies to encourage regular rotation going forward. See [AUTOTITLE](/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-personal-access-tokens-in-your-enterprise). + +### Audit for persistence mechanisms + +You will need to check for persistence mechanisms that the attacker may have established to maintain access even after your initial containment actions. + +This includes, but isn't limited to, checking for things like: +* Suspicious or unfamiliar workflow files that may have been added or modified. +* New webhooks pointing to unfamiliar domains. +* New self-hosted runners. +* Modifications to self-hosted runners. +* Newly installed {% data variables.product.prodname_github_apps %} or {% data variables.product.prodname_oauth_app %} authorizations. +* New deploy keys added to repositories. +* New binary files or executables. + +### Audit and reinstall dependencies + +Compromised dependencies can serve as an attack vector. Make sure you undertake a full audit of your dependencies and reinstall them from trusted sources. + +* Review {% data variables.product.prodname_dependabot %} alerts for vulnerable dependencies and, where available, {% data variables.product.prodname_dependabot_malware_alerts %} for malicious packages. ({% data variables.product.prodname_dependabot_malware_alerts %} are currently available for the npm ecosystem.) To investigate additional malware advisories, search for `type:malware` in the {% data variables.product.prodname_advisory_database %} and audit your dependency graph for matches. +* Pin dependencies to known-good versions or commit SHAs, and reinstall from your package registry. + +### Verify remediation + +Confirm that your remediation efforts have been successful. + +* Review {% data variables.product.prodname_code_scanning %} alerts to confirm that code vulnerabilities have been resolved, and no new vulnerabilities have been introduced. +* Review {% data variables.product.prodname_secret_scanning %} alerts to confirm that no secrets remain exposed in any repositories, and that all alerts have been resolved. +* Continue to review and monitor audit logs and other relevant surfaces in the coming days and weeks post-incident. + +## Step 5. Document + +Thorough documentation is essential for the remaining phases and for future reference. + +* Record all IoCs discovered during the investigation. +* Document all remediation steps taken, including timestamps and who performed each action. +* Maintain inventories of affected repositories, workflows, and accounts. +* Document decisions made and the reasoning behind them. +* Note any compliance, legal, or privacy implications. Consider whether this incident constitutes a data breach that requires notification. + +## Step 6: Reflect and harden + +The goal now is to learn from the incident and strengthen your security posture to prevent similar incidents. + +1. Write an **incident summary**. This should include a timeline of events from first indication to resolution, as well as the root cause analysis, decisions and actions taken, and lessons learned. +1. Track any **outstanding action items** from the security incident as issues, such as remaining remediation tasks and any security improvements that need to be implemented based on lessons learned. {% ifversion copilot %}{% data variables.product.prodname_copilot_short %} can help create these, and you can assign well-scoped issues to {% data variables.product.prodname_copilot_short %} to work on independently. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot).{% endif %} +1. If you don't already have one, ensure your company or team has an up-to-date **Security Incident Response Plan**. This should include defined roles and responsibilities, escalation paths, communication protocols, severity classification criteria, and step-by-step response procedures for common threat types. {% data variables.product.prodname_copilot_short %} can help generate and refine this plan based on your specific needs and resources. For additional guidance, see [What is incident response](https://github.com/resources/articles/what-is-incident-response#what-is-incident-response). + +## Next steps + +* If you haven't already, consider hardening your security posture to reduce the risk of future incidents. See [AUTOTITLE](/code-security/tutorials/secure-your-organization/protect-against-threats). diff --git a/content/copilot/concepts/context/mcp.md b/content/copilot/concepts/context/mcp.md index 8c37d93cfbf1..57b83b3a5765 100644 --- a/content/copilot/concepts/context/mcp.md +++ b/content/copilot/concepts/context/mcp.md @@ -92,7 +92,7 @@ To learn how to configure toolsets for the {% data variables.product.github %} M ### Security -For all public repositories, and private repositories covered by {% data variables.product.prodname_GHAS %}, interactions with the {% data variables.product.github %} MCP server are secured by push protection, which blocks secrets from being included in AI-generated responses and prevents you from exposing secrets through any actions you perform using the server, such as creating an issue. For more information, see [AUTOTITLE](/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-and-the-github-mcp-server). +For all public repositories, and private repositories covered by {% data variables.product.prodname_GHAS %}, interactions with the {% data variables.product.github %} MCP server are secured by push protection, which blocks secrets in AI-generated responses and prevents them from being included in actions taken on your behalf. You can also proactively scan your code for exposed secrets from within your AI coding agent. For more information, see [AUTOTITLE](/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server). ## About the {% data variables.product.github %} MCP Registry diff --git a/content/copilot/concepts/mcp-management.md b/content/copilot/concepts/mcp-management.md index ae2f28af8684..1f47d082dcbd 100644 --- a/content/copilot/concepts/mcp-management.md +++ b/content/copilot/concepts/mcp-management.md @@ -35,7 +35,7 @@ MCP management features are supported as follows: | Surface | Registry display | Allowlist enforcement | |---|:---:|:---:| -| {% data variables.copilot.copilot_cli_short %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | +| {% data variables.copilot.copilot_cli_short %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | {% data variables.copilot.copilot_cloud_agent %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | | Eclipse | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | JetBrains | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | diff --git a/content/copilot/how-tos/copilot-sdk/authenticate-copilot-sdk/authenticate-copilot-sdk.md b/content/copilot/how-tos/copilot-sdk/authenticate-copilot-sdk/authenticate-copilot-sdk.md index 3fae0b36e71a..9d2291247b5a 100644 --- a/content/copilot/how-tos/copilot-sdk/authenticate-copilot-sdk/authenticate-copilot-sdk.md +++ b/content/copilot/how-tos/copilot-sdk/authenticate-copilot-sdk/authenticate-copilot-sdk.md @@ -131,7 +131,6 @@ For complete setup instructions, including provider configuration options, limit When multiple authentication methods are available, the SDK uses them in this priority order: 1. **Explicit `githubToken`** — Token passed directly to the SDK constructor -1. **HMAC key** — `CAPI_HMAC_KEY` or `COPILOT_HMAC_KEY` environment variables 1. **Direct API token** — `GITHUB_COPILOT_API_TOKEN` with `COPILOT_API_URL` 1. **Environment variable tokens** — `COPILOT_GITHUB_TOKEN` → `GH_TOKEN` → `GITHUB_TOKEN` 1. **Stored OAuth credentials** — From previous `copilot` CLI sign-in diff --git a/content/copilot/how-tos/provide-context/use-mcp-in-your-ide/configure-toolsets.md b/content/copilot/how-tos/provide-context/use-mcp-in-your-ide/configure-toolsets.md index 6b9d0c32048f..1ced4190fdc4 100644 --- a/content/copilot/how-tos/provide-context/use-mcp-in-your-ide/configure-toolsets.md +++ b/content/copilot/how-tos/provide-context/use-mcp-in-your-ide/configure-toolsets.md @@ -15,7 +15,7 @@ category: The {% data variables.product.github %} MCP server includes default toolsets (`repos`, `issues`, and `pull_requests`) that are enabled automatically. You can customize toolset configuration by: -* **Enabling individual toolsets** such as `actions`, `code_security`, or `secret_protection` +* **Enabling individual toolsets** such as `actions`, `code_security`, or `secret_protection`. For a step-by-step guide to scanning for secrets using the `secret_protection` toolset, see [AUTOTITLE](/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server). * **Using special keywords** like `all` to enable every available toolset, or [`default`](https://github.com/github/github-mcp-server?tab=readme-ov-file#default-toolset) to include the standard set alongside others (for example, `default,stargazers`) * **Accessing remote-only toolsets** such as `copilot` (for {% data variables.copilot.copilot_cloud_agent %}) and `github_support_docs_search`, which are only available on the remote MCP server * **Selecting specific tools** for granular control when you want to exclude specific tools or combine toolsets with individual tools diff --git a/content/migrations/index.md b/content/migrations/index.md index b19ae6185d9a..c51b13592663 100644 --- a/content/migrations/index.md +++ b/content/migrations/index.md @@ -16,6 +16,7 @@ children: - /importing-source-code - /using-github-enterprise-importer - /using-ghe-migrator + - /troubleshooting includedCategories: - Plan your migration - Import source code diff --git a/content/migrations/troubleshooting/index.md b/content/migrations/troubleshooting/index.md new file mode 100644 index 000000000000..b4c6b2b05f22 --- /dev/null +++ b/content/migrations/troubleshooting/index.md @@ -0,0 +1,10 @@ +--- +title: Troubleshooting migrations +shortTitle: Troubleshoot migrations +intro: 'Troubleshoot common issues when migrating repositories with {% data variables.product.prodname_importer_proper_name %}.' +versions: + ghec: '*' +children: + - /troubleshooting-your-migration-with-github-enterprise-importer + - /setting-ruleset-bypasses-for-repository-migrations +--- diff --git a/content/migrations/troubleshooting/setting-ruleset-bypasses-for-repository-migrations.md b/content/migrations/troubleshooting/setting-ruleset-bypasses-for-repository-migrations.md new file mode 100644 index 000000000000..331bfc89eaf6 --- /dev/null +++ b/content/migrations/troubleshooting/setting-ruleset-bypasses-for-repository-migrations.md @@ -0,0 +1,52 @@ +--- +title: Setting ruleset bypasses for repository migrations +shortTitle: Ruleset bypasses +intro: 'When migrating repositories with {% data variables.product.prodname_importer_proper_name %}, evaluation of organization-level and enterprise-level rulesets can cause Git pushes to fail unless **Repository migrations** is added to the bypass list with the **Exempt** mode.' +versions: + ghec: '*' +--- + +## Background + +When you import a repository with {% data variables.product.prodname_importer_proper_name %}, an internal service pushes the repository's Git data to {% data variables.product.github %}, batching refs together for performance. This introduces a possible case where evaluation of organization-level or enterprise-level rulesets against the pushed refs can time out, causing the repository migration as a whole to fail. + +Because {% data variables.product.prodname_importer_proper_name %} tags its Git pushes as migration operations, you can create ruleset bypasses that apply only to repository migrations and not to other actors. This prevents ruleset evaluations from timing out and causing migration failures. + +## “Always allow” vs. “Exempt” + +Ruleset bypasses come in two types: “always allow” and “exempt.” Their differences are subtle, but material for the case of repository migrations: + +| Mode | Behavior | +|------|----------| +| **Always allow** | The ruleset will be evaluated and the selected actor(s) will be prompted to bypass | +| **Exempt** | The ruleset will not be evaluated and no bypass prompt will be shown | + +The key distinction for the purposes of Git migrations is not whether the ruleset will pass or fail (“always allow” would be sufficient in that case), but whether the ruleset is evaluated at all (necessitating “exempt” bypasses). + +## Adding the bypass + +The following steps walk through configuring ruleset bypasses required for migrations. You will need organization admin or enterprise admin permissions to edit the respective rulesets. + +1. In your organization’s settings, expand the **Repository** section, then navigate to **Rulesets**. + +1. Navigate to the ruleset you want to update. In the **Bypass list** section, you will see either an empty list or any bypasses already configured. + +1. If **Repository migrations** isn’t present in the bypass list, click **Add bypass**. A dropdown appears listing the available bypass actors; check the box next to **Repository migrations**, and note that the entry appears in your bypass list with a default mode of **Always allow**. + +1. Click the **···** menu on the Repository migrations entry. You will see two mode options and a delete action. Select **Exempt**. Do not leave the mode set to **Always allow**—as noted above, **Always allow** bypasses still allow evaluation, which is what times out. The bypass list now shows **Repository migrations** with mode **Exempt**. + +1. Scroll to the bottom of the ruleset page and click **Save changes**. The bypass takes effect immediately for subsequent migration runs. + +## Security and side effects + +As noted above, {% data variables.product.prodname_importer_proper_name %} uses a specific path for pushing Git data, and the **Repository migrations** bypass only targets that path—there is no path where ordinary users or Git pushes to existing repositories can bypass rulesets using the **Repository migrations** bypass. + +It is recommended that all **Repository migrations** bypasses be left in place for as long as you are running migrations. After migrations are complete, + leaving the bypass in place does not pose any security risk. + +## Related topics + +* [AUTOTITLE](/migrations/using-github-enterprise-importer/understanding-github-enterprise-importer/about-github-enterprise-importer) +* [AUTOTITLE](/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer) +* [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) +* [AUTOTITLE](/admin/enforcing-policies/enforcing-policies-for-your-enterprise/managing-policies-for-code-governance) diff --git a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer.md b/content/migrations/troubleshooting/troubleshooting-your-migration-with-github-enterprise-importer.md similarity index 99% rename from content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer.md rename to content/migrations/troubleshooting/troubleshooting-your-migration-with-github-enterprise-importer.md index 4f8a9f671de4..0c56b2eaf6ef 100644 --- a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer.md +++ b/content/migrations/troubleshooting/troubleshooting-your-migration-with-github-enterprise-importer.md @@ -9,8 +9,7 @@ versions: redirect_from: - /early-access/github/migrating-with-github-enterprise-importer/running-a-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer - /early-access/enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer -category: - - Run an enterprise migration + - /migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/troubleshooting-your-migration-with-github-enterprise-importer --- ## About troubleshooting steps for {% data variables.product.prodname_importer_proper_name %} diff --git a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/index.md b/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/index.md index eb984ac63b1f..2a06bf4b3fdc 100644 --- a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/index.md +++ b/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/index.md @@ -1,7 +1,7 @@ --- title: Completing your migration with GitHub Enterprise Importer shortTitle: Complete migration -intro: 'After you migrate repositories to {% data variables.product.prodname_dotcom %}, you can access migration logs, reclaim mannequins, and troubleshoot any unexpected results.' +intro: 'After you migrate repositories to {% data variables.product.prodname_dotcom %}, you can access migration logs and reclaim mannequins.' versions: fpt: '*' ghes: '*' @@ -9,7 +9,6 @@ versions: children: - /accessing-your-migration-logs-for-github-enterprise-importer - /reclaiming-mannequins-for-github-enterprise-importer - - /troubleshooting-your-migration-with-github-enterprise-importer redirect_from: - /early-access/enterprise-importer/completing-your-migration-with-github-enterprise-importer --- diff --git a/content/rest/copilot-spaces/resources.md b/content/rest/copilot-spaces/resources.md index 04d1cadb3bd8..007beff29165 100644 --- a/content/rest/copilot-spaces/resources.md +++ b/content/rest/copilot-spaces/resources.md @@ -1,6 +1,6 @@ --- -title: REST API endpoints for Copilot Spaces -shortTitle: Copilot Spaces +title: REST API endpoints for Copilot Spaces resources +shortTitle: Resources intro: Use the REST API to interact with Copilot Spaces resources. versions: # DO NOT MANUALLY EDIT. CHANGES WILL BE OVERWRITTEN BY A 🤖 fpt: '*' diff --git a/data/reusables/copilot/opus-47-promo-period.md b/data/reusables/copilot/opus-47-promo-period.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/data/reusables/enterprise-migration-tool/repository-migrations-bypass.md b/data/reusables/enterprise-migration-tool/repository-migrations-bypass.md index a6bc546cd8a6..4b9019b88192 100644 --- a/data/reusables/enterprise-migration-tool/repository-migrations-bypass.md +++ b/data/reusables/enterprise-migration-tool/repository-migrations-bypass.md @@ -6,4 +6,4 @@ To configure the bypass: 1. In the "Bypass list" section, click **Add bypass**. 1. Select **Repository migrations**. -For more information, see [AUTOTITLE](/organizations/managing-organization-settings/creating-rulesets-for-repositories-in-your-organization#granting-bypass-permissions-for-your-branch-or-tag-ruleset). +For more information, see [AUTOTITLE](/organizations/managing-organization-settings/creating-rulesets-for-repositories-in-your-organization#granting-bypass-permissions-for-your-branch-or-tag-ruleset) and [AUTOTITLE](/migrations/troubleshooting/setting-ruleset-bypasses-for-repository-migrations). diff --git a/data/reusables/enterprise-migration-tool/validate-migration-logs.md b/data/reusables/enterprise-migration-tool/validate-migration-logs.md index b4b2a9351289..3907250870fa 100644 --- a/data/reusables/enterprise-migration-tool/validate-migration-logs.md +++ b/data/reusables/enterprise-migration-tool/validate-migration-logs.md @@ -1,3 +1,3 @@ -When your migration is complete, we recommend reviewing your migration log. For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/accessing-your-migration-logs-for-github-enterprise-importer). +When your migration is complete, we recommend reviewing your migration log. For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/accessing-your-migration-logs-for-github-enterprise-importer). If your source repository contained rulesets and you're being blocked by them, see [AUTOTITLE](/migrations/troubleshooting/setting-ruleset-bypasses-for-repository-migrations). We recommend that you review your migrated repositories for a soundness check. diff --git a/src/links/lib/extract-links.ts b/src/links/lib/extract-links.ts index deac31b11964..7f2224bd64d8 100644 --- a/src/links/lib/extract-links.ts +++ b/src/links/lib/extract-links.ts @@ -24,6 +24,15 @@ const IMAGE_LINK_PATTERN = /!\[[^\]]*\]\(([^)]+)\)/g // Anchor link patterns (for same-page links) const ANCHOR_LINK_PATTERN = /\]\(#[^)]+\)/g +// Reference-style link definitions: [id]: /path or [id]: /path "title" +// Captures the URL from lines like: [ssh-agent-forwarding]: /authentication/... +const LINK_DEFINITION_PATTERN = /^\[[^\]]+\]:\s+(\/[^\s"'(<>]*)/gm + +// Links whose href starts with a Liquid tag rather than a literal '/' +// e.g. ]({% ifversion fpt %}/enterprise-cloud@latest{% endif %}/path) +// None of these Liquid tags contain ')' in practice, so [^)]+ is safe. +const LIQUID_HREF_PATTERN = /\]\(({%[^)]+)\)/g + export interface ExtractedLink { href: string line: number @@ -39,6 +48,12 @@ export interface LinkExtractionResult { externalLinks: ExtractedLink[] anchorLinks: ExtractedLink[] imageLinks: ExtractedLink[] + /** + * Links whose href begins with a Liquid tag (e.g. `]({% ifversion ... %}/path)`). + * The `href` field contains the raw unrendered Liquid string. Callers that need + * to validate these links must render the href to obtain its canonical path. + */ + liquidPrefixedLinks: ExtractedLink[] } /** @@ -83,6 +98,7 @@ export function extractLinksFromMarkdown(content: string): LinkExtractionResult const externalLinks: ExtractedLink[] = [] const anchorLinks: ExtractedLink[] = [] const imageLinks: ExtractedLink[] = [] + const liquidPrefixedLinks: ExtractedLink[] = [] // Strip fenced code blocks to avoid checking example/placeholder URLs // Replaces non-newline characters with spaces to preserve line numbers and positions @@ -189,11 +205,41 @@ export function extractLinksFromMarkdown(content: string): LinkExtractionResult // Reset regex IMAGE_LINK_PATTERN.lastIndex = 0 + // Extract reference-style link definitions ([id]: /path) + // These are distinct from inline links but point to the same targets that need validating. + while ((match = LINK_DEFINITION_PATTERN.exec(strippedContent)) !== null) { + const { line, column } = getLineAndColumn(strippedContent, match.index) + const href = match[1].split('#')[0] + internalLinks.push({ + href, + line, + column, + isAutotitle: false, + }) + } + + // Reset regex + LINK_DEFINITION_PATTERN.lastIndex = 0 + + // Extract links whose href starts with a Liquid tag + while ((match = LIQUID_HREF_PATTERN.exec(strippedContent)) !== null) { + const { line, column } = getLineAndColumn(strippedContent, match.index) + liquidPrefixedLinks.push({ + href: match[1], + line, + column, + }) + } + + // Reset regex + LIQUID_HREF_PATTERN.lastIndex = 0 + return { internalLinks, externalLinks, anchorLinks, imageLinks, + liquidPrefixedLinks, } } diff --git a/src/links/scripts/check-links-internal.ts b/src/links/scripts/check-links-internal.ts index c957fff48065..96a8d94b7a38 100644 --- a/src/links/scripts/check-links-internal.ts +++ b/src/links/scripts/check-links-internal.ts @@ -18,6 +18,8 @@ * CHECK_ANCHORS - Whether to check anchor links (default: true) */ +import fs from 'fs' + import { program } from 'commander' import chalk from 'chalk' import { load } from 'cheerio' @@ -31,6 +33,8 @@ import { checkInternalLink, checkAssetLink, isAssetLink, + extractLinksWithLiquid, + extractLinksFromMarkdown, } from '@/links/lib/extract-links' import { type BrokenLink, @@ -62,34 +66,134 @@ interface CheckResult { } /** - * Render a page and extract all internal links from the HTML + * Count how many lines the frontmatter block occupies in the raw source file. + * `page.markdown` has frontmatter stripped, so line numbers from markdown + * parsing are relative to the body. Adding this offset converts them to + * actual file line numbers. + * + * Results are cached by fullPath — the file is read once per page across + * both getLinksFromMarkdown() and checkAnchorsOnPage(). */ -async function getLinksFromRenderedPage( - page: Page, - permalink: Permalink, - context: Context, -): Promise<{ href: string; text: string }[]> { - const links: { href: string; text: string }[] = [] +const frontmatterLineOffsetCache = new Map() +function getFrontmatterLineOffset(fullPath: string): number { + const cached = frontmatterLineOffsetCache.get(fullPath) + if (cached !== undefined) return cached + + let offset = 0 try { - // Render the page content - const html = await renderContent(page.markdown, context) - const $ = load(html) + const raw = fs.readFileSync(fullPath, 'utf8') + if (raw.startsWith('---')) { + const lines = raw.split('\n') + for (let i = 1; i < lines.length; i++) { + if (lines[i].trimEnd() === '---') { + // i is the 0-based index of the closing `---`; adding 1 gives the + // 1-based line number of that delimiter, which is the total number + // of frontmatter lines. Body content starts on the next line. + offset = i + 1 + break + } + } + } + } catch { + // ignore — fall back to no offset + } - // Extract all anchor links - $('a[href]').each((_, el) => { - const href = $(el).attr('href') - const text = $(el).text() + frontmatterLineOffsetCache.set(fullPath, offset) + return offset +} - if (href && href.startsWith('/')) { - links.push({ href, text }) +/** + * Extract all internal links from the markdown source with accurate line numbers. + * + * Links are discovered from the Liquid-rendered content (which expands {% data reusables.xxx %} + * and respects {% ifversion %} for the current version), so coverage matches the original + * HTML-based checker. Line numbers are resolved against the raw markdown source to avoid + * drift caused by Liquid post-processing (blank-line collapsing). Links that originate + * from a reusable file rather than the page itself fall back to line 0. + */ +async function getLinksFromMarkdown( + page: Page, + context: Context, +): Promise<{ href: string; text: string | undefined; line: number }[]> { + const fmOffset = getFrontmatterLineOffset(page.fullPath) + + // Build a map of raw-markdown line numbers per href, plus a parallel index + // map to consume them in encounter order without shifting (O(1) per lookup). + // + // When a raw href contains Liquid tags (e.g. `/{% ifversion fpt %}enterprise-cloud@latest/{% endif %}/path`), + // the rendered href will differ from the raw string, so rawLinesByHref.get() would miss. + // To fix this, we lazily import renderLiquid once and use it to resolve those hrefs to + // their canonical (rendered) form before keying the map — matching what extractLinksWithLiquid produces. + const rawResult = extractLinksFromMarkdown(page.markdown) + + const needsLiquidHrefResolution = + rawResult.internalLinks.some((l) => l.href.includes('{%') || l.href.includes('{{')) || + rawResult.liquidPrefixedLinks.length > 0 + type RenderLiquidFn = (template: string, context: unknown) => Promise + let renderLiquidFn: RenderLiquidFn | null = null + if (needsLiquidHrefResolution) { + const mod = await import('@/content-render/liquid/index') + renderLiquidFn = mod.renderLiquid + } + + const rawLinesByHref = new Map() + for (const link of rawResult.internalLinks) { + let canonicalHref = link.href + if (renderLiquidFn && (canonicalHref.includes('{%') || canonicalHref.includes('{{'))) { + try { + // Render only the href string so we get the same canonical href that + // extractLinksWithLiquid will produce, without affecting line positions. + canonicalHref = (await renderLiquidFn(canonicalHref, context)).trim() + } catch { + // fall back to raw href if rendering fails } - }) - } catch (error) { - console.warn(`Failed to render ${page.relativePath} (${permalink.href}):`, error) + } + const existing = rawLinesByHref.get(canonicalHref) + if (existing) { + existing.push(link.line + fmOffset) + } else { + rawLinesByHref.set(canonicalHref, [link.line + fmOffset]) + } } - return links + // Liquid-prefixed links (href starts with `{%`) are absent from internalLinks because + // INTERNAL_LINK_PATTERN requires a leading '/'. Render each href to its canonical form + // and, if the result is an internal path, add it to the map so lookups don't miss. + if (renderLiquidFn) { + for (const link of rawResult.liquidPrefixedLinks) { + try { + const rendered = (await renderLiquidFn(link.href, context)).trim().split('#')[0] + if (rendered.startsWith('/')) { + const existing = rawLinesByHref.get(rendered) + if (existing) { + existing.push(link.line + fmOffset) + } else { + rawLinesByHref.set(rendered, [link.line + fmOffset]) + } + } + } catch { + // skip — can't resolve line number for this link + } + } + } + // Tracks how many line numbers have been consumed for each href. + const rawLinesIndex = new Map() + + // The Liquid-rendered set drives which links are actually checked (expands + // reusables, excludes version-gated links that don't apply here). + // extractLinksWithLiquid already catches Liquid render failures internally and + // falls back to raw extraction with a warning, so no outer try/catch is needed. + const renderedResult = await extractLinksWithLiquid(page.markdown, context) + const renderedLinks = renderedResult.internalLinks.map((l) => ({ href: l.href, text: l.text })) + + return renderedLinks.map((link) => { + const lines = rawLinesByHref.get(link.href) + const idx = rawLinesIndex.get(link.href) ?? 0 + const line = lines && idx < lines.length ? lines[idx] : 0 + rawLinesIndex.set(link.href, idx + 1) + return { href: link.href, text: link.text, line } + }) } /** @@ -111,6 +215,17 @@ async function checkAnchorsOnPage( } try { + // Extract anchor links from markdown first to get accurate line numbers + const mdResult = extractLinksFromMarkdown(page.markdown) + const fmOffset = getFrontmatterLineOffset(page.fullPath) + const anchorLineMap = new Map() + for (const link of mdResult.anchorLinks) { + // Store the first occurrence of each anchor href + if (!anchorLineMap.has(link.href)) { + anchorLineMap.set(link.href, link.line + fmOffset) + } + } + const html = await renderContent(page.markdown, context) const $ = load(html) @@ -126,10 +241,12 @@ async function checkAnchorsOnPage( const targetExists = $(`#${escapedId}`).length > 0 || $(`[name="${targetId}"]`).length > 0 if (!targetExists) { + // Look up the line number from the markdown source + const line = anchorLineMap.get(href) ?? 0 brokenAnchors.push({ href, file: page.relativePath, - lines: [0], // Line number not available from rendered HTML + lines: [line], text: $(el).text(), isAutotitle: false, }) @@ -194,8 +311,8 @@ async function checkVersion( // awaits before the next begins), so there is no concurrent access to baseContext. baseContext.page = page - // Get links from rendered page - const links = await getLinksFromRenderedPage(page, permalink, baseContext) + // Get links from markdown source (preserves accurate line numbers) + const links = await getLinksFromMarkdown(page, baseContext) totalLinksChecked += links.length // Check each link @@ -208,7 +325,7 @@ async function checkVersion( brokenLinks.push({ href: link.href, file: page.relativePath, - lines: [0], + lines: [link.line], text: link.text, }) } @@ -222,14 +339,14 @@ async function checkVersion( brokenLinks.push({ href: link.href, file: page.relativePath, - lines: [0], + lines: [link.line], text: link.text, }) } else if (result.isRedirect) { redirectLinks.push({ href: link.href, file: page.relativePath, - lines: [0], + lines: [link.line], text: link.text, isRedirect: true, redirectTarget: result.redirectTarget, diff --git a/src/links/tests/extract-links.ts b/src/links/tests/extract-links.ts index bdf7b73decf6..d660763f287e 100644 --- a/src/links/tests/extract-links.ts +++ b/src/links/tests/extract-links.ts @@ -219,6 +219,100 @@ See [Using [brackets] in text](/guides/brackets). expect(result.internalLinks).toHaveLength(2) }) + + test('extracts reference-style link definitions', () => { + const content = ` +See [the guide][ssh-agent] for details. +Also [generating keys][gen-keys]. + +[ssh-agent]: /authentication/connecting-to-github-with-ssh/using-ssh-agent-forwarding +[gen-keys]: /authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key +` + const result = extractLinksFromMarkdown(content) + + expect(result.internalLinks).toHaveLength(2) + expect(result.internalLinks[0].href).toBe( + '/authentication/connecting-to-github-with-ssh/using-ssh-agent-forwarding', + ) + // Anchor fragment should be stripped from the href + expect(result.internalLinks[1].href).toBe( + '/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent', + ) + }) + + test('reports correct line numbers for reference-style link definitions', () => { + const content = `Line 1 +Line 2 + +[ref-a]: /path/one +[ref-b]: /path/two +` + const result = extractLinksFromMarkdown(content) + + expect(result.internalLinks).toHaveLength(2) + expect(result.internalLinks[0].line).toBe(4) + expect(result.internalLinks[1].line).toBe(5) + }) + + test('does not extract external reference-style link definitions', () => { + const content = ` +[external]: https://example.com +[internal]: /docs/overview +` + const result = extractLinksFromMarkdown(content) + + expect(result.internalLinks).toHaveLength(1) + expect(result.internalLinks[0].href).toBe('/docs/overview') + }) +}) + +describe('liquidPrefixedLinks', () => { + test('extracts links whose href starts with a Liquid tag', () => { + const content = ` +See [About EMUs]({% ifversion fpt or ghes %}/enterprise-cloud@latest{% endif %}/admin/identity-and-access-management/about-enterprise-managed-users). +` + const result = extractLinksFromMarkdown(content) + + expect(result.liquidPrefixedLinks).toHaveLength(1) + expect(result.liquidPrefixedLinks[0].href).toBe( + '{% ifversion fpt or ghes %}/enterprise-cloud@latest{% endif %}/admin/identity-and-access-management/about-enterprise-managed-users', + ) + }) + + test('does not include Liquid-prefixed links in internalLinks', () => { + const content = ` +See [AUTOTITLE]({% ifversion not ghes %}/enterprise-server@latest{% endif %}/admin/overview). +Also see [normal link](/actions/overview). +` + const result = extractLinksFromMarkdown(content) + + expect(result.internalLinks).toHaveLength(1) + expect(result.internalLinks[0].href).toBe('/actions/overview') + expect(result.liquidPrefixedLinks).toHaveLength(1) + }) + + test('reports correct line numbers for Liquid-prefixed links', () => { + const content = `Line 1 +Line 2 +See [AUTOTITLE]({% ifversion not ghes %}/enterprise-server@latest{% endif %}/admin/overview). +Line 4 +See [AUTOTITLE]({% ifversion fpt %}/enterprise-cloud@latest{% endif %}/billing/overview). +` + const result = extractLinksFromMarkdown(content) + + expect(result.liquidPrefixedLinks).toHaveLength(2) + expect(result.liquidPrefixedLinks[0].line).toBe(3) + expect(result.liquidPrefixedLinks[1].line).toBe(5) + }) + + test('returns empty liquidPrefixedLinks when none present', () => { + const content = ` +See [normal link](/actions/overview) for details. +` + const result = extractLinksFromMarkdown(content) + + expect(result.liquidPrefixedLinks).toHaveLength(0) + }) }) describe('normalizeLinkPath', () => { diff --git a/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml b/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml index d10a6b7ae455..6b3dfa0a0af9 100644 --- a/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml +++ b/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml @@ -1487,7 +1487,7 @@ secretType: ccdb_api_key isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -2137,7 +2137,7 @@ secretType: flutterwave_test_api_secret_key isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -2551,7 +2551,7 @@ secretType: hackclub_ai_api_key isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false @@ -3571,7 +3571,7 @@ secretType: openrouter_api_key isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -3921,7 +3921,7 @@ secretType: posthog_oauth_refresh_token isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false @@ -4681,7 +4681,7 @@ secretType: supabase_personal_access_token isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false diff --git a/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml b/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml index d10a6b7ae455..6b3dfa0a0af9 100644 --- a/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml +++ b/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml @@ -1487,7 +1487,7 @@ secretType: ccdb_api_key isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -2137,7 +2137,7 @@ secretType: flutterwave_test_api_secret_key isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -2551,7 +2551,7 @@ secretType: hackclub_ai_api_key isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false @@ -3571,7 +3571,7 @@ secretType: openrouter_api_key isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: true hasExtendedMetadata: false base64Supported: false @@ -3921,7 +3921,7 @@ secretType: posthog_oauth_refresh_token isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false @@ -4681,7 +4681,7 @@ secretType: supabase_personal_access_token isPublic: true isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false