@openviking/dsh-memory-plugin 0.5.28 → 0.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.mjs +11 -2
- package/package.json +1 -1
- package/runtime.mjs +13 -4
- package/shared/config-schema.mjs +34 -1
- package/shared/pending-queue.mjs +23 -1
- package/shared/recall-core.mjs +2 -0
- package/shared/redact.mjs +522 -0
- package/shared/secret-rules.mjs +294 -0
package/client.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOvHttp } from "./shared/ov-http.mjs";
|
|
2
|
+
import { redactPayload } from "./shared/redact.mjs";
|
|
2
3
|
|
|
3
4
|
export class OpenVikingClient {
|
|
4
5
|
constructor(config) {
|
|
@@ -33,12 +34,20 @@ export class OpenVikingClient {
|
|
|
33
34
|
return response.ok ? response.result : null;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
/**
|
|
38
|
+
* POST one captured message. The payload is secret-redacted first under
|
|
39
|
+
* `options.redactTier` (default: this client's `captureRedact`), unless
|
|
40
|
+
* `options.redacted` says the caller already did it with its own tier.
|
|
41
|
+
*/
|
|
42
|
+
async addMessage(sessionId, payload, actorPeerId, options = {}) {
|
|
43
|
+
const body = options.redacted === true
|
|
44
|
+
? payload
|
|
45
|
+
: redactPayload(payload, { tier: options.redactTier ?? this.config.captureRedact });
|
|
37
46
|
return this.fetchJSON(
|
|
38
47
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/messages`,
|
|
39
48
|
{
|
|
40
49
|
method: "POST",
|
|
41
|
-
body: JSON.stringify(
|
|
50
|
+
body: JSON.stringify(body),
|
|
42
51
|
},
|
|
43
52
|
{ actorPeerId },
|
|
44
53
|
);
|
package/package.json
CHANGED
package/runtime.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
listPending,
|
|
8
8
|
replayPending,
|
|
9
9
|
} from "./shared/pending-queue.mjs";
|
|
10
|
+
import { redactPayload } from "./shared/redact.mjs";
|
|
10
11
|
import { isRetryableFailure } from "./shared/retryable.mjs";
|
|
11
12
|
import { resolveEffectivePeerId } from "./shared/workspace-peer.mjs";
|
|
12
13
|
import {
|
|
@@ -150,9 +151,13 @@ export class OpenVikingRuntime {
|
|
|
150
151
|
capture(session, event) {
|
|
151
152
|
const state = this.stateFor(session);
|
|
152
153
|
if (!isCaptureEnabled(state.config)) return;
|
|
153
|
-
const
|
|
154
|
-
if (!
|
|
154
|
+
const captured = captureEvent(event, state.config, state.toolNames);
|
|
155
|
+
if (!captured) return;
|
|
155
156
|
this.enqueueWrite(state, async () => {
|
|
157
|
+
// Redacted once, inside the write chain so a slow scan never blocks the
|
|
158
|
+
// host's event: the direct POST and the pending queue both carry this
|
|
159
|
+
// copy, never the plaintext.
|
|
160
|
+
const payload = redactPayload(captured, { tier: state.config.captureRedact });
|
|
156
161
|
if (state.hasPendingWrites) {
|
|
157
162
|
await this.enqueuePendingMessage(state, payload);
|
|
158
163
|
return;
|
|
@@ -171,6 +176,7 @@ export class OpenVikingRuntime {
|
|
|
171
176
|
state.ovSessionId,
|
|
172
177
|
payload,
|
|
173
178
|
state.config.peerId,
|
|
179
|
+
{ redacted: true },
|
|
174
180
|
);
|
|
175
181
|
if (isRetryableFailure(response)) {
|
|
176
182
|
await this.enqueuePendingMessage(state, payload);
|
|
@@ -265,7 +271,10 @@ export class OpenVikingRuntime {
|
|
|
265
271
|
async enqueuePending(state, type, payload) {
|
|
266
272
|
const createdAt = Math.max(Date.now(), state.pendingCreatedAt + 1);
|
|
267
273
|
state.pendingCreatedAt = createdAt;
|
|
268
|
-
const result = await enqueue(type, state.ovSessionId, payload, {
|
|
274
|
+
const result = await enqueue(type, state.ovSessionId, payload, {
|
|
275
|
+
createdAt,
|
|
276
|
+
redactTier: state.config.captureRedact,
|
|
277
|
+
});
|
|
269
278
|
if (result.ok) {
|
|
270
279
|
// Log the latch transition only: every message that follows while the
|
|
271
280
|
// latch holds takes the cheap enqueue path, so this fires once per
|
|
@@ -334,7 +343,7 @@ export class OpenVikingRuntime {
|
|
|
334
343
|
await replayPending(
|
|
335
344
|
(path, init) => this.client.fetchJSON(path, init),
|
|
336
345
|
(stage, data) => this.log(stage, data),
|
|
337
|
-
options,
|
|
346
|
+
{ redactTier: this.config.captureRedact, ...options },
|
|
338
347
|
);
|
|
339
348
|
}
|
|
340
349
|
|
package/shared/config-schema.mjs
CHANGED
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
* harness per-harness default, where one genuinely differs
|
|
25
25
|
* min/max clamped, not rejected: a config file must not kill a hook
|
|
26
26
|
* values the enum's members; anything else falls back to the default
|
|
27
|
+
* boolValues enum only: the member a boolean-ish value (`true`/`yes`/`on`,
|
|
28
|
+
* `false`/`no`/`off`/`0`) stands for, so `false` can mean "off"
|
|
29
|
+
* unknownToDefault
|
|
30
|
+
* enum only: a value naming no member resolves to the default
|
|
31
|
+
* instead of leaving the lower layer's value standing
|
|
27
32
|
* env OPENVIKING_* variable, the highest-priority layer
|
|
28
33
|
* aliases older spellings, honoured forever; the doctor names them
|
|
29
34
|
* workspace dotted key in `.openviking/config.json`
|
|
@@ -84,6 +89,9 @@ export const KNOBS = [
|
|
|
84
89
|
{ name: "recallMaxContentChars", type: "int", default: 500, min: 100, max: 5000, env: "OPENVIKING_RECALL_MAX_CONTENT_CHARS", capability: "recall" },
|
|
85
90
|
{ name: "recallPreferAbstract", type: "bool", default: true, env: "OPENVIKING_RECALL_PREFER_ABSTRACT", capability: "recall" },
|
|
86
91
|
{ name: "recallPeerScope", type: "enum", values: ["all", "actor"], default: "all", env: "OPENVIKING_RECALL_PEER_SCOPE", workspace: "recall.peer_scope", capability: "recall" },
|
|
92
|
+
// Sent as events_time_decay_protection ("7d", "12h"): event memories keep their score for
|
|
93
|
+
// that long and decay afterwards. Empty leaves decay off, as the server does by default.
|
|
94
|
+
{ name: "recallEventsDecayProtection", type: "string", default: "", env: "OPENVIKING_RECALL_EVENTS_DECAY_PROTECTION", capability: "recall" },
|
|
87
95
|
{ name: "recallDedupTurns", type: "int", default: 5, min: 0, max: 20, env: "OPENVIKING_RECALL_DEDUP_TURNS", workspace: "recall.dedup_turns", capability: "recall" },
|
|
88
96
|
{ name: "recallMaxTokens", type: "int", default: 1600, min: 64, max: 200000, env: "OPENVIKING_RECALL_MAX_TOKENS", sendOnlyWhenConfigured: true, capability: "recall" },
|
|
89
97
|
{ name: "recallQueryExpansion", type: "enum", values: ["auto", "off"], default: "auto", env: "OPENVIKING_RECALL_QUERY_EXPANSION", sendOnlyWhenConfigured: true, capability: "recall" },
|
|
@@ -148,6 +156,23 @@ export const KNOBS = [
|
|
|
148
156
|
// tool results, so it captures them by default.
|
|
149
157
|
{ name: "captureToolResults", type: "bool", default: false, harness: { dsh: true }, env: "OPENVIKING_CAPTURE_TOOL_RESULTS", capability: "capture" },
|
|
150
158
|
{ name: "captureFilters", type: "list", default: [], env: "OPENVIKING_CAPTURE_FILTERS", capability: "capture" },
|
|
159
|
+
// Secret redaction of every captured payload before it is sent or queued
|
|
160
|
+
// (lib/redact.mjs); the tiers are REDACT_TIERS there, in the same order.
|
|
161
|
+
// User-level only — deliberately no `workspace` key, so a repository's
|
|
162
|
+
// `.openviking/config.json` cannot switch redaction off for whoever opens it.
|
|
163
|
+
// `false` means off rather than "unparseable"; a tier this build does not
|
|
164
|
+
// know (a newer config read by an older plugin) means the default, never a
|
|
165
|
+
// weaker value left over from a lower layer.
|
|
166
|
+
{
|
|
167
|
+
name: "captureRedact",
|
|
168
|
+
type: "enum",
|
|
169
|
+
values: ["off", "standard", "strict"],
|
|
170
|
+
default: "standard",
|
|
171
|
+
boolValues: { true: "standard", false: "off" },
|
|
172
|
+
unknownToDefault: true,
|
|
173
|
+
env: "OPENVIKING_CAPTURE_REDACT",
|
|
174
|
+
capability: "capture",
|
|
175
|
+
},
|
|
151
176
|
// 0 means "derive from timeoutMs": a write gets a longer budget than a read.
|
|
152
177
|
{ name: "captureTimeoutMs", type: "int", default: 0, min: 0, max: 600000, env: "OPENVIKING_CAPTURE_TIMEOUT_MS", capability: "capture" },
|
|
153
178
|
{ name: "commitTokenThreshold", type: "int", default: 20000, min: 1000, max: 1000000, env: "OPENVIKING_COMMIT_TOKEN_THRESHOLD", workspace: "capture.commit_token_threshold", capability: "capture" },
|
|
@@ -314,8 +339,16 @@ export function coerceKnobValue(knob, raw, fallback) {
|
|
|
314
339
|
return knob.max === undefined ? floored : Math.min(knob.max, floored);
|
|
315
340
|
}
|
|
316
341
|
case "enum": {
|
|
342
|
+
const values = knob.values || [];
|
|
317
343
|
const word = String(raw ?? "").trim();
|
|
318
|
-
|
|
344
|
+
if (values.includes(word)) return word;
|
|
345
|
+
if (knob.boolValues) {
|
|
346
|
+
const lower = word.toLowerCase();
|
|
347
|
+
if (values.includes(lower)) return lower;
|
|
348
|
+
if (raw === true || TRUE_WORDS.includes(lower)) return knob.boolValues.true;
|
|
349
|
+
if (raw === false || FALSE_WORDS.includes(lower)) return knob.boolValues.false;
|
|
350
|
+
}
|
|
351
|
+
return knob.unknownToDefault && word ? knobDefault(knob) : fallback;
|
|
319
352
|
}
|
|
320
353
|
// A peer template may be one string or an ordered list of fallbacks, and
|
|
321
354
|
// `String([a, b])` would quietly turn the list into one bogus template.
|
package/shared/pending-queue.mjs
CHANGED
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Each file contains: { type, sessionId, payload, createdAt, retries, dedupKey }
|
|
13
13
|
*
|
|
14
|
+
* An addMessage payload is secret-redacted (lib/redact.mjs) before it is
|
|
15
|
+
* written, and again before it is replayed: the queue is plaintext on disk, and
|
|
16
|
+
* an entry written by an older plugin, or by a caller that skipped redaction,
|
|
17
|
+
* must not reach the server as it was. Redaction is idempotent, so replaying an
|
|
18
|
+
* already-redacted entry sends the same bytes.
|
|
19
|
+
*
|
|
14
20
|
* Config (env vars):
|
|
15
21
|
* OPENVIKING_PENDING_DIR pending queue directory
|
|
16
22
|
* (default: ~/.openviking/pending)
|
|
@@ -25,6 +31,7 @@ import { mkdir, readdir, readFile, rename, writeFile, unlink, stat, chmod, utime
|
|
|
25
31
|
import { createHash } from "node:crypto";
|
|
26
32
|
import { join } from "node:path";
|
|
27
33
|
import { homedir } from "node:os";
|
|
34
|
+
import { redactPayload } from "./redact.mjs";
|
|
28
35
|
import { isRetryableFailure } from "./retryable.mjs";
|
|
29
36
|
|
|
30
37
|
const DEFAULT_MAX_RETRIES = 3;
|
|
@@ -184,8 +191,21 @@ async function recoverStaleProcessing(dir) {
|
|
|
184
191
|
* @param {object} payload - the data that failed to send
|
|
185
192
|
* @param {object} options
|
|
186
193
|
* @param {number} options.createdAt - optional queue timestamp override
|
|
194
|
+
* @param {string} [options.redactTier] - the captureRedact tier an addMessage
|
|
195
|
+
* payload is redacted under before it is written (default "standard")
|
|
196
|
+
* @param {boolean} [options.redacted] - the caller already redacted `payload`
|
|
197
|
+
* under its configured tier, so it is written as it is
|
|
187
198
|
*/
|
|
188
199
|
export async function enqueue(type, sessionId, payload, options = {}) {
|
|
200
|
+
if (type === "addMessage" && options.redacted !== true) {
|
|
201
|
+
try {
|
|
202
|
+
payload = redactPayload(payload, { tier: options.redactTier });
|
|
203
|
+
} catch (err) {
|
|
204
|
+
// redactPayload fails closed on its own; this is the last line before
|
|
205
|
+
// plaintext would be written to disk, so refuse rather than write it.
|
|
206
|
+
return { ok: false, error: `redaction failed: ${err?.message || String(err)}` };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
189
209
|
const dir = getPendingDir();
|
|
190
210
|
const now = Number.isFinite(options.createdAt) ? options.createdAt : Date.now();
|
|
191
211
|
const dedupKey = makeDedupKey(type, sessionId, payload);
|
|
@@ -378,6 +398,8 @@ export async function cleanStale() {
|
|
|
378
398
|
* a background drainer can keep retrying a transient failure without
|
|
379
399
|
* burning the session-start retry budget. Exhausted and non-retryable
|
|
380
400
|
* entries are deleted exactly as in the default mode.
|
|
401
|
+
* @param {string} [options.redactTier="standard"] - the captureRedact tier
|
|
402
|
+
* every replayed addMessage payload is redacted under before it is sent
|
|
381
403
|
* @returns {{ replayed: number, failed: number, skipped: number, deferred: number }}
|
|
382
404
|
*/
|
|
383
405
|
export async function replayPending(fetchJSON, log, options = {}) {
|
|
@@ -422,7 +444,7 @@ export async function replayPending(fetchJSON, log, options = {}) {
|
|
|
422
444
|
if (entry.type === "addMessage") {
|
|
423
445
|
res = await fetchJSON(`/api/v1/sessions/${encodedSid}/messages`, {
|
|
424
446
|
method: "POST",
|
|
425
|
-
body: JSON.stringify(entry.payload),
|
|
447
|
+
body: JSON.stringify(redactPayload(entry.payload, { tier: options.redactTier })),
|
|
426
448
|
});
|
|
427
449
|
} else if (entry.type === "commitSession") {
|
|
428
450
|
res = await fetchJSON(`/api/v1/sessions/${encodedSid}/commit`, {
|
package/shared/recall-core.mjs
CHANGED
|
@@ -129,6 +129,8 @@ export function buildContextSearchBody(cfg = {}, options = {}) {
|
|
|
129
129
|
if (limitConfigured) body.quotas = codingQuotas(limit);
|
|
130
130
|
if (maxTokensConfigured) body.max_tokens = maxTokens;
|
|
131
131
|
if (cfg.recallPeerScope === "actor") body.peer_scope = "actor";
|
|
132
|
+
const decayProtection = String(cfg.recallEventsDecayProtection || "").trim();
|
|
133
|
+
if (decayProtection) body.events_time_decay_protection = decayProtection;
|
|
132
134
|
|
|
133
135
|
const sessionId = String(options.sessionId || "").trim();
|
|
134
136
|
if (sessionId) {
|
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
// GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
|
|
2
|
+
/**
|
|
3
|
+
* Client-side secret redaction for captured transcripts.
|
|
4
|
+
*
|
|
5
|
+
* An agent that runs `cat .env` or prints a token puts that credential in the
|
|
6
|
+
* transcript the memory plugins capture. This module replaces such secrets
|
|
7
|
+
* before a payload leaves the machine — before the POST to OpenViking and
|
|
8
|
+
* before the local pending queue writes it to disk — so the server, its
|
|
9
|
+
* extractor and the memories it writes never see the plaintext.
|
|
10
|
+
*
|
|
11
|
+
* The rules are gitleaks' default rule set plus OpenViking's own key formats
|
|
12
|
+
* (lib/secret-rules.mjs, generated), and detection follows gitleaks: a
|
|
13
|
+
* case-insensitive keyword prefilter, the rule regex, the secret taken from
|
|
14
|
+
* the rule's `secretGroup` or else the first non-empty capture group, the
|
|
15
|
+
* Shannon entropy threshold, then the global and the rule's allowlists and
|
|
16
|
+
* stopwords. Only the secret span is replaced, so `API_KEY=sk-...` becomes
|
|
17
|
+
* `API_KEY={{ov_redacted:<rule>:<tag>}}` and the turn still reads as what
|
|
18
|
+
* happened.
|
|
19
|
+
*
|
|
20
|
+
* The tag is the first 8 hex characters of HMAC-SHA256(install key, secret):
|
|
21
|
+
* the same secret gets the same tag across turns and sessions on one machine,
|
|
22
|
+
* but the tag cannot be checked against a guessed secret without the key,
|
|
23
|
+
* which never leaves the machine.
|
|
24
|
+
*
|
|
25
|
+
* Failure policy: redaction fails closed per string. A scan that throws
|
|
26
|
+
* replaces the whole string with `{{ov_redacted:scan-failed:<tag>}}`; it never
|
|
27
|
+
* throws to the hook and never lets the string through unscanned. Text past
|
|
28
|
+
* `maxChars` (MAX_SCAN_CHARS by default) is not scanned either: it is cut at a
|
|
29
|
+
* whitespace boundary (before an unterminated `-----BEGIN` line) and replaced
|
|
30
|
+
* with `{{ov_redacted:scan-oversize:<tag>}}`. The same happens once one call
|
|
31
|
+
* has scanned `maxTotalChars` (MAX_SCAN_TOTAL_CHARS) across all its strings,
|
|
32
|
+
* which keeps a hook's redaction time bounded however large the batch.
|
|
33
|
+
* A missing or unwritable key file only costs tag stability (an in-process
|
|
34
|
+
* random key is used), never redaction itself.
|
|
35
|
+
*
|
|
36
|
+
* Redaction is idempotent: existing `{{ov_redacted:<rule>:<tag>}}`
|
|
37
|
+
* placeholders and well-formed `{{ov_privacy:...}}` references are never
|
|
38
|
+
* scanned or touched, so replaying a pending entry or redacting twice changes
|
|
39
|
+
* nothing.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { createHmac, randomBytes } from "node:crypto";
|
|
43
|
+
import { linkSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
44
|
+
import { dirname, join } from "node:path";
|
|
45
|
+
|
|
46
|
+
import SECRET_RULES, { GLOBAL_ALLOWLISTS, TIERS } from "./secret-rules.mjs";
|
|
47
|
+
import { stateDir } from "./workspace-identity.mjs";
|
|
48
|
+
|
|
49
|
+
/** Ordered, cumulative: each tier runs its own rules and every earlier tier's. */
|
|
50
|
+
export const REDACT_TIERS = Object.freeze([...TIERS]);
|
|
51
|
+
export const DEFAULT_REDACT_TIER = "standard";
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The most characters of one string that are scanned. It matches the
|
|
55
|
+
* largest tool output a plugin captures (`captureToolMaxChars`, at most
|
|
56
|
+
* 1,000,000), so nothing a plugin builds by default is cut.
|
|
57
|
+
*/
|
|
58
|
+
export const MAX_SCAN_CHARS = 1_000_000;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The most characters scanned in one redactText / redactPayload /
|
|
62
|
+
* redactPayloads call, summed over every string in it. Ordinary text scans at
|
|
63
|
+
* well under 1 s per MB, but keyword-dense data (hashes, base64) can take
|
|
64
|
+
* 10-20 s per MB, and a hook that times out re-sends the same turns next time.
|
|
65
|
+
*/
|
|
66
|
+
export const MAX_SCAN_TOTAL_CHARS = 2_000_000;
|
|
67
|
+
|
|
68
|
+
const OFF_WORDS = new Set(["off", "false", "0", "no"]);
|
|
69
|
+
const ON_WORDS = new Set(["on", "true", "1", "yes"]);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Map a configured value onto a tier name. Anything that says "no" (`false`,
|
|
73
|
+
* `0`, `"off"`, any case) is `off`; a value naming no tier this build knows (a
|
|
74
|
+
* newer config, a typo) falls back to the default, so it can only redact more.
|
|
75
|
+
*/
|
|
76
|
+
export function normalizeRedactTier(value, fallback = DEFAULT_REDACT_TIER) {
|
|
77
|
+
const safeFallback = REDACT_TIERS.includes(fallback) ? fallback : DEFAULT_REDACT_TIER;
|
|
78
|
+
if (value === false || value === 0) return "off";
|
|
79
|
+
if (value === true || value === 1) return DEFAULT_REDACT_TIER;
|
|
80
|
+
if (typeof value !== "string") return safeFallback;
|
|
81
|
+
const word = value.trim().toLowerCase();
|
|
82
|
+
if (!word) return safeFallback;
|
|
83
|
+
if (OFF_WORDS.has(word)) return "off";
|
|
84
|
+
if (REDACT_TIERS.includes(word)) return word;
|
|
85
|
+
if (ON_WORDS.has(word)) return DEFAULT_REDACT_TIER;
|
|
86
|
+
return safeFallback;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Install key
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
const KEY_HEX_RE = /^[0-9a-f]{64}$/;
|
|
94
|
+
let cachedKey = null;
|
|
95
|
+
let processKey = null;
|
|
96
|
+
|
|
97
|
+
function readKeyFile(file) {
|
|
98
|
+
try {
|
|
99
|
+
const text = readFileSync(file, "utf8").trim();
|
|
100
|
+
return KEY_HEX_RE.test(text) ? Buffer.from(text, "hex") : null;
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create the key file without exposing a half-written one: a private temp
|
|
108
|
+
* file is hard-linked into place, which fails if a concurrent hook got there
|
|
109
|
+
* first (its key is then the one read back). A garbage key file, or a
|
|
110
|
+
* filesystem without hard links, gets the temp file renamed over it.
|
|
111
|
+
*/
|
|
112
|
+
function createKeyFile(file) {
|
|
113
|
+
mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
|
|
114
|
+
const tmp = `${file}.${process.pid}.${randomBytes(6).toString("hex")}`;
|
|
115
|
+
writeFileSync(tmp, `${randomBytes(32).toString("hex")}\n`, { mode: 0o600, flag: "wx" });
|
|
116
|
+
try {
|
|
117
|
+
linkSync(tmp, file);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (error?.code !== "EEXIST" || !readKeyFile(file)) renameSync(tmp, file);
|
|
120
|
+
} finally {
|
|
121
|
+
try { unlinkSync(tmp); } catch { /* renamed into place */ }
|
|
122
|
+
}
|
|
123
|
+
return readKeyFile(file);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The per-install HMAC key: 32 random bytes in `<state dir>/redact/install-key`
|
|
128
|
+
* (dir 0700, file 0600). When it cannot be read or created, a random key for
|
|
129
|
+
* this process is used: tags then differ between processes, nothing else.
|
|
130
|
+
*/
|
|
131
|
+
export function loadInstallKey({ env = process.env } = {}) {
|
|
132
|
+
let file = "";
|
|
133
|
+
try {
|
|
134
|
+
file = join(stateDir(env), "redact", "install-key");
|
|
135
|
+
} catch {
|
|
136
|
+
// No state dir: process key.
|
|
137
|
+
}
|
|
138
|
+
if (cachedKey && cachedKey.file === file) return cachedKey.key;
|
|
139
|
+
let key = file ? readKeyFile(file) : null;
|
|
140
|
+
if (!key && file) {
|
|
141
|
+
try {
|
|
142
|
+
key = createKeyFile(file);
|
|
143
|
+
} catch {
|
|
144
|
+
key = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
key ||= processKey ||= randomBytes(32);
|
|
148
|
+
cachedKey = { file, key };
|
|
149
|
+
return key;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function placeholder(ruleId, key, secret) {
|
|
153
|
+
const tag = createHmac("sha256", key).update(String(secret), "utf8").digest("hex").slice(0, 8);
|
|
154
|
+
return `{{ov_redacted:${ruleId}:${tag}}}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Detection (gitleaks semantics)
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
|
|
161
|
+
function compileAllowlists(list) {
|
|
162
|
+
return (list || []).map((al) => ({
|
|
163
|
+
and: al.condition === "AND",
|
|
164
|
+
target: al.regexTarget || "secret",
|
|
165
|
+
regexes: (al.regexes || []).map((r) => new RegExp(r.regex, r.flags)),
|
|
166
|
+
stopwords: (al.stopwords || []).map((w) => String(w).toLowerCase()),
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const compiledCache = new Map();
|
|
171
|
+
|
|
172
|
+
/** Compile the rules once per process; throws if a rule does not compile. */
|
|
173
|
+
export function compileRuleSet(rules = SECRET_RULES, globalAllowlists = GLOBAL_ALLOWLISTS) {
|
|
174
|
+
const hit = compiledCache.get(rules);
|
|
175
|
+
if (hit && hit.globalsSource === globalAllowlists) return hit;
|
|
176
|
+
const set = {
|
|
177
|
+
globalsSource: globalAllowlists,
|
|
178
|
+
globals: compileAllowlists(globalAllowlists),
|
|
179
|
+
rules: rules.map((rule) => ({
|
|
180
|
+
id: rule.id,
|
|
181
|
+
tierIndex: REDACT_TIERS.indexOf(rule.tier || DEFAULT_REDACT_TIER),
|
|
182
|
+
keywords: (rule.keywords || []).map((k) => String(k).toLowerCase()),
|
|
183
|
+
entropy: Number(rule.entropy) || 0,
|
|
184
|
+
secretGroup: Number(rule.secretGroup) || 0,
|
|
185
|
+
scan: new RegExp(rule.regex, `${rule.flags || ""}g`),
|
|
186
|
+
groups: new RegExp(rule.regex, `${rule.flags || ""}d`),
|
|
187
|
+
allowlists: compileAllowlists(rule.allowlists),
|
|
188
|
+
generic: rule.id.includes("generic"),
|
|
189
|
+
})),
|
|
190
|
+
};
|
|
191
|
+
compiledCache.set(rules, set);
|
|
192
|
+
return set;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Shannon entropy as gitleaks computes it: symbol frequencies over code
|
|
197
|
+
* points, divided by the UTF-8 byte length (Go's `len(string)`).
|
|
198
|
+
*/
|
|
199
|
+
export function shannonEntropy(data) {
|
|
200
|
+
if (!data) return 0;
|
|
201
|
+
const counts = new Map();
|
|
202
|
+
let bytes = 0;
|
|
203
|
+
for (const ch of data) {
|
|
204
|
+
counts.set(ch, (counts.get(ch) || 0) + 1);
|
|
205
|
+
const cp = ch.codePointAt(0);
|
|
206
|
+
bytes += cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4;
|
|
207
|
+
}
|
|
208
|
+
let entropy = 0;
|
|
209
|
+
for (const count of counts.values()) entropy -= (count / bytes) * Math.log2(count / bytes);
|
|
210
|
+
return entropy;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function isAllowed(allowlists, secret, match, line) {
|
|
214
|
+
const secretLower = secret.toLowerCase();
|
|
215
|
+
for (const al of allowlists) {
|
|
216
|
+
const target = al.target === "match" ? match : al.target === "line" ? line() : secret;
|
|
217
|
+
const checks = [];
|
|
218
|
+
if (al.regexes.length) checks.push(target !== "" && al.regexes.some((re) => re.test(target)));
|
|
219
|
+
if (al.stopwords.length) checks.push(al.stopwords.some((word) => secretLower.includes(word)));
|
|
220
|
+
if (al.and ? checks.every(Boolean) : checks.some(Boolean)) return true;
|
|
221
|
+
}
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* The secret spans gitleaks would report in `text`. The `gitleaks:allow`
|
|
227
|
+
* marker is deliberately not honoured: in a transcript it would be a way to
|
|
228
|
+
* opt a line out of redaction.
|
|
229
|
+
*/
|
|
230
|
+
function detect(text, rules, globals) {
|
|
231
|
+
const findings = [];
|
|
232
|
+
const lower = text.toLowerCase();
|
|
233
|
+
for (const rule of rules) {
|
|
234
|
+
if (rule.keywords.length && !rule.keywords.some((kw) => lower.includes(kw))) continue;
|
|
235
|
+
const re = rule.scan;
|
|
236
|
+
re.lastIndex = 0;
|
|
237
|
+
for (let m; (m = re.exec(text)) !== null;) {
|
|
238
|
+
if (m[0].length === 0) {
|
|
239
|
+
re.lastIndex++;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
// gitleaks trims newlines off the match and re-runs the regex on it.
|
|
243
|
+
let start = m.index;
|
|
244
|
+
let end = m.index + m[0].length;
|
|
245
|
+
while (start < end && text.charCodeAt(start) === 10) start++;
|
|
246
|
+
while (end > start && text.charCodeAt(end - 1) === 10) end--;
|
|
247
|
+
const match = text.slice(start, end);
|
|
248
|
+
let span = [0, match.length];
|
|
249
|
+
const sub = match ? rule.groups.exec(match) : null;
|
|
250
|
+
if (sub && sub.length >= 2) {
|
|
251
|
+
if (rule.secretGroup > 0) span = sub.indices[rule.secretGroup] || [0, 0];
|
|
252
|
+
else span = sub.indices.slice(1).find((idx) => idx && idx[1] > idx[0]) || span;
|
|
253
|
+
}
|
|
254
|
+
const secret = match.slice(span[0], span[1]);
|
|
255
|
+
if (!secret) continue;
|
|
256
|
+
if (rule.entropy && shannonEntropy(secret) <= rule.entropy) continue;
|
|
257
|
+
const line = () => {
|
|
258
|
+
const from = text.lastIndexOf("\n", start - 1) + 1;
|
|
259
|
+
const to = text.indexOf("\n", end);
|
|
260
|
+
return text.slice(from, to < 0 ? text.length : to);
|
|
261
|
+
};
|
|
262
|
+
if (isAllowed(globals, secret, match, line) || isAllowed(rule.allowlists, secret, match, line)) continue;
|
|
263
|
+
findings.push({ start: start + span[0], end: start + span[1], id: rule.id, secret, generic: rule.generic });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return findings;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
// Redaction
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Spans that are already placeholders and are never scanned: exactly the
|
|
275
|
+
* placeholders this module writes, and OpenViking privacy references in the
|
|
276
|
+
* grammar the server parses (openviking/privacy/reference.py). Anything else
|
|
277
|
+
* that merely starts with `{{ov_` is scanned like any other text.
|
|
278
|
+
*/
|
|
279
|
+
const PROTECTED_RE = new RegExp(
|
|
280
|
+
[
|
|
281
|
+
"\\{\\{ov_redacted:[a-z0-9][a-z0-9-]{0,99}:[0-9a-f]{8}\\}\\}",
|
|
282
|
+
"\\{\\{[ \\t]*ov_privacy:(?:" +
|
|
283
|
+
"ambiguous" +
|
|
284
|
+
"|skill:[A-Za-z0-9_.@-]{1,255}:[^\\s:{}]{1,255}" +
|
|
285
|
+
"|[^\\s:{}]{1,255}:viking://~/privacy/[^/\\s{}]{1,255}/[^#\\s{}]{1,1024}#/values/[^\\s{}]{1,1024}" +
|
|
286
|
+
")[ \\t]*\\}\\}",
|
|
287
|
+
].join("|"),
|
|
288
|
+
"g",
|
|
289
|
+
);
|
|
290
|
+
// One pass is not always a fixed point: a placeholder can give the text after
|
|
291
|
+
// it a word boundary it lacked (`ghp_<36>AKIA<16>`: aws-access-token needs
|
|
292
|
+
// `\bAKIA`, which only exists once the GitHub token is replaced). Passes repeat
|
|
293
|
+
// until nothing changes, so a replayed entry is sent byte for byte; a string
|
|
294
|
+
// with no finding costs one pass.
|
|
295
|
+
const MAX_PASSES = 3;
|
|
296
|
+
|
|
297
|
+
/** The [start, end) stretches of `text` outside existing placeholders. */
|
|
298
|
+
function scannableSegments(text) {
|
|
299
|
+
const segments = [];
|
|
300
|
+
let last = 0;
|
|
301
|
+
for (const m of text.matchAll(PROTECTED_RE)) {
|
|
302
|
+
if (m.index > last) segments.push([last, m.index]);
|
|
303
|
+
last = m.index + m[0].length;
|
|
304
|
+
}
|
|
305
|
+
if (last < text.length) segments.push([last, text.length]);
|
|
306
|
+
return segments;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Where scanning stops in a string with more than `max` scannable characters:
|
|
311
|
+
* the `max`-th one, pulled back to whitespace within 4 KiB so a token is not
|
|
312
|
+
* split with its head left in the scanned part. A `-----BEGIN` block whose
|
|
313
|
+
* `-----END ...-----` line lies past the cut cannot match the private-key rule,
|
|
314
|
+
* so the cut moves to the start of the BEGIN line instead.
|
|
315
|
+
*/
|
|
316
|
+
function cutPoint(text, segments, max) {
|
|
317
|
+
let budget = max;
|
|
318
|
+
for (const [a, b] of segments) {
|
|
319
|
+
if (b - a <= budget) {
|
|
320
|
+
budget -= b - a;
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const hard = a + budget;
|
|
324
|
+
const head = text.slice(a, hard).toLowerCase();
|
|
325
|
+
const begin = head.lastIndexOf("-----begin");
|
|
326
|
+
if (begin >= 0 && !/-----end[^\n]*-----/.test(head.slice(begin))) return a + head.lastIndexOf("\n", begin) + 1;
|
|
327
|
+
for (let k = hard; k > Math.max(a, hard - 4096); k--) if (/\s/.test(text[k - 1])) return k;
|
|
328
|
+
return hard;
|
|
329
|
+
}
|
|
330
|
+
return text.length;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Overlapping findings become one span, named by a provider rule over the generic one. */
|
|
334
|
+
function mergeFindings(findings) {
|
|
335
|
+
findings.sort((x, y) => x.start - y.start || y.end - x.end || Number(x.generic) - Number(y.generic));
|
|
336
|
+
const merged = [];
|
|
337
|
+
for (const f of findings) {
|
|
338
|
+
const last = merged[merged.length - 1];
|
|
339
|
+
if (last && f.start < last.end) {
|
|
340
|
+
last.end = Math.max(last.end, f.end);
|
|
341
|
+
if (last.rep.generic && !f.generic) last.rep = f;
|
|
342
|
+
} else {
|
|
343
|
+
merged.push({ start: f.start, end: f.end, rep: f });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return merged;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* One scan-and-replace pass over `full`; `base` is where the value starts
|
|
351
|
+
* after a key prefix, and `max` how many characters of the value to scan.
|
|
352
|
+
* Returns the redacted value and how many of its characters were scanned.
|
|
353
|
+
*/
|
|
354
|
+
function redactOnce(full, base, ctx, max) {
|
|
355
|
+
const segments = scannableSegments(full);
|
|
356
|
+
const scannable = segments.reduce((n, [a, b]) => n + (b - a), 0);
|
|
357
|
+
const limit = scannable > base + max ? Math.max(base, cutPoint(full, segments, base + max)) : full.length;
|
|
358
|
+
const findings = [];
|
|
359
|
+
for (const [a, b] of segments) {
|
|
360
|
+
if (Math.min(b, limit) <= a) continue;
|
|
361
|
+
for (const f of detect(full.slice(a, Math.min(b, limit)), ctx.rules, ctx.globals)) {
|
|
362
|
+
const start = Math.max(a + f.start, base);
|
|
363
|
+
if (a + f.end > start) findings.push({ ...f, start, end: a + f.end });
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
let out = "";
|
|
367
|
+
let pos = base;
|
|
368
|
+
for (const span of mergeFindings(findings)) {
|
|
369
|
+
out += full.slice(pos, span.start) + placeholder(span.rep.id, ctx.key(), span.rep.secret);
|
|
370
|
+
pos = span.end;
|
|
371
|
+
}
|
|
372
|
+
out += full.slice(pos, limit);
|
|
373
|
+
if (limit < full.length) out += placeholder("scan-oversize", ctx.key(), full.slice(limit));
|
|
374
|
+
return { text: out, scanned: Math.max(0, Math.min(scannable, base + max) - base) };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function makeContext(opts = {}) {
|
|
378
|
+
const tier = normalizeRedactTier(opts.tier ?? DEFAULT_REDACT_TIER);
|
|
379
|
+
let key = opts.key ? Buffer.from(opts.key) : null;
|
|
380
|
+
const ctx = {
|
|
381
|
+
tier,
|
|
382
|
+
rules: [],
|
|
383
|
+
globals: [],
|
|
384
|
+
maxChars: Number.isFinite(opts.maxChars) && opts.maxChars > 0 ? opts.maxChars : MAX_SCAN_CHARS,
|
|
385
|
+
// What is left of the call's scan budget; every string's first pass draws on it.
|
|
386
|
+
budget: Number.isFinite(opts.maxTotalChars) && opts.maxTotalChars > 0 ? opts.maxTotalChars : MAX_SCAN_TOTAL_CHARS,
|
|
387
|
+
key: () => (key ||= loadInstallKey(opts.env ? { env: opts.env } : undefined)),
|
|
388
|
+
};
|
|
389
|
+
if (tier === "off") return ctx;
|
|
390
|
+
try {
|
|
391
|
+
const set = compileRuleSet(opts.rules || SECRET_RULES, opts.globalAllowlists || GLOBAL_ALLOWLISTS);
|
|
392
|
+
const index = REDACT_TIERS.indexOf(tier);
|
|
393
|
+
ctx.rules = set.rules.filter((rule) => rule.tierIndex > 0 && rule.tierIndex <= index);
|
|
394
|
+
ctx.globals = set.globals;
|
|
395
|
+
} catch (error) {
|
|
396
|
+
ctx.broken = error;
|
|
397
|
+
}
|
|
398
|
+
return ctx;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function failClosed(text, ctx) {
|
|
402
|
+
try {
|
|
403
|
+
return placeholder("scan-failed", ctx.key(), text);
|
|
404
|
+
} catch {
|
|
405
|
+
return "{{ov_redacted:scan-failed:00000000}}";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function redactStringIn(text, ctx, keyName = null) {
|
|
410
|
+
if (typeof text !== "string" || text === "") return text;
|
|
411
|
+
if (ctx.broken) return failClosed(text, ctx);
|
|
412
|
+
const prefix = keyName ? `${keyName}=` : "";
|
|
413
|
+
// Fixed for every pass, so a later pass never cuts what the first one scanned.
|
|
414
|
+
const max = Math.min(ctx.maxChars, ctx.budget);
|
|
415
|
+
try {
|
|
416
|
+
let current = text;
|
|
417
|
+
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
418
|
+
const { text: next, scanned } = redactOnce(prefix + current, prefix.length, ctx, max);
|
|
419
|
+
if (pass === 0) ctx.budget -= scanned;
|
|
420
|
+
if (next === current) return current;
|
|
421
|
+
current = next;
|
|
422
|
+
}
|
|
423
|
+
// Still changing after several passes: not a state to send.
|
|
424
|
+
return failClosed(text, ctx);
|
|
425
|
+
} catch {
|
|
426
|
+
return failClosed(text, ctx);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Redact the secrets in one string.
|
|
432
|
+
*
|
|
433
|
+
* @param {string} text
|
|
434
|
+
* @param {object} [opts]
|
|
435
|
+
* @param {string} [opts.tier="standard"] - one of REDACT_TIERS; "off" returns the input
|
|
436
|
+
* @param {string} [opts.keyName] - a field name to scan the value under, as `keyName=value`
|
|
437
|
+
* @param {number} [opts.maxChars] - scannable characters of one string before the rest is cut
|
|
438
|
+
* @param {number} [opts.maxTotalChars] - the same, summed over every string in the call
|
|
439
|
+
* @returns {string}
|
|
440
|
+
*/
|
|
441
|
+
export function redactText(text, opts = {}) {
|
|
442
|
+
const ctx = makeContext(opts);
|
|
443
|
+
if (ctx.tier === "off") return text;
|
|
444
|
+
return redactStringIn(text, ctx, opts.keyName || null);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Message and part fields that identify or describe rather than carry text.
|
|
448
|
+
const META_KEYS = new Set([
|
|
449
|
+
"role", "type", "id", "uri", "peer_id", "session_id", "created_at", "tool_id", "tool_name", "tool_status",
|
|
450
|
+
"context_type", "tool_output_mime_type", "tool_output_externalized_reason",
|
|
451
|
+
]);
|
|
452
|
+
const META_SUFFIX_RE = /_(?:id|uri|ref|sha256|at)$/;
|
|
453
|
+
const KEY_CONTEXT_RE = /^[A-Za-z_][\w.-]{0,63}$/;
|
|
454
|
+
|
|
455
|
+
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Redact every string under `value`. Inside an object each value is scanned
|
|
459
|
+
* as `<key>=<value>`, so a rule that needs a key-ish word (generic-api-key)
|
|
460
|
+
* sees `{ "API_TOKEN": "..." }` as it would see `API_TOKEN=...` in a file;
|
|
461
|
+
* only the value is replaced. Keys are scanned as text of their own.
|
|
462
|
+
*/
|
|
463
|
+
function redactDeep(value, ctx, keyName) {
|
|
464
|
+
if (typeof value === "string") return redactStringIn(value, ctx, keyName);
|
|
465
|
+
if (Array.isArray(value)) return value.map((item) => redactDeep(item, ctx, keyName));
|
|
466
|
+
if (!isObject(value)) return value;
|
|
467
|
+
const out = {};
|
|
468
|
+
for (const [k, v] of Object.entries(value)) {
|
|
469
|
+
const key = redactStringIn(k, ctx, null);
|
|
470
|
+
out[key] = redactDeep(v, ctx, key === k && KEY_CONTEXT_RE.test(k) ? k : null);
|
|
471
|
+
}
|
|
472
|
+
return out;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** A message or part: its fields, metadata copied and the rest redacted. */
|
|
476
|
+
function redactFields(value, ctx) {
|
|
477
|
+
if (!isObject(value)) return redactDeep(value, ctx, null);
|
|
478
|
+
const out = {};
|
|
479
|
+
for (const [k, v] of Object.entries(value)) {
|
|
480
|
+
if (k === "parts" && Array.isArray(v)) out[k] = v.map((part) => redactFields(part, ctx));
|
|
481
|
+
else if (META_KEYS.has(k) || META_SUFFIX_RE.test(k)) out[k] = v;
|
|
482
|
+
else out[k] = redactDeep(v, ctx, null);
|
|
483
|
+
}
|
|
484
|
+
return out;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Redact one session add-message payload — `{ role, content }` or
|
|
489
|
+
* `{ role, parts: [...] }` — and return a redacted copy. Text-bearing fields
|
|
490
|
+
* are scanned (`content`, `parts[].text`, `parts[].tool_output`, every leaf of
|
|
491
|
+
* `parts[].tool_input`, `abstract`, any other non-metadata field); ids, URIs,
|
|
492
|
+
* roles, statuses and timestamps are copied. The caller's object is never
|
|
493
|
+
* mutated.
|
|
494
|
+
*/
|
|
495
|
+
export function redactPayload(payload, opts = {}) {
|
|
496
|
+
const ctx = makeContext(opts);
|
|
497
|
+
if (ctx.tier === "off") return payload;
|
|
498
|
+
return redactPayloadIn(payload, ctx);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function redactPayloadIn(payload, ctx) {
|
|
502
|
+
if (payload == null) return payload;
|
|
503
|
+
if (typeof payload === "string") return redactStringIn(payload, ctx, null);
|
|
504
|
+
if (typeof payload !== "object") return payload;
|
|
505
|
+
// Walk the data the payload is on the wire (class instances, `toJSON`), as a
|
|
506
|
+
// copy; a payload that cannot be serialised could not be sent either.
|
|
507
|
+
let data;
|
|
508
|
+
try {
|
|
509
|
+
data = JSON.parse(JSON.stringify(payload));
|
|
510
|
+
} catch {
|
|
511
|
+
return failClosed("", ctx);
|
|
512
|
+
}
|
|
513
|
+
return redactFields(data, ctx);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/** redactPayload over a list, with one scan budget (maxTotalChars) for the whole list. */
|
|
517
|
+
export function redactPayloads(payloads, opts = {}) {
|
|
518
|
+
if (!Array.isArray(payloads)) return payloads;
|
|
519
|
+
const ctx = makeContext(opts);
|
|
520
|
+
if (ctx.tier === "off") return payloads;
|
|
521
|
+
return payloads.map((payload) => redactPayloadIn(payload, ctx));
|
|
522
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
|
|
2
|
+
// GENERATED by examples/memory-plugin-shared/scripts/update-secret-rules.mjs. DO NOT EDIT.
|
|
3
|
+
//
|
|
4
|
+
// Secret detection rules for lib/redact.mjs: the gitleaks v8.30.1 default
|
|
5
|
+
// configuration (config/gitleaks.toml, https://github.com/gitleaks/gitleaks),
|
|
6
|
+
// converted from Go to JavaScript regex syntax and otherwise unchanged, plus
|
|
7
|
+
// the rules for OpenViking's own key formats.
|
|
8
|
+
// Source file sha256: e163e53b9e7e8a8511e77271e2b323ed057759542a6d988258afe3a1fa329caf
|
|
9
|
+
//
|
|
10
|
+
// Tier `strict`: generic-api-key. Every other rule is tier `standard`.
|
|
11
|
+
// Skipped gitleaks rules:
|
|
12
|
+
// cisco-meraki-api-key: nested [\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url
|
|
13
|
+
// cohere-api-token: nested [\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url
|
|
14
|
+
// curl-auth-header: time quadratic in line length: minutes for a 1 MB line of `curl ...;` commands
|
|
15
|
+
// curl-auth-user: time quadratic in line length: minutes for a 1 MB line of `curl ...;` commands
|
|
16
|
+
// freemius-secret-key: path-scoped rule; captured text has no file path
|
|
17
|
+
// hashicorp-tf-password: path-scoped rule; captured text has no file path
|
|
18
|
+
// kubernetes-secret-yaml: path-scoped rule; captured text has no file path
|
|
19
|
+
// nuget-config-password: path-scoped rule; captured text has no file path
|
|
20
|
+
// okta-access-token: nested [\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url
|
|
21
|
+
// pkcs12-file: path-scoped rule; captured text has no file path
|
|
22
|
+
// privateai-api-token: nested [\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url
|
|
23
|
+
// sumologic-access-id: nested [\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url
|
|
24
|
+
// OpenViking rules (not from gitleaks):
|
|
25
|
+
// openviking-gateway-key: ovgw_... issued by openviking_gateway/management.py
|
|
26
|
+
// openviking-gateway-management-key: ovgm_... issued by openviking_gateway/cli.py
|
|
27
|
+
// openviking-oauth-access-token: ovat_... issued by openviking/server/oauth/provider.py
|
|
28
|
+
// openviking-oauth-refresh-token: ovrt_... issued by openviking/server/oauth/provider.py
|
|
29
|
+
// openviking-oauth-auth-code: ovac_... issued by openviking/server/oauth/provider.py
|
|
30
|
+
//
|
|
31
|
+
// The gitleaks rule data is used under its license:
|
|
32
|
+
//
|
|
33
|
+
// MIT License
|
|
34
|
+
//
|
|
35
|
+
// Copyright (c) 2019 Zachary Rice
|
|
36
|
+
//
|
|
37
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
38
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
39
|
+
// in the Software without restriction, including without limitation the rights
|
|
40
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
41
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
42
|
+
// furnished to do so, subject to the following conditions:
|
|
43
|
+
//
|
|
44
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
45
|
+
// copies or substantial portions of the Software.
|
|
46
|
+
//
|
|
47
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
48
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
49
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
50
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
51
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
52
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
53
|
+
// SOFTWARE.
|
|
54
|
+
|
|
55
|
+
export const GITLEAKS_VERSION = "v8.30.1";
|
|
56
|
+
|
|
57
|
+
export const TIERS = ["off","standard","strict"];
|
|
58
|
+
|
|
59
|
+
export const SKIPPED_RULES = [
|
|
60
|
+
{"id":"cisco-meraki-api-key","reason":"nested [\\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url"},
|
|
61
|
+
{"id":"cohere-api-token","reason":"nested [\\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url"},
|
|
62
|
+
{"id":"curl-auth-header","reason":"time quadratic in line length: minutes for a 1 MB line of `curl ...;` commands"},
|
|
63
|
+
{"id":"curl-auth-user","reason":"time quadratic in line length: minutes for a 1 MB line of `curl ...;` commands"},
|
|
64
|
+
{"id":"freemius-secret-key","reason":"path-scoped rule; captured text has no file path"},
|
|
65
|
+
{"id":"hashicorp-tf-password","reason":"path-scoped rule; captured text has no file path"},
|
|
66
|
+
{"id":"kubernetes-secret-yaml","reason":"path-scoped rule; captured text has no file path"},
|
|
67
|
+
{"id":"nuget-config-password","reason":"path-scoped rule; captured text has no file path"},
|
|
68
|
+
{"id":"okta-access-token","reason":"nested [\\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url"},
|
|
69
|
+
{"id":"pkcs12-file","reason":"path-scoped rule; captured text has no file path"},
|
|
70
|
+
{"id":"privateai-api-token","reason":"nested [\\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url"},
|
|
71
|
+
{"id":"sumologic-access-id","reason":"nested [\\w.-]{0,50}? prefixes: ~3-11 s per MB of hashes or base64url"},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export const GLOBAL_ALLOWLISTS = [
|
|
75
|
+
{"condition":"OR","regexTarget":"secret","regexes":[{"regex":"^true|false|null$","flags":"i"},{"regex":"^(?:[aA]+|[bB]+|[cC]+|[dD]+|[eE]+|[fF]+|[gG]+|[hH]+|[iI]+|[jJ]+|[kK]+|[lL]+|[mM]+|[nN]+|[oO]+|[pP]+|[qQ]+|[rR]+|[sS]+|[tT]+|[uU]+|[vV]+|[wW]+|[xX]+|[yY]+|[zZ]+|\\*+|\\.+)$","flags":""},{"regex":"^\\$(?:\\d+|{\\d+})$","flags":""},{"regex":"^\\$(?:[A-Z_]+|[a-z_]+)$","flags":""},{"regex":"^\\${(?:[A-Z_]+|[a-z_]+)}$","flags":""},{"regex":"^\\{\\{[ \\t]*[\\w ().|]+[ \\t]*}}$","flags":""},{"regex":"^\\$\\{\\{[ \\t]*(?:(?:env|github|secrets|vars)(?:\\.[A-Za-z]\\w+)+[\\w \"'&./=|]*)[ \\t]*}}$","flags":""},{"regex":"^%(?:[A-Z_]+|[a-z_]+)%$","flags":""},{"regex":"^%[+\\-# 0]?[bcdeEfFgGoOpqstTUvxX]$","flags":""},{"regex":"^\\{\\d{0,2}}$","flags":""},{"regex":"^@(?:[A-Z_]+|[a-z_]+)@$","flags":""},{"regex":"^/Users/[a-z0-9A-Z]+/[\\w .-/]+$","flags":""},{"regex":"^/(?:bin|etc|home|opt|tmp|usr|var)/[\\w ./\\-]+$","flags":""}],"stopwords":["014df517-39d1-4453-b7b3-9930c563627c","abcdefghijklmnopqrstuvwxyz"]},
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
export default [
|
|
79
|
+
{"id":"1password-secret-key","regex":"\\bA3-[A-Z0-9]{6}-(?:(?:[A-Z0-9]{11})|(?:[A-Z0-9]{6}-[A-Z0-9]{5}))-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}\\b","flags":"","keywords":["a3-"],"entropy":3.8,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
80
|
+
{"id":"1password-service-account-token","regex":"ops_eyJ[a-zA-Z0-9+/]{250,}={0,3}","flags":"","keywords":["ops_"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
81
|
+
{"id":"adafruit-api-key","regex":"[\\w.\\-]{0,50}?(?:adafruit)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9_\\-]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["adafruit"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
82
|
+
{"id":"adobe-client-id","regex":"[\\w.\\-]{0,50}?(?:adobe)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["adobe"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
83
|
+
{"id":"adobe-client-secret","regex":"\\b(p8e-[a-z0-9A-Z]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["p8e-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
84
|
+
{"id":"age-secret-key","regex":"AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}","flags":"","keywords":["age-secret-key-1"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
85
|
+
{"id":"airtable-api-key","regex":"[\\w.\\-]{0,50}?(?:airtable)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{17})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["airtable"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
86
|
+
{"id":"airtable-personnal-access-token","regex":"\\b(pat[0-9A-Za-z]{14}\\.[a-f0-9]{64})\\b","flags":"","keywords":["airtable"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
87
|
+
{"id":"algolia-api-key","regex":"[\\w.\\-]{0,50}?(?:algolia)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["algolia"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
88
|
+
{"id":"alibaba-access-key-id","regex":"\\b(LTAI[a-z0-9A-Z]{20})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["ltai"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
89
|
+
{"id":"alibaba-secret-key","regex":"[\\w.\\-]{0,50}?(?:alibaba)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{30})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["alibaba"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
90
|
+
{"id":"anthropic-admin-api-key","regex":"\\b(sk-ant-admin01-[a-zA-Z0-9_\\-]{93}AA)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sk-ant-admin01"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
91
|
+
{"id":"anthropic-api-key","regex":"\\b(sk-ant-api03-[a-zA-Z0-9_\\-]{93}AA)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sk-ant-api03"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
92
|
+
{"id":"artifactory-api-key","regex":"\\bAKCp[A-Za-z0-9]{69}\\b","flags":"","keywords":["akcp"],"entropy":4.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
93
|
+
{"id":"artifactory-reference-token","regex":"\\bcmVmd[A-Za-z0-9]{59}\\b","flags":"","keywords":["cmvmd"],"entropy":4.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
94
|
+
{"id":"asana-client-id","regex":"[\\w.\\-]{0,50}?(?:asana)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["asana"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
95
|
+
{"id":"asana-client-secret","regex":"[\\w.\\-]{0,50}?(?:asana)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["asana"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
96
|
+
{"id":"atlassian-api-token","regex":"[\\w.\\-]{0,50}?(?:(?:ATLASSIAN|[Aa]tlassian)|(?:CONFLUENCE|[Cc]onfluence)|(?:JIRA|[Jj]ira))(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9A-Z]{20}[a-f0-9A-F]{4})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)|\\b([Aa][Tt][Aa][Tt][Tt]3[A-Za-z0-9_\\-=a-zA-Z]{186})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)","flags":"","keywords":["atlassian","confluence","jira","atatt3"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
97
|
+
{"id":"authress-service-client-access-key","regex":"\\b((?:sc|ext|scauth|authress)_[a-z0-9A-Z]{5,30}\\.[a-z0-9A-Z]{4,6}\\.(?:acc)[_\\-][a-z0-9\\-A-Z]{10,32}\\.[a-z0-9+/_=\\-A-Z]{30,120})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sc_","ext_","scauth_","authress_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
98
|
+
{"id":"aws-access-token","regex":"\\b((?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z2-7]{16})\\b","flags":"","keywords":["a3t","akia","asia","abia","acca"],"entropy":3,"secretGroup":0,"allowlists":[{"condition":"OR","regexTarget":"secret","regexes":[{"regex":"[^\\n]+EXAMPLE$","flags":""}],"stopwords":[]}],"tier":"standard"},
|
|
99
|
+
{"id":"aws-amazon-bedrock-api-key-long-lived","regex":"\\b(ABSK[A-Za-z0-9+/]{109,269}={0,2})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["absk"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
100
|
+
{"id":"aws-amazon-bedrock-api-key-short-lived","regex":"bedrock-api-key-YmVkcm9jay5hbWF6b25hd3MuY29t","flags":"","keywords":["bedrock-api-key-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
101
|
+
{"id":"azure-ad-client-secret","regex":"(?:^|[\\\\'\"\\x60\\s>=:(,)])([a-zA-Z0-9_~.]{3}\\dQ~[a-zA-Z0-9_~.\\-]{31,34})(?:$|[\\\\'\"\\x60\\s<),])","flags":"","keywords":["q~"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
102
|
+
{"id":"beamer-api-token","regex":"[\\w.\\-]{0,50}?(?:beamer)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(b_[a-z0-9=_\\-]{44})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["beamer"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
103
|
+
{"id":"bitbucket-client-id","regex":"[\\w.\\-]{0,50}?(?:bitbucket)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["bitbucket"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
104
|
+
{"id":"bitbucket-client-secret","regex":"[\\w.\\-]{0,50}?(?:bitbucket)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["bitbucket"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
105
|
+
{"id":"bittrex-access-key","regex":"[\\w.\\-]{0,50}?(?:bittrex)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["bittrex"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
106
|
+
{"id":"bittrex-secret-key","regex":"[\\w.\\-]{0,50}?(?:bittrex)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["bittrex"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
107
|
+
{"id":"clickhouse-cloud-api-secret-key","regex":"\\b(4b1d[A-Za-z0-9]{38})\\b","flags":"","keywords":["4b1d"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
108
|
+
{"id":"clojars-api-token","regex":"CLOJARS_[a-z0-9]{60}","flags":"i","keywords":["clojars_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
109
|
+
{"id":"cloudflare-api-key","regex":"[\\w.\\-]{0,50}?(?:cloudflare)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9_\\-]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["cloudflare"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
110
|
+
{"id":"cloudflare-global-api-key","regex":"[\\w.\\-]{0,50}?(?:cloudflare)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{37})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["cloudflare"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
111
|
+
{"id":"cloudflare-origin-ca-key","regex":"\\b(v1\\.0-[a-f0-9]{24}-[a-f0-9]{146})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["cloudflare","v1.0-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
112
|
+
{"id":"codecov-access-token","regex":"[\\w.\\-]{0,50}?(?:codecov)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["codecov"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
113
|
+
{"id":"coinbase-access-token","regex":"[\\w.\\-]{0,50}?(?:coinbase)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9_\\-]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["coinbase"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
114
|
+
{"id":"confluent-access-token","regex":"[\\w.\\-]{0,50}?(?:confluent)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["confluent"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
115
|
+
{"id":"confluent-secret-key","regex":"[\\w.\\-]{0,50}?(?:confluent)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["confluent"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
116
|
+
{"id":"contentful-delivery-api-token","regex":"[\\w.\\-]{0,50}?(?:contentful)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{43})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["contentful"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
117
|
+
{"id":"databricks-api-token","regex":"\\b(dapi[a-f0-9]{32}(?:-\\d)?)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["dapi"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
118
|
+
{"id":"datadog-access-token","regex":"[\\w.\\-]{0,50}?(?:datadog)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["datadog"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
119
|
+
{"id":"defined-networking-api-token","regex":"[\\w.\\-]{0,50}?(?:dnkey)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(dnkey-[a-z0-9=_\\-]{26}-[a-z0-9=_\\-]{52})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["dnkey"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
120
|
+
{"id":"digitalocean-access-token","regex":"\\b(doo_v1_[a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["doo_v1_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
121
|
+
{"id":"digitalocean-pat","regex":"\\b(dop_v1_[a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["dop_v1_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
122
|
+
{"id":"digitalocean-refresh-token","regex":"\\b(dor_v1_[a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["dor_v1_"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
123
|
+
{"id":"discord-api-token","regex":"[\\w.\\-]{0,50}?(?:discord)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["discord"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
124
|
+
{"id":"discord-client-id","regex":"[\\w.\\-]{0,50}?(?:discord)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9]{18})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["discord"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
125
|
+
{"id":"discord-client-secret","regex":"[\\w.\\-]{0,50}?(?:discord)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["discord"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
126
|
+
{"id":"doppler-api-token","regex":"dp\\.pt\\.[a-z0-9A-Z]{43}","flags":"","keywords":["dp.pt."],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
127
|
+
{"id":"droneci-access-token","regex":"[\\w.\\-]{0,50}?(?:droneci)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["droneci"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
128
|
+
{"id":"dropbox-api-token","regex":"[\\w.\\-]{0,50}?(?:dropbox)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{15})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["dropbox"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
129
|
+
{"id":"dropbox-long-lived-api-token","regex":"[\\w.\\-]{0,50}?(?:dropbox)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\\-_=]{43})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["dropbox"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
130
|
+
{"id":"dropbox-short-lived-api-token","regex":"[\\w.\\-]{0,50}?(?:dropbox)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(sl\\.[a-z0-9\\-=_]{135})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["dropbox"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
131
|
+
{"id":"duffel-api-token","regex":"duffel_(?:test|live)_[a-z0-9_\\-=A-Z]{43}","flags":"","keywords":["duffel_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
132
|
+
{"id":"dynatrace-api-token","regex":"dt0c01\\.[a-z0-9A-Z]{24}\\.[a-z0-9A-Z]{64}","flags":"","keywords":["dt0c01."],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
133
|
+
{"id":"easypost-api-token","regex":"\\bEZAK[a-z0-9A-Z]{54}\\b","flags":"","keywords":["ezak"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
134
|
+
{"id":"easypost-test-api-token","regex":"\\bEZTK[a-z0-9A-Z]{54}\\b","flags":"","keywords":["eztk"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
135
|
+
{"id":"etsy-access-token","regex":"[\\w.\\-]{0,50}?(?:(?:ETSY|[Ee]tsy))(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9A-Z]{24})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)","flags":"","keywords":["etsy"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
136
|
+
{"id":"facebook-access-token","regex":"\\b(\\d{15,16}(\\||%)[0-9a-z\\-_]{27,40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["facebook"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
137
|
+
{"id":"facebook-page-access-token","regex":"\\b(EAA[MC][a-z0-9A-Z]{100,})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["eaam","eaac"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
138
|
+
{"id":"facebook-secret","regex":"[\\w.\\-]{0,50}?(?:facebook)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["facebook"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
139
|
+
{"id":"fastly-api-token","regex":"[\\w.\\-]{0,50}?(?:fastly)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["fastly"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
140
|
+
{"id":"finicity-api-token","regex":"[\\w.\\-]{0,50}?(?:finicity)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["finicity"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
141
|
+
{"id":"finicity-client-secret","regex":"[\\w.\\-]{0,50}?(?:finicity)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{20})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["finicity"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
142
|
+
{"id":"finnhub-access-token","regex":"[\\w.\\-]{0,50}?(?:finnhub)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{20})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["finnhub"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
143
|
+
{"id":"flickr-access-token","regex":"[\\w.\\-]{0,50}?(?:flickr)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["flickr"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
144
|
+
{"id":"flutterwave-encryption-key","regex":"FLWSECK_TEST-[a-h0-9A-H]{12}","flags":"","keywords":["flwseck_test"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
145
|
+
{"id":"flutterwave-public-key","regex":"FLWPUBK_TEST-[a-h0-9A-H]{32}-[Xx]","flags":"","keywords":["flwpubk_test"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
146
|
+
{"id":"flutterwave-secret-key","regex":"FLWSECK_TEST-[a-h0-9A-H]{32}-[Xx]","flags":"","keywords":["flwseck_test"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
147
|
+
{"id":"flyio-access-token","regex":"\\b((?:fo1_[\\w\\-]{43}|fm1[ar]_[a-zA-Z0-9+\\/]{100,}={0,3}|fm2_[a-zA-Z0-9+\\/]{100,}={0,3}))(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["fo1_","fm1","fm2_"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
148
|
+
{"id":"frameio-api-token","regex":"fio-u-[a-z0-9\\-_=A-Z]{64}","flags":"","keywords":["fio-u-"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
149
|
+
{"id":"freshbooks-access-token","regex":"[\\w.\\-]{0,50}?(?:freshbooks)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["freshbooks"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
150
|
+
{"id":"gcp-api-key","regex":"\\b(AIza[\\w\\-]{35})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["aiza"],"entropy":4,"secretGroup":0,"allowlists":[{"condition":"OR","regexTarget":"secret","regexes":[{"regex":"AIzaSyabcdefghijklmnopqrstuvwxyz1234567","flags":""},{"regex":"AIzaSyAnLA7NfeLquW1tJFpx_eQCxoX-oo6YyIs","flags":""},{"regex":"AIzaSyCkEhVjf3pduRDt6d1yKOMitrUEke8agEM","flags":""},{"regex":"AIzaSyDMAScliyLx7F0NPDEJi1QmyCgHIAODrlU","flags":""},{"regex":"AIzaSyD3asb-2pEZVqMkmL6M9N6nHZRR_znhrh0","flags":""},{"regex":"AIzayDNSXIbFmlXbIE6mCzDLQAqITYefhixbX4A","flags":""},{"regex":"AIzaSyAdOS2zB6NCsk1pCdZ4-P6GBdi_UUPwX7c","flags":""},{"regex":"AIzaSyASWm6HmTMdYWpgMnjRBjxcQ9CKctWmLd4","flags":""},{"regex":"AIzaSyANUvH9H9BsUccjsu2pCmEkOPjjaXeDQgY","flags":""},{"regex":"AIzaSyA5_iVawFQ8ABuTZNUdcwERLJv_a_p4wtM","flags":""},{"regex":"AIzaSyA4UrcGxgwQFTfaI3no3t7Lt1sjmdnP5sQ","flags":""},{"regex":"AIzaSyDSb51JiIcB6OJpwwMicseKRhhrOq1cS7g","flags":""},{"regex":"AIzaSyBF2RrAIm4a0mO64EShQfqfd2AFnzAvvuU","flags":""},{"regex":"AIzaSyBcE-OOIbhjyR83gm4r2MFCu4MJmprNXsw","flags":""},{"regex":"AIzaSyB8qGxt4ec15vitgn44duC5ucxaOi4FmqE","flags":""},{"regex":"AIzaSyA8vmApnrHNFE0bApF4hoZ11srVL_n0nvY","flags":""}],"stopwords":[]}],"tier":"standard"},
|
|
151
|
+
{"id":"generic-api-key","regex":"[\\w.\\-]{0,50}?(?:[aA][cC][cC][eE][sS][sS]|[aA][uU][tT][hH]|(?:[Aa]pi|API)|[cC][rR][eE][dD][eE][nN][tT][iI][aA][lL]|[cC][rR][eE][dD][sS]|[kK][eE][yY]|[pP][aA][sS][sS][wW](?:[oO][rR])?[dD]|[sS][eE][cC][rR][eE][tT]|[tT][oO][kK][eE][nN])(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([\\w.=\\-]{10,150}|[a-z0-9A-Z][a-z0-9+/A-Z]{11,}={0,3})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)","flags":"","keywords":["access","api","auth","key","credential","creds","passwd","password","secret","token"],"entropy":3.5,"secretGroup":0,"allowlists":[{"condition":"OR","regexTarget":"secret","regexes":[{"regex":"^[a-zA-Z_.\\-]+$","flags":""}],"stopwords":[]},{"condition":"OR","regexTarget":"match","regexes":[{"regex":"(?:[aA][cC][cC][eE][sS][sS](?:[iI][bB][iI][lL][iI][tT][yY]|[oO][rR])|[aA][cC][cC][eE][sS][sS][_.\\-]?[iI][dD]|[rR][aA][nN][dD][oO][mM][_.\\-]?[aA][cC][cC][eE][sS][sS]|[aA][pP][iI][_.\\-]?(?:[iI][dD]|[nN][aA][mM][eE]|[vV][eE][rR][sS][iI][oO][nN])|[rR][aA][pP][iI][dD]|[cC][aA][pP][iI][tT][aA][lL]|[a-z0-9\\-A-Z]*?[aA][pP][iI][a-z0-9\\-A-Z]*?:[jJ][aA][rR]:|[aA][uU][tT][hH][oO][rR]|[Xx]-[Mm][Ss]-[Ee][xX][cC][hH][aA][nN][gG][eE]-[Oo][rR][gG][aA][nN][iI][zZ][aA][tT][iI][oO][nN]-[Aa][uU][tT][hH]|[Aa][uU][tT][hH][eE][nN][tT][iI][cC][aA][tT][iI][oO][nN]-[Rr][eE][sS][uU][lL][tT][sS]|(?:[cC][rR][eE][dD][eE][nN][tT][iI][aA][lL][sS]?[_.\\-]?[iI][dD]|[wW][iI][tT][hH][Cc][rR][eE][dD][eE][nN][tT][iI][aA][lL][sS])|(?:[bB][uU][cC][kK][eE][tT]|[fF][oO][rR][eE][iI][gG][nN]|[hH][oO][tT]|[iI][dD][xX]|[nN][aA][tT][uU][rR][aA][lL]|[pP][rR][iI][mM][aA][rR][yY]|[pP][uU][bB](?:[lL][iI][cC])?|[sS][cC][hH][eE][mM][aA]|[sS][eE][qQ][uU][eE][nN][cC][eE])[_.\\-]?[kK][eE][yY]|(?:[tT][uU][rR][kK][eE][yY])|[kK][eE][yY][_.\\-]?(?:[aA][lL][iI][aA][sS]|[bB][oO][aA][rR][dD]|[cC][oO][dD][eE]|[fF][rR][aA][mM][eE]|[iI][dD]|[lL][eE][nN][gG][tT][hH]|[mM][eE][sS][hH]|[nN][aA][mM][eE]|[pP][aA][iI][rR]|[pP][rR][eE][sS][sS](?:[eE][dD])?|[rR][iI][nN][gG]|[sS][eE][lL][eE][cC][tT][oO][rR]|[sS][iI][gG][nN][aA][tT][uU][rR][eE]|[sS][iI][zZ][eE]|[sS][tT][oO][nN][eE]|[sS][tT][oO][rR][eE][tT][yY][pP][eE]|[wW][oO][rR][dD]|[uU][pP]|[dD][oO][wW][nN]|[lL][eE][fF][tT]|[rR][iI][gG][hH][tT])|[kK][eE][yY][_.\\-]?[vV][aA][uU][lL][tT][_.\\-]?(?:[iI][dD]|[nN][aA][mM][eE])|[kK][eE][yY][Vv][aA][uU][lL][tT][Tt][oO][Ss][tT][oO][rR][eE][Ss][eE][cC][rR][eE][tT][sS]|[kK][eE][yY](?:[sS][tT][oO][rR][eE]|[tT][aA][bB])[_.\\-]?(?:[fF][iI][lL][eE]|[pP][aA][tT][hH])|[iI][sS][sS][uU][eE][rR][kK][eE][yY][hH][aA][sS][hH]|(?:[DdMm]onkey|[DM]ONKEY)|[kK][eE][yY][iI][nN][gG]|(?:[sS][eE][cC][rR][eE][tT])[_.\\-]?(?:[lL][eE][nN][gG][tT][hH]|[nN][aA][mM][eE]|[sS][iI][zZ][eE])|[Uu][sS][eE][rR][Ss][eE][cC][rR][eE][tT][sS][Ii][dD]|(?:[cC][sS][rR][fF])[_.\\-]?[tT][oO][kK][eE][nN]|(?:[iI][oO]\\.[jJ][sS][oO][nN][wW][eE][bB][tT][oO][kK][eE][nN][ \\t]?:[ \\t]?[\\w\\-]+)|(?:[aA][pP][iI]|[cC][rR][eE][dD][eE][nN][tT][iI][aA][lL][sS]|[tT][oO][kK][eE][nN])[_.\\-]?(?:[eE][nN][dD][pP][oO][iI][nN][tT]|[uU][rR][ilIL])|[pP][uU][bB][lL][iI][cC][_.\\-]?[tT][oO][kK][eE][nN]|(?:[kK][eE][yY]|[tT][oO][kK][eE][nN])[_.\\-]?[fF][iI][lL][eE]|(?:(?:[A-Z_]+=\\n[A-Z_]+=|[a-z_]+=\\n[a-z_]+=)(?:\\n|$))|(?:(?:[A-Z.]+=\\n[A-Z.]+=|[a-z.]+=\\n[a-z.]+=)(?:\\n|$)))","flags":""}],"stopwords":["000000","6fe4476ee5a1832882e326b506d14126","_ec2_","aaaaaa","about","abstract","academy","acces","account","act-","act.","act_","action","active","actively","activity","adapter","add-","add-on","add.","add_","addon","addres","admin","adobe","advanced","adventure","agent","agile","air-","air.","air_","ajax","akka","alert","alfred","algorithm","all-","all.","all_","alloy","alpha","amazon","amqp","analysi","analytic","analyzer","android","angular","angularj","animate","animation","another","ansible","answer","ant-","ant.","ant_","any-","any.","any_","apache","app-","app.","app_","apple","arch","archive","archived","arduino","array","art-","art.","art_","article","asp-","asp.","asp_","asset","async","atom","attention","audio","audit","aura","auth","author","authorize","auto","automated","automatic","awesome","aws_","azure","back","backbone","backend","backup","bar-","bar.","bar_","base","based","bash","basic","batch","been","beer","behavior","being","benchmark","best","beta","better","big-","big.","big_","binary","binding","bit-","bit.","bit_","bitcoin","block","blog","board","book","bookmark","boost","boot","bootstrap","bosh","bot-","bot.","bot_","bower","box-","box.","box_","boxen","bracket","branch","bridge","browser","brunch","buffer","bug-","bug.","bug_","build","builder","building","buildout","buildpack","built","bundle","busines","but-","but.","but_","button","cache","caching","cakephp","calendar","call","camera","campfire","can-","can.","can_","canva","captcha","capture","card","carousel","case","cassandra","cat-","cat.","cat_","category","center","cento","challenge","change","changelog","channel","chart","chat","cheat","check","checker","chef","ches","chinese","chosen","chrome","ckeditor","clas","classe","classic","clean","cli-","cli.","cli_","client","clojure","clone","closure","cloud","club","cluster","cms-","cms_","coco","code","coding","coffee","color","combination","combo","command","commander","comment","commit","common","community","compas","compiler","complete","component","composer","computer","computing","con-","con.","con_","concept","conf","config","connect","connector","console","contact","container","contao","content","contest","context","control","convert","converter","conway'","cookbook","cookie","cool","copy","cordova","core","couchbase","couchdb","countdown","counter","course","craft","crawler","create","creating","creator","credential","crm-","crm.","crm_","cros","crud","csv-","csv.","csv_","cube","cucumber","cuda","current","currently","custom","daemon","dark","dart","dash","dashboard","data","database","date","day-","day.","day_","dead","debian","debug","debugger","deck","define","del-","del.","del_","delete","demo","deploy","design","designer","desktop","detection","detector","dev-","dev.","dev_","develop","developer","device","devise","diff","digital","directive","directory","discovery","display","django","dns-","dns_","doc-","doc.","doc_","docker","docpad","doctrine","document","doe-","doe.","doe_","dojo","dom-","dom.","dom_","domain","don't","done","dot-","dot.","dot_","dotfile","download","draft","drag","drill","drive","driven","driver","drop","dropbox","drupal","dsl-","dsl.","dsl_","dynamic","easy","ecdsa","eclipse","edit","editing","edition","editor","element","emac","email","embed","embedded","ember","emitter","emulator","encoding","endpoint","engine","english","enhanced","entity","entry","env_","episode","erlang","error","espresso","event","evented","example","exchange","exercise","experiment","expire","exploit","explorer","export","exporter","expres","ext-","ext.","ext_","extended","extension","external","extra","extractor","fabric","facebook","factory","fake","fast","feature","feed","fewfwef","ffmpeg","field","file","filter","find","finder","firefox","firmware","first","fish","fix-","fix_","flash","flask","flat","flex","flexible","flickr","flow","fluent","fluentd","fluid","folder","font","force","foreman","fork","form","format","formatter","forum","foundry","framework","free","friend","friendly","front-end","frontend","ftp-","ftp.","ftp_","fuel","full","fun-","fun.","fun_","func","future","gaia","gallery","game","gateway","gem-","gem.","gem_","gen-","gen.","gen_","general","generator","generic","genetic","get-","get.","get_","getenv","getting","ghost","gist","git-","git.","git_","github","gitignore","gitlab","glas","gmail","gnome","gnu-","gnu.","gnu_","goal","golang","gollum","good","google","gpu-","gpu.","gpu_","gradle","grail","graph","graphic","great","grid","groovy","group","grunt","guard","gui-","gui.","gui_","guide","guideline","gulp","gwt-","gwt.","gwt_","hack","hackathon","hacker","hacking","hadoop","haml","handler","hardware","has-","has_","hash","haskell","have","haxe","hello","help","helper","here","hero","heroku","high","hipchat","history","home","homebrew","homepage","hook","host","hosting","hot-","hot.","hot_","house","how-","how.","how_","html","http","hub-","hub.","hub_","hubot","human","icon","ide-","ide.","ide_","idea","identity","idiomatic","image","impact","import","important","importer","impres","index","infinite","info","injection","inline","input","inside","inspector","instagram","install","installer","instant","intellij","interface","internet","interview","into","intro","ionic","iphone","ipython","irc-","irc_","iso-","iso.","iso_","issue","jade","jasmine","java","jbos","jekyll","jenkin","jetbrains","job-","job.","job_","joomla","jpa-","jpa.","jpa_","jquery","json","just","kafka","karma","kata","kernel","keyboard","kindle","kit-","kit.","kit_","kitchen","knife","koan","kohana","lab-","lab.","lab_","lambda","lamp","language","laravel","last","latest","latex","launcher","layer","layout","lazy","ldap","leaflet","league","learn","learning","led-","led.","led_","leetcode","les-","les.","les_","level","leveldb","lib-","lib.","lib_","librarie","library","license","life","liferay","light","lightbox","like","line","link","linked","linkedin","linux","lisp","list","lite","little","load","loader","local","location","lock","log-","log.","log_","logger","logging","logic","login","logstash","longer","look","love","lua-","lua.","lua_","mac-","mac.","mac_","machine","made","magento","magic","mail","make","maker","making","man-","man.","man_","manage","manager","manifest","manual","map-","map.","map_","mapper","mapping","markdown","markup","master","math","matrix","maven","md5","mean","media","mediawiki","meetup","memcached","memory","menu","merchant","message","messaging","meta","metadata","meteor","method","metric","micro","middleman","migration","minecraft","miner","mini","minimal","mirror","mit-","mit.","mit_","mobile","mocha","mock","mod-","mod.","mod_","mode","model","modern","modular","module","modx","money","mongo","mongodb","mongoid","mongoose","monitor","monkey","more","motion","moved","movie","mozilla","mqtt","mule","multi","multiple","music","mustache","mvc-","mvc.","mvc_","mysql","nagio","name","native","need","neo-","neo.","neo_","nest","nested","net-","net.","net_","nette","network","new-","new.","new_","next","nginx","ninja","nlp-","nlp.","nlp_","node","nodej","nosql","not-","not.","not_","note","notebook","notepad","notice","notifier","now-","now.","now_","number","oauth","object","objective","obsolete","ocaml","octopres","official","old-","old.","old_","onboard","online","only","open","opencv","opengl","openshift","openwrt","option","oracle","org-","org.","org_","origin","original","orm-","orm.","orm_","osx-","osx_","our-","our.","our_","out-","out.","out_","output","over","overview","own-","own.","own_","pack","package","packet","page","panel","paper","paperclip","para","parallax","parallel","parse","parser","parsing","particle","party","password","patch","path","pattern","payment","paypal","pdf-","pdf.","pdf_","pebble","people","perl","personal","phalcon","phoenix","phone","phonegap","photo","php-","php.","php_","physic","picker","pipeline","platform","play","player","please","plu-","plu.","plu_","plug-in","plugin","plupload","png-","png.","png_","poker","polyfill","polymer","pool","pop-","pop.","pop_","popcorn","popup","port","portable","portal","portfolio","post","power","powered","powerful","prelude","pretty","preview","principle","print","pro-","pro.","pro_","problem","proc","product","profile","profiler","program","progres","project","protocol","prototype","provider","proxy","public","pull","puppet","pure","purpose","push","pusher","pyramid","python","quality","query","queue","quick","rabbitmq","rack","radio","rail","railscast","random","range","raspberry","rdf-","rdf.","rdf_","react","reactive","read","reader","readme","ready","real","real-time","reality","realtime","recipe","recorder","red-","red.","red_","reddit","redi","redmine","reference","refinery","refresh","registry","related","release","remote","rendering","repo","report","request","require","required","requirej","research","resource","response","resque","rest","restful","resume","reveal","reverse","review","riak","rich","right","ring","robot","role","room","router","routing","rpc-","rpc.","rpc_","rpg-","rpg.","rpg_","rspec","ruby-","ruby.","ruby_","rule","run-","run.","run_","runner","running","runtime","rust","rvm-","rvm.","rvm_","salt","sample","sandbox","sas-","sas.","sas_","sbt-","sbt.","sbt_","scala","scalable","scanner","schema","scheme","school","science","scraper","scratch","screen","script","scroll","scs-","scs.","scs_","sdk-","sdk.","sdk_","sdl-","sdl.","sdl_","search","secure","security","see-","see.","see_","seed","select","selector","selenium","semantic","sencha","send","sentiment","serie","server","service","session","set-","set.","set_","setting","setup","sha1","sha2","sha256","share","shared","sharing","sheet","shell","shield","shipping","shop","shopify","shortener","should","show","showcase","side","silex","simple","simulator","single","site","skeleton","sketch","skin","slack","slide","slider","slim","small","smart","smtp","snake","snapshot","snippet","soap","social","socket","software","solarized","solr","solution","solver","some","soon","source","space","spark","spatial","spec","sphinx","spine","spotify","spree","spring","sprite","sql-","sql.","sql_","sqlite","ssh-","ssh.","ssh_","stack","staging","standard","stanford","start","started","starter","startup","stat","statamic","state","static","statistic","statsd","statu","steam","step","still","stm-","stm.","stm_","storage","store","storm","story","strategy","stream","streaming","string","stripe","structure","studio","study","stuff","style","sublime","sugar","suite","summary","super","support","supported","svg-","svg.","svg_","svn-","svn.","svn_","swagger","swift","switch","switcher","symfony","symphony","sync","synopsi","syntax","system","tab-","tab.","tab_","table","tag-","tag.","tag_","talk","target","task","tcp-","tcp.","tcp_","tdd-","tdd.","tdd_","team","tech","template","term","terminal","testing","tetri","text","textmate","theme","theory","three","thrift","time","timeline","timer","tiny","tinymce","tip-","tip.","tip_","title","todo","todomvc","token","tool","toolbox","toolkit","top-","top.","top_","tornado","touch","tower","tracker","tracking","traffic","training","transfer","translate","transport","tree","trello","try-","try.","try_","tumblr","tut-","tut.","tut_","tutorial","tweet","twig","twitter","type","typo","ubuntu","uiview","ultimate","under","unit","unity","universal","unix","update","updated","upgrade","upload","uploader","uri-","uri.","uri_","url-","url.","url_","usage","usb-","usb.","usb_","use-","use.","use_","used","useful","user","using","util","utilitie","utility","vagrant","validator","value","variou","varnish","version","via-","via.","via_","video","view","viewer","vim-","vim.","vim_","vimrc","virtual","vision","visual","vpn","want","warning","watch","watcher","wave","way-","way.","way_","weather","web-","web_","webapp","webgl","webhook","webkit","webrtc","website","websocket","welcome","what","what'","when","where","which","why-","why.","why_","widget","wifi","wiki","win-","win.","win_","window","wip-","wip.","wip_","within","without","wizard","word","wordpres","work","worker","workflow","working","workshop","world","wrapper","write","writer","writing","written","www-","www.","www_","xamarin","xcode","xml-","xml.","xml_","xmpp","xxxxxx","yahoo","yaml","yandex","yeoman","yet-","yet.","yet_","yii-","yii.","yii_","youtube","yui-","yui.","yui_","zend","zero","zip-","zip.","zip_","zsh-","zsh.","zsh_"]},{"condition":"OR","regexTarget":"line","regexes":[{"regex":"--mount=type=secret,","flags":""},{"regex":"import[ \\t]+{[ \\t\\w,]+}[ \\t]+from[ \\t]+['\"][^'\"]+['\"]","flags":""}],"stopwords":[]}],"tier":"strict"},
|
|
152
|
+
{"id":"github-app-token","regex":"(?:ghu|ghs)_[0-9a-zA-Z]{36}","flags":"","keywords":["ghu_","ghs_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
153
|
+
{"id":"github-fine-grained-pat","regex":"github_pat_\\w{82}","flags":"","keywords":["github_pat_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
154
|
+
{"id":"github-oauth","regex":"gho_[0-9a-zA-Z]{36}","flags":"","keywords":["gho_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
155
|
+
{"id":"github-pat","regex":"ghp_[0-9a-zA-Z]{36}","flags":"","keywords":["ghp_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
156
|
+
{"id":"github-refresh-token","regex":"ghr_[0-9a-zA-Z]{36}","flags":"","keywords":["ghr_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
157
|
+
{"id":"gitlab-cicd-job-token","regex":"glcbt-[0-9a-zA-Z]{1,5}_[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["glcbt-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
158
|
+
{"id":"gitlab-deploy-token","regex":"gldt-[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["gldt-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
159
|
+
{"id":"gitlab-feature-flag-client-token","regex":"glffct-[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["glffct-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
160
|
+
{"id":"gitlab-feed-token","regex":"glft-[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["glft-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
161
|
+
{"id":"gitlab-incoming-mail-token","regex":"glimt-[0-9a-zA-Z_\\-]{25}","flags":"","keywords":["glimt-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
162
|
+
{"id":"gitlab-kubernetes-agent-token","regex":"glagent-[0-9a-zA-Z_\\-]{50}","flags":"","keywords":["glagent-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
163
|
+
{"id":"gitlab-oauth-app-secret","regex":"gloas-[0-9a-zA-Z_\\-]{64}","flags":"","keywords":["gloas-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
164
|
+
{"id":"gitlab-pat","regex":"glpat-[\\w\\-]{20}","flags":"","keywords":["glpat-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
165
|
+
{"id":"gitlab-pat-routable","regex":"\\bglpat-[0-9a-zA-Z_\\-]{27,300}\\.[0-9a-z]{2}[0-9a-z]{7}\\b","flags":"","keywords":["glpat-"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
166
|
+
{"id":"gitlab-ptt","regex":"glptt-[0-9a-f]{40}","flags":"","keywords":["glptt-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
167
|
+
{"id":"gitlab-rrt","regex":"GR1348941[\\w\\-]{20}","flags":"","keywords":["gr1348941"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
168
|
+
{"id":"gitlab-runner-authentication-token","regex":"glrt-[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["glrt-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
169
|
+
{"id":"gitlab-runner-authentication-token-routable","regex":"\\bglrt-t\\d_[0-9a-zA-Z_\\-]{27,300}\\.[0-9a-z]{2}[0-9a-z]{7}\\b","flags":"","keywords":["glrt-"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
170
|
+
{"id":"gitlab-scim-token","regex":"glsoat-[0-9a-zA-Z_\\-]{20}","flags":"","keywords":["glsoat-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
171
|
+
{"id":"gitlab-session-cookie","regex":"_gitlab_session=[0-9a-z]{32}","flags":"","keywords":["_gitlab_session="],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
172
|
+
{"id":"gitter-access-token","regex":"[\\w.\\-]{0,50}?(?:gitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9_\\-]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["gitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
173
|
+
{"id":"gocardless-api-token","regex":"[\\w.\\-]{0,50}?(?:gocardless)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(live_[a-z0-9\\-_=A-Z]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["live_","gocardless"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
174
|
+
{"id":"grafana-api-key","regex":"\\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,3})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["eyjrijoi"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
175
|
+
{"id":"grafana-cloud-api-token","regex":"\\b(glc_[A-Za-z0-9+/]{32,400}={0,3})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["glc_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
176
|
+
{"id":"grafana-service-account-token","regex":"\\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["glsa_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
177
|
+
{"id":"harness-api-key","regex":"(?:pat|sat)\\.[a-zA-Z0-9_\\-]{22}\\.[a-zA-Z0-9]{24}\\.[a-zA-Z0-9]{20}","flags":"","keywords":["pat.","sat."],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
178
|
+
{"id":"hashicorp-tf-api-token","regex":"[a-z0-9A-Z]{14}\\.(?:atlasv1)\\.[a-z0-9\\-_=A-Z]{60,70}","flags":"","keywords":["atlasv1"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
179
|
+
{"id":"heroku-api-key","regex":"[\\w.\\-]{0,50}?(?:heroku)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["heroku"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
180
|
+
{"id":"heroku-api-key-v2","regex":"\\b((HRKU-AA[0-9a-zA-Z_\\-]{58}))(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["hrku-aa"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
181
|
+
{"id":"hubspot-api-key","regex":"[\\w.\\-]{0,50}?(?:hubspot)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["hubspot"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
182
|
+
{"id":"huggingface-access-token","regex":"\\b(hf_(?:[a-zA-Z]{34}))(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["hf_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
183
|
+
{"id":"huggingface-organization-api-token","regex":"\\b(api_org_(?:[a-zA-Z]{34}))(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["api_org_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
184
|
+
{"id":"infracost-api-token","regex":"\\b(ico-[a-zA-Z0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["ico-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
185
|
+
{"id":"intercom-api-key","regex":"[\\w.\\-]{0,50}?(?:intercom)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{60})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["intercom"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
186
|
+
{"id":"intra42-client-secret","regex":"\\b(s-s4t2(?:ud|af)-[abcdef0123456789ABCDEF]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["intra","s-s4t2ud-","s-s4t2af-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
187
|
+
{"id":"jfrog-api-key","regex":"[\\w.\\-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{73})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["jfrog","artifactory","bintray","xray"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
188
|
+
{"id":"jfrog-identity-token","regex":"[\\w.\\-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["jfrog","artifactory","bintray","xray"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
189
|
+
{"id":"jwt","regex":"\\b(ey[a-zA-Z0-9]{17,}\\.ey[a-zA-Z0-9\\/\\\\_\\-]{17,}\\.(?:[a-zA-Z0-9\\/\\\\_\\-]{10,}={0,2})?)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["ey"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
190
|
+
{"id":"jwt-base64","regex":"\\bZXlK(?:(?<alg>aGJHY2lPaU)|(?<apu>aGNIVWlPaU)|(?<apv>aGNIWWlPaU)|(?<aud>aGRXUWlPaU)|(?<b64>aU5qUWlP)|(?<crit>amNtbDBJanBi)|(?<cty>amRIa2lPaU)|(?<epk>bGNHc2lPbn)|(?<enc>bGJtTWlPaU)|(?<jku>cWEzVWlPaU)|(?<jwk>cWQyc2lPb)|(?<iss>cGMzTWlPaU)|(?<iv>cGRpSTZJ)|(?<kid>cmFXUWlP)|(?<key_ops>clpYbGZiM0J6SWpwY)|(?<kty>cmRIa2lPaUp)|(?<nonce>dWIyNWpaU0k2)|(?<p2c>d01tTWlP)|(?<p2s>d01uTWlPaU)|(?<ppt>d2NIUWlPaU)|(?<sub>emRXSWlPaU)|(?<svt>emRuUWlP)|(?<tag>MFlXY2lPaU)|(?<typ>MGVYQWlPaUp)|(?<url>MWNtd2l)|(?<use>MWMyVWlPaUp)|(?<ver>MlpYSWlPaU)|(?<version>MlpYSnphVzl1SWpv)|(?<x>NElqb2)|(?<x5c>NE5XTWlP)|(?<x5t>NE5YUWlPaU)|(?<x5ts256>NE5YUWpVekkxTmlJNkl)|(?<x5u>NE5YVWlPaU)|(?<zip>NmFYQWlPaU))[a-zA-Z0-9\\/\\\\_+\\-\\r\\n]{40,}={0,2}","flags":"","keywords":["zxlk"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
191
|
+
{"id":"kraken-access-token","regex":"[\\w.\\-]{0,50}?(?:kraken)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9\\/=_\\+\\-]{80,90})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["kraken"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
192
|
+
{"id":"kucoin-access-token","regex":"[\\w.\\-]{0,50}?(?:kucoin)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{24})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["kucoin"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
193
|
+
{"id":"kucoin-secret-key","regex":"[\\w.\\-]{0,50}?(?:kucoin)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["kucoin"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
194
|
+
{"id":"launchdarkly-access-token","regex":"[\\w.\\-]{0,50}?(?:launchdarkly)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["launchdarkly"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
195
|
+
{"id":"linear-api-key","regex":"lin_api_[a-z0-9A-Z]{40}","flags":"","keywords":["lin_api_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
196
|
+
{"id":"linear-client-secret","regex":"[\\w.\\-]{0,50}?(?:linear)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["linear"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
197
|
+
{"id":"linkedin-client-id","regex":"[\\w.\\-]{0,50}?(?:linked[_\\-]?in)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{14})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["linkedin","linked_in","linked-in"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
198
|
+
{"id":"linkedin-client-secret","regex":"[\\w.\\-]{0,50}?(?:linked[_\\-]?in)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["linkedin","linked_in","linked-in"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
199
|
+
{"id":"lob-api-key","regex":"[\\w.\\-]{0,50}?(?:lob)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}((live|test)_[a-f0-9]{35})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["test_","live_"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
200
|
+
{"id":"lob-pub-api-key","regex":"[\\w.\\-]{0,50}?(?:lob)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}((test|live)_pub_[a-f0-9]{31})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["test_pub","live_pub","_pub"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
201
|
+
{"id":"looker-client-id","regex":"[\\w.\\-]{0,50}?(?:looker)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{20})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["looker"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
202
|
+
{"id":"looker-client-secret","regex":"[\\w.\\-]{0,50}?(?:looker)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{24})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["looker"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
203
|
+
{"id":"mailchimp-api-key","regex":"[\\w.\\-]{0,50}?(?:MailchimpSDK[^\\n]initialize|mailchimp)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{32}-us\\d\\d)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mailchimp"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
204
|
+
{"id":"mailgun-private-api-token","regex":"[\\w.\\-]{0,50}?(?:mailgun)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(key-[a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mailgun"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
205
|
+
{"id":"mailgun-pub-key","regex":"[\\w.\\-]{0,50}?(?:mailgun)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(pubkey-[a-f0-9]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mailgun"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
206
|
+
{"id":"mailgun-signing-key","regex":"[\\w.\\-]{0,50}?(?:mailgun)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mailgun"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
207
|
+
{"id":"mapbox-api-token","regex":"[\\w.\\-]{0,50}?(?:mapbox)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(pk\\.[a-z0-9]{60}\\.[a-z0-9]{22})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mapbox"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
208
|
+
{"id":"mattermost-access-token","regex":"[\\w.\\-]{0,50}?(?:mattermost)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{26})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["mattermost"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
209
|
+
{"id":"maxmind-license-key","regex":"\\b([A-Za-z0-9]{6}_[A-Za-z0-9]{29}_mmk)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["_mmk"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
210
|
+
{"id":"messagebird-api-token","regex":"[\\w.\\-]{0,50}?(?:message[_\\-]?bird)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{25})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["messagebird","message-bird","message_bird"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
211
|
+
{"id":"messagebird-client-id","regex":"[\\w.\\-]{0,50}?(?:message[_\\-]?bird)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["messagebird","message-bird","message_bird"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
212
|
+
{"id":"microsoft-teams-webhook","regex":"https://[a-z0-9]+\\.webhook\\.office\\.com/webhookb2/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}/IncomingWebhook/[a-z0-9]{32}/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}","flags":"","keywords":["webhook.office.com","webhookb2","incomingwebhook"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
213
|
+
{"id":"netlify-access-token","regex":"[\\w.\\-]{0,50}?(?:netlify)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{40,46})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["netlify"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
214
|
+
{"id":"new-relic-browser-api-token","regex":"[\\w.\\-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(NRJS-[a-f0-9]{19})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["nrjs-"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
215
|
+
{"id":"new-relic-insert-key","regex":"[\\w.\\-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(NRII-[a-z0-9\\-]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["nrii-"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
216
|
+
{"id":"new-relic-user-api-id","regex":"[\\w.\\-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["new-relic","newrelic","new_relic"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
217
|
+
{"id":"new-relic-user-api-key","regex":"[\\w.\\-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(NRAK-[a-z0-9]{27})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["nrak"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
218
|
+
{"id":"notion-api-token","regex":"\\b(ntn_[0-9]{11}[A-Za-z0-9]{32}[A-Za-z0-9]{3})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["ntn_"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
219
|
+
{"id":"npm-access-token","regex":"\\b(npm_[a-z0-9]{36})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["npm_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
220
|
+
{"id":"nytimes-access-token","regex":"[\\w.\\-]{0,50}?(?:nytimes|new-york-times,|newyorktimes)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9=_\\-]{32})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["nytimes","new-york-times","newyorktimes"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
221
|
+
{"id":"octopus-deploy-api-key","regex":"\\b(API-[A-Z0-9]{26})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["api-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
222
|
+
{"id":"openai-api-key","regex":"\\b(sk-(?:proj|svcacct|admin)-(?:[A-Za-z0-9_\\-]{74}|[A-Za-z0-9_\\-]{58})T3BlbkFJ(?:[A-Za-z0-9_\\-]{74}|[A-Za-z0-9_\\-]{58})\\b|sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["t3blbkfj"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
223
|
+
{"id":"openshift-user-token","regex":"\\b(sha256~[\\w\\-]{43})(?:[^\\w\\-]|$)","flags":"","keywords":["sha256~"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
224
|
+
{"id":"perplexity-api-key","regex":"\\b(pplx-[a-zA-Z0-9]{48})(?:[\\x60'\"\\s;]|\\\\[nr]|$|\\b)","flags":"","keywords":["pplx-"],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
225
|
+
{"id":"plaid-api-token","regex":"[\\w.\\-]{0,50}?(?:plaid)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["plaid"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
226
|
+
{"id":"plaid-client-id","regex":"[\\w.\\-]{0,50}?(?:plaid)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{24})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["plaid"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
227
|
+
{"id":"plaid-secret-key","regex":"[\\w.\\-]{0,50}?(?:plaid)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{30})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["plaid"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
228
|
+
{"id":"planetscale-api-token","regex":"\\b(pscale_tkn_[\\w=\\.\\-]{32,64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["pscale_tkn_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
229
|
+
{"id":"planetscale-oauth-token","regex":"\\b(pscale_oauth_[\\w=\\.\\-]{32,64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["pscale_oauth_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
230
|
+
{"id":"planetscale-password","regex":"\\b(pscale_pw_[\\w=\\.\\-]{32,64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["pscale_pw_"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
231
|
+
{"id":"postman-api-token","regex":"\\b(PMAK-[a-f0-9A-F]{24}\\-[a-f0-9A-F]{34})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["pmak-"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
232
|
+
{"id":"prefect-api-token","regex":"\\b(pnu_[a-zA-Z0-9]{36})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["pnu_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
233
|
+
{"id":"private-key","regex":"-----BEGIN[ A-Z0-9_\\-]{0,100}PRIVATE KEY(?: BLOCK)?-----[\\s\\S\\-]{64,}?KEY(?: BLOCK)?-----","flags":"i","keywords":["-----begin"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
234
|
+
{"id":"pulumi-api-token","regex":"\\b(pul-[a-f0-9]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["pul-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
235
|
+
{"id":"pypi-upload-token","regex":"pypi-AgEIcHlwaS5vcmc[\\w\\-]{50,1000}","flags":"","keywords":["pypi-ageichlwas5vcmc"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
236
|
+
{"id":"rapidapi-access-token","regex":"[\\w.\\-]{0,50}?(?:rapidapi)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9_\\-]{50})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["rapidapi"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
237
|
+
{"id":"readme-api-token","regex":"\\b(rdme_[a-z0-9]{70})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["rdme_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
238
|
+
{"id":"rubygems-api-token","regex":"\\b(rubygems_[a-f0-9]{48})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["rubygems_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
239
|
+
{"id":"scalingo-api-token","regex":"\\b(tk-us-[\\w\\-]{48})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["tk-us-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
240
|
+
{"id":"sendbird-access-id","regex":"[\\w.\\-]{0,50}?(?:sendbird)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["sendbird"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
241
|
+
{"id":"sendbird-access-token","regex":"[\\w.\\-]{0,50}?(?:sendbird)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["sendbird"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
242
|
+
{"id":"sendgrid-api-token","regex":"\\b(SG\\.[a-z0-9=_\\-\\.A-Z]{66})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sg."],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
243
|
+
{"id":"sendinblue-api-token","regex":"\\b(xkeysib-[a-f0-9]{64}\\-[a-z0-9A-Z]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["xkeysib-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
244
|
+
{"id":"sentry-access-token","regex":"[\\w.\\-]{0,50}?(?:sentry)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["sentry"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
245
|
+
{"id":"sentry-org-token","regex":"\\bsntrys_eyJpYXQiO[a-zA-Z0-9+/]{10,200}(?:LCJyZWdpb25fdXJs|InJlZ2lvbl91cmwi|cmVnaW9uX3VybCI6)[a-zA-Z0-9+/]{10,200}={0,2}_[a-zA-Z0-9+/]{43}(?:[^a-zA-Z0-9+/]|$)","flags":"","keywords":["sntrys_eyjpyxqio"],"entropy":4.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
246
|
+
{"id":"sentry-user-token","regex":"\\b(sntryu_[a-f0-9]{64})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sntryu_"],"entropy":3.5,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
247
|
+
{"id":"settlemint-application-access-token","regex":"\\b(sm_aat_[a-zA-Z0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sm_aat"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
248
|
+
{"id":"settlemint-personal-access-token","regex":"\\b(sm_pat_[a-zA-Z0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sm_pat"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
249
|
+
{"id":"settlemint-service-access-token","regex":"\\b(sm_sat_[a-zA-Z0-9]{16})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sm_sat"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
250
|
+
{"id":"shippo-api-token","regex":"\\b(shippo_(?:live|test)_[a-fA-F0-9]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["shippo_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
251
|
+
{"id":"shopify-access-token","regex":"shpat_[a-fA-F0-9]{32}","flags":"","keywords":["shpat_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
252
|
+
{"id":"shopify-custom-access-token","regex":"shpca_[a-fA-F0-9]{32}","flags":"","keywords":["shpca_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
253
|
+
{"id":"shopify-private-app-access-token","regex":"shppa_[a-fA-F0-9]{32}","flags":"","keywords":["shppa_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
254
|
+
{"id":"shopify-shared-secret","regex":"shpss_[a-fA-F0-9]{32}","flags":"","keywords":["shpss_"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
255
|
+
{"id":"sidekiq-secret","regex":"[\\w.\\-]{0,50}?(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["bundle_enterprise__contribsys__com","bundle_gems__contribsys__com"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
256
|
+
{"id":"sidekiq-sensitive-url","regex":"\\bhttps?://([a-f0-9]{8}:[a-f0-9]{8})@(?:gems[^\\n]contribsys[^\\n]com|enterprise[^\\n]contribsys[^\\n]com)(?:[\\/|\\#|\\?|:]|$)","flags":"i","keywords":["gems.contribsys.com","enterprise.contribsys.com"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
257
|
+
{"id":"slack-app-token","regex":"xapp-\\d-[A-Z0-9]+-\\d+-[a-z0-9]+","flags":"i","keywords":["xapp"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
258
|
+
{"id":"slack-bot-token","regex":"xoxb-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9\\-]*","flags":"","keywords":["xoxb"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
259
|
+
{"id":"slack-config-access-token","regex":"xoxe[^\\n]xox[bp]-\\d-[A-Z0-9]{163,166}","flags":"i","keywords":["xoxe.xoxb-","xoxe.xoxp-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
260
|
+
{"id":"slack-config-refresh-token","regex":"xoxe-\\d-[A-Z0-9]{146}","flags":"i","keywords":["xoxe-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
261
|
+
{"id":"slack-legacy-bot-token","regex":"xoxb-[0-9]{8,14}-[a-zA-Z0-9]{18,26}","flags":"","keywords":["xoxb"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
262
|
+
{"id":"slack-legacy-token","regex":"xox[os]-\\d+-\\d+-\\d+-[a-fA-F\\d]+","flags":"","keywords":["xoxo","xoxs"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
263
|
+
{"id":"slack-legacy-workspace-token","regex":"xox[ar]-(?:\\d-)?[0-9a-zA-Z]{8,48}","flags":"","keywords":["xoxa","xoxr"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
264
|
+
{"id":"slack-user-token","regex":"xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9\\-]{28,34}","flags":"","keywords":["xoxp-","xoxe-"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
265
|
+
{"id":"slack-webhook-url","regex":"(?:https?://)?hooks[^\\n]slack[^\\n]com/(?:services|workflows|triggers)/[A-Za-z0-9+/]{43,56}","flags":"","keywords":["hooks.slack.com"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
266
|
+
{"id":"snyk-api-token","regex":"[\\w.\\-]{0,50}?(?:snyk[_.\\-]?(?:(?:api|oauth)[_.\\-]?)?(?:key|token))(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["snyk"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
267
|
+
{"id":"sonar-api-token","regex":"[\\w.\\-]{0,50}?(?:sonar[_.\\-]?(login|token))(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}((?:squ_|sqp_|sqa_)?[a-z0-9=_\\-]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["sonar"],"entropy":0,"secretGroup":2,"allowlists":[],"tier":"standard"},
|
|
268
|
+
{"id":"sourcegraph-access-token","regex":"\\b(\\b(sgp_(?:[a-fA-F0-9]{16}|local)_[a-fA-F0-9]{40}|sgp_[a-fA-F0-9]{40}|[a-fA-F0-9]{40})\\b)(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["sgp_","sourcegraph"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
269
|
+
{"id":"square-access-token","regex":"\\b((?:EAAA|sq0atp-)[\\w\\-]{22,60})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sq0atp-","eaaa"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
270
|
+
{"id":"squarespace-access-token","regex":"[\\w.\\-]{0,50}?(?:squarespace)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["squarespace"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
271
|
+
{"id":"stripe-access-token","regex":"\\b((?:sk|rk)_(?:test|live|prod)_[a-zA-Z0-9]{10,99})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["sk_test","sk_live","sk_prod","rk_test","rk_live","rk_prod"],"entropy":2,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
272
|
+
{"id":"sumologic-access-token","regex":"[\\w.\\-]{0,50}?(?:(?:[Ss]umo|SUMO))(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9A-Z]{64})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)","flags":"","keywords":["sumo"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
273
|
+
{"id":"telegram-bot-api-token","regex":"[\\w.\\-]{0,50}?(?:[tT][eE][lL][eE][gG][rR])(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9]{5,16}:(?:A)[a-z0-9_\\-A-Z]{34})(?:[\\x60'\"\\s;]|\\\\[nrNR]|$)","flags":"","keywords":["telegr"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
274
|
+
{"id":"travisci-access-token","regex":"[\\w.\\-]{0,50}?(?:travis)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{22})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["travis"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
275
|
+
{"id":"twilio-api-key","regex":"SK[0-9a-fA-F]{32}","flags":"","keywords":["sk"],"entropy":3,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
276
|
+
{"id":"twitch-api-token","regex":"[\\w.\\-]{0,50}?(?:twitch)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{30})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitch"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
277
|
+
{"id":"twitter-access-secret","regex":"[\\w.\\-]{0,50}?(?:twitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{45})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
278
|
+
{"id":"twitter-access-token","regex":"[\\w.\\-]{0,50}?(?:twitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
279
|
+
{"id":"twitter-api-key","regex":"[\\w.\\-]{0,50}?(?:twitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{25})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
280
|
+
{"id":"twitter-api-secret","regex":"[\\w.\\-]{0,50}?(?:twitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{50})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
281
|
+
{"id":"twitter-bearer-token","regex":"[\\w.\\-]{0,50}?(?:twitter)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["twitter"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
282
|
+
{"id":"typeform-api-token","regex":"[\\w.\\-]{0,50}?(?:typeform)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(tfp_[a-z0-9\\-_\\.=]{59})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["tfp_"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
283
|
+
{"id":"vault-batch-token","regex":"\\b(hvb\\.[\\w\\-]{138,300})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["hvb."],"entropy":4,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
284
|
+
{"id":"vault-service-token","regex":"\\b((?:hvs\\.[\\w\\-]{90,120}|s\\.(?:[a-z0-9A-Z]{24})))(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"","keywords":["hvs.","s."],"entropy":3.5,"secretGroup":0,"allowlists":[{"condition":"OR","regexTarget":"secret","regexes":[{"regex":"s\\.[A-Za-z]{24}","flags":""}],"stopwords":[]}],"tier":"standard"},
|
|
285
|
+
{"id":"yandex-access-token","regex":"[\\w.\\-]{0,50}?(?:yandex)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(t1\\.[A-Z0-9a-z_\\-]+[=]{0,2}\\.[A-Z0-9a-z_\\-]{86}[=]{0,2})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["yandex"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
286
|
+
{"id":"yandex-api-key","regex":"[\\w.\\-]{0,50}?(?:yandex)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(AQVN[A-Za-z0-9_\\-]{35,38})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["yandex"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
287
|
+
{"id":"yandex-aws-access-token","regex":"[\\w.\\-]{0,50}?(?:yandex)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}(YC[a-zA-Z0-9_\\-]{38})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["yandex"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
288
|
+
{"id":"zendesk-secret-key","regex":"[\\w.\\-]{0,50}?(?:zendesk)(?:[ \\t\\w.\\-]{0,20})[\\s'\"]{0,3}(?:=|>|:{1,3}=|\\|\\||:|=>|\\?=|,)[\\x60'\"\\s=]{0,5}([a-z0-9]{40})(?:[\\x60'\"\\s;]|\\\\[nr]|$)","flags":"i","keywords":["zendesk"],"entropy":0,"secretGroup":0,"allowlists":[],"tier":"standard"},
|
|
289
|
+
{"id":"openviking-gateway-key","regex":"(?<![A-Za-z0-9_-])(ovgw_[A-Za-z0-9_-]{43})(?![A-Za-z0-9_-])","flags":"","keywords":["ovgw_"],"entropy":3,"secretGroup":1,"allowlists":[],"tier":"standard"},
|
|
290
|
+
{"id":"openviking-gateway-management-key","regex":"(?<![A-Za-z0-9_-])(ovgm_[A-Za-z0-9_-]{43})(?![A-Za-z0-9_-])","flags":"","keywords":["ovgm_"],"entropy":3,"secretGroup":1,"allowlists":[],"tier":"standard"},
|
|
291
|
+
{"id":"openviking-oauth-access-token","regex":"(?<![A-Za-z0-9_-])(ovat_[A-Za-z0-9_-]{54})(?![A-Za-z0-9_-])","flags":"","keywords":["ovat_"],"entropy":3,"secretGroup":1,"allowlists":[],"tier":"standard"},
|
|
292
|
+
{"id":"openviking-oauth-refresh-token","regex":"(?<![A-Za-z0-9_-])(ovrt_[A-Za-z0-9_-]{54})(?![A-Za-z0-9_-])","flags":"","keywords":["ovrt_"],"entropy":3,"secretGroup":1,"allowlists":[],"tier":"standard"},
|
|
293
|
+
{"id":"openviking-oauth-auth-code","regex":"(?<![A-Za-z0-9_-])(ovac_[A-Za-z0-9_-]{54})(?![A-Za-z0-9_-])","flags":"","keywords":["ovac_"],"entropy":3,"secretGroup":1,"allowlists":[],"tier":"standard"},
|
|
294
|
+
];
|