@tokenoftrust/storefront-runner 2.0.24 → 2.0.26
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/apps/storefront/src/lib/integration/bakedManagedInstalls.ts +56 -0
- package/apps/storefront/src/lib/integration/managedInstallDeclarations.ts +11 -3
- package/apps/storefront/src/lib/integration/stageDestinationIds.ts +103 -0
- package/apps/storefront/src/middleware/renderChain.ts +15 -1
- package/package.json +1 -1
- package/packages/public-runtime/schemas/managed-analytics/v1/adapter-definition.schema.json +2 -1
- package/packages/public-runtime/schemas/managed-analytics/v1/create-integration-install-request.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/create-migration-draft-request.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/integration-revision.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/migration-draft.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/revise-integration-install-request.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/update-migration-draft-request.schema.json +79 -0
- package/packages/public-runtime/src/customization-preview.ts +30 -18
- package/packages/public-runtime/src/gtm-migration/draft-generator.ts +5 -2
- package/packages/public-runtime/src/integration/baked-managed-installs.ts +188 -0
- package/packages/public-runtime/src/integration/index.ts +1 -0
- package/packages/public-runtime/src/integration/managed-analytics-api-v1.schemas.ts +18 -1
- package/packages/public-runtime/src/integration/managed-analytics-api-v1.ts +48 -3
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a tenant's BAKED managed installs off the materialize-only signed header.
|
|
3
|
+
*
|
|
4
|
+
* This is the read half of the wire documented in
|
|
5
|
+
* `packages/public-runtime/src/integration/baked-managed-installs.ts`. It exists because
|
|
6
|
+
* ADR 0013 gives a public page no per-request access to admin-installed state — the
|
|
7
|
+
* static bake has no D1 binding at all — so an active install can only reach a published
|
|
8
|
+
* bundle by being resolved and signed once, by the Worker, at go-live.
|
|
9
|
+
*
|
|
10
|
+
* Fail-safe at every step: not in materialize mode, no header, no secret, a signature
|
|
11
|
+
* that does not verify, or a payload that does not parse all yield an EMPTY list, and the
|
|
12
|
+
* render then resolves the environment-only plan exactly as it would for a tenant with no
|
|
13
|
+
* integrations. Nothing here can widen what a public request may inject, because gate one
|
|
14
|
+
* is a binding the deployed Worker never has.
|
|
15
|
+
*/
|
|
16
|
+
import {
|
|
17
|
+
MANAGED_INSTALLS_INPUT_HEADER,
|
|
18
|
+
MANAGED_INSTALLS_SIG_HEADER,
|
|
19
|
+
parseManagedInstalls,
|
|
20
|
+
verifyManagedInstallsSig,
|
|
21
|
+
MATERIALIZE_MODE_BINDING,
|
|
22
|
+
CONSENT_SNAPSHOT_HMAC_SECRET_BINDING,
|
|
23
|
+
type IntegrationDeclarationInput,
|
|
24
|
+
} from "@tot/public-runtime";
|
|
25
|
+
|
|
26
|
+
/** Reads a runtime binding; injected so this is testable without a Worker env. */
|
|
27
|
+
export type ReadEnv = (key: string) => Promise<string | undefined>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The signed, materialize-only managed installs for `tenantPublicId`, or `[]`.
|
|
31
|
+
*
|
|
32
|
+
* The signature is TENANT-BOUND, so a payload signed for one tenant cannot be replayed
|
|
33
|
+
* into another tenant's bundle even by something that legitimately holds a signed header
|
|
34
|
+
* — which matters because one publish job builds one tenant at a time from a shared
|
|
35
|
+
* pipeline.
|
|
36
|
+
*/
|
|
37
|
+
export async function readBakedManagedInstalls(
|
|
38
|
+
request: Request,
|
|
39
|
+
tenantPublicId: string,
|
|
40
|
+
readEnv: ReadEnv,
|
|
41
|
+
): Promise<IntegrationDeclarationInput[]> {
|
|
42
|
+
// Gate 1: the materialize-mode binding. The deployed Worker never declares it, so this
|
|
43
|
+
// header is unreadable on any public request and can never enter a cache key.
|
|
44
|
+
if ((await readEnv(MATERIALIZE_MODE_BINDING)) !== "1") return [];
|
|
45
|
+
|
|
46
|
+
const payload = request.headers.get(MANAGED_INSTALLS_INPUT_HEADER);
|
|
47
|
+
if (!payload) return [];
|
|
48
|
+
|
|
49
|
+
// Gate 2: the tenant-bound HMAC, verified constant-time against the go-live secret.
|
|
50
|
+
const secret = await readEnv(CONSENT_SNAPSHOT_HMAC_SECRET_BINDING);
|
|
51
|
+
if (!secret) return [];
|
|
52
|
+
const signature = request.headers.get(MANAGED_INSTALLS_SIG_HEADER);
|
|
53
|
+
if (!(await verifyManagedInstallsSig(secret, tenantPublicId, payload, signature))) return [];
|
|
54
|
+
|
|
55
|
+
return parseManagedInstalls(payload) ?? [];
|
|
56
|
+
}
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
import {
|
|
7
7
|
ENVIRONMENT_SCHEMA_VERSION,
|
|
8
8
|
buildPlatformAdapterDeclaration,
|
|
9
|
+
getPlatformAdapter,
|
|
9
10
|
validateIntegrationManifest,
|
|
10
11
|
type IntegrationDeclarationInput,
|
|
11
12
|
} from "@tot/public-runtime";
|
|
12
13
|
import { AppVersionStore } from "../apps/appVersionStore.js";
|
|
13
14
|
import type { Queryable } from "../d1/catalog.js";
|
|
15
|
+
import { parseStageDestinationIds } from "./stageDestinationIds.js";
|
|
14
16
|
|
|
15
17
|
const MANAGED_KIND = "managed-analytics-v1";
|
|
16
18
|
|
|
@@ -47,11 +49,17 @@ export async function loadActiveManagedInstallDeclarations(
|
|
|
47
49
|
if (!manifest.ok || !current || current.tenantId !== tenantPublicId) continue;
|
|
48
50
|
if (current.appVersion !== row.app_version || current.facets.appVersion !== row.app_version) continue;
|
|
49
51
|
if (current.facets.digest !== manifest.value.app.digest || manifest.value.app.id !== row.app_id) continue;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
// The stored per-stage map, re-parsed through the SAME validator the API used, so a
|
|
53
|
+
// row that no longer satisfies the contract disables its install rather than
|
|
54
|
+
// resolving a partial or stale destination set.
|
|
55
|
+
const ids = parseStageDestinationIds(
|
|
56
|
+
current.facets.publicConfig["destinationIds"],
|
|
57
|
+
getPlatformAdapter(row.app_id),
|
|
58
|
+
);
|
|
59
|
+
if (!ids.ok) continue;
|
|
52
60
|
const built = buildPlatformAdapterDeclaration({
|
|
53
61
|
adapterId: row.app_id,
|
|
54
|
-
ids:
|
|
62
|
+
ids: ids.value,
|
|
55
63
|
tenantPublicId,
|
|
56
64
|
environment: {
|
|
57
65
|
schemaVersion: ENVIRONMENT_SCHEMA_VERSION,
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-stage destination map, parsed once for both callers that need it: the
|
|
3
|
+
* managed-analytics API (validating what a merchant submits) and the render plane
|
|
4
|
+
* (rebuilding a stored install's declaration). One parser, so what the console accepts
|
|
5
|
+
* and what actually fires can never disagree.
|
|
6
|
+
*
|
|
7
|
+
* WHY PER STAGE. `resolveAdapterDestinationId` reads only the CURRENT stage's id, and
|
|
8
|
+
* `buildPlatformAdapterDeclaration` refuses a non-live stage that reuses the live one. So
|
|
9
|
+
* with a single id the runtime is already correct — a non-live stage resolves nothing and
|
|
10
|
+
* dispatches nothing — but the merchant has no way to measure anything off live either.
|
|
11
|
+
* A per-stage map is what makes non-live verification possible without pointing preview
|
|
12
|
+
* traffic at the property that carries real reporting.
|
|
13
|
+
*/
|
|
14
|
+
import {
|
|
15
|
+
ADAPTER_CONFIG_STAGES,
|
|
16
|
+
type AdapterConfigStage,
|
|
17
|
+
type DestinationIdsByEnvironment,
|
|
18
|
+
type PlatformAdapterDefinition,
|
|
19
|
+
} from "@tot/public-runtime";
|
|
20
|
+
|
|
21
|
+
export interface StageDestinationIdsOk {
|
|
22
|
+
ok: true;
|
|
23
|
+
value: DestinationIdsByEnvironment;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface StageDestinationIdsError {
|
|
27
|
+
ok: false;
|
|
28
|
+
details: { path: string; code: string; message: string }[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type StageDestinationIdsResult = StageDestinationIdsOk | StageDestinationIdsError;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse and validate a submitted per-stage map fail-closed.
|
|
35
|
+
*
|
|
36
|
+
* `live` is required because it is the stage that publishes; a non-live stage is optional
|
|
37
|
+
* and simply resolves nothing when absent. Every id is checked against the ADAPTER's own
|
|
38
|
+
* format validator, so a Meta pixel id cannot be accepted where a GA4 measurement id
|
|
39
|
+
* belongs. Reusing the live id on a non-live stage is refused HERE with a field-level
|
|
40
|
+
* message rather than left to the declaration builder, so the console can point at the
|
|
41
|
+
* offending stage instead of failing the whole submission opaquely.
|
|
42
|
+
*/
|
|
43
|
+
export function parseStageDestinationIds(
|
|
44
|
+
input: unknown,
|
|
45
|
+
platform: PlatformAdapterDefinition | undefined,
|
|
46
|
+
): StageDestinationIdsResult {
|
|
47
|
+
const base = "body.configuration.destinationIds";
|
|
48
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
details: [{ path: base, code: "type", message: "Expected a map of stage to destination identifier." }],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!platform) {
|
|
55
|
+
return { ok: false, details: [{ path: "body.adapterId", code: "unknown_adapter", message: "Unknown adapter." }] };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const entries = Object.entries(input as Record<string, unknown>);
|
|
59
|
+
const details: StageDestinationIdsError["details"] = [];
|
|
60
|
+
const value: DestinationIdsByEnvironment = {};
|
|
61
|
+
|
|
62
|
+
for (const [stage, id] of entries) {
|
|
63
|
+
const path = `${base}.${stage}`;
|
|
64
|
+
if (!(ADAPTER_CONFIG_STAGES as readonly string[]).includes(stage)) {
|
|
65
|
+
details.push({
|
|
66
|
+
path,
|
|
67
|
+
code: "unknown_enum",
|
|
68
|
+
message: `Stage must be one of: ${ADAPTER_CONFIG_STAGES.join(", ")}.`,
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (typeof id !== "string" || !platform.validateId(id)) {
|
|
73
|
+
details.push({ path, code: "format", message: "Destination identifier has an invalid format." });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
value[stage as AdapterConfigStage] = id;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!value.live) {
|
|
80
|
+
details.push({
|
|
81
|
+
path: `${base}.live`,
|
|
82
|
+
code: "required",
|
|
83
|
+
message: "A live destination identifier is required.",
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
for (const stage of ADAPTER_CONFIG_STAGES) {
|
|
87
|
+
if (stage === "live") continue;
|
|
88
|
+
if (value[stage] === value.live) {
|
|
89
|
+
details.push({
|
|
90
|
+
path: `${base}.${stage}`,
|
|
91
|
+
code: "live_destination_reused",
|
|
92
|
+
message:
|
|
93
|
+
"A non-live stage must use its own TEST destination, never the live one — " +
|
|
94
|
+
"otherwise preview and candidate traffic lands in the property that carries " +
|
|
95
|
+
"real reporting.",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (details.length > 0) return { ok: false, details };
|
|
102
|
+
return { ok: true, value };
|
|
103
|
+
}
|
|
@@ -62,6 +62,7 @@ import {
|
|
|
62
62
|
MATERIALIZE_MODE_BINDING,
|
|
63
63
|
verifyConsentSnapshotSig,
|
|
64
64
|
} from "@tot/public-runtime";
|
|
65
|
+
import { readBakedManagedInstalls } from "@/lib/integration/bakedManagedInstalls";
|
|
65
66
|
import type {
|
|
66
67
|
CapabilityConfig,
|
|
67
68
|
ConsentSnapshot,
|
|
@@ -219,7 +220,20 @@ export async function runRenderChain(input: RenderChainInput): Promise<Response>
|
|
|
219
220
|
? publicationSource.publicationTimestamp
|
|
220
221
|
: exactPublicationTimestamp(await readEnv("TOT_PUBLICATION_TIMESTAMP"));
|
|
221
222
|
|
|
222
|
-
|
|
223
|
+
// Managed installs reach this render one of two ways, never both. The control plane
|
|
224
|
+
// reads them from D1 per request (`controlPlane.ts`). A PUBLIC render supplies none by
|
|
225
|
+
// design (ADR 0013: "baked at publish, never read per request on a public page") — so
|
|
226
|
+
// on the materialize render, which is a public render with no D1 at all, they arrive
|
|
227
|
+
// BAKED: resolved and signed once by the go-live Worker, carried in a materialize-only
|
|
228
|
+
// signed header. Without this the bundle serves a plan whose `integrations` is empty
|
|
229
|
+
// for a tenant that has an active install, and nothing anywhere reports the difference.
|
|
230
|
+
//
|
|
231
|
+
// Read here, before declarations are assembled below, because the resolved plan and its
|
|
232
|
+
// compiled CSP both depend on the full declaration set.
|
|
233
|
+
const managedIntegrationDeclarations =
|
|
234
|
+
input.managedIntegrationDeclarations.length > 0
|
|
235
|
+
? input.managedIntegrationDeclarations
|
|
236
|
+
: await readBakedManagedInstalls(request, tenant.tenant_id, readEnv);
|
|
223
237
|
|
|
224
238
|
// Digest-addressed static-bundle serving. Deliberately before the edge page
|
|
225
239
|
// cache/catalog/theme machinery. A selected publication bypasses this legacy
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.26",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -147,6 +147,85 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"type": "integer"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"minProperties": 1,
|
|
155
|
+
"properties": {
|
|
156
|
+
"candidate": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"not": {
|
|
159
|
+
"anyOf": [
|
|
160
|
+
{
|
|
161
|
+
"type": "string",
|
|
162
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"type": "string",
|
|
166
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"type": "string",
|
|
170
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"type": "string",
|
|
174
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
"minLength": 1
|
|
179
|
+
},
|
|
180
|
+
"staged": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"not": {
|
|
183
|
+
"anyOf": [
|
|
184
|
+
{
|
|
185
|
+
"type": "string",
|
|
186
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"type": "string",
|
|
190
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"type": "string",
|
|
194
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "string",
|
|
198
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
"minLength": 1
|
|
203
|
+
},
|
|
204
|
+
"live": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"not": {
|
|
207
|
+
"anyOf": [
|
|
208
|
+
{
|
|
209
|
+
"type": "string",
|
|
210
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"type": "string",
|
|
214
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "string",
|
|
218
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"type": "string",
|
|
222
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"minLength": 1
|
|
227
|
+
}
|
|
228
|
+
}
|
|
150
229
|
}
|
|
151
230
|
]
|
|
152
231
|
}
|
|
@@ -120,6 +120,85 @@
|
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
122
|
"type": "integer"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"type": "object",
|
|
126
|
+
"additionalProperties": false,
|
|
127
|
+
"minProperties": 1,
|
|
128
|
+
"properties": {
|
|
129
|
+
"candidate": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"not": {
|
|
132
|
+
"anyOf": [
|
|
133
|
+
{
|
|
134
|
+
"type": "string",
|
|
135
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"type": "string",
|
|
139
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"type": "string",
|
|
143
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"type": "string",
|
|
147
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
"minLength": 1
|
|
152
|
+
},
|
|
153
|
+
"staged": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"not": {
|
|
156
|
+
"anyOf": [
|
|
157
|
+
{
|
|
158
|
+
"type": "string",
|
|
159
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"type": "string",
|
|
163
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "string",
|
|
167
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"type": "string",
|
|
171
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
"minLength": 1
|
|
176
|
+
},
|
|
177
|
+
"live": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"not": {
|
|
180
|
+
"anyOf": [
|
|
181
|
+
{
|
|
182
|
+
"type": "string",
|
|
183
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"type": "string",
|
|
187
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"type": "string",
|
|
191
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"type": "string",
|
|
195
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
"minLength": 1
|
|
200
|
+
}
|
|
201
|
+
}
|
|
123
202
|
}
|
|
124
203
|
]
|
|
125
204
|
}
|
package/packages/public-runtime/schemas/managed-analytics/v1/integration-revision.schema.json
CHANGED
|
@@ -176,6 +176,85 @@
|
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
"type": "integer"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"type": "object",
|
|
182
|
+
"additionalProperties": false,
|
|
183
|
+
"minProperties": 1,
|
|
184
|
+
"properties": {
|
|
185
|
+
"candidate": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"not": {
|
|
188
|
+
"anyOf": [
|
|
189
|
+
{
|
|
190
|
+
"type": "string",
|
|
191
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"type": "string",
|
|
195
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"type": "string",
|
|
199
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"type": "string",
|
|
203
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
"minLength": 1
|
|
208
|
+
},
|
|
209
|
+
"staged": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"not": {
|
|
212
|
+
"anyOf": [
|
|
213
|
+
{
|
|
214
|
+
"type": "string",
|
|
215
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"type": "string",
|
|
219
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"type": "string",
|
|
223
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"type": "string",
|
|
227
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
"minLength": 1
|
|
232
|
+
},
|
|
233
|
+
"live": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"not": {
|
|
236
|
+
"anyOf": [
|
|
237
|
+
{
|
|
238
|
+
"type": "string",
|
|
239
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"type": "string",
|
|
243
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"type": "string",
|
|
247
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"type": "string",
|
|
251
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
"minLength": 1
|
|
256
|
+
}
|
|
257
|
+
}
|
|
179
258
|
}
|
|
180
259
|
]
|
|
181
260
|
}
|
|
@@ -135,6 +135,85 @@
|
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
"type": "integer"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "object",
|
|
141
|
+
"additionalProperties": false,
|
|
142
|
+
"minProperties": 1,
|
|
143
|
+
"properties": {
|
|
144
|
+
"candidate": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"not": {
|
|
147
|
+
"anyOf": [
|
|
148
|
+
{
|
|
149
|
+
"type": "string",
|
|
150
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"type": "string",
|
|
154
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"type": "string",
|
|
158
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"type": "string",
|
|
162
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
"minLength": 1
|
|
167
|
+
},
|
|
168
|
+
"staged": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"not": {
|
|
171
|
+
"anyOf": [
|
|
172
|
+
{
|
|
173
|
+
"type": "string",
|
|
174
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"type": "string",
|
|
178
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"type": "string",
|
|
182
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"type": "string",
|
|
186
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
"minLength": 1
|
|
191
|
+
},
|
|
192
|
+
"live": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"not": {
|
|
195
|
+
"anyOf": [
|
|
196
|
+
{
|
|
197
|
+
"type": "string",
|
|
198
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"type": "string",
|
|
202
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"type": "string",
|
|
206
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"type": "string",
|
|
210
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
"minLength": 1
|
|
215
|
+
}
|
|
216
|
+
}
|
|
138
217
|
}
|
|
139
218
|
]
|
|
140
219
|
}
|
|
@@ -146,6 +146,85 @@
|
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
"type": "integer"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"type": "object",
|
|
152
|
+
"additionalProperties": false,
|
|
153
|
+
"minProperties": 1,
|
|
154
|
+
"properties": {
|
|
155
|
+
"candidate": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"not": {
|
|
158
|
+
"anyOf": [
|
|
159
|
+
{
|
|
160
|
+
"type": "string",
|
|
161
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"type": "string",
|
|
165
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"type": "string",
|
|
169
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"type": "string",
|
|
173
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
"minLength": 1
|
|
178
|
+
},
|
|
179
|
+
"staged": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"not": {
|
|
182
|
+
"anyOf": [
|
|
183
|
+
{
|
|
184
|
+
"type": "string",
|
|
185
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"type": "string",
|
|
189
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"type": "string",
|
|
193
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"type": "string",
|
|
197
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"minLength": 1
|
|
202
|
+
},
|
|
203
|
+
"live": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"not": {
|
|
206
|
+
"anyOf": [
|
|
207
|
+
{
|
|
208
|
+
"type": "string",
|
|
209
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"type": "string",
|
|
213
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"type": "string",
|
|
217
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"type": "string",
|
|
221
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
"minLength": 1
|
|
226
|
+
}
|
|
227
|
+
}
|
|
149
228
|
}
|
|
150
229
|
]
|
|
151
230
|
}
|
|
@@ -147,6 +147,85 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"type": "integer"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"minProperties": 1,
|
|
155
|
+
"properties": {
|
|
156
|
+
"candidate": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"not": {
|
|
159
|
+
"anyOf": [
|
|
160
|
+
{
|
|
161
|
+
"type": "string",
|
|
162
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"type": "string",
|
|
166
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"type": "string",
|
|
170
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"type": "string",
|
|
174
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
"minLength": 1
|
|
179
|
+
},
|
|
180
|
+
"staged": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"not": {
|
|
183
|
+
"anyOf": [
|
|
184
|
+
{
|
|
185
|
+
"type": "string",
|
|
186
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"type": "string",
|
|
190
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"type": "string",
|
|
194
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "string",
|
|
198
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
"minLength": 1
|
|
203
|
+
},
|
|
204
|
+
"live": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"not": {
|
|
207
|
+
"anyOf": [
|
|
208
|
+
{
|
|
209
|
+
"type": "string",
|
|
210
|
+
"pattern": "(?:[Gg][Tt][Mm]-[A-Za-z0-9]+|[Uu][Aa]-[0-9]+-[0-9]+)"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"type": "string",
|
|
214
|
+
"pattern": "(?:-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----|\\bAKIA[0-9A-Z]{16}\\b|\\bsk-proj-[A-Za-z0-9_-]{8,}\\b|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:sk|rk)_(?:live|test|prod)_[A-Za-z0-9_-]{8,}\\b|\\b(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}\\b|\\b(?:npm_|glpat-)[A-Za-z0-9_.-]{8,}\\b|\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b|\\bAIza[A-Za-z0-9_-]{20,}\\b|\\bSG\\.[A-Za-z0-9_.-]{8,}\\b|\\b(?:[Ss]ecret|[Pp]assword|[Cc]redential)[_-][A-Za-z0-9_-]{4,}\\b|\\b[Bb]earer\\s+[A-Za-z0-9._~+/-]{12,}={0,2}\\b|\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]+\\b|\\b(?:api[_ -]?[Kk]ey|client[_ -]?[Ss]ecret|[Pp]assword|[Cc]redential|private[_ -]?[Kk]ey)\\s*[:=]\\s*\\S+)"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "string",
|
|
218
|
+
"pattern": "(?:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}|\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b|\\b(?:[0-9][ -]?){13,19}\\b|(?:^|[^0-9])(?:\\+?1[ .-]?)?(?:\\([2-9][0-9]{2}\\)|[2-9][0-9]{2})[ .-]?[0-9]{3}[ .-]?[0-9]{4}(?=$|[^0-9]))"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"type": "string",
|
|
222
|
+
"pattern": "(?:</?[A-Za-z][^>]*>|[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]\\s*:|[Ee][Vv][Aa][Ll]\\s*\\(|(?:[Aa][Ll][Ee][Rr][Tt]|[Ff][Ee][Tt][Cc][Hh])\\s*\\(|\\{\\{|\\}\\}|\\$\\{|#[A-Za-z_][A-Za-z0-9_-]*|(?:^|[\\s,>+~])\\.[A-Za-z_-][A-Za-z0-9_-]*(?:$|[\\s,>+~.#[\\:])|\\[[A-Za-z_:][-A-Za-z0-9_:.]*(?:[~|^$*]?=[^\\]]+)?\\]|(?:[Ll][Oo][Cc][Aa][Ll]|[Ss][Ee][Ss][Ss][Ii][Oo][Nn])[Ss][Tt][Oo][Rr][Aa][Gg][Ee]|[Ii][Nn][Dd][Ee][Xx][Ee][Dd][Dd][Bb]|[Qq][Uu][Ee][Rr][Yy][Ss][Ee][Ll][Ee][Cc][Tt][Oo][Rr]|(?:[Ww][Ii][Nn][Dd][Oo][Ww]|[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]|[Gg][Ll][Oo][Bb][Aa][Ll][Tt][Hh][Ii][Ss]|[Cc][Oo][Nn][Ss][Oo][Ll][Ee])\\s*(?:\\.|\\[)|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\.\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*\\(|[A-Za-z_$][A-Za-z0-9_$]*\\s*\\([^)]*\\)\\s*;|[Rr][Ee][Tt][Uu][Rr][Nn][^;{}]*;|[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]|=>|(?:[Vv][Aa][Rr]|[Ll][Ee][Tt]|[Cc][Oo][Nn][Ss][Tt])\\s+[A-Za-z_$])"
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"minLength": 1
|
|
227
|
+
}
|
|
228
|
+
}
|
|
150
229
|
}
|
|
151
230
|
]
|
|
152
231
|
}
|
|
@@ -273,18 +273,34 @@ export function isPreviewDispatcherPath(pathname: string): boolean {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
/**
|
|
276
|
-
* Decide which customization environment to serve.
|
|
277
|
-
* `
|
|
278
|
-
*
|
|
279
|
-
*
|
|
276
|
+
* Decide which customization environment to serve. A valid, unexpired,
|
|
277
|
+
* tenant-matching `__preview`/`tot_preview` token grants `test` (noindex) on
|
|
278
|
+
* ANY host — the token is checked before the host is, so a signed preview
|
|
279
|
+
* link keeps working even when opened on the tenant's normal (non-`preview.*`)
|
|
280
|
+
* host. Without such a token, production hosts always get `live`; preview
|
|
281
|
+
* hosts are auth-gated and reject a missing/invalid/cross-tenant token. The
|
|
282
|
+
* one exception is the token-dispenser path itself (see
|
|
280
283
|
* {@link isPreviewDispatcherPath}) — it renders the dispatcher's own minimal
|
|
281
|
-
* page, never tenant content, so it's
|
|
282
|
-
* than 401ing on the very request that would otherwise
|
|
284
|
+
* page, never tenant content, so it's always `live`/no-token regardless of
|
|
285
|
+
* host or token, rather than 401ing on the very request that would otherwise
|
|
286
|
+
* fetch a token.
|
|
283
287
|
*/
|
|
284
288
|
export async function resolveCustomizationEnv(
|
|
285
289
|
input: EnvResolutionInput,
|
|
286
290
|
): Promise<EnvResolution> {
|
|
287
|
-
if (
|
|
291
|
+
if (isPreviewDispatcherPath(input.pathname ?? "")) {
|
|
292
|
+
return { env: "live", noindex: false };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const tokenResult =
|
|
296
|
+
input.secret && input.token
|
|
297
|
+
? await verifyPreviewToken(input.secret, input.token, input.nowSeconds)
|
|
298
|
+
: null;
|
|
299
|
+
if (tokenResult?.ok && tokenResult.claims.tenantId === input.tenantId) {
|
|
300
|
+
return { env: "test", noindex: true };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!input.isPreviewHost) {
|
|
288
304
|
return { env: "live", noindex: false };
|
|
289
305
|
}
|
|
290
306
|
if (!input.secret) {
|
|
@@ -301,20 +317,16 @@ export async function resolveCustomizationEnv(
|
|
|
301
317
|
reject: { status: 401, message: "Preview token required." },
|
|
302
318
|
};
|
|
303
319
|
}
|
|
304
|
-
|
|
305
|
-
if (!result.ok) {
|
|
320
|
+
if (!tokenResult!.ok) {
|
|
306
321
|
return {
|
|
307
322
|
env: "live",
|
|
308
323
|
noindex: true,
|
|
309
|
-
reject: { status: 401, message: `Invalid preview token (${
|
|
324
|
+
reject: { status: 401, message: `Invalid preview token (${tokenResult!.reason}).` },
|
|
310
325
|
};
|
|
311
326
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
return { env: "test", noindex: true };
|
|
327
|
+
return {
|
|
328
|
+
env: "live",
|
|
329
|
+
noindex: true,
|
|
330
|
+
reject: { status: 403, message: "Preview token is for a different tenant." },
|
|
331
|
+
};
|
|
320
332
|
}
|
|
@@ -58,7 +58,7 @@ export const WS1_GOOGLE_MEASUREMENT_ADAPTER_ID: OpaquePublicId = "platform.googl
|
|
|
58
58
|
* The canonical WS1 config field key the google-measurement adapter declares for
|
|
59
59
|
* its destination id. Used as the DEFAULT config key when no catalog is supplied.
|
|
60
60
|
*/
|
|
61
|
-
export const WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY = "
|
|
61
|
+
export const WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY = "destinationIds";
|
|
62
62
|
|
|
63
63
|
/** The opaque adapter handle used when a container has no supported GA4 concept. */
|
|
64
64
|
export const NO_ADAPTER_SELECTED_ID: OpaquePublicId = "none-selected";
|
|
@@ -343,7 +343,10 @@ export function generateDisabledMigrationDraft(
|
|
|
343
343
|
break; // deterministic: first config carrying a literal id wins.
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
-
|
|
346
|
+
// A container's GA4 id is the merchant's LIVE destination, so the draft proposes it
|
|
347
|
+
// at that stage only. A non-live stage needs its own TEST id, which the merchant adds
|
|
348
|
+
// before verifying — the contract refuses reusing the live one there.
|
|
349
|
+
if (destinationId !== null) proposedConfiguration[destinationKey] = { live: destinationId };
|
|
347
350
|
}
|
|
348
351
|
|
|
349
352
|
// --- Redacted finding codes (no source text; stable, sorted-by-construction). -
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The baked managed-install wire (ADR 0013).
|
|
3
|
+
*
|
|
4
|
+
* ADR 0013 already specifies what a public page does about admin-installed state:
|
|
5
|
+
* managed installs are "baked at publish, never read per request on a public page"
|
|
6
|
+
* (`publicRender.ts`). The read side honored that by supplying no declarations; this is
|
|
7
|
+
* the bake side that gives it something to honor. Without it a tenant whose public site
|
|
8
|
+
* serves CDN → content-addressed storage can never measure anything, however correctly
|
|
9
|
+
* its install is configured — the served page carries a complete-looking integration
|
|
10
|
+
* plan with an empty `integrations` list, which is indistinguishable from "this tenant
|
|
11
|
+
* has no integrations" on every surface that reports configuration rather than delivery.
|
|
12
|
+
*
|
|
13
|
+
* WHAT IS SIGNED: the resolved DECLARATIONS, not the resolved plan. A plan is
|
|
14
|
+
* route-dependent — `deriveSiteSurface` varies `siteSurface` by pathname, and the stage
|
|
15
|
+
* comes from the request — so one signed plan cannot serve every route of a bundle.
|
|
16
|
+
* Declarations are route-independent, so the render resolves each route's own plan from
|
|
17
|
+
* them exactly as the Worker does, through the same resolver.
|
|
18
|
+
*
|
|
19
|
+
* The trust model mirrors the consent snapshot's, because the constraint is the same: the
|
|
20
|
+
* go-live Worker holds D1 and the signing secret, the bake holds neither. Two gates make
|
|
21
|
+
* the header un-forgeable, and BOTH must hold:
|
|
22
|
+
* 1. MATERIALIZE-MODE binding — honored only when `TOT_MATERIALIZE_MODE` is set, which
|
|
23
|
+
* the materializer's wrangler dev injects and the DEPLOYED Worker never has. So a
|
|
24
|
+
* client cannot inject installs on the live Worker, and no cacheable response can
|
|
25
|
+
* vary on the header, because it is never read there.
|
|
26
|
+
* 2. HMAC-SHA256 over a length-prefixed, DOMAIN-SEPARATED framing of
|
|
27
|
+
* (purpose, tenantId, serialized) — verified constant-time. The purpose label is
|
|
28
|
+
* what keeps this envelope and the consent envelope from being interchangeable
|
|
29
|
+
* under one secret: a signature minted for one can never be replayed as the other,
|
|
30
|
+
* independently of whether the payload would happen to parse.
|
|
31
|
+
*
|
|
32
|
+
* Either gate failing ⇒ no baked installs, and the render falls through to the
|
|
33
|
+
* environment-only plan (nothing loads). Fail-safe, never fail-open.
|
|
34
|
+
*
|
|
35
|
+
* Web Crypto only (`crypto.subtle`), so it runs unchanged on workerd.
|
|
36
|
+
*/
|
|
37
|
+
import type { IntegrationDeclarationInput } from "./resolve.js";
|
|
38
|
+
import { validateIntegrationManifest } from "./manifest.js";
|
|
39
|
+
import { findForbiddenFields } from "./secrets.js";
|
|
40
|
+
|
|
41
|
+
/** The materialize-only request header carrying a tenant's resolved managed installs. */
|
|
42
|
+
export const MANAGED_INSTALLS_INPUT_HEADER = "x-tot-managed-installs";
|
|
43
|
+
|
|
44
|
+
/** The hex HMAC-SHA256 signature over {@link MANAGED_INSTALLS_INPUT_HEADER}. */
|
|
45
|
+
export const MANAGED_INSTALLS_SIG_HEADER = "x-tot-managed-installs-sig";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The domain-separation label for this envelope's signatures. It is part of the signed
|
|
49
|
+
* bytes, so a signature is bound to this purpose and cannot be reused for another.
|
|
50
|
+
*/
|
|
51
|
+
const MANAGED_INSTALLS_SIG_PURPOSE = "managed-installs.v1";
|
|
52
|
+
|
|
53
|
+
const encoder = new TextEncoder();
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The exact string a signature covers: purpose, tenant and payload each prefixed by
|
|
57
|
+
* their own UTF-8 byte length, so no value can be read as a field separator and no
|
|
58
|
+
* field's content can shift a byte across a boundary.
|
|
59
|
+
*/
|
|
60
|
+
function signaturePayload(tenantId: string, serialized: string): string {
|
|
61
|
+
const purposeBytes = encoder.encode(MANAGED_INSTALLS_SIG_PURPOSE).length;
|
|
62
|
+
const tenantBytes = encoder.encode(tenantId).length;
|
|
63
|
+
const payloadBytes = encoder.encode(serialized).length;
|
|
64
|
+
return (
|
|
65
|
+
`${purposeBytes}:${MANAGED_INSTALLS_SIG_PURPOSE}` +
|
|
66
|
+
`${tenantBytes}:${tenantId}` +
|
|
67
|
+
`${payloadBytes}:${serialized}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function hmacKey(secret: string): Promise<CryptoKey> {
|
|
72
|
+
return crypto.subtle.importKey(
|
|
73
|
+
"raw",
|
|
74
|
+
encoder.encode(secret) as unknown as BufferSource,
|
|
75
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
76
|
+
false,
|
|
77
|
+
["sign", "verify"],
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function hexToBytes(hex: string): Uint8Array | null {
|
|
82
|
+
if (hex.length === 0 || hex.length % 2 !== 0 || /[^0-9a-fA-F]/.test(hex)) return null;
|
|
83
|
+
const out = new Uint8Array(hex.length / 2);
|
|
84
|
+
for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Serialize resolved declarations for transport. The inverse of {@link parseManagedInstalls}. */
|
|
89
|
+
export function serializeManagedInstalls(
|
|
90
|
+
declarations: readonly IntegrationDeclarationInput[],
|
|
91
|
+
): string {
|
|
92
|
+
return JSON.stringify(declarations);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse a serialized managed-install list fail-closed. Anything unexpected — malformed
|
|
97
|
+
* JSON, a non-array, an entry missing its fields, a manifest that does not validate, or
|
|
98
|
+
* any secret-bearing public config — yields `null` for the WHOLE list rather than a
|
|
99
|
+
* partial one, so a tampered payload can never contribute a subset of declarations.
|
|
100
|
+
*
|
|
101
|
+
* The resolver re-validates every manifest again downstream; this is the outer layer, so
|
|
102
|
+
* a bad payload is rejected before it can reach plan resolution at all.
|
|
103
|
+
*/
|
|
104
|
+
export function parseManagedInstalls(
|
|
105
|
+
raw: unknown,
|
|
106
|
+
): IntegrationDeclarationInput[] | null {
|
|
107
|
+
let parsed: unknown = raw;
|
|
108
|
+
if (typeof raw === "string") {
|
|
109
|
+
try {
|
|
110
|
+
parsed = JSON.parse(raw);
|
|
111
|
+
} catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!Array.isArray(parsed)) return null;
|
|
116
|
+
|
|
117
|
+
const out: IntegrationDeclarationInput[] = [];
|
|
118
|
+
for (const entry of parsed) {
|
|
119
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return null;
|
|
120
|
+
const record = entry as Record<string, unknown>;
|
|
121
|
+
if (typeof record["origin"] !== "string" || typeof record["ref"] !== "string") return null;
|
|
122
|
+
|
|
123
|
+
const publicConfig = record["publicConfig"];
|
|
124
|
+
if (typeof publicConfig !== "object" || publicConfig === null || Array.isArray(publicConfig)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (findForbiddenFields(publicConfig, "publicConfig").length > 0) return null;
|
|
128
|
+
|
|
129
|
+
const assets = record["materializedAssets"];
|
|
130
|
+
if (!Array.isArray(assets) || assets.some((a) => typeof a !== "string")) return null;
|
|
131
|
+
|
|
132
|
+
const manifest = validateIntegrationManifest(record["manifest"]);
|
|
133
|
+
if (!manifest.ok) return null;
|
|
134
|
+
|
|
135
|
+
out.push({
|
|
136
|
+
origin: record["origin"] as IntegrationDeclarationInput["origin"],
|
|
137
|
+
ref: record["ref"],
|
|
138
|
+
manifest: manifest.value,
|
|
139
|
+
publicConfig: publicConfig as Record<string, unknown>,
|
|
140
|
+
materializedAssets: assets as string[],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Sign a tenant's serialized managed installs: hex HMAC-SHA256 over the length-prefixed,
|
|
148
|
+
* domain-separated {@link signaturePayload}. The go-live Worker calls this; the
|
|
149
|
+
* materialize render verifies with the same secret via {@link verifyManagedInstallsSig}.
|
|
150
|
+
*/
|
|
151
|
+
export async function signManagedInstalls(
|
|
152
|
+
secret: string,
|
|
153
|
+
tenantId: string,
|
|
154
|
+
serialized: string,
|
|
155
|
+
): Promise<string> {
|
|
156
|
+
const key = await hmacKey(secret);
|
|
157
|
+
const sig = await crypto.subtle.sign(
|
|
158
|
+
"HMAC",
|
|
159
|
+
key,
|
|
160
|
+
encoder.encode(signaturePayload(tenantId, serialized)) as unknown as BufferSource,
|
|
161
|
+
);
|
|
162
|
+
let hex = "";
|
|
163
|
+
for (const b of new Uint8Array(sig)) hex += b.toString(16).padStart(2, "0");
|
|
164
|
+
return hex;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Verify a managed-install signature (constant-time via `crypto.subtle.verify`). A
|
|
169
|
+
* malformed, short, or absent signature returns `false` rather than throwing — fail
|
|
170
|
+
* closed, so no caller can smuggle in unsigned or forged installs.
|
|
171
|
+
*/
|
|
172
|
+
export async function verifyManagedInstallsSig(
|
|
173
|
+
secret: string,
|
|
174
|
+
tenantId: string,
|
|
175
|
+
serialized: string,
|
|
176
|
+
signatureHex: string | null | undefined,
|
|
177
|
+
): Promise<boolean> {
|
|
178
|
+
if (!signatureHex) return false;
|
|
179
|
+
const sig = hexToBytes(signatureHex.trim());
|
|
180
|
+
if (!sig) return false;
|
|
181
|
+
const key = await hmacKey(secret);
|
|
182
|
+
return crypto.subtle.verify(
|
|
183
|
+
"HMAC",
|
|
184
|
+
key,
|
|
185
|
+
sig as unknown as BufferSource,
|
|
186
|
+
encoder.encode(signaturePayload(tenantId, serialized)) as unknown as BufferSource,
|
|
187
|
+
);
|
|
188
|
+
}
|
|
@@ -62,6 +62,7 @@ export * from "./platform-adapter-runtime.js";
|
|
|
62
62
|
export * from "./render-phases.js";
|
|
63
63
|
export * from "./interim-bridge.js";
|
|
64
64
|
export * from "./consent-broker.js";
|
|
65
|
+
export * from "./baked-managed-installs.js";
|
|
65
66
|
export * from "./consent-cmp-demand.js";
|
|
66
67
|
export * from "./consent-config.js";
|
|
67
68
|
export * from "./consent-preview.js";
|
|
@@ -28,6 +28,22 @@ const PUBLIC_IDENTIFIER = { ...SAFE_CONFIG_STRING, minLength: 1, maxLength: 128,
|
|
|
28
28
|
const FINDING_CODE = { ...SAFE_CONFIG_STRING, pattern: "^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$" } as const;
|
|
29
29
|
const REDACTED_PATH = { ...SAFE_CONFIG_STRING, pattern: "^(?:\\$|[A-Za-z][A-Za-z0-9]*)(?:\\.[A-Za-z][A-Za-z0-9]*|\\[[0-9]+\\])*$" } as const;
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* A per-stage destination map — the one non-primitive configuration value, and closed:
|
|
33
|
+
* only the declared stages, only safe strings. `local` is absent because the local dev
|
|
34
|
+
* loop ships no integrations, so a value there could never fire.
|
|
35
|
+
*/
|
|
36
|
+
const stageDestinationMap = {
|
|
37
|
+
type: "object",
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
minProperties: 1,
|
|
40
|
+
properties: {
|
|
41
|
+
candidate: SAFE_NON_EMPTY_STRING,
|
|
42
|
+
staged: SAFE_NON_EMPTY_STRING,
|
|
43
|
+
live: SAFE_NON_EMPTY_STRING,
|
|
44
|
+
},
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
31
47
|
const primitiveConfiguration = {
|
|
32
48
|
type: "object",
|
|
33
49
|
propertyNames: SAFE_CONFIG_KEY,
|
|
@@ -36,6 +52,7 @@ const primitiveConfiguration = {
|
|
|
36
52
|
SAFE_CONFIG_STRING,
|
|
37
53
|
{ type: "boolean" },
|
|
38
54
|
{ type: "integer" },
|
|
55
|
+
stageDestinationMap,
|
|
39
56
|
],
|
|
40
57
|
},
|
|
41
58
|
} as const;
|
|
@@ -64,7 +81,7 @@ export const ADAPTER_DEFINITION_V1_JSON_SCHEMA = {
|
|
|
64
81
|
key: SAFE_CONFIG_KEY,
|
|
65
82
|
label: SAFE_NON_EMPTY_STRING,
|
|
66
83
|
description: SAFE_NON_EMPTY_STRING,
|
|
67
|
-
kind: { type: "string", enum: ["string", "boolean", "integer"] },
|
|
84
|
+
kind: { type: "string", enum: ["string", "boolean", "integer", "stageMap"] },
|
|
68
85
|
required: { type: "boolean" },
|
|
69
86
|
},
|
|
70
87
|
},
|
|
@@ -28,9 +28,30 @@ export type IntegrationRevisionStatus = (typeof INTEGRATION_REVISION_STATUSES)[n
|
|
|
28
28
|
export const ADAPTER_AVAILABILITY = ["available", "deprecated"] as const;
|
|
29
29
|
export type AdapterAvailability = (typeof ADAPTER_AVAILABILITY)[number];
|
|
30
30
|
|
|
31
|
-
export const ADAPTER_CONFIG_VALUE_KINDS = ["string", "boolean", "integer"] as const;
|
|
31
|
+
export const ADAPTER_CONFIG_VALUE_KINDS = ["string", "boolean", "integer", "stageMap"] as const;
|
|
32
32
|
export type AdapterConfigValueKind = (typeof ADAPTER_CONFIG_VALUE_KINDS)[number];
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The stages a merchant may address a destination at. `local` is deliberately absent:
|
|
36
|
+
* the local dev loop ships no integrations and grants only essential consent, so a value
|
|
37
|
+
* there could never fire and offering one would imply otherwise.
|
|
38
|
+
*/
|
|
39
|
+
export const ADAPTER_CONFIG_STAGES = ["candidate", "staged", "live"] as const;
|
|
40
|
+
export type AdapterConfigStage = (typeof ADAPTER_CONFIG_STAGES)[number];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A per-stage destination map — the one non-primitive configuration value.
|
|
44
|
+
*
|
|
45
|
+
* Its shape is CLOSED: keys come from {@link ADAPTER_CONFIG_STAGES} and every value is a
|
|
46
|
+
* plain string held to the same executable-content and PII checks as any other
|
|
47
|
+
* configuration value. So the property that makes this contract safe is intact — a
|
|
48
|
+
* merchant still cannot supply markup, selectors, secrets, or arbitrary structure — while
|
|
49
|
+
* a destination can differ per stage, which is what makes the devbook's own rule (a
|
|
50
|
+
* non-live stage must not reuse the live property) satisfiable through the console at all.
|
|
51
|
+
*/
|
|
52
|
+
export type AdapterConfigStageMap = Partial<Record<AdapterConfigStage, string>>;
|
|
53
|
+
|
|
54
|
+
export type AdapterConfigValue = string | boolean | number | AdapterConfigStageMap;
|
|
34
55
|
/** Public identifiers are opaque handles: never emails, names, or user-provided labels. */
|
|
35
56
|
export type OpaquePublicId = string;
|
|
36
57
|
/** Stable, redacted machine code; migration findings never contain source text or PII. */
|
|
@@ -535,12 +556,36 @@ export function validateManagedAnalyticsSafePayload(input: unknown): ContractRes
|
|
|
535
556
|
return v.ok ? prepared : { ok: false, violations: v.items };
|
|
536
557
|
}
|
|
537
558
|
|
|
559
|
+
/** A plain object, i.e. a candidate per-stage map rather than a primitive. */
|
|
560
|
+
function isStageMap(value: unknown): boolean {
|
|
561
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
562
|
+
}
|
|
563
|
+
|
|
538
564
|
function validateConfig(input: unknown, v: Violations, path: string): void {
|
|
539
565
|
const obj = object(input, v, path);
|
|
540
566
|
if (!obj) return;
|
|
541
567
|
for (const [key, value] of Object.entries(obj)) {
|
|
542
568
|
if (!/^[a-z][a-zA-Z0-9]{0,63}$/.test(key)) v.add(pathAt(path, key), "format", "Configuration keys must be lower camel-case identifiers.");
|
|
543
|
-
|
|
569
|
+
// A per-stage map is the one permitted non-primitive, and it is CLOSED: stage keys
|
|
570
|
+
// only, string values only, each held to the same executable-content check below. So
|
|
571
|
+
// no arbitrary structure or depth can enter configuration through it.
|
|
572
|
+
if (isStageMap(value)) {
|
|
573
|
+
const entries = Object.entries(value as Record<string, unknown>);
|
|
574
|
+
if (entries.length === 0) v.add(pathAt(path, key), "empty", "A per-stage map must name at least one stage.");
|
|
575
|
+
for (const [stage, id] of entries) {
|
|
576
|
+
const stagePath = pathAt(pathAt(path, key), stage);
|
|
577
|
+
if (!(ADAPTER_CONFIG_STAGES as readonly string[]).includes(stage)) {
|
|
578
|
+
v.add(stagePath, "unknown_enum", `Stage must be one of: ${ADAPTER_CONFIG_STAGES.join(", ")}.`);
|
|
579
|
+
}
|
|
580
|
+
if (typeof id !== "string") {
|
|
581
|
+
v.add(stagePath, "type", "A per-stage value must be a string.");
|
|
582
|
+
} else if (EXECUTABLE_OR_INSTRUCTION_VALUE.test(id)) {
|
|
583
|
+
v.add(stagePath, "executable_value", "Configuration cannot contain markup, JavaScript, templates, selectors, or storage instructions.");
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
if (!(typeof value === "string" || typeof value === "boolean" || (typeof value === "number" && Number.isInteger(value)))) v.add(pathAt(path, key), "type", "Configuration values must be strings, booleans, integers, or a per-stage map of strings.");
|
|
544
589
|
if (typeof value === "string" && EXECUTABLE_OR_INSTRUCTION_VALUE.test(value)) v.add(pathAt(path, key), "executable_value", "Configuration cannot contain markup, JavaScript, templates, selectors, or storage instructions.");
|
|
545
590
|
}
|
|
546
591
|
const safe = validateManagedAnalyticsSafePayload(obj);
|