Skip to content

Commit b7e563b

Browse files
mchammer01Copilotjc-clarksarahs
authored
Overhaul the "Support patterns" article (#60991)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Joe Clark <31087804+jc-clark@users.noreply.github.com> Co-authored-by: Sarah Schneider <sarahs@users.noreply.github.com>
1 parent 716d940 commit b7e563b

16 files changed

Lines changed: 750 additions & 95 deletions

File tree

.github/workflows/headless-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jobs:
3333
node:
3434
- playwright-rendering
3535
- playwright-a11y
36+
- playwright-secret-scanning
3637
fail-fast: false
3738
timeout-minutes: 60
3839
steps:

content/code-security/reference/secret-security/supported-secret-scanning-patterns.md

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ redirect_from:
1010
- /code-security/secret-scanning/secret-scanning-partners
1111
- /code-security/secret-scanning/secret-scanning-patterns
1212
- /code-security/secret-scanning/introduction/supported-secret-scanning-patterns
13-
layout: inline
1413
shortTitle: Supported patterns
1514
autogenerated: secret-scanning
1615
contentType: reference
@@ -24,32 +23,33 @@ category:
2423

2524
For in-depth information about each alert type, see [AUTOTITLE](/code-security/secret-scanning/managing-alerts-from-secret-scanning/about-alerts).
2625

27-
For details about all the supported patterns, see the [Supported secrets](#supported-secrets) section below.
28-
2926
If you use the REST API for {% data variables.product.prodname_secret_scanning %}, you can use the `Secret type` to report on secrets from specific issuers. For more information, see [AUTOTITLE](/enterprise-cloud@latest/rest/secret-scanning).
3027

31-
If you believe that {% data variables.product.prodname_secret_scanning %} should have detected a secret committed to your repository, and it has not, you first need to check that {% data variables.product.prodname_dotcom %} supports your secret. For more information, refer to the following sections. For more advanced troubleshooting information, see [AUTOTITLE](/code-security/secret-scanning/troubleshooting-secret-scanning-and-push-protection/troubleshooting-secret-scanning).
28+
### Pattern categories
29+
30+
| Category | Description | Detection approach | Example |
31+
|----------|-------------|-------------------|---------|
32+
| **Generic** | Secrets not tied to a specific provider, such as private keys and database connection strings | Regex-based | `rsa_private_key` |
33+
| **AI-detected** | Generic passwords detected by {% data variables.secret-scanning.copilot-secret-scanning %} using AI models | AI-based | `password` |
34+
| **Provider** | Secrets tied to a specific service provider (such as AWS, Azure, Stripe) | Regex-based | `aws_access_key_id` |
3235

33-
## Supported secrets
36+
### Capabilities by category
3437

35-
The tables list the secrets supported by {% data variables.product.prodname_secret_scanning %} for each secret type. Information in the tables may include this data:
38+
| Capability | Generic patterns | AI-detected | Provider patterns |
39+
|------------|:-:|:-:|:-:|
40+
| User alerts | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} |
41+
| Partner notifications | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} (if partner) |
42+
| Push protection (default) | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} (most) |
43+
| Push protection (configurable) | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | Some |
44+
| Validity checks | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | Some |
45+
| Extended metadata | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | Some |
46+
| Base64 format support | {% octicon "x" aria-label="Not supported" %} | {% octicon "x" aria-label="Not supported" %} | Some |
3647

