field-redactor 1.2.0 → 1.6.0
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/.github/workflows/ci.yml +38 -0
- package/CHANGELOG.md +179 -0
- package/CONTRIBUTING.md +64 -0
- package/README.md +67 -670
- package/dist/api/fieldRedactor.d.ts +53 -0
- package/dist/api/fieldRedactor.d.ts.map +1 -0
- package/dist/api/fieldRedactor.js +169 -0
- package/dist/api/fieldRedactor.js.map +1 -0
- package/dist/api/fieldRedactorConfigBuilder.d.ts +57 -0
- package/dist/api/fieldRedactorConfigBuilder.d.ts.map +1 -0
- package/dist/api/fieldRedactorConfigBuilder.js +115 -0
- package/dist/api/fieldRedactorConfigBuilder.js.map +1 -0
- package/dist/api/fieldRedactorDeps.d.ts +19 -0
- package/dist/api/fieldRedactorDeps.d.ts.map +1 -0
- package/dist/api/fieldRedactorDeps.js +45 -0
- package/dist/api/fieldRedactorDeps.js.map +1 -0
- package/dist/arrayRedaction.d.ts +12 -0
- package/dist/arrayRedaction.d.ts.map +1 -0
- package/dist/arrayRedaction.js +70 -0
- package/dist/arrayRedaction.js.map +1 -0
- package/dist/config/configValidator.d.ts +9 -0
- package/dist/config/configValidator.d.ts.map +1 -0
- package/dist/config/configValidator.js +77 -0
- package/dist/config/configValidator.js.map +1 -0
- package/dist/config/customObjectSchemas.d.ts +7 -0
- package/dist/config/customObjectSchemas.d.ts.map +1 -0
- package/dist/config/customObjectSchemas.js +35 -0
- package/dist/config/customObjectSchemas.js.map +1 -0
- package/dist/config/presets.d.ts +22 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +50 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/config/redactionRules.d.ts +25 -0
- package/dist/config/redactionRules.d.ts.map +1 -0
- package/dist/config/redactionRules.js +108 -0
- package/dist/config/redactionRules.js.map +1 -0
- package/dist/configValidator.d.ts +9 -0
- package/dist/configValidator.d.ts.map +1 -0
- package/dist/configValidator.js +77 -0
- package/dist/configValidator.js.map +1 -0
- package/dist/copyOnWriteHelpers.d.ts +20 -0
- package/dist/copyOnWriteHelpers.d.ts.map +1 -0
- package/dist/copyOnWriteHelpers.js +58 -0
- package/dist/copyOnWriteHelpers.js.map +1 -0
- package/dist/customObjectFieldHandler.d.ts +21 -0
- package/dist/customObjectFieldHandler.d.ts.map +1 -0
- package/dist/customObjectFieldHandler.js +159 -0
- package/dist/customObjectFieldHandler.js.map +1 -0
- package/dist/customObjectManager.d.ts +14 -8
- package/dist/customObjectManager.d.ts.map +1 -1
- package/dist/customObjectManager.js +31 -30
- package/dist/customObjectManager.js.map +1 -1
- package/dist/customObjectSchemas.d.ts +7 -0
- package/dist/customObjectSchemas.d.ts.map +1 -0
- package/dist/customObjectSchemas.js +35 -0
- package/dist/customObjectSchemas.js.map +1 -0
- package/dist/dryRun.d.ts +9 -0
- package/dist/dryRun.d.ts.map +1 -0
- package/dist/dryRun.js +75 -0
- package/dist/dryRun.js.map +1 -0
- package/dist/dryRunAttribution.d.ts +10 -0
- package/dist/dryRunAttribution.d.ts.map +1 -0
- package/dist/dryRunAttribution.js +14 -0
- package/dist/dryRunAttribution.js.map +1 -0
- package/dist/dryrun/dryRun.d.ts +9 -0
- package/dist/dryrun/dryRun.d.ts.map +1 -0
- package/dist/dryrun/dryRun.js +75 -0
- package/dist/dryrun/dryRun.js.map +1 -0
- package/dist/dryrun/dryRunAttribution.d.ts +10 -0
- package/dist/dryrun/dryRunAttribution.d.ts.map +1 -0
- package/dist/dryrun/dryRunAttribution.js +14 -0
- package/dist/dryrun/dryRunAttribution.js.map +1 -0
- package/dist/engine/arrayRedaction.d.ts +12 -0
- package/dist/engine/arrayRedaction.d.ts.map +1 -0
- package/dist/engine/arrayRedaction.js +70 -0
- package/dist/engine/arrayRedaction.js.map +1 -0
- package/dist/engine/customObjectFieldHandler.d.ts +35 -0
- package/dist/engine/customObjectFieldHandler.d.ts.map +1 -0
- package/dist/engine/customObjectFieldHandler.js +167 -0
- package/dist/engine/customObjectFieldHandler.js.map +1 -0
- package/dist/engine/objectRedactor.d.ts +18 -0
- package/dist/engine/objectRedactor.d.ts.map +1 -0
- package/dist/engine/objectRedactor.js +38 -0
- package/dist/engine/objectRedactor.js.map +1 -0
- package/dist/engine/objectRedactorCustomObject.d.ts +27 -0
- package/dist/engine/objectRedactorCustomObject.d.ts.map +1 -0
- package/dist/engine/objectRedactorCustomObject.js +54 -0
- package/dist/engine/objectRedactorCustomObject.js.map +1 -0
- package/dist/engine/objectRedactorHelpers.d.ts +9 -0
- package/dist/engine/objectRedactorHelpers.d.ts.map +1 -0
- package/dist/engine/objectRedactorHelpers.js +61 -0
- package/dist/engine/objectRedactorHelpers.js.map +1 -0
- package/dist/engine/objectRedactorMutation.d.ts +10 -0
- package/dist/engine/objectRedactorMutation.d.ts.map +1 -0
- package/dist/engine/objectRedactorMutation.js +89 -0
- package/dist/engine/objectRedactorMutation.js.map +1 -0
- package/dist/engine/objectRedactorSync.d.ts +2 -0
- package/dist/engine/objectRedactorSync.d.ts.map +1 -0
- package/dist/engine/objectRedactorSync.js +7 -0
- package/dist/engine/objectRedactorSync.js.map +1 -0
- package/dist/engine/objectRedactorTraversal.d.ts +41 -0
- package/dist/engine/objectRedactorTraversal.d.ts.map +1 -0
- package/dist/engine/objectRedactorTraversal.js +201 -0
- package/dist/engine/objectRedactorTraversal.js.map +1 -0
- package/dist/engine/primitiveRedactor.d.ts +33 -0
- package/dist/engine/primitiveRedactor.d.ts.map +1 -0
- package/dist/engine/primitiveRedactor.js +75 -0
- package/dist/engine/primitiveRedactor.js.map +1 -0
- package/dist/engine/traversalServices.d.ts +21 -0
- package/dist/engine/traversalServices.d.ts.map +1 -0
- package/dist/engine/traversalServices.js +3 -0
- package/dist/engine/traversalServices.js.map +1 -0
- package/dist/fieldDisposition.d.ts +3 -0
- package/dist/fieldDisposition.d.ts.map +1 -0
- package/dist/fieldDisposition.js +6 -0
- package/dist/fieldDisposition.js.map +1 -0
- package/dist/fieldRedactor.d.ts +34 -11
- package/dist/fieldRedactor.d.ts.map +1 -1
- package/dist/fieldRedactor.js +116 -35
- package/dist/fieldRedactor.js.map +1 -1
- package/dist/fieldRedactorConfigBuilder.d.ts +55 -0
- package/dist/fieldRedactorConfigBuilder.d.ts.map +1 -0
- package/dist/fieldRedactorConfigBuilder.js +111 -0
- package/dist/fieldRedactorConfigBuilder.js.map +1 -0
- package/dist/fieldRedactorDeps.d.ts +19 -0
- package/dist/fieldRedactorDeps.d.ts.map +1 -0
- package/dist/fieldRedactorDeps.js +43 -0
- package/dist/fieldRedactorDeps.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/jsonWalk.d.ts +11 -0
- package/dist/jsonWalk.d.ts.map +1 -0
- package/dist/jsonWalk.js +55 -0
- package/dist/jsonWalk.js.map +1 -0
- package/dist/maybeAsync.d.ts +7 -0
- package/dist/maybeAsync.d.ts.map +1 -0
- package/dist/maybeAsync.js +56 -0
- package/dist/maybeAsync.js.map +1 -0
- package/dist/objectRedactor.d.ts +10 -34
- package/dist/objectRedactor.d.ts.map +1 -1
- package/dist/objectRedactor.js +11 -298
- package/dist/objectRedactor.js.map +1 -1
- package/dist/objectRedactorCow.d.ts +35 -0
- package/dist/objectRedactorCow.d.ts.map +1 -0
- package/dist/objectRedactorCow.js +300 -0
- package/dist/objectRedactorCow.js.map +1 -0
- package/dist/objectRedactorCustomObject.d.ts +28 -0
- package/dist/objectRedactorCustomObject.d.ts.map +1 -0
- package/dist/objectRedactorCustomObject.js +57 -0
- package/dist/objectRedactorCustomObject.js.map +1 -0
- package/dist/objectRedactorHelpers.d.ts +9 -0
- package/dist/objectRedactorHelpers.d.ts.map +1 -0
- package/dist/objectRedactorHelpers.js +61 -0
- package/dist/objectRedactorHelpers.js.map +1 -0
- package/dist/objectRedactorMutation.d.ts +10 -0
- package/dist/objectRedactorMutation.d.ts.map +1 -0
- package/dist/objectRedactorMutation.js +89 -0
- package/dist/objectRedactorMutation.js.map +1 -0
- package/dist/objectRedactorSync.d.ts +2 -0
- package/dist/objectRedactorSync.d.ts.map +1 -0
- package/dist/objectRedactorSync.js +7 -0
- package/dist/objectRedactorSync.js.map +1 -0
- package/dist/objectRedactorTraversal.d.ts +41 -0
- package/dist/objectRedactorTraversal.d.ts.map +1 -0
- package/dist/objectRedactorTraversal.js +201 -0
- package/dist/objectRedactorTraversal.js.map +1 -0
- package/dist/pathParsing.d.ts +11 -0
- package/dist/pathParsing.d.ts.map +1 -0
- package/dist/pathParsing.js +53 -0
- package/dist/pathParsing.js.map +1 -0
- package/dist/pathRuleMatcher.d.ts +19 -0
- package/dist/pathRuleMatcher.d.ts.map +1 -0
- package/dist/pathRuleMatcher.js +42 -0
- package/dist/pathRuleMatcher.js.map +1 -0
- package/dist/presets.d.ts +22 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +50 -0
- package/dist/presets.js.map +1 -0
- package/dist/primitiveRedactor.d.ts +13 -8
- package/dist/primitiveRedactor.d.ts.map +1 -1
- package/dist/primitiveRedactor.js +32 -27
- package/dist/primitiveRedactor.js.map +1 -1
- package/dist/redactionRules.d.ts +22 -0
- package/dist/redactionRules.d.ts.map +1 -0
- package/dist/redactionRules.js +74 -0
- package/dist/redactionRules.js.map +1 -0
- package/dist/regexUtils.d.ts +3 -0
- package/dist/regexUtils.d.ts.map +1 -0
- package/dist/regexUtils.js +8 -0
- package/dist/regexUtils.js.map +1 -0
- package/dist/ruleResolver.d.ts +65 -0
- package/dist/ruleResolver.d.ts.map +1 -0
- package/dist/ruleResolver.js +193 -0
- package/dist/ruleResolver.js.map +1 -0
- package/dist/rules/customObjectManager.d.ts +28 -0
- package/dist/rules/customObjectManager.d.ts.map +1 -0
- package/dist/rules/customObjectManager.js +60 -0
- package/dist/rules/customObjectManager.js.map +1 -0
- package/dist/rules/fieldDisposition.d.ts +3 -0
- package/dist/rules/fieldDisposition.d.ts.map +1 -0
- package/dist/rules/fieldDisposition.js +6 -0
- package/dist/rules/fieldDisposition.js.map +1 -0
- package/dist/rules/pathRuleMatcher.d.ts +19 -0
- package/dist/rules/pathRuleMatcher.d.ts.map +1 -0
- package/dist/rules/pathRuleMatcher.js +40 -0
- package/dist/rules/pathRuleMatcher.js.map +1 -0
- package/dist/rules/ruleResolver.d.ts +65 -0
- package/dist/rules/ruleResolver.d.ts.map +1 -0
- package/dist/rules/ruleResolver.js +194 -0
- package/dist/rules/ruleResolver.js.map +1 -0
- package/dist/rules/secretManager.d.ts +32 -0
- package/dist/rules/secretManager.d.ts.map +1 -0
- package/dist/rules/secretManager.js +85 -0
- package/dist/rules/secretManager.js.map +1 -0
- package/dist/rules/valuePatternMatcher.d.ts +15 -0
- package/dist/rules/valuePatternMatcher.d.ts.map +1 -0
- package/dist/rules/valuePatternMatcher.js +30 -0
- package/dist/rules/valuePatternMatcher.js.map +1 -0
- package/dist/secretManager.d.ts +17 -24
- package/dist/secretManager.d.ts.map +1 -1
- package/dist/secretManager.js +47 -32
- package/dist/secretManager.js.map +1 -1
- package/dist/traversalServices.d.ts +21 -0
- package/dist/traversalServices.d.ts.map +1 -0
- package/dist/traversalServices.js +3 -0
- package/dist/traversalServices.js.map +1 -0
- package/dist/types.d.ts +139 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -1
- package/dist/types.js.map +1 -1
- package/dist/util/jsonWalk.d.ts +10 -0
- package/dist/util/jsonWalk.d.ts.map +1 -0
- package/dist/util/jsonWalk.js +53 -0
- package/dist/util/jsonWalk.js.map +1 -0
- package/dist/util/maybeAsync.d.ts +7 -0
- package/dist/util/maybeAsync.d.ts.map +1 -0
- package/dist/util/maybeAsync.js +56 -0
- package/dist/util/maybeAsync.js.map +1 -0
- package/dist/util/pathParsing.d.ts +11 -0
- package/dist/util/pathParsing.d.ts.map +1 -0
- package/dist/util/pathParsing.js +53 -0
- package/dist/util/pathParsing.js.map +1 -0
- package/dist/util/regexUtils.d.ts +3 -0
- package/dist/util/regexUtils.d.ts.map +1 -0
- package/dist/util/regexUtils.js +8 -0
- package/dist/util/regexUtils.js.map +1 -0
- package/dist/valuePatternMatcher.d.ts +15 -0
- package/dist/valuePatternMatcher.d.ts.map +1 -0
- package/dist/valuePatternMatcher.js +30 -0
- package/dist/valuePatternMatcher.js.map +1 -0
- package/docs/guides/anti-patterns.md +107 -0
- package/docs/guides/metadata-redaction.md +112 -0
- package/docs/guides/migration-1.2-to-1.5.md +106 -0
- package/docs/guides/migration-1.5-to-1.6.md +56 -0
- package/docs/guides/path-rules.md +47 -0
- package/docs/guides/secret-key-modes.md +108 -0
- package/docs/guides/value-pattern-redaction.md +58 -0
- package/docs/reference/config.md +139 -0
- package/docs/release-notes/2.0.0.md +19 -0
- package/docs/release-notes/2.1.0.md +17 -0
- package/docs/release-notes/2.2.0.md +16 -0
- package/docs/release-notes/2.3.0.md +17 -0
- package/docs/release-notes/2.3.1.md +17 -0
- package/docs/release-notes/2.4.0.md +30 -0
- package/docs/release-notes/2.5.0.md +33 -0
- package/docs/release-notes/2.5.1.md +17 -0
- package/docs/release-notes/README.md +32 -0
- package/docs/release-notes/v1.0.0.md +17 -0
- package/docs/release-notes/v1.1.0.md +18 -0
- package/docs/release-notes/v1.2.0.md +18 -0
- package/docs/release-notes/v1.2.1.md +16 -0
- package/docs/release-notes/v1.2.2.md +19 -0
- package/docs/release-notes/v1.3.0.md +112 -0
- package/docs/release-notes/v1.5.0.md +88 -0
- package/docs/release-notes/v1.6.0.md +59 -0
- package/jest.config.js +6 -1
- package/package.json +8 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CustomObjectManager } from './customObjectManager';
|
|
2
|
+
import { PathRuleMatcher } from './pathRuleMatcher';
|
|
3
|
+
import { SecretManager } from './secretManager';
|
|
4
|
+
import { ValuePatternMatcher } from './valuePatternMatcher';
|
|
5
|
+
import { CustomObject, DryRunPathRule, JsonValue, PathRule, SecretSpecifierValue } from '../types';
|
|
6
|
+
export type KeyRule = 'remove' | 'opaque' | 'deep' | 'shallow';
|
|
7
|
+
export type KeyRuleLabel = KeyRule | 'default';
|
|
8
|
+
export type FieldDisposition = {
|
|
9
|
+
action: 'default';
|
|
10
|
+
} | {
|
|
11
|
+
action: 'skip';
|
|
12
|
+
} | {
|
|
13
|
+
action: 'remove';
|
|
14
|
+
} | {
|
|
15
|
+
action: 'opaque';
|
|
16
|
+
} | {
|
|
17
|
+
action: 'deep';
|
|
18
|
+
} | {
|
|
19
|
+
action: 'shallow';
|
|
20
|
+
} | {
|
|
21
|
+
action: 'pass-key-recurse';
|
|
22
|
+
};
|
|
23
|
+
type AttributionContext = {
|
|
24
|
+
before: JsonValue | undefined;
|
|
25
|
+
path: string;
|
|
26
|
+
segments: Array<string | number>;
|
|
27
|
+
objectKeys: string[];
|
|
28
|
+
};
|
|
29
|
+
/** Shared path-rule + pass-key disposition used during traversal. */
|
|
30
|
+
export declare const resolvePathDisposition: (secretManager: SecretManager, pathRuleMatcher: PathRuleMatcher, key: string, pathSegments: Array<string | number>, forceDeepRedaction: boolean) => FieldDisposition;
|
|
31
|
+
/**
|
|
32
|
+
* Single source of truth for field-level rule precedence shared by traversal and dry-run attribution.
|
|
33
|
+
* Precedence: schema → path rule → enclosing opaque/deep key → leaf key rule → value pattern → default.
|
|
34
|
+
*/
|
|
35
|
+
export declare class RuleResolver {
|
|
36
|
+
private readonly secretManager;
|
|
37
|
+
private readonly pathRuleMatcher;
|
|
38
|
+
private readonly valuePatternMatcher;
|
|
39
|
+
private readonly customObjectManager;
|
|
40
|
+
constructor(secretManager: SecretManager, pathRuleMatcher: PathRuleMatcher, valuePatternMatcher: ValuePatternMatcher, customObjectManager: CustomObjectManager);
|
|
41
|
+
resolvePathDisposition(pathSegments: Array<string | number>, key: string, forceDeepRedaction: boolean): FieldDisposition;
|
|
42
|
+
getMatchingPathRule(segments: Array<string | number>): PathRule | undefined;
|
|
43
|
+
shouldRemoveByKey(key: SecretSpecifierValue): boolean;
|
|
44
|
+
shouldOpaqueByKey(key: SecretSpecifierValue): boolean;
|
|
45
|
+
shouldTraverseContainerByKey(key: SecretSpecifierValue, forceDeepRedaction: boolean): boolean;
|
|
46
|
+
containerForceDeepRedaction(key: SecretSpecifierValue, forceDeepRedaction: boolean): boolean;
|
|
47
|
+
nestedObjectForceDeepRedaction(key: SecretSpecifierValue, forceDeepRedaction: boolean): boolean;
|
|
48
|
+
attributeKeyRule(path: string, action: DryRunPathRule['action'], key: SecretSpecifierValue): DryRunPathRule;
|
|
49
|
+
findEnclosingOpaqueOrDeepKey(objectKeys: string[]): {
|
|
50
|
+
key: string;
|
|
51
|
+
rule: 'opaque' | 'deep';
|
|
52
|
+
} | undefined;
|
|
53
|
+
resolveSchemaAttribution(context: AttributionContext): DryRunPathRule | undefined;
|
|
54
|
+
resolvePathRuleAttribution(context: AttributionContext): DryRunPathRule | undefined;
|
|
55
|
+
resolveEnclosingKeyAttribution(context: AttributionContext): DryRunPathRule | undefined;
|
|
56
|
+
resolveLeafKeyAttribution(context: AttributionContext): DryRunPathRule | undefined;
|
|
57
|
+
resolveValuePatternAttribution(context: AttributionContext): DryRunPathRule | undefined;
|
|
58
|
+
attributeRedactPath(before: JsonValue | undefined, path: string): DryRunPathRule;
|
|
59
|
+
attributeDeletePath(before: JsonValue | undefined, path: string): DryRunPathRule;
|
|
60
|
+
/** Returns the matching schema when a shaped object should be handled at this node. */
|
|
61
|
+
getMatchingSchema(value: JsonValue): CustomObject | undefined;
|
|
62
|
+
}
|
|
63
|
+
export declare const buildPathRules: (before: JsonValue | undefined, redactedPaths: readonly string[], deletedPaths: readonly string[], resolver: RuleResolver) => DryRunPathRule[];
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=ruleResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleResolver.d.ts","sourceRoot":"","sources":["../../src/rules/ruleResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EACL,YAAY,EACZ,cAAc,EAGd,SAAS,EACT,QAAQ,EAER,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAEnC,KAAK,kBAAkB,GAAG;IACxB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAeF,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,kBAClB,aAAa,mBACX,eAAe,OAC3B,MAAM,gBACG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,sBAChB,OAAO,KAC1B,gBA4BF,CAAC;AAEF;;;GAGG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAHnB,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,mBAAmB,EAAE,mBAAmB;IAG3D,sBAAsB,CACpB,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,EACpC,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,OAAO,GAC1B,gBAAgB;IAInB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,QAAQ,GAAG,SAAS;IAK3E,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAIrD,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAIrD,4BAA4B,CAAC,GAAG,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO;IAQ7F,2BAA2B,CAAC,GAAG,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO;IAI5F,8BAA8B,CAAC,GAAG,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO;IAI/F,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAChC,GAAG,EAAE,oBAAoB,GACxB,cAAc;IASjB,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAE,GAAG,SAAS;IAYxG,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IA4BjF,0BAA0B,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IAanF,8BAA8B,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IAWvF,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IASlF,8BAA8B,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IAgBvF,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc;IA2BhF,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc;IAehF,uFAAuF;IACvF,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS;CAG9D;AAED,eAAO,MAAM,cAAc,WACjB,SAAS,GAAG,SAAS,iBACd,SAAS,MAAM,EAAE,gBAClB,SAAS,MAAM,EAAE,YACrB,YAAY,KACrB,cAAc,EAGhB,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildPathRules = exports.RuleResolver = exports.resolvePathDisposition = void 0;
|
|
4
|
+
const objectRedactorHelpers_1 = require("../engine/objectRedactorHelpers");
|
|
5
|
+
const jsonWalk_1 = require("../util/jsonWalk");
|
|
6
|
+
const pathParsing_1 = require("../util/pathParsing");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const objectKeysFromPath = (segments) => segments.filter((segment) => typeof segment === 'string');
|
|
9
|
+
const toPathRule = (path, action, rule, extras = {}) => (Object.assign({ path, action, rule }, extras));
|
|
10
|
+
const patternForKey = (secretManager, key, rule) => secretManager.getKeyRulePattern(key, rule);
|
|
11
|
+
/** Shared path-rule + pass-key disposition used during traversal. */
|
|
12
|
+
const resolvePathDisposition = (secretManager, pathRuleMatcher, key, pathSegments, forceDeepRedaction) => {
|
|
13
|
+
const pathRule = pathRuleMatcher.getMatchingRule([...pathSegments, key]);
|
|
14
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'pass') {
|
|
15
|
+
return { action: 'skip' };
|
|
16
|
+
}
|
|
17
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'remove') {
|
|
18
|
+
return { action: 'remove' };
|
|
19
|
+
}
|
|
20
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'opaque') {
|
|
21
|
+
return { action: 'opaque' };
|
|
22
|
+
}
|
|
23
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'deep') {
|
|
24
|
+
return { action: 'deep' };
|
|
25
|
+
}
|
|
26
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'shallow') {
|
|
27
|
+
return { action: 'shallow' };
|
|
28
|
+
}
|
|
29
|
+
if (forceDeepRedaction && secretManager.isPassKey(key)) {
|
|
30
|
+
return { action: 'pass-key-recurse' };
|
|
31
|
+
}
|
|
32
|
+
return { action: 'default' };
|
|
33
|
+
};
|
|
34
|
+
exports.resolvePathDisposition = resolvePathDisposition;
|
|
35
|
+
/**
|
|
36
|
+
* Single source of truth for field-level rule precedence shared by traversal and dry-run attribution.
|
|
37
|
+
* Precedence: schema → path rule → enclosing opaque/deep key → leaf key rule → value pattern → default.
|
|
38
|
+
*/
|
|
39
|
+
class RuleResolver {
|
|
40
|
+
constructor(secretManager, pathRuleMatcher, valuePatternMatcher, customObjectManager) {
|
|
41
|
+
this.secretManager = secretManager;
|
|
42
|
+
this.pathRuleMatcher = pathRuleMatcher;
|
|
43
|
+
this.valuePatternMatcher = valuePatternMatcher;
|
|
44
|
+
this.customObjectManager = customObjectManager;
|
|
45
|
+
}
|
|
46
|
+
resolvePathDisposition(pathSegments, key, forceDeepRedaction) {
|
|
47
|
+
return (0, exports.resolvePathDisposition)(this.secretManager, this.pathRuleMatcher, key, pathSegments, forceDeepRedaction);
|
|
48
|
+
}
|
|
49
|
+
getMatchingPathRule(segments) {
|
|
50
|
+
const match = this.pathRuleMatcher.getMatchingRule(segments);
|
|
51
|
+
return (match === null || match === void 0 ? void 0 : match.mode) === 'pass' ? undefined : match;
|
|
52
|
+
}
|
|
53
|
+
shouldRemoveByKey(key) {
|
|
54
|
+
return this.secretManager.isDeleteSecretKey(key);
|
|
55
|
+
}
|
|
56
|
+
shouldOpaqueByKey(key) {
|
|
57
|
+
return this.secretManager.isFullSecretKey(key);
|
|
58
|
+
}
|
|
59
|
+
shouldTraverseContainerByKey(key, forceDeepRedaction) {
|
|
60
|
+
return (this.secretManager.isSecretKey(key) ||
|
|
61
|
+
this.secretManager.isDeepSecretKey(key) ||
|
|
62
|
+
forceDeepRedaction);
|
|
63
|
+
}
|
|
64
|
+
containerForceDeepRedaction(key, forceDeepRedaction) {
|
|
65
|
+
return forceDeepRedaction || this.secretManager.isDeepSecretKey(key);
|
|
66
|
+
}
|
|
67
|
+
nestedObjectForceDeepRedaction(key, forceDeepRedaction) {
|
|
68
|
+
return forceDeepRedaction || this.secretManager.isDeepSecretKey(key);
|
|
69
|
+
}
|
|
70
|
+
attributeKeyRule(path, action, key) {
|
|
71
|
+
var _a;
|
|
72
|
+
const rule = (_a = this.secretManager.classifyKeyRule(key)) !== null && _a !== void 0 ? _a : 'default';
|
|
73
|
+
if (rule === 'default') {
|
|
74
|
+
return toPathRule(path, action, rule);
|
|
75
|
+
}
|
|
76
|
+
return toPathRule(path, action, rule, { pattern: patternForKey(this.secretManager, key, rule) });
|
|
77
|
+
}
|
|
78
|
+
findEnclosingOpaqueOrDeepKey(objectKeys) {
|
|
79
|
+
for (let index = objectKeys.length - 2; index >= 0; index--) {
|
|
80
|
+
const key = objectKeys[index];
|
|
81
|
+
const rule = this.secretManager.classifyKeyRule(key);
|
|
82
|
+
if (rule === 'opaque' || rule === 'deep') {
|
|
83
|
+
return { key, rule };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
resolveSchemaAttribution(context) {
|
|
89
|
+
const { parent, leaf } = (0, jsonWalk_1.getParentContext)(context.before, context.segments);
|
|
90
|
+
if (!(0, types_1.isJsonObject)(parent) || typeof leaf !== 'string') {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const schema = this.customObjectManager.getMatchingCustomObject(parent);
|
|
94
|
+
if (!schema || !(leaf in schema)) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
let pattern;
|
|
98
|
+
if (typeof schema[leaf] === 'string') {
|
|
99
|
+
const siblingSpecifier = (0, objectRedactorHelpers_1.getStringSpecifiedCustomObjectSecretKeyValueIfExists)(parent, schema, leaf);
|
|
100
|
+
if (siblingSpecifier !== undefined) {
|
|
101
|
+
const siblingRule = this.secretManager.classifyKeyRule(siblingSpecifier);
|
|
102
|
+
if (siblingRule && siblingRule !== 'default') {
|
|
103
|
+
pattern = patternForKey(this.secretManager, siblingSpecifier, siblingRule);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return toPathRule(context.path, 'redact', 'schema', Object.assign(Object.assign({}, this.customObjectManager.getSchemaMetadata(schema)), (pattern ? { pattern } : {})));
|
|
108
|
+
}
|
|
109
|
+
resolvePathRuleAttribution(context) {
|
|
110
|
+
const match = this.getMatchingPathRule(context.segments);
|
|
111
|
+
if (!match) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
if (match.mode === 'remove') {
|
|
115
|
+
return toPathRule(context.path, 'delete', 'remove', { pattern: match.path });
|
|
116
|
+
}
|
|
117
|
+
return toPathRule(context.path, 'redact', match.mode, { pattern: match.path });
|
|
118
|
+
}
|
|
119
|
+
resolveEnclosingKeyAttribution(context) {
|
|
120
|
+
const enclosing = this.findEnclosingOpaqueOrDeepKey(context.objectKeys);
|
|
121
|
+
if (!enclosing) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return toPathRule(context.path, 'redact', enclosing.rule, {
|
|
125
|
+
pattern: patternForKey(this.secretManager, enclosing.key, enclosing.rule)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
resolveLeafKeyAttribution(context) {
|
|
129
|
+
const leafKey = context.objectKeys.at(-1);
|
|
130
|
+
if (!leafKey || !this.secretManager.classifyKeyRule(leafKey)) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return this.attributeKeyRule(context.path, 'redact', leafKey);
|
|
134
|
+
}
|
|
135
|
+
resolveValuePatternAttribution(context) {
|
|
136
|
+
const value = (0, jsonWalk_1.getJsonValueAtPath)(context.before, context.segments);
|
|
137
|
+
if (value === undefined || (typeof value !== 'string' && typeof value !== 'number')) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
const match = this.valuePatternMatcher.findMatching((0, objectRedactorHelpers_1.toRedactablePrimitive)(value));
|
|
141
|
+
if (!match) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return toPathRule(context.path, 'redact', 'value', {
|
|
145
|
+
pattern: this.valuePatternMatcher.formatPattern(match)
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
attributeRedactPath(before, path) {
|
|
149
|
+
const segments = (0, pathParsing_1.parseJsonPath)(path);
|
|
150
|
+
const context = {
|
|
151
|
+
before,
|
|
152
|
+
path,
|
|
153
|
+
segments,
|
|
154
|
+
objectKeys: objectKeysFromPath(segments)
|
|
155
|
+
};
|
|
156
|
+
const resolvers = [
|
|
157
|
+
() => this.resolveSchemaAttribution(context),
|
|
158
|
+
() => this.resolvePathRuleAttribution(context),
|
|
159
|
+
() => this.resolveEnclosingKeyAttribution(context),
|
|
160
|
+
() => this.resolveLeafKeyAttribution(context),
|
|
161
|
+
() => this.resolveValuePatternAttribution(context)
|
|
162
|
+
];
|
|
163
|
+
for (const resolve of resolvers) {
|
|
164
|
+
const rule = resolve();
|
|
165
|
+
if (rule) {
|
|
166
|
+
return rule;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return toPathRule(path, 'redact', 'default');
|
|
170
|
+
}
|
|
171
|
+
attributeDeletePath(before, path) {
|
|
172
|
+
const segments = (0, pathParsing_1.parseJsonPath)(path);
|
|
173
|
+
const pathRule = this.getMatchingPathRule(segments);
|
|
174
|
+
if ((pathRule === null || pathRule === void 0 ? void 0 : pathRule.mode) === 'remove') {
|
|
175
|
+
return toPathRule(path, 'delete', 'remove', { pattern: pathRule.path });
|
|
176
|
+
}
|
|
177
|
+
const deleteKey = objectKeysFromPath(segments).at(-1);
|
|
178
|
+
if (deleteKey) {
|
|
179
|
+
return this.attributeKeyRule(path, 'delete', deleteKey);
|
|
180
|
+
}
|
|
181
|
+
return toPathRule(path, 'delete', 'default');
|
|
182
|
+
}
|
|
183
|
+
/** Returns the matching schema when a shaped object should be handled at this node. */
|
|
184
|
+
getMatchingSchema(value) {
|
|
185
|
+
return (0, types_1.isJsonObject)(value) ? this.customObjectManager.getMatchingCustomObject(value) : undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.RuleResolver = RuleResolver;
|
|
189
|
+
const buildPathRules = (before, redactedPaths, deletedPaths, resolver) => [
|
|
190
|
+
...deletedPaths.map((path) => resolver.attributeDeletePath(before, path)),
|
|
191
|
+
...redactedPaths.map((path) => resolver.attributeRedactPath(before, path))
|
|
192
|
+
];
|
|
193
|
+
exports.buildPathRules = buildPathRules;
|
|
194
|
+
//# sourceMappingURL=ruleResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleResolver.js","sourceRoot":"","sources":["../../src/rules/ruleResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SecretManagerConfig, SecretSpecifierValue } from '../types';
|
|
2
|
+
type KeyRule = 'remove' | 'opaque' | 'deep' | 'shallow';
|
|
3
|
+
/**
|
|
4
|
+
* Utility class for managing secrets and determining if a given value is a secret of any type. If no secrets of
|
|
5
|
+
* any type are provided in the configuration then all values are considered secrets (but not deep or full secrets).
|
|
6
|
+
*/
|
|
7
|
+
export declare class SecretManager {
|
|
8
|
+
private secretKeys?;
|
|
9
|
+
private deepSecretKeys?;
|
|
10
|
+
private fullSecretKeys?;
|
|
11
|
+
private deleteSecretKeys?;
|
|
12
|
+
private passKeys?;
|
|
13
|
+
constructor(config: SecretManagerConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Determines if the given key is a secret. If no secrets of any type are provided then this function
|
|
16
|
+
* always returns true.
|
|
17
|
+
*/
|
|
18
|
+
isSecretKey(key: SecretSpecifierValue): boolean;
|
|
19
|
+
isDeepSecretKey(key: SecretSpecifierValue): boolean;
|
|
20
|
+
isFullSecretKey(key: SecretSpecifierValue): boolean;
|
|
21
|
+
isDeleteSecretKey(key: SecretSpecifierValue): boolean;
|
|
22
|
+
/** Determines if a key is allowlisted and should not be redacted under deep parents. */
|
|
23
|
+
isPassKey(key: SecretSpecifierValue): boolean;
|
|
24
|
+
getKeyRulePattern(key: SecretSpecifierValue, rule: KeyRule): string | undefined;
|
|
25
|
+
classifyKeyRule(key: SecretSpecifierValue): KeyRule | 'default' | null;
|
|
26
|
+
private matchesRule;
|
|
27
|
+
private regexListFor;
|
|
28
|
+
private static findMatchingRegex;
|
|
29
|
+
private static matchesAnyRegex;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=secretManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secretManager.d.ts","sourceRoot":"","sources":["../../src/rules/secretManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErE,KAAK,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAIxD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAC,CAAW;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAW;IAClC,OAAO,CAAC,cAAc,CAAC,CAAW;IAClC,OAAO,CAAC,gBAAgB,CAAC,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,CAAW;gBAEhB,MAAM,EAAE,mBAAmB;IAavC;;;OAGG;IACI,WAAW,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAQ/C,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAInD,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAInD,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAI5D,wFAAwF;IACjF,SAAS,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAI7C,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAK/E,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI;IAc7E,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAIhC,OAAO,CAAC,MAAM,CAAC,eAAe;CAG/B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SecretManager = void 0;
|
|
4
|
+
const regexUtils_1 = require("../util/regexUtils");
|
|
5
|
+
const KEY_RULE_PRECEDENCE = ['remove', 'opaque', 'deep', 'shallow'];
|
|
6
|
+
/**
|
|
7
|
+
* Utility class for managing secrets and determining if a given value is a secret of any type. If no secrets of
|
|
8
|
+
* any type are provided in the configuration then all values are considered secrets (but not deep or full secrets).
|
|
9
|
+
*/
|
|
10
|
+
class SecretManager {
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.deepSecretKeys = config.deepSecretKeys;
|
|
13
|
+
this.fullSecretKeys = config.fullSecretKeys;
|
|
14
|
+
this.deleteSecretKeys = config.deleteSecretKeys;
|
|
15
|
+
this.passKeys = config.passKeys;
|
|
16
|
+
if (!config.secretKeys && (config.deepSecretKeys || config.fullSecretKeys || config.deleteSecretKeys)) {
|
|
17
|
+
this.secretKeys = [];
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.secretKeys = config.secretKeys;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Determines if the given key is a secret. If no secrets of any type are provided then this function
|
|
25
|
+
* always returns true.
|
|
26
|
+
*/
|
|
27
|
+
isSecretKey(key) {
|
|
28
|
+
if (!this.secretKeys) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return this.matchesRule(key, 'shallow');
|
|
32
|
+
}
|
|
33
|
+
isDeepSecretKey(key) {
|
|
34
|
+
return this.matchesRule(key, 'deep');
|
|
35
|
+
}
|
|
36
|
+
isFullSecretKey(key) {
|
|
37
|
+
return this.matchesRule(key, 'opaque');
|
|
38
|
+
}
|
|
39
|
+
isDeleteSecretKey(key) {
|
|
40
|
+
return this.matchesRule(key, 'remove');
|
|
41
|
+
}
|
|
42
|
+
/** Determines if a key is allowlisted and should not be redacted under deep parents. */
|
|
43
|
+
isPassKey(key) {
|
|
44
|
+
return !!this.passKeys && SecretManager.matchesAnyRegex(key, this.passKeys);
|
|
45
|
+
}
|
|
46
|
+
getKeyRulePattern(key, rule) {
|
|
47
|
+
const match = SecretManager.findMatchingRegex(key, this.regexListFor(rule));
|
|
48
|
+
return match ? (0, regexUtils_1.formatRegExp)(match) : undefined;
|
|
49
|
+
}
|
|
50
|
+
classifyKeyRule(key) {
|
|
51
|
+
for (const rule of KEY_RULE_PRECEDENCE) {
|
|
52
|
+
if (this.matchesRule(key, rule)) {
|
|
53
|
+
return rule;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (this.isSecretKey(key)) {
|
|
57
|
+
return this.secretKeys ? 'shallow' : 'default';
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
matchesRule(key, rule) {
|
|
62
|
+
const regexes = this.regexListFor(rule);
|
|
63
|
+
return !!regexes && SecretManager.matchesAnyRegex(key, regexes);
|
|
64
|
+
}
|
|
65
|
+
regexListFor(rule) {
|
|
66
|
+
switch (rule) {
|
|
67
|
+
case 'remove':
|
|
68
|
+
return this.deleteSecretKeys;
|
|
69
|
+
case 'opaque':
|
|
70
|
+
return this.fullSecretKeys;
|
|
71
|
+
case 'deep':
|
|
72
|
+
return this.deepSecretKeys;
|
|
73
|
+
case 'shallow':
|
|
74
|
+
return this.secretKeys;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
static findMatchingRegex(key, regexes) {
|
|
78
|
+
return regexes === null || regexes === void 0 ? void 0 : regexes.find((regex) => regex.test(String(key)));
|
|
79
|
+
}
|
|
80
|
+
static matchesAnyRegex(value, regexes) {
|
|
81
|
+
return regexes.some((regex) => regex.test(String(value)));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.SecretManager = SecretManager;
|
|
85
|
+
//# sourceMappingURL=secretManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secretManager.js","sourceRoot":"","sources":["../../src/rules/secretManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RedactablePrimitive } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Opt-in regex matching against scalar **values** (not key names).
|
|
4
|
+
* Applied only when key-based rules do not already redact the field.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ValuePatternMatcher {
|
|
7
|
+
private readonly patterns;
|
|
8
|
+
constructor(patterns?: RegExp[]);
|
|
9
|
+
hasPatterns(): boolean;
|
|
10
|
+
findMatching(value: RedactablePrimitive | undefined): RegExp | undefined;
|
|
11
|
+
formatPattern(regex: RegExp): string;
|
|
12
|
+
}
|
|
13
|
+
/** Shared empty matcher for tests and configs without value patterns. */
|
|
14
|
+
export declare const EMPTY_VALUE_PATTERN_MATCHER: ValuePatternMatcher;
|
|
15
|
+
//# sourceMappingURL=valuePatternMatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valuePatternMatcher.d.ts","sourceRoot":"","sources":["../../src/rules/valuePatternMatcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,QAAQ,CAAC,EAAE,MAAM,EAAE;IAIxB,WAAW,IAAI,OAAO;IAItB,YAAY,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS;IASxE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAG5C;AAED,yEAAyE;AACzE,eAAO,MAAM,2BAA2B,qBAA4B,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EMPTY_VALUE_PATTERN_MATCHER = exports.ValuePatternMatcher = void 0;
|
|
4
|
+
const regexUtils_1 = require("../util/regexUtils");
|
|
5
|
+
/**
|
|
6
|
+
* Opt-in regex matching against scalar **values** (not key names).
|
|
7
|
+
* Applied only when key-based rules do not already redact the field.
|
|
8
|
+
*/
|
|
9
|
+
class ValuePatternMatcher {
|
|
10
|
+
constructor(patterns) {
|
|
11
|
+
this.patterns = patterns !== null && patterns !== void 0 ? patterns : [];
|
|
12
|
+
}
|
|
13
|
+
hasPatterns() {
|
|
14
|
+
return this.patterns.length > 0;
|
|
15
|
+
}
|
|
16
|
+
findMatching(value) {
|
|
17
|
+
if (value === undefined || value === null || typeof value === 'boolean') {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const text = String(value);
|
|
21
|
+
return this.patterns.find((pattern) => pattern.test(text));
|
|
22
|
+
}
|
|
23
|
+
formatPattern(regex) {
|
|
24
|
+
return (0, regexUtils_1.formatRegExp)(regex);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.ValuePatternMatcher = ValuePatternMatcher;
|
|
28
|
+
/** Shared empty matcher for tests and configs without value patterns. */
|
|
29
|
+
exports.EMPTY_VALUE_PATTERN_MATCHER = new ValuePatternMatcher();
|
|
30
|
+
//# sourceMappingURL=valuePatternMatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valuePatternMatcher.js","sourceRoot":"","sources":["../../src/rules/valuePatternMatcher.ts"],"names":[],"mappings":";;;AAAA,mDAAkD;AAGlD;;;GAGG;AACH,MAAa,mBAAmB;IAG9B,YAAY,QAAmB;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC;IACjC,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAEM,YAAY,CAAC,KAAsC;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACxE,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,CAAC;IAEM,aAAa,CAAC,KAAa;QAChC,OAAO,IAAA,yBAAY,EAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF;AAvBD,kDAuBC;AAED,yEAAyE;AAC5D,QAAA,2BAA2B,GAAG,IAAI,mBAAmB,EAAE,CAAC"}
|
package/dist/secretManager.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { SecretManagerConfig } from './types';
|
|
1
|
+
import { SecretManagerConfig, SecretSpecifierValue } from './types';
|
|
2
|
+
type KeyRule = 'remove' | 'opaque' | 'deep' | 'shallow';
|
|
2
3
|
/**
|
|
3
|
-
* Utility class for managing secrets and determining if a
|
|
4
|
+
* Utility class for managing secrets and determining if a given value is a secret of any type. If no secrets of
|
|
4
5
|
* any type are provided in the configuration then all values are considered secrets (but not deep or full secrets).
|
|
5
6
|
*/
|
|
6
7
|
export declare class SecretManager {
|
|
@@ -8,32 +9,24 @@ export declare class SecretManager {
|
|
|
8
9
|
private deepSecretKeys?;
|
|
9
10
|
private fullSecretKeys?;
|
|
10
11
|
private deleteSecretKeys?;
|
|
12
|
+
private passKeys?;
|
|
11
13
|
constructor(config: SecretManagerConfig);
|
|
12
14
|
/**
|
|
13
15
|
* Determines if the given key is a secret. If no secrets of any type are provided then this function
|
|
14
16
|
* always returns true.
|
|
15
|
-
* @param key The key to check.
|
|
16
|
-
* @returns True if the key is a secret key or no secret keys exist, otherwise false.
|
|
17
17
|
*/
|
|
18
|
-
isSecretKey(key:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
isFullSecretKey(key: string): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Determines if a key is a delete secret based on the deleteSecretKeys configuration provided in the constructor.
|
|
33
|
-
* @param key The key to check.
|
|
34
|
-
* @returns True if the key is a delete secret key, otherwise false.
|
|
35
|
-
*/
|
|
36
|
-
isDeleteSecretKey(key: string): boolean;
|
|
37
|
-
private static valueMatchesAnyRegexValue;
|
|
18
|
+
isSecretKey(key: SecretSpecifierValue): boolean;
|
|
19
|
+
isDeepSecretKey(key: SecretSpecifierValue): boolean;
|
|
20
|
+
isFullSecretKey(key: SecretSpecifierValue): boolean;
|
|
21
|
+
isDeleteSecretKey(key: SecretSpecifierValue): boolean;
|
|
22
|
+
/** Determines if a key is allowlisted and should not be redacted under deep parents. */
|
|
23
|
+
isPassKey(key: SecretSpecifierValue): boolean;
|
|
24
|
+
getKeyRulePattern(key: SecretSpecifierValue, rule: KeyRule): string | undefined;
|
|
25
|
+
classifyKeyRule(key: SecretSpecifierValue): KeyRule | 'default' | null;
|
|
26
|
+
private matchesRule;
|
|
27
|
+
private regexListFor;
|
|
28
|
+
private static findMatchingRegex;
|
|
29
|
+
private static matchesAnyRegex;
|
|
38
30
|
}
|
|
31
|
+
export {};
|
|
39
32
|
//# sourceMappingURL=secretManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretManager.d.ts","sourceRoot":"","sources":["../src/secretManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secretManager.d.ts","sourceRoot":"","sources":["../src/secretManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpE,KAAK,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAIxD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAC,CAAW;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAW;IAClC,OAAO,CAAC,cAAc,CAAC,CAAW;IAClC,OAAO,CAAC,gBAAgB,CAAC,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,CAAW;gBAEhB,MAAM,EAAE,mBAAmB;IAavC;;;OAGG;IACI,WAAW,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAQ/C,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAInD,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAInD,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAI5D,wFAAwF;IACjF,SAAS,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO;IAI7C,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAK/E,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI;IAc7E,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAIhC,OAAO,CAAC,MAAM,CAAC,eAAe;CAG/B"}
|
package/dist/secretManager.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SecretManager = void 0;
|
|
4
|
+
const regexUtils_1 = require("./regexUtils");
|
|
5
|
+
const KEY_RULE_PRECEDENCE = ['remove', 'opaque', 'deep', 'shallow'];
|
|
4
6
|
/**
|
|
5
|
-
* Utility class for managing secrets and determining if a
|
|
7
|
+
* Utility class for managing secrets and determining if a given value is a secret of any type. If no secrets of
|
|
6
8
|
* any type are provided in the configuration then all values are considered secrets (but not deep or full secrets).
|
|
7
9
|
*/
|
|
8
10
|
class SecretManager {
|
|
@@ -10,6 +12,7 @@ class SecretManager {
|
|
|
10
12
|
this.deepSecretKeys = config.deepSecretKeys;
|
|
11
13
|
this.fullSecretKeys = config.fullSecretKeys;
|
|
12
14
|
this.deleteSecretKeys = config.deleteSecretKeys;
|
|
15
|
+
this.passKeys = config.passKeys;
|
|
13
16
|
if (!config.secretKeys && (config.deepSecretKeys || config.fullSecretKeys || config.deleteSecretKeys)) {
|
|
14
17
|
this.secretKeys = [];
|
|
15
18
|
}
|
|
@@ -20,50 +23,62 @@ class SecretManager {
|
|
|
20
23
|
/**
|
|
21
24
|
* Determines if the given key is a secret. If no secrets of any type are provided then this function
|
|
22
25
|
* always returns true.
|
|
23
|
-
* @param key The key to check.
|
|
24
|
-
* @returns True if the key is a secret key or no secret keys exist, otherwise false.
|
|
25
26
|
*/
|
|
26
27
|
isSecretKey(key) {
|
|
27
28
|
if (!this.secretKeys) {
|
|
28
29
|
return true;
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return this.matchesRule(key, 'shallow');
|
|
31
32
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Determines if a key is a deep secret based on the deepSecretKeys configuration provided in the constructor.
|
|
34
|
-
* @param key The key to check.
|
|
35
|
-
* @returns True if the key is a deep secret key, otherwise false.
|
|
36
|
-
*/
|
|
37
33
|
isDeepSecretKey(key) {
|
|
38
|
-
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
return SecretManager.valueMatchesAnyRegexValue(key, this.deepSecretKeys);
|
|
34
|
+
return this.matchesRule(key, 'deep');
|
|
42
35
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Determines if a key is a full secret based on the fullSecretKeys configuration provided in the constructor.
|
|
45
|
-
* @param key The key to check.
|
|
46
|
-
* @returns True if the key is a full secret key, otherwise false.
|
|
47
|
-
*/
|
|
48
36
|
isFullSecretKey(key) {
|
|
49
|
-
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
return SecretManager.valueMatchesAnyRegexValue(key, this.fullSecretKeys);
|
|
37
|
+
return this.matchesRule(key, 'opaque');
|
|
53
38
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Determines if a key is a delete secret based on the deleteSecretKeys configuration provided in the constructor.
|
|
56
|
-
* @param key The key to check.
|
|
57
|
-
* @returns True if the key is a delete secret key, otherwise false.
|
|
58
|
-
*/
|
|
59
39
|
isDeleteSecretKey(key) {
|
|
60
|
-
|
|
61
|
-
|
|
40
|
+
return this.matchesRule(key, 'remove');
|
|
41
|
+
}
|
|
42
|
+
/** Determines if a key is allowlisted and should not be redacted under deep parents. */
|
|
43
|
+
isPassKey(key) {
|
|
44
|
+
return !!this.passKeys && SecretManager.matchesAnyRegex(key, this.passKeys);
|
|
45
|
+
}
|
|
46
|
+
getKeyRulePattern(key, rule) {
|
|
47
|
+
const match = SecretManager.findMatchingRegex(key, this.regexListFor(rule));
|
|
48
|
+
return match ? (0, regexUtils_1.formatRegExp)(match) : undefined;
|
|
49
|
+
}
|
|
50
|
+
classifyKeyRule(key) {
|
|
51
|
+
for (const rule of KEY_RULE_PRECEDENCE) {
|
|
52
|
+
if (this.matchesRule(key, rule)) {
|
|
53
|
+
return rule;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (this.isSecretKey(key)) {
|
|
57
|
+
return this.secretKeys ? 'shallow' : 'default';
|
|
62
58
|
}
|
|
63
|
-
return
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
matchesRule(key, rule) {
|
|
62
|
+
const regexes = this.regexListFor(rule);
|
|
63
|
+
return !!regexes && SecretManager.matchesAnyRegex(key, regexes);
|
|
64
|
+
}
|
|
65
|
+
regexListFor(rule) {
|
|
66
|
+
switch (rule) {
|
|
67
|
+
case 'remove':
|
|
68
|
+
return this.deleteSecretKeys;
|
|
69
|
+
case 'opaque':
|
|
70
|
+
return this.fullSecretKeys;
|
|
71
|
+
case 'deep':
|
|
72
|
+
return this.deepSecretKeys;
|
|
73
|
+
case 'shallow':
|
|
74
|
+
return this.secretKeys;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
static findMatchingRegex(key, regexes) {
|
|
78
|
+
return regexes === null || regexes === void 0 ? void 0 : regexes.find((regex) => regex.test(String(key)));
|
|
64
79
|
}
|
|
65
|
-
static
|
|
66
|
-
return regexes.some((regex) => regex.test(value));
|
|
80
|
+
static matchesAnyRegex(value, regexes) {
|
|
81
|
+
return regexes.some((regex) => regex.test(String(value)));
|
|
67
82
|
}
|
|
68
83
|
}
|
|
69
84
|
exports.SecretManager = SecretManager;
|