A token acts as the member who created it. It carries no permissions of its
own, which means nobody can mint a token more powerful than themselves — and it
inherits their role, so a token made by a non-admin cannot reach an
admin-only endpoint.
A token can only read. Every request that is not a GET is refused, and so
is the one GET that changes state — /api/github/callback, which links a
GitHub App installation. Without that second rule a “read-only” credential
could have attached an installation to its own organisation and granted itself
repository access.
It also cannot outlive its creator’s membership. Removing a member revokes
their tokens, and every request independently re-checks that the creator is
still a member — so a token that somehow escaped revocation still stops
working.
Only a SHA-256 of the token is stored. It is displayed at creation and never
again, by the page or by anyone else, because there is nothing left to display
it from. If you lose it, revoke it and create another.The listing shows a hint (pf_625d53d4…) instead — the public half, which
identifies the row and cannot be used to reconstruct the token.
30 days, 90 days, a year, or never. “Never” is offered and labelled rather than
being a silent default: a credential with no end date is a decision, and the
page says what it means — the token stays valid until someone revokes it or its
creator leaves.
The column that makes the page worth opening. Never used and last used in
March are different words, not a shared blank cell, because only one of them
means “safe to revoke without asking anyone”.Use is recorded to the minute. A busy caller does not turn every read into a
write, and no finer resolution helps answer the only question the column
exists for.
Immediate and permanent. A revoked token stays listed, struck through, with its
own history — so “this existed, it was used until the 12th, and it is now dead”
remains readable rather than vanishing.Creating and revoking a token are both recorded in the
audit log.
An unknown token, a wrong one, a revoked one and an expired one all return the
same 401 with the same body. A client that could tell them apart could use
the difference to work out which tokens exist.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Pipefort","description":"Scan GitHub Actions workflows for the OWASP Top 10 CI/CD risks — via CLI or a multi-tenant web dashboard.","colors":{"primary":"#6366f1","light":"#818cf8","dark":"#7c3aed"},"logo":{"light":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/light.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=0603d0920c0fb24833a95cd83cf82214","dark":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/dark.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=5b20cdc0cf52696bd7860083a3dcc547"},"favicon":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/shield.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=50ddd6ec7558eaa1b12d8b79780d371e","appearance":{"default":"dark","strict":true},"navbar":{"primary":{"type":"button","label":"Get started","href":"/quickstart"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"pipefort","hasAudioNarration":false,"actualSubdomain":"pipefort","customDomains":["docs.pipefort.com"],"gitSource":{"type":"github","owner":"raphabot","repo":"pipefort-cloud","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6a9f73638d98389808c4e557","clientVersion":"0.0.4087","searchFilterCounts":[{"language":"default","tag":"Documentation","count":121},{"language":"default","tag":"Rules reference","count":83},{"language":"default","tag":"Web app","count":23},{"language":"default","tag":"CLI","count":9},{"language":"default","tag":"Get started","count":4},{"language":"default","tag":"Concepts","count":1},{"language":"default","tag":"Editor","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"webapp/api-tokens","slug":"/webapp/api-tokens","pageMetadata":{"title":"API tokens","description":"Read Pipefort from CI or a script, with a credential that can only read.","href":"/webapp/api-tokens"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Read Pipefort from CI or a script, with a credential that can only read.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Settings → API tokens`}),` issues credentials for reading Pipefort from\nsomewhere that is not a browser. Admins only.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer pf_...\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://your-pipefort/api/attack-paths?org=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`org-i`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`d`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`what-a-token-can-do`,children:`What a token can do`}),`\n`,_jsxs(_components.p,{children:[`A token `,_jsx(_components.strong,{children:`acts as the member who created it`}),`. It carries no permissions of its\nown, which means nobody can mint a token more powerful than themselves — and it\ninherits their role, so a token made by a non-admin cannot reach an\nadmin-only endpoint.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`A token can only read.`}),` Every request that is not a `,_jsx(_components.code,{children:`GET`}),` is refused, and so\nis the one `,_jsx(_components.code,{children:`GET`}),` that changes state — `,_jsx(_components.code,{children:`/api/github/callback`}),`, which links a\nGitHub App installation. Without that second rule a “read-only” credential\ncould have attached an installation to its own organisation and granted itself\nrepository access.`]})}),`\n`,_jsxs(_components.p,{children:[`It also `,_jsx(_components.strong,{children:`cannot outlive its creator’s membership`}),`. Removing a member revokes\ntheir tokens, and every request independently re-checks that the creator is\nstill a member — so a token that somehow escaped revocation still stops\nworking.`]}),`\n`,_jsx(Heading,{level:`2`,id:`the-value-is-shown-once`,children:`The value is shown once`}),`\n`,_jsx(_components.p,{children:`Only a SHA-256 of the token is stored. It is displayed at creation and never\nagain, by the page or by anyone else, because there is nothing left to display\nit from. If you lose it, revoke it and create another.`}),`\n`,_jsxs(_components.p,{children:[`The listing shows a `,_jsx(_components.strong,{children:`hint`}),` (`,_jsx(_components.code,{children:`pf_625d53d4…`}),`) instead — the public half, which\nidentifies the row and cannot be used to reconstruct the token.`]}),`\n`,_jsx(Heading,{level:`2`,id:`choosing-an-expiry`,children:`Choosing an expiry`}),`\n`,_jsx(_components.p,{children:`30 days, 90 days, a year, or never. “Never” is offered and labelled rather than\nbeing a silent default: a credential with no end date is a decision, and the\npage says what it means — the token stays valid until someone revokes it or its\ncreator leaves.`}),`\n`,_jsx(Heading,{level:`2`,id:`last-used`,children:`Last used`}),`\n`,_jsxs(_components.p,{children:[`The column that makes the page worth opening. `,_jsx(_components.strong,{children:`Never used`}),` and `,_jsx(_components.strong,{children:`last used in\nMarch`}),` are different words, not a shared blank cell, because only one of them\nmeans “safe to revoke without asking anyone”.`]}),`\n`,_jsx(_components.p,{children:`Use is recorded to the minute. A busy caller does not turn every read into a\nwrite, and no finer resolution helps answer the only question the column\nexists for.`}),`\n`,_jsx(Heading,{level:`2`,id:`revoking`,children:`Revoking`}),`\n`,_jsx(_components.p,{children:`Immediate and permanent. A revoked token stays listed, struck through, with its\nown history — so “this existed, it was used until the 12th, and it is now dead”\nremains readable rather than vanishing.`}),`\n`,_jsxs(_components.p,{children:[`Creating and revoking a token are both recorded in the\n`,_jsx(_components.a,{href:`/webapp/audit-log`,children:`audit log`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`every-rejection-looks-the-same`,children:`Every rejection looks the same`}),`\n`,_jsxs(_components.p,{children:[`An unknown token, a wrong one, a revoked one and an expired one all return the\nsame `,_jsx(_components.code,{children:`401`}),` with the same body. A client that could tell them apart could use\nthe difference to work out which tokens exist.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"API tokens","description":"Read Pipefort from CI or a script, with a credential that can only read.","href":"/webapp/api-tokens"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What a token can do","slug":"what-a-token-can-do","depth":2,"children":[]},{"title":"The value is shown once","slug":"the-value-is-shown-once","depth":2,"children":[]},{"title":"Choosing an expiry","slug":"choosing-an-expiry","depth":2,"children":[]},{"title":"Last used","slug":"last-used","depth":2,"children":[]},{"title":"Revoking","slug":"revoking","depth":2,"children":[]},{"title":"Every rejection looks the same","slug":"every-rejection-looks-the-same","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"pipefort","siteName":"Pipefort","title":"API tokens - Pipefort","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-16T04:33:46.265Z","originalFileLocation":"webapp/api-tokens.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=\"dark\";if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Read Pipefort from CI or a script, with a credential that can only read.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Pipefort\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"API tokens - Pipefort\">\u003cmeta data-mint-head property=\"og:description\" content=\"Read Pipefort from CI or a script, with a credential that can only read.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Pipefort\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.pipefort.com/webapp/api-tokens\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://pipefort.mintlify.site/_mintlify/api/og/v2?division=Web+app\u0026amp;title=API+tokens\u0026amp;description=Read+Pipefort+from+CI+or+a+script%2C+with+a+credential+that+can+only+read.\u0026amp;theme=0e4b43e2e988d8c2899aac73\u0026amp;signature=7617dc8734089f876f4f26b2315aa9cd1a5770e5cd460a6c63158d93f404d449\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"API tokens - Pipefort\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Read Pipefort from CI or a script, with a credential that can only read.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://pipefort.mintlify.site/_mintlify/api/og/v2?division=Web+app\u0026amp;title=API+tokens\u0026amp;description=Read+Pipefort+from+CI+or+a+script%2C+with+a+credential+that+can+only+read.\u0026amp;theme=0e4b43e2e988d8c2899aac73\u0026amp;signature=7617dc8734089f876f4f26b2315aa9cd1a5770e5cd460a6c63158d93f404d449\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Pipefort\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#6366f1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.pipefort.com/webapp/api-tokens\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/webapp/api-tokens.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.pipefort.com/#organization\",\"name\":\"Pipefort\",\"url\":\"https://docs.pipefort.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/light.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=0603d0920c0fb24833a95cd83cf82214\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.pipefort.com#website\",\"name\":\"Pipefort\",\"url\":\"https://docs.pipefort.com\",\"publisher\":{\"@id\":\"https://docs.pipefort.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.pipefort.com/webapp/api-tokens#webpage\",\"url\":\"https://docs.pipefort.com/webapp/api-tokens\",\"name\":\"API tokens\",\"description\":\"Read Pipefort from CI or a script, with a credential that can only read.\",\"dateModified\":\"2026-08-16T04:33:46.265Z\",\"isPartOf\":{\"@id\":\"https://docs.pipefort.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.pipefort.com/webapp/api-tokens#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.pipefort.com/webapp/api-tokens#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Web app\",\"item\":\"https://docs.pipefort.com/webapp/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"API tokens\",\"item\":\"https://docs.pipefort.com/webapp/api-tokens\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.pipefort.com/webapp/api-tokens#article\",\"headline\":\"API tokens\",\"name\":\"API tokens\",\"description\":\"Read Pipefort from CI or a script, with a credential that can only read.\",\"url\":\"https://docs.pipefort.com/webapp/api-tokens\",\"mainEntityOfPage\":{\"@id\":\"https://docs.pipefort.com/webapp/api-tokens#webpage\"},\"dateModified\":\"2026-08-16T04:33:46.265Z\",\"publisher\":{\"@id\":\"https://docs.pipefort.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.pipefort.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Pipefort\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Pipefort","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get started","pages":[{"title":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"How it works","href":"/architecture"},{"title":"How Pipefort compares","href":"/comparison"}]},{"group":"CLI","pages":[{"title":"Overview","href":"/cli/overview"},{"title":"Installation","href":"/cli/installation"},{"title":"Usage","href":"/cli/usage"},{"title":"Flags","href":"/cli/flags"},{"title":"Auto-fix","href":"/cli/auto-fix"},{"title":"Configuration file","href":"/cli/configuration"},{"title":"MCP server","href":"/cli/mcp"},{"title":"GitLab CLI usage","href":"/cli/gitlab"},{"title":"CI integration","href":"/cli/ci-integration"}]},{"group":"Editor","pages":[{"title":"VS Code extension","href":"/editor/vscode"}]},{"group":"Web app","pages":[{"title":"Overview","href":"/webapp/overview"},{"title":"Public repo scanner","href":"/webapp/public-scan"},{"title":"Status badge","href":"/webapp/badge"},{"title":"Organizations","href":"/webapp/organizations"},{"title":"GitHub setup","href":"/webapp/github-setup"},{"title":"Monitored repos","href":"/webapp/monitored-repos"},{"title":"Pull request checks","href":"/webapp/pr-checks"},{"title":"Finding triage \u0026 new findings","href":"/webapp/finding-triage"},{"title":"Action risk scores","href":"/webapp/action-risk-scores"},{"title":"Secure Workflow Hardener","href":"/webapp/workflow-hardener"},{"title":"Actions inventory","href":"/webapp/actions-inventory"},{"title":"Secrets hygiene","href":"/webapp/secrets-hygiene"},{"title":"Bulk remediation campaigns","href":"/webapp/bulk-remediation"},{"title":"Notifications","href":"/webapp/notifications"},{"title":"SLSA dashboard","href":"/webapp/slsa"},{"title":"Attacker Mind dashboard","href":"/webapp/attacker-mind"},{"title":"Insights","href":"/webapp/insights"},{"title":"Rule policy","href":"/webapp/rule-settings"},{"title":"Alert rules","description":"Choose which alerts reach your Slack, and at what severity.","href":"/webapp/alert-rules"},{"title":"API tokens","href":"/webapp/api-tokens"},{"title":"Audit log","description":"An append-only record of who changed this organisation's configuration.","href":"/webapp/audit-log"},{"title":"API reference","href":"/webapp/api-reference"},{"title":"Agent discovery","href":"/webapp/agent-discovery"}]},{"group":"Concepts","pages":[{"title":"Github app permissions","href":"/concepts/github-app-permissions"},{"title":"Attacker Mind \u0026 toxic combinations","href":"/concepts/attacker-mind"}]},{"group":"Rules reference","pages":[{"title":"Rules overview","href":"/rules/overview"},{"title":"SLSA framework overview","href":"/rules/slsa-overview"},{"title":"CICD-SEC-1 — Dangerous pull_request_target checkout","href":"/rules/cicd-sec-1"},{"title":"CICD-SEC-1 — workflow_run downloads artifacts from the triggering run","href":"/rules/cicd-sec-1-workflow-run-artifact-poisoning"},{"title":"CICD-SEC-1 — Checkout persists credentials under a privileged trigger","href":"/rules/cicd-sec-1-checkout-persist-credentials"},{"title":"CICD-SEC-1 — Security decision based on a spoofable actor check","href":"/rules/cicd-sec-1-spoofable-actor-condition"},{"title":"CICD-SEC-1 — Job/step condition is always true","href":"/rules/cicd-sec-1-unsound-condition"},{"title":"CICD-SEC-1 — Spoofable contains() membership check","href":"/rules/cicd-sec-1-unsound-contains"},{"title":"CICD-SEC-1 — pull_request_target trigger boundary confusion","href":"/rules/cicd-sec-1-pr-target-dual-trigger"},{"title":"CICD-SEC-1 — Unsafe YAML tag or multiplying anchor expansion","href":"/rules/cicd-sec-1-yaml-parser-hardening"},{"title":"CICD-SEC-2 — Long-lived personal access token in workflow","href":"/rules/cicd-sec-2"},{"title":"CICD-SEC-2 — Package published with a long-lived token instead of OIDC","href":"/rules/cicd-sec-2-use-trusted-publishing"},{"title":"CICD-SEC-2 — Static cloud credential where OIDC federation is available","href":"/rules/cicd-sec-2-cloud-credentials"},{"title":"CICD-SEC-3 — Unpinned third-party action","href":"/rules/cicd-sec-3"},{"title":"CICD-SEC-3 — Unpinned container image","href":"/rules/cicd-sec-3-unpinned-image"},{"title":"CICD-SEC-3 — Known-vulnerable action version","href":"/rules/cicd-sec-3-known-vulnerable-action"},{"title":"CICD-SEC-3 — Impostor commit pin","href":"/rules/cicd-sec-3-impostor-commit"},{"title":"CICD-SEC-3 — Pinned SHA does not match its version comment","href":"/rules/cicd-sec-3-ref-version-mismatch"},{"title":"CICD-SEC-3 — Possible typosquatted action","href":"/rules/cicd-sec-3-typosquat-action"},{"title":"CICD-SEC-3 — Action's upstream repository is archived","href":"/rules/cicd-sec-3-archived-action"},{"title":"CICD-SEC-3 — Pinned SHA is not any released tag","href":"/rules/cicd-sec-3-stale-action-ref"},{"title":"CICD-SEC-3 — Action ref exists as both a branch and a tag","href":"/rules/cicd-sec-3-ref-confusion"},{"title":"CICD-SEC-4 — Poisoned Pipeline Execution (shell injection)","href":"/rules/cicd-sec-4"},{"title":"CICD-SEC-4 — Untrusted input written to GITHUB_ENV/GITHUB_PATH","href":"/rules/cicd-sec-4-github-env-injection"},{"title":"CICD-SEC-4 — Reusable workflow called with secrets: inherit under a privileged trigger","href":"/rules/cicd-sec-4-secrets-inherit-pr-target"},{"title":"CICD-SEC-4 — Obfuscated expression or run script","href":"/rules/cicd-sec-4-obfuscated-expression"},{"title":"CICD-SEC-4 — Caching enabled in a publishing workflow","href":"/rules/cicd-sec-4-cache-poisoning-release"},{"title":"CICD-SEC-5 — Missing permissions specification","href":"/rules/cicd-sec-5"},{"title":"CICD-SEC-5 — Action not permitted by forbidden-uses policy","href":"/rules/cicd-sec-5-forbidden-uses"},{"title":"CICD-SEC-6 — Hardcoded credentials","href":"/rules/cicd-sec-6"},{"title":"CICD-SEC-6 — Secret printed to logs or written to step output","href":"/rules/cicd-sec-6-secret-in-run-output"},{"title":"CICD-SEC-6 — Secrets over-provisioned to the whole workflow","href":"/rules/cicd-sec-6-overprovisioned-secrets"},{"title":"CICD-SEC-6 — Run step dumps the environment or echoes a CI token","href":"/rules/cicd-sec-6-env-exfil"},{"title":"CICD-SEC-7 — Actions debug logging enabled in workflow","href":"/rules/cicd-sec-7"},{"title":"CICD-SEC-7 — Build artifact published without a retention cap","href":"/rules/cicd-sec-7-artifact-exposure"},{"title":"CICD-SEC-8 — repository_dispatch trigger without event-type allowlist","href":"/rules/cicd-sec-8"},{"title":"CICD-SEC-8 — Sensitive job on a self-hosted runner with no declared egress restriction","href":"/rules/cicd-sec-8-selfhosted-egress"},{"title":"CICD-SEC-9 — Downloaded artifact has no integrity check","href":"/rules/cicd-sec-9"},{"title":"CICD-SEC-10 — Job-level continue-on-error suppresses failure visibility","href":"/rules/cicd-sec-10"},{"title":"BEST-PRAC-1 — Command piped directly to shell","href":"/rules/best-prac-1"},{"title":"BEST-PRAC-2 — Job timeout not configured","href":"/rules/best-prac-2"},{"title":"BEST-PRAC-3 — Self-hosted runner usage","href":"/rules/best-prac-3"},{"title":"BEST-PRAC-4 — Deploy/release workflow has no concurrency guard","href":"/rules/best-prac-4-missing-concurrency"},{"title":"BEST-PRAC-5 — Multi-command shell step runs without strict mode","href":"/rules/best-prac-5-shell-hardening"},{"title":"SLSA-BUILD-L2 — Build provenance is not generated","href":"/rules/slsa-build-l2-provenance"},{"title":"SLSA-BUILD-L2 — Provenance/signing step is missing id-token: write","href":"/rules/slsa-build-l2-oidc-token-scope"},{"title":"SLSA-BUILD-L2 — Permissions block grants overly broad scopes","href":"/rules/slsa-build-l2-perms-overly-broad"},{"title":"SLSA-BUILD-L2 — Workflow consumes artifacts but does not verify provenance","href":"/rules/slsa-build-l2-verify-step"},{"title":"SLSA-BUILD-L3 — Provenance is generated in-job, not isolated","href":"/rules/slsa-build-l3-provenance-isolated"},{"title":"SLSA-BUILD-L3 — Cache key in pull_request_target derived from PR input","href":"/rules/slsa-build-l3-cache-poisoning"},{"title":"CICD-SEC-1 — Default branch has no branch protection rule","href":"/rules/cicd-sec-1-bp-missing"},{"title":"CICD-SEC-1 — Default branch allows force pushes","href":"/rules/cicd-sec-1-bp-force-push"},{"title":"CICD-SEC-1 — Default branch can be deleted","href":"/rules/cicd-sec-1-bp-deletion"},{"title":"CICD-SEC-1 — Default branch does not require pull request reviews","href":"/rules/cicd-sec-1-bp-no-review"},{"title":"CICD-SEC-1 — Default branch requires fewer than 2 approving reviews","href":"/rules/cicd-sec-1-bp-few-reviewers"},{"title":"CICD-SEC-1 — Default branch does not dismiss stale reviews on new commits","href":"/rules/cicd-sec-1-bp-stale-reviews"},{"title":"CICD-SEC-1 — Default branch does not require status checks to pass","href":"/rules/cicd-sec-1-bp-no-status-checks"},{"title":"CICD-SEC-1 — Admins can bypass branch protection","href":"/rules/cicd-sec-1-bp-admin-bypass"},{"title":"CICD-SEC-1 — CODEOWNERS exists but their review is not required","href":"/rules/cicd-sec-1-bp-no-codeowners-review"},{"title":"CICD-SEC-1 — Default branch does not require signed commits","href":"/rules/cicd-sec-1-bp-no-signed-commits"},{"title":"CICD-SEC-4 — Default GITHUB_TOKEN permissions are read-write","href":"/rules/cicd-sec-4-wperm-write"},{"title":"CICD-SEC-4 — GitHub Actions can approve pull requests","href":"/rules/cicd-sec-4-wperm-pr-approve"},{"title":"CICD-SEC-5 — All GitHub Actions and reusable workflows are allowed","href":"/rules/cicd-sec-5-actions-all-allowed"},{"title":"CICD-SEC-3 — Dependabot alerts are disabled","href":"/rules/cicd-sec-3-dependabot-alerts-off"},{"title":"CICD-SEC-3 — Dependabot security updates are disabled","href":"/rules/cicd-sec-3-dependabot-fixes-off"},{"title":"CICD-SEC-6 — Secret scanning is disabled","href":"/rules/cicd-sec-6-secret-scanning-off"},{"title":"CICD-SEC-6 — Secret-scanning push protection is disabled","href":"/rules/cicd-sec-6-secret-push-protection-off"},{"title":"CICD-SEC-1 (GitLab) — Pipeline runs untrusted merge-request code with protected secrets","href":"/rules/cicd-sec-1-gl-mr-target"},{"title":"CICD-SEC-2 (GitLab) — Long-lived access token used instead of CI_JOB_TOKEN","href":"/rules/cicd-sec-2-gl-pat-secret"},{"title":"CICD-SEC-3 (GitLab) — Unpinned remote include","href":"/rules/cicd-sec-3-gl-unpinned-include"},{"title":"CICD-SEC-4 (GitLab) — Shell injection from pipeline variables","href":"/rules/cicd-sec-4-gl-shell-injection"},{"title":"CICD-SEC-6 (GitLab) — Hardcoded secret in pipeline config","href":"/rules/cicd-sec-6-gl-hardcoded-secrets"},{"title":"CICD-SEC-7 (GitLab) — Debug tracing enabled","href":"/rules/cicd-sec-7-gl-debug-trace"},{"title":"CICD-SEC-8 (GitLab) — Trigger/pipeline job without source filtering","href":"/rules/cicd-sec-8-gl-trigger-unfiltered"},{"title":"CICD-SEC-10 (GitLab) — allow_failure hides job failures","href":"/rules/cicd-sec-10-gl-allow-failure"},{"title":"BEST-PRAC-2 (GitLab) — Job has no timeout","href":"/rules/best-prac-2-gl-missing-timeout"},{"title":"BEST-PRAC-3 (GitLab) — Job targets a self-hosted runner","href":"/rules/best-prac-3-gl-self-hosted-tags"},{"title":"BEST-PRAC-4 (GitLab) — Deploy job has no resource_group","href":"/rules/best-prac-4-gl-missing-resource-group"},{"title":"CICD-SEC-1 (GitLab) — Default branch is not protected","href":"/rules/cicd-sec-1-gl-bp-missing"},{"title":"CICD-SEC-1 (GitLab) — Protected default branch allows force push","href":"/rules/cicd-sec-1-gl-bp-force-push"},{"title":"CICD-SEC-1 (GitLab) — Merges allowed without a passing pipeline","href":"/rules/cicd-sec-1-gl-merge-without-pipeline"},{"title":"CICD-SEC-1 (GitLab) — Merge requests require no approvals","href":"/rules/cicd-sec-1-gl-no-approvals"},{"title":"CICD-SEC-4 (GitLab) — Public pipelines expose job logs and artifacts","href":"/rules/cicd-sec-4-gl-public-pipelines"}]}]}]},"basePath":"","title":"API tokens - Pipefort","buildId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","deploymentId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","dynamics":[],"chunks":[]}