37-
* **Provider:** Name of the token provider.{% ifversion fpt or ghec %}
38-
* **Partner:** Token for which leaks are reported to the relevant token partner. Applies to public repositories and all gists, including secret gists. Secret gists are not private and can be accessed by anyone with the URL. See [About gists](/get-started/writing-on-github/editing-and-sharing-content-with-gists/creating-gists#about-gists).
39-
* **User:** Token for which leaks are reported to users on {% data variables.product.prodname_dotcom %}.
40-
* Applies to public repositories, and to private repositories where {% data variables.product.prodname_GH_secret_protection %} and {% data variables.product.prodname_secret_scanning %} are enabled.
41-
* Includes {% ifversion secret-scanning-alert-experimental-list %}default{% else %}high confidence{% endif %} tokens, which relate to supported patterns and specified custom patterns, as well as non-provider tokens such as private keys, which usually have a higher ratio of false positives.
42-
* For {% data variables.product.prodname_secret_scanning %} to scan for non-provider patterns, the detection of non-provider patterns must be enabled for the repository or the organization. For more information, see [AUTOTITLE](/code-security/secret-scanning/enabling-secret-scanning-features/enabling-secret-scanning-for-your-repository).
43-
{% data reusables.secret-scanning.non-provider-patterns-beta %}{% endif %}{% ifversion ghes %}
44-
* **{% data variables.product.prodname_secret_scanning_caps %} alert:** Token for which leaks are reported to users on {% data variables.product.prodname_dotcom %}.
45-
* Applies to private repositories where {% data variables.product.prodname_GH_secret_protection %} and {% data variables.product.prodname_secret_scanning %} are enabled.
46-
* Includes {% ifversion secret-scanning-alert-experimental-list %}default{% else %}high confidence{% endif %} tokens, which relate to supported patterns and specified custom patterns, as well as non-provider tokens such as private keys, which often result in false positives.{% endif %}
47-
* **Push protection:** Token for which leaks are reported to users on {% data variables.product.prodname_dotcom %}. Applies to repositories with {% data variables.product.prodname_secret_scanning %} and push protection enabled.
48-
* **Validity check:** Token for which a validity check is implemented. {% ifversion secret-scanning-validity-check-partner-patterns %}For partner tokens, {% data variables.product.prodname_dotcom %} sends the token to the relevant partner. Note that not all partners are based in the United States. For more information, see [{% data variables.product.prodname_AS %}](/free-pro-team@latest/site-policy/github-terms/github-terms-for-additional-products-and-features#advanced-security) in the Site Policy documentation.{% else %} Currently only applies to {% data variables.product.prodname_dotcom %} tokens.{% endif %}
49-
* **Metadata check:** Token for which extended metadata is available, providing additional context about the detected secret.
50-
* **Base64:** Token for which Base64-encoded versions are supported.
48+
>[! NOTE] Validity and extended metadata checks are only available to users with {% data variables.product.prodname_team %} or {% data variables.product.prodname_enterprise %} who enable the feature as part of {% data variables.product.prodname_GH_secret_protection %}.
5149
52-
### Non-provider patterns
50+
## Supported generic patterns
51+
52+
<!-- Generic is what we know internally as non-provider -->
5353

5454
{% data reusables.secret-scanning.non-provider-patterns-beta %}
5555

@@ -96,11 +96,11 @@ Precision levels are estimated based on the pattern type's typical false positiv
9696
{% endif %}
9797

9898
>[!NOTE]
99-
> Validity checks are **not supported** for non-provider patterns.
99+
> Validity checks are **not supported** for generic/ non-provider patterns.
100100
101101
{% ifversion secret-scanning-ai-generic-secret-detection %}
102102

103-
### {% data variables.secret-scanning.copilot-secret-scanning %}
103+
## Supported AI-detected patterns
104104

105105
{% data variables.product.prodname_secret_scanning_caps %} uses {% data variables.product.prodname_copilot_short %} to detect generic passwords. See [AUTOTITLE](/code-security/secret-scanning/copilot-secret-scanning/responsible-ai-generic-secrets).
106106

@@ -111,44 +111,14 @@ Precision levels are estimated based on the pattern type's typical false positiv
111111
>[!NOTE] Push protection and validity checks are not supported for passwords.
112112
{% endif %}
113113

114-
### {% ifversion secret-scanning-alert-experimental-list %}Default{% else %}High confidence{% endif %} patterns
115-
116-
<!-- Team plan and GHEC version of table -->
117-
{% ifversion fpt or ghec %}
118-
119-
> [!NOTE]
120-
> Validity and extended metadata checks are only available to users with {% data variables.product.prodname_team %} or {% data variables.product.prodname_enterprise %} who enable the feature as part of {% data variables.product.prodname_GH_secret_protection %}.
121-
122-
| Provider | Token | Partner | User | Push protection | Validity check | Metadata check | Base64 |
123-
|----|:----|:----:|:----:|:----:|:----:|:----:|:----:|
124-
{%- for entry in secretScanningData %}
125-
| {{ entry.provider }} | {{ entry.secretType }} | {% if entry.isPublic %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.isPrivateWithGhas %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.hasPushProtection %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.hasValidityCheck %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.hasExtendedMetadata %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.base64Supported %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} |
126-
{%- endfor %}
127-
128-
{% endif %}
129-
130-
<!-- GHES 3.9+ table -->
131-
{% ifversion ghes %}
132-
133-
| Provider | Token | {% data variables.product.prodname_secret_scanning_caps %} alert | Push protection | Validity check | Base64 |
134-
|----|:----|:----:|:----:|:----:|:----:|
135-
{%- for entry in secretScanningData %}
136-
| {{ entry.provider }} | {{ entry.secretType }} | {% if entry.isPrivateWithGhas %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.hasPushProtection %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.hasValidityCheck %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} | {% if entry.base64Supported %}<span role="img" class="octicon-bg-check" aria-label="Supported">✓</span>{% else %}<span role="img" class="octicon-bg-x" aria-label="Unsupported">✗</span>{% endif %} |
137-
{%- endfor %}
138-
139-
{% endif %}
114+
## Supported provider patterns
140115

141-
#### Token versions
116+
Use the table below to search, filter, and browse all supported patterns. You can filter by provider name, push protection support, validity checks, and more.
142117

143118
<a name="token-versions"></a>
144119

145-
Service providers update the patterns used to generate tokens periodically and may support more than one version of a token. Push protection only supports the most recent token versions that {% data variables.product.prodname_secret_scanning %} can identify with confidence. This avoids push protection blocking commits unnecessarily when a result may be a false positive, which is more likely to happen with legacy tokens.<!-- markdownlint-disable-line MD053 -->
146-
147-
## Further reading
120+
> [!NOTE] Service providers update the patterns used to generate tokens periodically and may support more than one version of a token. Push protection only supports the most recent token versions that {% data variables.product.prodname_secret_scanning %} can identify with confidence. This avoids push protection blocking commits unnecessarily when a result may be a false positive, which is more likely to happen with legacy tokens.<!-- markdownlint-disable-line MD053 -->
148121
149-
* [AUTOTITLE](/code-security/secret-scanning/managing-alerts-from-secret-scanning/about-alerts)
150-
{%- ifversion fpt or ghec %}
151-
* [AUTOTITLE](/code-security/secret-scanning/secret-scanning-partnership-program/secret-scanning-partner-program)
152-
{%- endif %}
153-
* [AUTOTITLE](/code-security/getting-started/securing-your-repository)
154-
* [AUTOTITLE](/authentication/keeping-your-account-and-data-secure)
122+
<!-- The interactive "Supported patterns" table is autogenerated from YAML
123+
data files in src/secret-scanning/data/pattern-docs/. The dropdown
124+
and column names live in data/ui.yml under secret_scanning. -->

data/ui.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,32 @@ rest_reference:
198198
notes: Notes
199199
parameters: Parameters for "{{ RESTOperationTitle }}"
200200
response: Response
201+
secret_scanning:
202+
search_placeholder: Search by provider or secret name...
203+
search_aria_label: Search patterns
204+
filter_aria_label: Filter secret scanning patterns
205+
filter_push_protection: 'Push protection'
206+
filter_validity_check: 'Validity check'
207+
filter_partner_alert: 'Partner alert'
208+
filter_metadata: Metadata check
209+
filter_base64: Base64
210+
filter_all: All
211+
filter_yes: 'Yes'
212+
filter_no: 'No'
213+
showing_patterns: 'Showing {filtered} of {total} patterns'
214+
column_provider: Provider
215+
column_secret: Secret
216+
column_partner: Partner
217+
column_user_alert: User alert
218+
column_push_protection: Push protection
219+
column_validity_check: Validity check
220+
column_metadata: Metadata check
221+
column_base64: Base64
222+
bool_yes: 'Yes'
223+
bool_no: 'No'
224+
token_versions: Token versions
225+
table_title: Supported patterns
226+
pagination_label: Secret scanning patterns pagination
201227
request_example: Request example
202228
request_examples: Request examples
203229
example_response: Example response

src/article-api/transformers/secret-scanning-transformer.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,34 @@ export class SecretScanningTransformer implements PageTransformer {
6666
context.markdownRequested = true
6767
let content = await page.render(context)
6868

69+
// Inject the full patterns table for agent/crawler access
70+
// (The React DataTable is not rendered in markdown mode)
71+
if (context.secretScanningData && context.secretScanningData.length > 0) {
72+
const bool = (v: unknown) => (v ? '✓' : '✗')
73+
const escape = (s: string) => s.replace(/\\/g, '\\\\').replace(/\|/g, '\\|')
74+
// Strip HTML from secretType before inserting into markdown table rows.
75+
// The isduplicate logic above appends <br/><a> HTML which would break
76+
// single-line markdown table rows once <br/> is later converted to \n.
77+
const cleanSecretType = (s: string) =>
78+
s
79+
.replace(
80+
/ <br\/><a href="#token-versions">Token versions<\/a>/,
81+
', [Token versions](#token-versions)',
82+
)
83+
.replace(/<br\s*\/?>/gi, ', ')
84+
.replace(/<a\s+href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, '[$2]($1)')
85+
.replace(/<[^>]+>/g, '')
86+
const header =
87+
'| Provider | Secret | Secret type | Partner | User alert | Push protection | Validity check | Metadata | Base64 |'
88+
const separator = '| --- | --- | --- | :---: | :---: | :---: | :---: | :---: | :---: |'
89+
const rows = context.secretScanningData.map(
90+
(entry: Record<string, unknown>) =>
91+
`| ${escape(String(entry.provider))} | ${escape(String(entry.supportedSecret))} | ${escape(cleanSecretType(String(entry.secretType)))} | ${bool(entry.isPublic)} | ${bool(entry.isPrivateWithGhas)} | ${bool(entry.hasPushProtection)} | ${bool(entry.hasValidityCheck)} | ${bool(entry.hasExtendedMetadata)} | ${bool(entry.base64Supported)} |`,
92+
)
93+
const table = ['\n\n## Supported patterns\n', header, separator, ...rows].join('\n')
94+
content += table
95+
}
96+
6997
// Strip HTML comments from the rendered content
7098
content = content.replace(/<!--.*?-->/gs, '')
7199

@@ -75,11 +103,16 @@ export class SecretScanningTransformer implements PageTransformer {
75103
// Convert <br/> tags to newlines and <a href="...">text</a> to markdown links
76104
content = content.replace(/<br\s*\/?>/gi, '\n')
77105
content = content.replace(/<a\s+href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, '[$2]($1)')
78-
// Strip any remaining HTML tags (loop to handle nested/malformed tags)
106+
// Strip any remaining HTML tags. Loop until stable to handle nested or
107+
// malformed tags (e.g. "<scr<script>ipt>"). Limit iterations to prevent
108+
// infinite loops on pathological input.
79109
let previous = ''
80-
while (content !== previous) {
110+
let iterations = 0
111+
const MAX_STRIP_ITERATIONS = 10
112+
while (content !== previous && iterations < MAX_STRIP_ITERATIONS) {
81113
previous = content
82114
content = content.replace(/<[^>]+>/g, '')
115+
iterations++
83116
}
84117

85118
// Normalize whitespace after stripping comments

0 commit comments

Comments
 (0)