Supabase Key
Detects Supabase credentials: personal access tokens (sbp_), the new opaque secret API keys (sb_secret_) introduced in 2025 to replace the legacy service_role JWT, and, when labelled with Supabase context in an assignment, the legacy anon/service_role JWT keys that remain valid until late 2026. A leaked secret key or service_role JWT grants full admin access to the project's production Postgres database, bypassing Row Level Security; a leaked personal access token grants account-wide Management API control.
- Type
- regex
- Engine
- universal
- Confidence
- high
- Confidence justification
- High confidence: both distinctive prefixes are multiply attested. sbp_ is pinned at a 40-character body by two independent production detectors (TruffleHog sbp_[a-z0-9]{40}, Kingfisher sbp_[a-z0-9_-]{40} case-insensitive) and confirmed as the personal-access-token format by Supabase's own Management API and CLI documentation. sb_secret_ is confirmed by Supabase's changelog (new API keys, June 2025), by a literal default key hardcoded in Supabase's own open-source CLI (of the form sb_secret_ABCDEFGHIJKLMNOPQRSTUV_abcdefgh -- a 31-character body: 22 chars + underscore + 8-char suffix), and by Kingfisher's production rule (sb_secret_[a-z0-9_-]{31}) -- two convergent sources pinning 31 exactly, so the body is bounded 28-36: the pin plus a small hedge, because the vendor documents the keys only as opaque random strings and a hard 31 would silently miss minor generation-format drift. The legacy JWT branch is deliberately context-gated: eyJ-prefixed JWTs are one of the most common token shapes in any log or config file, so it requires a labelled assignment and never fires value-only.
- Jurisdictions
- global
- Regulations
- Criminal Code Act 1995 (Cth)
- Frameworks
- CIS Controls, ISO 27001, NIST CSF, SOC 2
- Data categories
- credentials, security
- Scope
- narrow
- Risk rating
- 9
- Platform compatibility
- Purview: Compatible, GCP DLP: Unsupported, Macie: Unsupported, Zscaler: Compatible, Palo Alto: Unsupported, Netskope: Unsupported
Pattern
(?<![A-Za-z0-9_-])(?:sbp_[A-Za-z0-9_-]{40}|sb_secret_[A-Za-z0-9_-]{28,36})(?![A-Za-z0-9_-])
Corroborative evidence keywords
supabase, supabase.co, SUPABASE_ACCESS_TOKEN, SUPABASE_SERVICE_ROLE_KEY, service_role, api key, api_key, apikey, access key, access token, auth token, authorization, bearer, conn str, connection string, connectionstring, cookie, credential, database, host (+38 more)
Proximity: 300 characters
Should match
SUPABASE_ACCESS_TOKEN=sbp_abcdefghijklmnopqrstuvwxyz01234567890123— Supabase personal access token (sbp_ + 40-char body) in the canonical env varsbp_0123456789abcdefghij0123456789abcdefghij— Bare Supabase personal access token (distinctive prefix, no label needed)sb_secret_ABCDEFGHIJKLMNOPQRSTUV_abcdefgh— Supabase secret API key (sb_secret_ + 31-char body, the structure in Supabase's own CLI example)SUPABASE_SERVICE_ROLE_KEY=eyJABCDEFGHIJKLMNOPQRSTUVWXYZ.eyJabcdefghijklmnopqrstuvwxyz.0123456789ABCDEFGHIJabcdefghij— Legacy service_role JWT in a labelled assignment (context-gated branch)supabase anon key: eyJabcdefghijklmnopqrstuvwxyz.eyJABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz012345— Legacy anon JWT after a prose-style supabase label with colon separatorservice_role="eyJ0123456789ABCDEFGHIJ.eyJKLMNOPQRSTUVWXYZabcdefgh.ijklmnopqrstuvwxyz0123456789ABCD"— Legacy service_role JWT in a quoted config assignment keyed on the service_role label
Should not match
sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH— Supabase publishable key (safe to expose by design, deliberately not detected; value is Supabase's own public CLI default)sbp_abcdefghij— sbp_ body far too short (10 chars, not 40)eyJABCDEFGHIJKLMNOPQRSTUVWXYZ.eyJabcdefghijklmnopqrstuvwxyz.0123456789ABCDEFGHIJabcdefghij— Bare JWT with no Supabase label anywhere (eyJ tokens are ubiquitous; never fires value-only)rotate the supabase service_role key in project settings— Prose mention without a token valuetemplate example placeholder record identifier— Template/sample context should be excluded even when anchor words are present
Known false positives
- Any JWT (session token, OIDC id_token, other vendors' API keys) appearing near the words supabase/service_role in configuration or documentation -- eyJ-prefixed JWTs are ubiquitous and carry no vendor marker in the visible string. Mitigation: The JWT branch requires a Supabase-specific label plus an assignment separator (enforced in the regex), is context-gated only, and never fires value-only; corroborative keywords add further gating.
- Supabase publishable keys (sb_publishable_) and the project anon JWT are designed to be public; flagging them as leaked credentials would be noise. Mitigation: sb_publishable_ is structurally excluded from the regex; the anon JWT is only reported when it appears in a labelled Supabase assignment, where treating it as sensitive is a reasonable default.
- Documentation or examples showing placeholder sbp_/sb_secret_ strings. Mitigation: Require corroborative Supabase keywords and check for placeholder markers (example, xxxx).
References
- Supabase changelog introducing sb_publishable_/sb_secret_ opaque API keys (June 2025) and the legacy JWT deprecation timeline (late 2026)
- Understanding API keys - Supabase Docs (sb_secret_ replaces service_role JWT; sb_publishable_ is safe to expose)
- Supabase's own CLI source (literal sb_secret_/sb_publishable_ default keys, 31-character bodies)
- TruffleHog production Supabase detector (sbp_[a-z0-9]{40} personal access token)
- Kingfisher production Supabase rules (sbp_ 40-char, sb_secret_ 31-char, sb_publishable_ 24-40)
- Supabase Service Role JWT - GitGuardian detector documentation (unprefixed JWT, admin rights over the whole database)