@j-schreiber/sf-cli-security-audit 0.2.0 → 0.4.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/README.md +10 -2
- package/lib/commands/org/audit/init.d.ts +17 -0
- package/lib/commands/org/audit/init.js +61 -0
- package/lib/commands/org/audit/init.js.map +1 -0
- package/lib/commands/org/audit/run.d.ts +22 -0
- package/lib/commands/org/audit/run.js +113 -0
- package/lib/commands/org/audit/run.js.map +1 -0
- package/lib/libs/audit/types.d.ts +154 -0
- package/lib/libs/audit/types.js +2 -0
- package/lib/libs/audit/types.js.map +1 -0
- package/lib/libs/config/audit-run/auditConfigFileManager.d.ts +26 -0
- package/lib/libs/config/audit-run/auditConfigFileManager.js +98 -0
- package/lib/libs/config/audit-run/auditConfigFileManager.js.map +1 -0
- package/lib/libs/config/audit-run/schema.d.ts +100 -0
- package/lib/libs/config/audit-run/schema.js +45 -0
- package/lib/libs/config/audit-run/schema.js.map +1 -0
- package/lib/libs/config/defaultPolicyClassification.d.ts +2 -0
- package/lib/libs/config/defaultPolicyClassification.js +63 -0
- package/lib/libs/config/defaultPolicyClassification.js.map +1 -0
- package/lib/libs/config/queries.d.ts +5 -0
- package/lib/libs/config/queries.js +6 -0
- package/lib/libs/config/queries.js.map +1 -0
- package/lib/libs/config/registries/connectedApps.d.ts +5 -0
- package/lib/libs/config/registries/connectedApps.js +13 -0
- package/lib/libs/config/registries/connectedApps.js.map +1 -0
- package/lib/libs/config/registries/permissionSets.d.ts +5 -0
- package/lib/libs/config/registries/permissionSets.js +11 -0
- package/lib/libs/config/registries/permissionSets.js.map +1 -0
- package/lib/libs/config/registries/profiles.d.ts +5 -0
- package/lib/libs/config/registries/profiles.js +13 -0
- package/lib/libs/config/registries/profiles.js.map +1 -0
- package/lib/libs/config/registries/ruleRegistry.d.ts +29 -0
- package/lib/libs/config/registries/ruleRegistry.js +48 -0
- package/lib/libs/config/registries/ruleRegistry.js.map +1 -0
- package/lib/libs/config/registries/types.d.ts +7 -0
- package/lib/libs/config/registries/types.js +2 -0
- package/lib/libs/config/registries/types.js.map +1 -0
- package/lib/libs/mdapiRetriever.d.ts +18 -0
- package/lib/libs/mdapiRetriever.js +60 -0
- package/lib/libs/mdapiRetriever.js.map +1 -0
- package/lib/libs/policies/auditRun.d.ts +36 -0
- package/lib/libs/policies/auditRun.js +92 -0
- package/lib/libs/policies/auditRun.js.map +1 -0
- package/lib/libs/policies/connectedAppPolicy.d.ts +18 -0
- package/lib/libs/policies/connectedAppPolicy.js +78 -0
- package/lib/libs/policies/connectedAppPolicy.js.map +1 -0
- package/lib/libs/policies/initialisation/auditConfig.d.ts +27 -0
- package/lib/libs/policies/initialisation/auditConfig.js +41 -0
- package/lib/libs/policies/initialisation/auditConfig.js.map +1 -0
- package/lib/libs/policies/initialisation/permissionsClassification.d.ts +17 -0
- package/lib/libs/policies/initialisation/permissionsClassification.js +71 -0
- package/lib/libs/policies/initialisation/permissionsClassification.js.map +1 -0
- package/lib/libs/policies/initialisation/policyConfigs.d.ts +25 -0
- package/lib/libs/policies/initialisation/policyConfigs.js +67 -0
- package/lib/libs/policies/initialisation/policyConfigs.js.map +1 -0
- package/lib/libs/policies/interfaces/policyRuleInterfaces.d.ts +30 -0
- package/lib/libs/policies/interfaces/policyRuleInterfaces.js +2 -0
- package/lib/libs/policies/interfaces/policyRuleInterfaces.js.map +1 -0
- package/lib/libs/policies/permissionSetPolicy.d.ts +17 -0
- package/lib/libs/policies/permissionSetPolicy.js +61 -0
- package/lib/libs/policies/permissionSetPolicy.js.map +1 -0
- package/lib/libs/policies/policy.d.ts +32 -0
- package/lib/libs/policies/policy.js +95 -0
- package/lib/libs/policies/policy.js.map +1 -0
- package/lib/libs/policies/profilePolicy.d.ts +17 -0
- package/lib/libs/policies/profilePolicy.js +71 -0
- package/lib/libs/policies/profilePolicy.js.map +1 -0
- package/lib/libs/policies/rules/allUsedAppsUnderManagement.d.ts +7 -0
- package/lib/libs/policies/rules/allUsedAppsUnderManagement.js +23 -0
- package/lib/libs/policies/rules/allUsedAppsUnderManagement.js.map +1 -0
- package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.d.ts +7 -0
- package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.js +51 -0
- package/lib/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.js.map +1 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.d.ts +7 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.js +51 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnPermSets.js.map +1 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.d.ts +7 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.js +53 -0
- package/lib/libs/policies/rules/enforceUserPermsClassificationOnProfiles.js.map +1 -0
- package/lib/libs/policies/rules/noUserCanSelfAuthorize.d.ts +7 -0
- package/lib/libs/policies/rules/noUserCanSelfAuthorize.js +31 -0
- package/lib/libs/policies/rules/noUserCanSelfAuthorize.js.map +1 -0
- package/lib/libs/policies/rules/policyRule.d.ts +16 -0
- package/lib/libs/policies/rules/policyRule.js +29 -0
- package/lib/libs/policies/rules/policyRule.js.map +1 -0
- package/lib/libs/policies/salesforceStandardTypes.d.ts +39 -0
- package/lib/libs/policies/salesforceStandardTypes.js +2 -0
- package/lib/libs/policies/salesforceStandardTypes.js.map +1 -0
- package/lib/libs/policies/types.d.ts +36 -0
- package/lib/libs/policies/types.js +45 -0
- package/lib/libs/policies/types.js.map +1 -0
- package/lib/libs/utils.d.ts +3 -0
- package/lib/libs/utils.js +13 -0
- package/lib/libs/utils.js.map +1 -0
- package/lib/ux/auditRunMultiStage.d.ts +65 -0
- package/lib/ux/auditRunMultiStage.js +117 -0
- package/lib/ux/auditRunMultiStage.js.map +1 -0
- package/messages/org.audit.init.md +1 -1
- package/messages/org.audit.run.md +0 -4
- package/messages/policies.general.md +12 -0
- package/messages/rules.connectedApps.md +11 -0
- package/oclif.manifest.json +159 -2
- package/package.json +2 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import PolicyRule from './policyRule.js';
|
|
3
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
4
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.connectedApps');
|
|
5
|
+
export default class AllUsedAppsUnderManagement extends PolicyRule {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts);
|
|
8
|
+
}
|
|
9
|
+
run(context) {
|
|
10
|
+
const result = this.initResult();
|
|
11
|
+
const resolvedConnectedApps = context.resolvedEntities;
|
|
12
|
+
Object.values(resolvedConnectedApps).forEach((app) => {
|
|
13
|
+
if (app.origin === 'OauthToken') {
|
|
14
|
+
result.violations.push({
|
|
15
|
+
identifier: [app.name],
|
|
16
|
+
message: messages.getMessage('violations.app-used-but-not-registered', [app.users.length, app.useCount]),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return Promise.resolve(result);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=allUsedAppsUnderManagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allUsedAppsUnderManagement.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/allUsedAppsUnderManagement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,qBAAqB,CAAC,CAAC;AAEpG,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,UAAgC;IACtF,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA+C;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;oBACrB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;oBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wCAAwC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;iBACzG,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
|
|
2
|
+
import { ResolvedProfile } from '../profilePolicy.js';
|
|
3
|
+
import PolicyRule, { RuleOptions } from './policyRule.js';
|
|
4
|
+
export default class EnforceCustomPermsClassificationOnProfiles extends PolicyRule<ResolvedProfile> {
|
|
5
|
+
constructor(opts: RuleOptions);
|
|
6
|
+
run(context: RuleAuditContext<ResolvedProfile>): Promise<PartialPolicyRuleResult>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
|
|
3
|
+
import PolicyRule from './policyRule.js';
|
|
4
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
|
|
5
|
+
export default class EnforceCustomPermsClassificationOnProfiles extends PolicyRule {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts);
|
|
8
|
+
}
|
|
9
|
+
run(context) {
|
|
10
|
+
const result = this.initResult();
|
|
11
|
+
const resolvedProfiles = context.resolvedEntities;
|
|
12
|
+
Object.values(resolvedProfiles).forEach((profile) => {
|
|
13
|
+
const customPerms = profile.metadata.customPermissions ?? [];
|
|
14
|
+
customPerms.forEach((perm) => {
|
|
15
|
+
const identifier = [profile.name, perm.name];
|
|
16
|
+
const classifiedPerm = this.resolveCustomPermission(perm.name);
|
|
17
|
+
if (classifiedPerm) {
|
|
18
|
+
if (classifiedPerm.classification === PolicyRiskLevel.BLOCKED) {
|
|
19
|
+
result.violations.push({
|
|
20
|
+
identifier,
|
|
21
|
+
message: messages.getMessage('violations.permission-is-blocked'),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (!permissionAllowedInPreset(classifiedPerm.classification, profile.preset)) {
|
|
25
|
+
result.violations.push({
|
|
26
|
+
identifier,
|
|
27
|
+
message: messages.getMessage('violations.classification-preset-mismatch', [
|
|
28
|
+
classifiedPerm.classification,
|
|
29
|
+
profile.preset,
|
|
30
|
+
]),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else if (classifiedPerm.classification === PolicyRiskLevel.UNKNOWN) {
|
|
34
|
+
result.warnings.push({
|
|
35
|
+
identifier,
|
|
36
|
+
message: messages.getMessage('warnings.permission-unknown'),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
result.warnings.push({
|
|
42
|
+
identifier,
|
|
43
|
+
message: messages.getMessage('warnings.permission-not-classified-in-profile'),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return Promise.resolve(result);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=enforceCustomPermsClassificationOnProfiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforceCustomPermsClassificationOnProfiles.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceCustomPermsClassificationOnProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,0CAA2C,SAAQ,UAA2B;IACjG,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA0C;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,EAAE,CAAC;YAC7D,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC3B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,IAAI,cAAc,EAAE,CAAC;oBACnB,IAAI,cAAc,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBAC9D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;yBACjE,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBACrF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;gCACxE,cAAc,CAAC,cAAc;gCAC7B,OAAO,CAAC,MAAM;6BACf,CAAC;yBACH,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,cAAc,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBACrE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;yBAC5D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU;wBACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,+CAA+C,CAAC;qBAC9E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
|
|
2
|
+
import { ResolvedPermissionSet } from '../permissionSetPolicy.js';
|
|
3
|
+
import PolicyRule, { RuleOptions } from './policyRule.js';
|
|
4
|
+
export default class EnforceUserPermsClassificationOnPermSets extends PolicyRule<ResolvedPermissionSet> {
|
|
5
|
+
constructor(opts: RuleOptions);
|
|
6
|
+
run(context: RuleAuditContext<ResolvedPermissionSet>): Promise<PartialPolicyRuleResult>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
|
|
3
|
+
import PolicyRule from './policyRule.js';
|
|
4
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
|
|
5
|
+
export default class EnforceUserPermsClassificationOnPermSets extends PolicyRule {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts);
|
|
8
|
+
}
|
|
9
|
+
run(context) {
|
|
10
|
+
const result = this.initResult();
|
|
11
|
+
const resolvedPermsets = context.resolvedEntities;
|
|
12
|
+
Object.values(resolvedPermsets).forEach((permset) => {
|
|
13
|
+
const userPerms = permset.metadata.userPermissions ?? [];
|
|
14
|
+
userPerms.forEach((userPerm) => {
|
|
15
|
+
const identifier = [permset.name, userPerm.name];
|
|
16
|
+
const classifiedUserPerm = this.resolveUserPermission(userPerm.name);
|
|
17
|
+
if (classifiedUserPerm) {
|
|
18
|
+
if (classifiedUserPerm.classification === PolicyRiskLevel.BLOCKED) {
|
|
19
|
+
result.violations.push({
|
|
20
|
+
identifier,
|
|
21
|
+
message: messages.getMessage('violations.permission-is-blocked'),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (!permissionAllowedInPreset(classifiedUserPerm.classification, permset.preset)) {
|
|
25
|
+
result.violations.push({
|
|
26
|
+
identifier,
|
|
27
|
+
message: messages.getMessage('violations.classification-preset-mismatch', [
|
|
28
|
+
classifiedUserPerm.classification,
|
|
29
|
+
permset.preset,
|
|
30
|
+
]),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else if (classifiedUserPerm.classification === PolicyRiskLevel.UNKNOWN) {
|
|
34
|
+
result.warnings.push({
|
|
35
|
+
identifier,
|
|
36
|
+
message: messages.getMessage('warnings.permission-unknown'),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
result.warnings.push({
|
|
42
|
+
identifier,
|
|
43
|
+
message: messages.getMessage('warnings.permission-not-classified-in-permission-set'),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return Promise.resolve(result);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=enforceUserPermsClassificationOnPermSets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforceUserPermsClassificationOnPermSets.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceUserPermsClassificationOnPermSets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,wCAAyC,SAAQ,UAAiC;IACrG,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAAgD;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;YACzD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC7B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACrE,IAAI,kBAAkB,EAAE,CAAC;oBACvB,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBAClE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;yBACjE,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBACzF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;4BACrB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;gCACxE,kBAAkB,CAAC,cAAc;gCACjC,OAAO,CAAC,MAAM;6BACf,CAAC;yBACH,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;wBACzE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;yBAC5D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU;wBACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sDAAsD,CAAC;qBACrF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
|
|
2
|
+
import { ResolvedProfile } from '../profilePolicy.js';
|
|
3
|
+
import PolicyRule, { RuleOptions } from './policyRule.js';
|
|
4
|
+
export default class EnforceUserPermsClassificationOnProfiles extends PolicyRule<ResolvedProfile> {
|
|
5
|
+
constructor(opts: RuleOptions);
|
|
6
|
+
run(context: RuleAuditContext<ResolvedProfile>): Promise<PartialPolicyRuleResult>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import { isNullish } from '../../utils.js';
|
|
3
|
+
import { permissionAllowedInPreset, PolicyRiskLevel } from '../types.js';
|
|
4
|
+
import PolicyRule from './policyRule.js';
|
|
5
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
|
|
6
|
+
export default class EnforceUserPermsClassificationOnProfiles extends PolicyRule {
|
|
7
|
+
constructor(opts) {
|
|
8
|
+
super(opts);
|
|
9
|
+
}
|
|
10
|
+
run(context) {
|
|
11
|
+
const result = this.initResult();
|
|
12
|
+
const resolvedProfiles = context.resolvedEntities;
|
|
13
|
+
Object.values(resolvedProfiles).forEach((profile) => {
|
|
14
|
+
if (!isNullish(profile.metadata.userPermissions)) {
|
|
15
|
+
profile.metadata.userPermissions.forEach((userPerm) => {
|
|
16
|
+
const identifier = [profile.name, userPerm.name];
|
|
17
|
+
const classifiedUserPerm = this.resolveUserPermission(userPerm.name);
|
|
18
|
+
if (classifiedUserPerm) {
|
|
19
|
+
if (classifiedUserPerm.classification === PolicyRiskLevel.BLOCKED) {
|
|
20
|
+
result.violations.push({
|
|
21
|
+
identifier,
|
|
22
|
+
message: messages.getMessage('violations.permission-is-blocked'),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else if (!permissionAllowedInPreset(classifiedUserPerm.classification, profile.preset)) {
|
|
26
|
+
result.violations.push({
|
|
27
|
+
identifier,
|
|
28
|
+
message: messages.getMessage('violations.classification-preset-mismatch', [
|
|
29
|
+
classifiedUserPerm.classification,
|
|
30
|
+
profile.preset,
|
|
31
|
+
]),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else if (classifiedUserPerm.classification === PolicyRiskLevel.UNKNOWN) {
|
|
35
|
+
result.warnings.push({
|
|
36
|
+
identifier,
|
|
37
|
+
message: messages.getMessage('warnings.permission-unknown'),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result.warnings.push({
|
|
43
|
+
identifier,
|
|
44
|
+
message: messages.getMessage('warnings.permission-not-classified-in-profile'),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return Promise.resolve(result);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=enforceUserPermsClassificationOnProfiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforceUserPermsClassificationOnProfiles.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/enforceUserPermsClassificationOnProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,oCAAoC,CAAC,CAAC;AAEnH,MAAM,CAAC,OAAO,OAAO,wCAAyC,SAAQ,UAA2B;IAC/F,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA0C;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACpD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACrE,IAAI,kBAAkB,EAAE,CAAC;wBACvB,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;4BAClE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gCACrB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,kCAAkC,CAAC;6BACjE,CAAC,CAAC;wBACL,CAAC;6BAAM,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;4BACzF,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gCACrB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2CAA2C,EAAE;oCACxE,kBAAkB,CAAC,cAAc;oCACjC,OAAO,CAAC,MAAM;iCACf,CAAC;6BACH,CAAC,CAAC;wBACL,CAAC;6BAAM,IAAI,kBAAkB,CAAC,cAAc,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC;4BACzE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gCACnB,UAAU;gCACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;6BAC5D,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACnB,UAAU;4BACV,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,+CAA+C,CAAC;yBAC9E,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PartialPolicyRuleResult, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
|
|
2
|
+
import { ResolvedConnectedApp } from '../connectedAppPolicy.js';
|
|
3
|
+
import PolicyRule, { RuleOptions } from './policyRule.js';
|
|
4
|
+
export default class NoUserCanSelfAuthorize extends PolicyRule<ResolvedConnectedApp> {
|
|
5
|
+
constructor(opts: RuleOptions);
|
|
6
|
+
run(context: RuleAuditContext<ResolvedConnectedApp>): Promise<PartialPolicyRuleResult>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
import PolicyRule from './policyRule.js';
|
|
3
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
4
|
+
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.connectedApps');
|
|
5
|
+
export default class NoUserCanSelfAuthorize extends PolicyRule {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts);
|
|
8
|
+
}
|
|
9
|
+
run(context) {
|
|
10
|
+
const result = this.initResult();
|
|
11
|
+
const resolvedConnectedApps = context.resolvedEntities;
|
|
12
|
+
Object.values(resolvedConnectedApps).forEach((app) => {
|
|
13
|
+
if (!app.onlyAdminApprovedUsersAllowed) {
|
|
14
|
+
if (app.overrideByApiSecurityAccess) {
|
|
15
|
+
result.warnings.push({
|
|
16
|
+
identifier: [app.name],
|
|
17
|
+
message: messages.getMessage('warnings.users-can-self-authorize-but-setting-overrides'),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
result.violations.push({
|
|
22
|
+
identifier: [app.name],
|
|
23
|
+
message: messages.getMessage('violations.users-can-self-authorize'),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return Promise.resolve(result);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=noUserCanSelfAuthorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noUserCanSelfAuthorize.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/noUserCanSelfAuthorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,UAA2B,MAAM,iBAAiB,CAAC;AAE1D,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,qBAAqB,CAAC,CAAC;AAEpG,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,UAAgC;IAClF,YAAmB,IAAiB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,OAA+C;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC;gBACvC,IAAI,GAAG,CAAC,2BAA2B,EAAE,CAAC;oBACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACnB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;wBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,yDAAyD,CAAC;qBACxF,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBACrB,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;wBACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,qCAAqC,CAAC;qBACpE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PartialPolicyRuleResult, RowLevelPolicyRule, RuleAuditContext } from '../interfaces/policyRuleInterfaces.js';
|
|
2
|
+
import { AuditRunConfig, NamedPermissionsClassification } from '../../config/audit-run/schema.js';
|
|
3
|
+
export type RuleOptions = {
|
|
4
|
+
auditContext: AuditRunConfig;
|
|
5
|
+
ruleDisplayName: string;
|
|
6
|
+
ruleConfig?: unknown;
|
|
7
|
+
};
|
|
8
|
+
export default abstract class PolicyRule<EntityType> implements RowLevelPolicyRule<EntityType> {
|
|
9
|
+
auditContext: AuditRunConfig;
|
|
10
|
+
ruleDisplayName: string;
|
|
11
|
+
constructor(opts: RuleOptions);
|
|
12
|
+
protected initResult(): PartialPolicyRuleResult;
|
|
13
|
+
protected resolveUserPermission(permName: string): NamedPermissionsClassification | undefined;
|
|
14
|
+
protected resolveCustomPermission(permName: string): NamedPermissionsClassification | undefined;
|
|
15
|
+
abstract run(context: RuleAuditContext<EntityType>): Promise<PartialPolicyRuleResult>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Messages } from '@salesforce/core';
|
|
2
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
3
|
+
export default class PolicyRule {
|
|
4
|
+
auditContext;
|
|
5
|
+
ruleDisplayName;
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
this.auditContext = opts.auditContext;
|
|
8
|
+
this.ruleDisplayName = opts.ruleDisplayName;
|
|
9
|
+
}
|
|
10
|
+
initResult() {
|
|
11
|
+
return {
|
|
12
|
+
ruleName: this.ruleDisplayName,
|
|
13
|
+
violations: new Array(),
|
|
14
|
+
mutedViolations: new Array(),
|
|
15
|
+
warnings: new Array(),
|
|
16
|
+
errors: new Array(),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
resolveUserPermission(permName) {
|
|
20
|
+
return nameClassification(permName, this.auditContext.classifications.userPermissions?.content.permissions[permName]);
|
|
21
|
+
}
|
|
22
|
+
resolveCustomPermission(permName) {
|
|
23
|
+
return nameClassification(permName, this.auditContext.classifications.customPermissions?.content.permissions[permName]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function nameClassification(permName, perm) {
|
|
27
|
+
return perm ? { name: permName, ...perm } : undefined;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=policyRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policyRule.js","sourceRoot":"","sources":["../../../../src/libs/policies/rules/policyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAS5C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAQ7D,MAAM,CAAC,OAAO,OAAgB,UAAU;IAC/B,YAAY,CAAiB;IAC7B,eAAe,CAAS;IAE/B,YAAmB,IAAiB;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;IAC9C,CAAC;IAES,UAAU;QAClB,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI,KAAK,EAAuB;YAC5C,eAAe,EAAE,IAAI,KAAK,EAA2B;YACrD,QAAQ,EAAE,IAAI,KAAK,EAAwB;YAC3C,MAAM,EAAE,IAAI,KAAK,EAAwB;SAC1C,CAAC;IACJ,CAAC;IAES,qBAAqB,CAAC,QAAgB;QAC9C,OAAO,kBAAkB,CACvB,QAAQ,EACR,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CACjF,CAAC;IACJ,CAAC;IAES,uBAAuB,CAAC,QAAgB;QAChD,OAAO,kBAAkB,CACvB,QAAQ,EACR,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CACnF,CAAC;IACJ,CAAC;CAGF;AAED,SAAS,kBAAkB,CACzB,QAAgB,EAChB,IAAgC;IAEhC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Record } from '@jsforce/jsforce-node';
|
|
2
|
+
import { Profile as JsForceProfile } from '@jsforce/jsforce-node/lib/api/metadata.js';
|
|
3
|
+
export type CustomPermission = Record & {
|
|
4
|
+
Id: string;
|
|
5
|
+
MasterLabel: string;
|
|
6
|
+
DeveloperName: string;
|
|
7
|
+
};
|
|
8
|
+
export type ConnectedApp = Record & {
|
|
9
|
+
Id: string;
|
|
10
|
+
Name: string;
|
|
11
|
+
OptionsAllowAdminApprovedUsersOnly: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type OauthToken = Record & {
|
|
14
|
+
Id: string;
|
|
15
|
+
User: Pick<User, 'Username'>;
|
|
16
|
+
AppName: string;
|
|
17
|
+
UseCount: number;
|
|
18
|
+
};
|
|
19
|
+
export type User = Record & {
|
|
20
|
+
Username: string;
|
|
21
|
+
};
|
|
22
|
+
export type Profile = ProfileBasic & {
|
|
23
|
+
Metadata: JsForceProfile;
|
|
24
|
+
};
|
|
25
|
+
type ProfileBasic = Record & {
|
|
26
|
+
Id: string;
|
|
27
|
+
Name: string;
|
|
28
|
+
UserType: string;
|
|
29
|
+
};
|
|
30
|
+
export type PermissionSet = Record & {
|
|
31
|
+
Id: string;
|
|
32
|
+
IsOwnedByProfile: boolean;
|
|
33
|
+
IsCustom: boolean;
|
|
34
|
+
Name: string;
|
|
35
|
+
Label: string;
|
|
36
|
+
Profile: ProfileBasic;
|
|
37
|
+
NamespacePrefix?: string;
|
|
38
|
+
};
|
|
39
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salesforceStandardTypes.js","sourceRoot":"","sources":["../../../src/libs/policies/salesforceStandardTypes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare enum PolicyRiskLevel {
|
|
2
|
+
/** Blacklisted permissions that are considered too critical and not allowed */
|
|
3
|
+
BLOCKED = "Blocked",
|
|
4
|
+
/** Developer permissions, allow to modify the application */
|
|
5
|
+
CRITICAL = "Critical",
|
|
6
|
+
/** Admin permissions, allow to manage users and change permissions */
|
|
7
|
+
HIGH = "High",
|
|
8
|
+
/** Elevated business permissions for privileged users */
|
|
9
|
+
MEDIUM = "Medium",
|
|
10
|
+
/** Regular user permissions, typically needed for day-to-day work */
|
|
11
|
+
LOW = "Low",
|
|
12
|
+
/** Not categorized or unknown permission */
|
|
13
|
+
UNKNOWN = "Unknown"
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Presets can be assigned to profiles and permission sets.
|
|
17
|
+
* A preset allows permissions up to a fixed risk level.
|
|
18
|
+
*/
|
|
19
|
+
export declare enum PermissionRiskLevelPresets {
|
|
20
|
+
/** Allows up to "Critical" permissions */
|
|
21
|
+
DEVELOPER = "Developer",
|
|
22
|
+
/** Allows up to "High" permissions */
|
|
23
|
+
ADMIN = "Admin",
|
|
24
|
+
/** Allows up to "Medium" permissions */
|
|
25
|
+
POWER_USER = "Power User",
|
|
26
|
+
/** Allows only "Low" permissions */
|
|
27
|
+
STANDARD_USER = "Standard User",
|
|
28
|
+
/** Disables the profile for audit */
|
|
29
|
+
UNKNOWN = "Unknown"
|
|
30
|
+
}
|
|
31
|
+
export type PolicyWriteResult = {
|
|
32
|
+
paths: Record<string, string>;
|
|
33
|
+
};
|
|
34
|
+
export declare function resolveRiskLevelOrdinalValue(value: string): number;
|
|
35
|
+
export declare function resolvePresetOrdinalValue(value: string): number;
|
|
36
|
+
export declare function permissionAllowedInPreset(permClassification: string, preset: string): boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export var PolicyRiskLevel;
|
|
2
|
+
(function (PolicyRiskLevel) {
|
|
3
|
+
/** Blacklisted permissions that are considered too critical and not allowed */
|
|
4
|
+
PolicyRiskLevel["BLOCKED"] = "Blocked";
|
|
5
|
+
/** Developer permissions, allow to modify the application */
|
|
6
|
+
PolicyRiskLevel["CRITICAL"] = "Critical";
|
|
7
|
+
/** Admin permissions, allow to manage users and change permissions */
|
|
8
|
+
PolicyRiskLevel["HIGH"] = "High";
|
|
9
|
+
/** Elevated business permissions for privileged users */
|
|
10
|
+
PolicyRiskLevel["MEDIUM"] = "Medium";
|
|
11
|
+
/** Regular user permissions, typically needed for day-to-day work */
|
|
12
|
+
PolicyRiskLevel["LOW"] = "Low";
|
|
13
|
+
/** Not categorized or unknown permission */
|
|
14
|
+
PolicyRiskLevel["UNKNOWN"] = "Unknown";
|
|
15
|
+
})(PolicyRiskLevel || (PolicyRiskLevel = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Presets can be assigned to profiles and permission sets.
|
|
18
|
+
* A preset allows permissions up to a fixed risk level.
|
|
19
|
+
*/
|
|
20
|
+
export var PermissionRiskLevelPresets;
|
|
21
|
+
(function (PermissionRiskLevelPresets) {
|
|
22
|
+
/** Allows up to "Critical" permissions */
|
|
23
|
+
PermissionRiskLevelPresets["DEVELOPER"] = "Developer";
|
|
24
|
+
/** Allows up to "High" permissions */
|
|
25
|
+
PermissionRiskLevelPresets["ADMIN"] = "Admin";
|
|
26
|
+
/** Allows up to "Medium" permissions */
|
|
27
|
+
PermissionRiskLevelPresets["POWER_USER"] = "Power User";
|
|
28
|
+
/** Allows only "Low" permissions */
|
|
29
|
+
PermissionRiskLevelPresets["STANDARD_USER"] = "Standard User";
|
|
30
|
+
/** Disables the profile for audit */
|
|
31
|
+
PermissionRiskLevelPresets["UNKNOWN"] = "Unknown";
|
|
32
|
+
})(PermissionRiskLevelPresets || (PermissionRiskLevelPresets = {}));
|
|
33
|
+
export function resolveRiskLevelOrdinalValue(value) {
|
|
34
|
+
return Object.keys(PolicyRiskLevel).indexOf(value.toUpperCase());
|
|
35
|
+
}
|
|
36
|
+
export function resolvePresetOrdinalValue(value) {
|
|
37
|
+
return Object.keys(PermissionRiskLevelPresets).indexOf(value.toUpperCase().replace(' ', '_'));
|
|
38
|
+
}
|
|
39
|
+
export function permissionAllowedInPreset(permClassification, preset) {
|
|
40
|
+
// this works, as long as we are mindful when adding new risk levels and presets
|
|
41
|
+
const invertedPermValue = Object.keys(PolicyRiskLevel).length - resolveRiskLevelOrdinalValue(permClassification);
|
|
42
|
+
const invertedPresetValue = Object.keys(PermissionRiskLevelPresets).length - resolvePresetOrdinalValue(preset);
|
|
43
|
+
return invertedPresetValue >= invertedPermValue;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/libs/policies/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,eAaX;AAbD,WAAY,eAAe;IACzB,+EAA+E;IAC/E,sCAAmB,CAAA;IACnB,6DAA6D;IAC7D,wCAAqB,CAAA;IACrB,sEAAsE;IACtE,gCAAa,CAAA;IACb,yDAAyD;IACzD,oCAAiB,CAAA;IACjB,qEAAqE;IACrE,8BAAW,CAAA;IACX,4CAA4C;IAC5C,sCAAmB,CAAA;AACrB,CAAC,EAbW,eAAe,KAAf,eAAe,QAa1B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,0BAWX;AAXD,WAAY,0BAA0B;IACpC,0CAA0C;IAC1C,qDAAuB,CAAA;IACvB,sCAAsC;IACtC,6CAAe,CAAA;IACf,wCAAwC;IACxC,uDAAyB,CAAA;IACzB,oCAAoC;IACpC,6DAA+B,CAAA;IAC/B,qCAAqC;IACrC,iDAAmB,CAAA;AACrB,CAAC,EAXW,0BAA0B,KAA1B,0BAA0B,QAWrC;AAMD,MAAM,UAAU,4BAA4B,CAAC,KAAa;IACxD,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,kBAA0B,EAAE,MAAc;IAClF,gFAAgF;IAChF,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,4BAA4B,CAAC,kBAAkB,CAAC,CAAC;IACjH,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC/G,OAAO,mBAAmB,IAAI,iBAAiB,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function isEmpty(anything) {
|
|
2
|
+
if (isNullish(anything)) {
|
|
3
|
+
return true;
|
|
4
|
+
}
|
|
5
|
+
if (typeof anything === 'object') {
|
|
6
|
+
return Object.entries(anything).length === 0;
|
|
7
|
+
}
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
export function isNullish(anything) {
|
|
11
|
+
return !(Boolean(anything) && anything !== null);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/libs/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAC,QAAkB;IACxC,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,OAAO,CAAC,QAAS,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAiB;IACzC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MultiStageOutput, MultiStageOutputOptions } from '@oclif/multi-stage-output';
|
|
2
|
+
import AuditRun from '../libs/policies/auditRun.js';
|
|
3
|
+
export declare const LOAD_AUDIT_CONFIG = "Loading audit config";
|
|
4
|
+
export declare const RESOLVE_POLICIES = "Resolving policies";
|
|
5
|
+
export declare const EXECUTE_RULES = "Executing rules";
|
|
6
|
+
export declare const FINALISE = "Formatting results";
|
|
7
|
+
export type AuditRunStageOptions = {
|
|
8
|
+
targetOrg: string;
|
|
9
|
+
directoryRootPath: string;
|
|
10
|
+
jsonEnabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* This type mimics the original "StageBlockInfo" type from
|
|
14
|
+
* MultiStageOutput and allows us to make test asserts.
|
|
15
|
+
*/
|
|
16
|
+
type StageBlockInfo<T> = {
|
|
17
|
+
stage: string;
|
|
18
|
+
type: 'dynamic-key-value' | 'static-key-value' | 'message';
|
|
19
|
+
label?: string;
|
|
20
|
+
get(data: T): string;
|
|
21
|
+
};
|
|
22
|
+
export default class AuditRunMultiStageOutput {
|
|
23
|
+
mso: MultiStageOutput<AuditRunData>;
|
|
24
|
+
stageSpecificBlocks: Array<StageBlockInfo<AuditRunData>>;
|
|
25
|
+
private polStats;
|
|
26
|
+
constructor(opts: MultiStageOutputOptions<AuditRunData>);
|
|
27
|
+
/**
|
|
28
|
+
* In unit tests, we stub the actual UX class to hide output in terminal.
|
|
29
|
+
*
|
|
30
|
+
* @param opts
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
static initUx(opts: MultiStageOutputOptions<AuditRunData>): MultiStageOutput<AuditRunData>;
|
|
34
|
+
/**
|
|
35
|
+
* This pattern allows to stub multi-stage outputs in tests to mute output
|
|
36
|
+
* to stdout during test execution.
|
|
37
|
+
*
|
|
38
|
+
* In your code, create a new instance like this
|
|
39
|
+
* ```
|
|
40
|
+
* const ms = AuditRunMultiStageOutput.create(sobj, flags.json);
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param opts
|
|
44
|
+
* @param jsonEnabled
|
|
45
|
+
* @returns
|
|
46
|
+
*/
|
|
47
|
+
static create(opts: AuditRunStageOptions): AuditRunMultiStageOutput;
|
|
48
|
+
start(): void;
|
|
49
|
+
startPolicyResolve(runInstance: AuditRun): void;
|
|
50
|
+
startRuleExecution(): void;
|
|
51
|
+
finish(): void;
|
|
52
|
+
private addPolicyStatsListener;
|
|
53
|
+
}
|
|
54
|
+
export type AuditRunData = {
|
|
55
|
+
enabledRulesInPolicy: string[];
|
|
56
|
+
currentStatus: string;
|
|
57
|
+
policies: PolicyStatistics;
|
|
58
|
+
};
|
|
59
|
+
type PolicyStatistics = {
|
|
60
|
+
[policyName: string]: {
|
|
61
|
+
total?: number;
|
|
62
|
+
resolved?: number;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export {};
|