redact-secret · Report
Integration token
ntn_ prefixed integration token from Notion's 2024-09 rollout.
Research record
What blocks the research
- Issuance-gatedLeading digit run (11 per gitleaks and secretlint, 9 per CredSweeper) and body alphabet rest on peer rules only (one class); needs one integration token and one PAT measured (structure only).
3 events in the review history: 2 observed, 1 reviewed. Latest: observed on 2026-09-29 by automation, project maintainer. Project-maintained review is not independent validation. The family record at this release.
Format
What it looks like
- Descriptive pattern
^ntn_[0-9]{11}[A-Za-z0-9]{35}$
Parts are shown as recorded. Evidence classes belong to the facts below; no class is assigned to a part.
Format facts
Unresolved ·
candidate-source· current · observed 2026-09-24Candidate provider source, not accepted as the provider source by the legacy contract (2024-09 Public API token prefix migration): the ntn_ prefix for newly generated tokens and the secret_ legacy relationship; no body grammar
- developers.notion.com/page/changelogprovider-documentation · last read 2026-09-29 · latest outcome read · supports the ntn_ prefix for newly generated tokens and the secret_ legacy relationship; no body grammar
Tool corroborated ·
tool-corroboration· current · observed 2026-09-24Pinned scanner rules are consistent with the contract grammar (2 artifacts: gitleaks 8.30.1; secretlint).
- gitleaks/gitleaks @ v8.30.1: config/gitleaks.tomlscanner-rule-source · last read 2026-10-04 · latest outcome read · supports gitleaks 8.30.1: notion-api-token
- secretlint/secretlint @ master: packages/%40secretlint/secretlint-rule-notionscanner-rule-source · last read 2026-09-24 · latest outcome read · supports secretlint: secretlint-rule-notion
Provider documented ·
field-prefix· current · observed 2026-09-24prefix: Newly generated Public API tokens begin with ntn_ from 2024-09-25; existing secret_ tokens keep working. (secret_ is the separate legacy family notion:legacy-integration-token (registry notion-token); it is never a control or twin here.)
- developers.notion.com/page/changelogprovider-documentation · last read 2026-09-29 · latest outcome read · supports Changelog 2024-09-11. Also: Notion "strongly advise[s] against" regex identification; the format "may change over time"; treat tokens as opaque.
Tool corroborated ·
field-body· current · observed 2026-09-24body: After ntn_: 11 digits then 35 alphanumerics (50 characters total). (Provider warns against exactly this kind of grammar. Positives use 11+35 so they satisfy gitleaks, secretlint, flare-redact (46 in 40–50), makenotion/lore's ntn_[A-Za-z0-9_-]{20,} redaction and the product; no twin mutates the digit run or the length.)
- flare-collection/flare-redact @ c652ea7946028b70527069d7c282752b8a0ccee3: spec/detectors.jsonscanner-rule-source · last read 2026-09-24 · latest outcome read · supports Disagrees: ntn_[A-Za-z0-9]{40,50} with no digit run. · #L1472
- github.com/gitleaks/gitleaks/pull/1890scanner-rule-source · last read 2026-09-24 · latest outcome read · supports Single contributor's samples; Betterleaks/Kingfisher/TruffleHog PR #4318 share the lineage (not independent).
- gitleaks/gitleaks @ 83d9cd684c87d95d656c1458ef04895a7f1cbd8e: config/gitleaks.tomlscanner-rule-source · last read 2026-09-27 · latest outcome read · supports gitleaks 8.30.1 notion-api-token: \b(ntn_[0-9]{11}[A-Za-z0-9]{32}[A-Za-z0-9]{3})(?:[\x60'"\s;]|\\[nr]|$), entropy 4. · #L2652
- secretlint/secretlint @ master: packages/%40secretlint/secretlint-rule-notionscanner-rule-source · last read 2026-09-24 · latest outcome read · supports (?<!\p{L})ntn_[0-9]{11}[A-Za-z0-9]{35}(?![A-Za-z0-9]).
Unresolved ·
field-digit-run-semantics· current · observed 2026-09-24digit-run-semantics: What the 11-digit run is (timestamp, per-workspace/bot id, random).
- github.com/gitleaks/gitleaks/pull/1890scanner-rule-source · last read 2026-09-24 · latest outcome read · supports "11-digit timestamp" claim; 11 digits fits neither epoch seconds nor ms; the three samples share one lead.
Unresolved ·
field-role· current · observed 2026-09-24role: Whether internal-integration, PAT, ntn-CLI and OAuth access tokens share one ntn_ grammar. (Roles are not merged: every positive is an internal-integration context (NOTION_TOKEN / NOTION_API_KEY / installation access token). PAT, OAuth and org-bot tokens are secrets of undetermined grammar, so they are neither positives nor controls; development_ntn_ is recorded, never asserted either way.)
- developers.notion.com/guides/get-started/personal-access-tokens.mdprovider-sdk-source · last read 2026-09-24 · latest outcome read · supports PATs exist (2026); their prefix appears only in placeholders (ntn_***).
- makenotion/lore @ main: src/auth/token-prefix.tsprovider-sdk-source · last read 2026-09-24 · latest outcome read · supports ntn_ PATs and CLI tokens are "indistinguishable by prefix"; development_ntn_ for dev-environment tokens.
- makenotion/notion-mcp-server @ main: src/openapi-mcp-server/mcp/token.tsprovider-sdk-source · last read 2026-09-24 · latest outcome read · supports Comment: ntn_ for "current internal & OAuth integration tokens".
Unresolved ·
listed-references· current · observed 2026-09-24The legacy contract lists 3 references without stating which property each supports.
- developers.notion.com/guides/get-started/internal-integrations.mdother · last read 2026-09-24 · latest outcome read · supports Listed as a reference by the legacy contract
- makenotion/lore @ main: src/auth/token-prefix.tsprovider-sdk-source · last read 2026-09-24 · latest outcome read · supports Listed as a reference by the legacy contract
- github.com/redact-secret/redact-secret-benchmarks/issues/225issue-or-discussion · last read 2026-09-24 · latest outcome read · supports Listed as a reference by the legacy contract
Provider documented ·
dossier-research· current · observed 2026-09-29Legacy dossier research (verdict issuance-gated, tier T1) cited 8 sources; the dossier does not attribute sources to individual properties.
- developers.notion.com/page/changelogprovider-documentation · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family
- gitleaks/gitleaks @ b58d3f102cf3a2c84cb7f923d05c25c9b1aed84b: config/gitleaks.tomlother · last read 2026-10-05 · latest outcome read · supports Cited by the legacy dossier research for this family · #L2652-L2656
- makenotion/lore @ 6e741b1bb91a36b47213f4d3af5bbdfaa2f2081d: src/auth/token-prefix.tsother · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family · #L6-L44
- makenotion/notion-mcp-server @ 730ae781ba28beeaf0865025a3f2ed4c25ea2387: src/openapi-mcp-server/mcp/token.tsother · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family · #L21-L32
- redact-secret/redact-secret @ 378581770a87751d72e27529796c4f790649fd00: docs/audits/evidence/1012/notion-integration-token.mdproject-research-note · last read 2026-09-29 · latest outcome read · supports Final research evidence recorded by the legacy dossier
- Samsung/CredSweeper @ f21ab2f2553eea288a72273b9658cd297ab1d11f: credsweeper/rules/config.yamlscanner-rule-source · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family · #L1630-L1644
- secretlint/secretlint @ 0001184f56165e7db7ab1b3adc1f957911c78f46: packages/%40secretlint/secretlint-rule-notion/src/index.tsother · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family · #L38-L50
- x.com/NotionHQ/status/1914437336789553311other · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family
Provider documented ·
taxonomy-sources· current · observed 2026-09-29The legacy taxonomy lists 1 source for this family. The taxonomy records no date; the dossier researchedAt is used as the observed-at date.
- developers.notion.com/page/changelogprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy
Open questions
No open question is recorded for this revision.
Benchmark dossier notes
- Shape
- prefix
ntn_, 11 digits, then 35 letters and digits (50 in total). The prefix is provider-documented. The body comes from one contributor's samples in gitleaks issue 1890, carried into betterleaks, Kingfisher and TruffleHog; secretlint agrees on lengths; flare-redact disagrees (no digit run). Notion's docs show a placeholder with 33 lowercase letters afterntn_, which does not fit. - Basis
- - provider changelog (T1, prefix): 2024-09-11 entry, "newly generated Public API tokens will automatically use the ntn_ prefix", plus the warning against regex validation. - provider statement off the docs domain (R3, prefix): @NotionHQ on X, 2025-04-21, "The ntn_ format is our current standard for integration tokens"; no length or alphabet. - provider code (R6, prefix and role only): notion-mcp-server accepts
ntn_andsecret_with a length of 8 to 300 and says it avoids coupling to an exact server-side length; notion-skills-github-sync also acceptsdevelopment_ntn_and redacts at a floor of 20; lore classesntn_as production personal access or bot token,development_ntn_as development andsecret_as integration. - peer scanner rules (T2 input, one lineage): gitleaksntn_+ 11 digits + 35 alphanumerics (betterleaks and Kingfisher carry the same rule); secretlint agrees. - contradicting peer rule: CredSweeperntn_+ 9 digits + 36 to 255 of[0-9A-Za-z_-]; its 50-character test samples have a 9-digit lead followed by a letter. - Searched with nothing further: the docsllms-full.txt(placeholders), the Notion SDKs (no validation), trufflehog (secret_only), noseyparker and osv-scalibr (no Notion rule). GitHub's list names the type without a regex. - Issuance
- not attempted. Internal connection tokens come from the developer portal Configuration tab; PATs from Settings; checklist in benchmarks#225. The #1012 check: issue one internal-integration token and one personal access token, and for each record the total length (50?), the count of leading digits after
ntn_(11 or 9), whether the rest is only[A-Za-z0-9], and whether the two tokens share the digit run (is it an ID?). Then revoke. - Contract in core
- detector-families.md (frozen in the #726 record; already implemented before #729, which left it unchanged):
ntn_+ exactly 11 digits + exactly 35[A-Za-z0-9]. A token with a 9-digit lead, if CredSweeper's samples reflect real issuance, is a false negative;development_ntn_stays out through the leading boundary.
In this benchmark
- Fixtures
- 24
- Left readable
- 0
- Redacted too much
- 0
- False alarms
- 0
24 fixtures: 10 expect a redaction, 14 must stay quiet. See every row
| Evidence level | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| T2Tool-corroborated | 19 | 0 | 0 | 0 |
| T3Project policy | 5 | 0 | 0 | 0 |
Every scanner on the same fixtures
In run order. Counts are what each scanner recorded on this family's fixtures, whichever rules it has; a scanner with no rule for the family has nothing to report on it.
| Scanner | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| flare-redactRuntime library · 1.6.1 · Published npm package · secrets-only (pii, generic_assignment disabled) · JavaScript engine1 rule targets it | 24 | 0 | 2 | 0 |
| gitleaksRepository scanner · 8.30.1 · Directory scan · default rules1 rule targets it | 24 | 1 | 0 | 0 |
| redact-secretProduct measured here · 0.1.0-beta.14 · Published npm package · default detectorsNo detector mapped | 24 | 0 | 0 | 0 |
| trufflehogRepository scanner · 3.97.4 · Filesystem scan · verification disabledNo rule maps to it | 24 | 10 | 0 | 0 |
Benchmark dossier questions
- Blocked by
- Leading digit run (11 per gitleaks and secretlint, 9 per CredSweeper) and body alphabet rest on peer rules only (one class); needs one integration token and one PAT measured (structure only).
- Open caveat
- The prefix is provider-documented but the 11 digit plus 35 alphanumeric body is tool-only, one class, and contradicted by a new peer rule (9 digits); Notion advises against regexes for its tokens (checklist in benchmarks#225).
Looks like it, but isn't
- Collisions
- the same
ntn_prefix is documented for PATs,ntnCLI tokens and connection tokens, and possibly OAuth access tokens (Notion's MCP server comment); a shared body grammar is unknown.nrt_(OAuth refresh, one docs sample of 13 digits plus 32 alphanumerics) anddevelopment_ntn_are siblings. Ids (bot_id,workspace_id, PAT record id) are UUIDs and public.
Scanner rules for this family
| Scanner | Rule | What the rule matches |
|---|---|---|
| flare-redact · rules 1.6.1 | notion_token | ntn_ + 40-50 or secret_ + 43 characters |
| gitleaks · rules 8.30.1 | notion-api-token | ntn_ + 11 digits + 35 characters |
No rule maps to this family in openredaction, trufflehog.
Fixtures in this family
| Fixture | Kind and evidence | redact-secret |
|---|---|---|
notion-integration-token-actions-envnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-agent-session-jsonlnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-bearer-headernotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-compose-mcpnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-curl-users-menotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-dotenv-notion-tokennotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-escaped-openapi-headersnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-export-api-keynotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-js-clientnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-mcp-server-envnotion · documented-format-literal | Must redactT2 · Tool-corroborated | Redacted |
notion-integration-token-bearer-header-separator-twinnotion · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
notion-integration-token-database-id-public-idnotion · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
notion-integration-token-docker-env-passthrough-referencenotion · templated-reference | Must not flagT3 · Project policy | Quiet |
notion-integration-token-docs-sentence-prosenotion · prose-mention | Must not flagT3 · Project policy | Quiet |
notion-integration-token-dotenv-notion-token-prefix-twinnotion · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
notion-integration-token-export-api-key-case-twinnotion · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
notion-integration-token-js-client-alphabet-twinnotion · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
notion-integration-token-masked-env-placeholdernotion · documentation-placeholder | Must not flagT3 · Project policy | Quiet |
notion-integration-token-mcp-server-env-boundary-twinnotion · boundary-violation | Must not flagT2 · Tool-corroborated · twin | Quiet |
notion-integration-token-oauth-ids-public-idnotion · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
notion-integration-token-page-url-public-idnotion · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
notion-integration-token-prefix-only-near-missnotion · format-near-miss | Must not flagT2 · Tool-corroborated | Quiet |
notion-integration-token-process-env-referencenotion · templated-reference | Must not flagT3 · Project policy | Quiet |
notion-integration-token-words-placeholder-placeholdernotion · documentation-placeholder | Must not flagT3 · Project policy | Quiet |
Sources
Documentation and code
- developers.notion.com/page/changelog
- x.com/NotionHQ/status/1914437336789553311
- github.com/makenotion/notion-mcp-server/blob/730ae781ba28beeaf0865025a3f2ed4c25ea2387/src/openapi-mcp-server/mcp/token.ts#L21-L32
- github.com/makenotion/lore/blob/6e741b1bb91a36b47213f4d3af5bbdfaa2f2081d/src/auth/token-prefix.ts#L6-L44
- github.com/gitleaks/gitleaks/blob/b58d3f102cf3a2c84cb7f923d05c25c9b1aed84b/config/gitleaks.toml#L2652-L2656
- github.com/secretlint/secretlint/blob/0001184f56165e7db7ab1b3adc1f957911c78f46/packages/%40secretlint/secretlint-rule-notion/src/index.ts#L38-L50
- github.com/Samsung/CredSweeper/blob/f21ab2f2553eea288a72273b9658cd297ab1d11f/credsweeper/rules/config.yaml#L1630-L1644
Research log
- redact-secret/redact-secret-benchmarks#225Research issue
- redact-secret/redact-secret#514Research issue
- redact-secret/redact-secret#726Research issue
- redact-secret/redact-secret#729Research issue
- redact-secret/redact-secret#1012Research issue
- Final evidence, pinned to a commit/redact-secret/redact-secret/blob/378581770a87751d72e27529796c4f790649fd00/docs/audits/evidence/1012/notion-integration-token.md