Credential patterns¶
Every credential shape cloop recognises by pattern, generated from the
registry in pkg/redact. Do not edit this file: it is rendered by
tests/docs/credential_patterns_test.go, and a CI check fails when it stops
matching. Regenerate with make docs-credentials.
Who uses this list¶
Four scanners handle text whose secrets they cannot know in advance, and all four ask this registry rather than keeping a list of their own:
| Scanner | What it does with a match |
|---|---|
cloop audit |
reports the detector's label for .cloop/ git history and task artifacts |
| the provider-call audit | stores the error as <lead>[REDACTED] — sk-ant-api03-[REDACTED] |
| the secret broker's audit reasons | stores [redacted] |
| browser telemetry | stores [redacted] |
Which text each one sees, and what else it applies, is in the security model.
This is not the primary defence. A credential a lease delivered is removed by its exact value wherever task output is captured, whatever its shape; these patterns are the backstop for text that never passed through that match.
How to read the table¶
The detector is a stable name: cloop audit and the test corpus key on it,
so a detector is retired rather than renamed. Reported as is the wording a
finding uses. A finding never includes the value.
Rows are in precedence order. When two detectors claim the same text — a
GitHub token inside an Authorization header inside a URL — the redactors
replace it once, and the detector listed first names the match. cloop audit
reports every detector that matched.
Context a detector needs in order to recognise a credential is kept: Bearer,
a field's key, a URL's scheme and host. Only the credential is replaced, and
a field's value is replaced to the next delimiter, so one that holds
punctuation the detector does not list goes whole.
What documentation prints in a credential's place is not a finding. A
detector that recognises a prefix leaves alone a body that is mostly one
repeated character (ghp_xxxx…), and a field detector leaves alone a
value that ends that way (GITHUB_TOKEN=ghp_xxxx…) or is a template
($TOKEN, ${DB_PASSWORD}).
Detectors¶
| Detector | Reported as | Recognises |
|---|---|---|
pem-private-key |
PEM private key | A -----BEGIN … PRIVATE KEY----- block (RSA, EC, DSA, OPENSSH, ENCRYPTED, PKCS#8, PGP PRIVATE KEY BLOCK) through its END line, or through the lines of key after it when the block was cut off. A header with no key after it, certificates and public keys are not matched. |
cloop-api-token |
cloop API token | cloop_pat_<id>_<secret> — operator PATs, service-account tokens and display-glasses links. |
cloop-glasses-link |
cloop display-glasses link token | cloop_glasses_…. No build has minted this prefix — glasses links are cloop_pat_ tokens — but the telemetry scrubber matched it from the start, and keeping it costs nothing. |
cloop-scim-credential |
cloop SCIM provisioning credential | cloop_scim_<id>_<secret>, the bearer an identity provider presents to /scim/v2 (Task 20415). |
cloop-ci-token |
cloop CI relay session token | cloop_ci_<id>.<secret>, the session token a CI job presents to the Claude relay. |
cloop-relay-token |
cloop model relay session token | cloop_relay_<id>.<secret>, the session token a sandboxed run presents to the hub's model relay in place of its Claude credential (Task 20435). |
cloop-git-proxy-session |
cloop git proxy session password | cloop_git1_<43 base64url>, the password a sandbox's git presents to the hub's git proxy in place of a GitHub credential (Task 20454). Passwords minted before that task carry no prefix and no shape. |
cloop-kube-guard-session |
cloop Kubernetes monitor session token | cloop_kube1_<id>.<secret>, the bearer token a sandbox's kubectl presents to the hub's Kubernetes access monitor (Task 20454). Tokens minted before that task are a bare <id>.<secret>, which has no shape. |
cloop-egress-session |
cloop egress proxy session password | cloop_egress1_<64 hex>, the password in the HTTPS_PROXY a sandbox reaches the Internet through (Task 20454). Passwords minted before that task are bare hex, which has no shape. |
cloop-knowledge-session |
cloop run knowledge session token | cloop_know1_<id>.<secret>, the bearer token a run presents to the hub's run-scoped knowledge search (Task 20472). |
cloop-enrollment-token |
cloop executor enrollment token | clet1.<id>.<secret>.<mac>, the single-use token an edge device enrolls with. |
cloop-runner-token |
cloop executor pool runner token | clrt1.<id>.<secret>.<mac>, the single-use token an executor pool's ephemeral runner enrolls with (Task 20482). |
cloop-runner-credential |
cloop executor pool runner credential | clrc1.<agent>.<secret>.<mac>, the credential an executor pool's ephemeral runner reconnects with during its one run (Task 20482). |
cloop-pool-credential |
cloop executor pool controller credential | cloop_pool1_<id>.<secret>, the long-lived credential an executor pool's controller presents to the hub's demand feed and runner endpoint (Task 20482). |
cloop-enrollment-bundle |
cloop executor enrollment bundle | cloopenroll1.<base64url>, the copy-paste bundle that carries an enrollment token. |
cloop-agent-credential |
cloop executor agent credential | clac1.<agent>.<secret>.<mac>, the long-lived credential an enrolled agent reconnects with. |
github-token-long |
GitHub token (long form) | ghp_, gho_, ghu_, ghs_ or ghr_ followed by 31 or more characters including _ or . — the dotted form GitHub has issued installation tokens in since September 2026 (ghs_<7 digits>_<36>.<254>.<86>, 390 characters) — or by that form's lead alone, the digits and the underscore after them, which is what a line break or a truncating log leaves of one on its first line. The body must carry a digit or a capital, which a snake_case identifier does not. |
github-token |
GitHub token | ghp_, gho_, ghu_, ghs_ or ghr_ followed by 16 or more letters and digits — the classic form (36). |
github-fine-grained-pat |
GitHub fine-grained personal access token | github_pat_ followed by 16 or more letters, digits and underscores (82 in practice), with a digit or a capital among them. |
anthropic-api-key |
Anthropic API key | sk-ant-api03-… (any two-digit version). |
anthropic-oauth-token |
Anthropic OAuth token | sk-ant-oat01-… access tokens and sk-ant-ort01-… refresh tokens — what a Claude subscription login holds. |
anthropic-key |
Anthropic credential (other form) | Any other sk-ant-… credential with a body of 12 or more characters: admin keys, session keys, forms not yet issued. |
openai-api-key |
OpenAI API key | sk-proj-…, sk-svcacct-…, sk-admin-… and sk-None-… keys, and legacy sk- followed by 20 or more letters and digits. Not when sk- ends a longer word: task-…, risk-…. |
slack-token |
Slack token | xoxb-, xoxp-, xoxa-, xoxr-, xoxs-, xoxo-, xoxe- (and rotating xoxe.xox?-) and app-level xapp- tokens. |
atlassian-api-token |
Atlassian API token | ATATT followed by 24 or more letters, digits, _, - and = — the API token an Atlassian account signs in to Confluence and Jira Cloud with (ATATT3 and 186 more in practice, the last nine an = and a hexadecimal checksum). Not when ATATT ends a longer word, nor a short run such as an issue key (ATATT-1234). |
aws-access-key-id |
AWS access key ID | AKIA, ASIA, ABIA or ACCA followed by exactly 16 capitals and digits, standing alone. AWS's documentation keys, which end in EXAMPLE, are not matched. |
google-api-key |
Google API key | AIza followed by 30 or more letters, digits, _ and - (35 in practice). |
jwt |
JSON Web Token | eyJ… header, payload and signature segments joined by dots (and the two further segments of a JWE). A lone base64 JSON blob, with no dots, is not matched. |
kubeconfig-client-key |
kubeconfig client key | The base64 value of a kubeconfig client-key-data field. client-certificate-data and certificate-authority-data are public and are left alone. |
aws-secret-access-key |
AWS secret access key | The 40-character value of an aws_secret_access_key / SecretAccessKey field — the half of an AWS key pair that is actually secret, and has no prefix of its own. AWS's documentation key, which holds EXAMPLE, is not matched. |
token-field |
credential field | The value of a token, id-token, refresh-token, access-token, auth-token, session-token, api-token or client-secret field (any case, - or _ or neither, and after a prefix such as GITHUB_ or X-Auth-) in YAML, JSON — escaped or not — key=value or Go header form, the = percent-encoded or not: a kubeconfig user's token:, an OAuth token response, a token parameter in a URL carried inside another. The value runs to the next delimiter and must look generated — a digit, an interior capital, or 32 characters — and be neither a placeholder such as $TOKEN or YOUR_TOKEN nor a name in code such as cfg.APIToken. |
authorization-header |
Authorization header | The credential in an Authorization: or Proxy-Authorization: header — after Bearer, Basic, token, Bot or Negotiate, or with no scheme when it looks generated — as curl, an HTTP dump or a JSON headers object, escaped or not, would print it, to the next delimiter. Placeholders are left alone, and so is a word such as forbidden where a credential would be. |
bearer-token |
bearer token | A value following the word Bearer anywhere, to the next delimiter, when it looks generated (a digit, an interior capital, or 32 characters) and is not a name in code — so a sentence about "bearer authentication" or a TokenSource is not a finding. |
url-userinfo |
credentials in a URL | The userinfo of scheme://user:password@host — a git remote, a proxy URL, a database DSN — when it has a password, or a username long and generated enough to be a token. ssh://git@github.com/… is not a credential and is left alone. |