@j-schreiber/sf-cli-security-audit 0.19.3 → 0.20.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.
Files changed (62) hide show
  1. package/README.md +3 -3
  2. package/lib/commands/org/audit/init.d.ts +1 -1
  3. package/lib/commands/org/audit/init.js +8 -8
  4. package/lib/commands/org/audit/init.js.map +1 -1
  5. package/lib/commands/org/audit/run.js +4 -1
  6. package/lib/commands/org/audit/run.js.map +1 -1
  7. package/lib/libs/audit-engine/auditRun.d.ts +3 -4
  8. package/lib/libs/audit-engine/auditRun.js +21 -9
  9. package/lib/libs/audit-engine/auditRun.js.map +1 -1
  10. package/lib/libs/audit-engine/file-manager/fileManager.d.ts +5 -6
  11. package/lib/libs/audit-engine/file-manager/fileManager.js +34 -15
  12. package/lib/libs/audit-engine/file-manager/fileManager.js.map +1 -1
  13. package/lib/libs/audit-engine/file-manager/fileManager.types.d.ts +1 -0
  14. package/lib/libs/audit-engine/index.d.ts +72 -43
  15. package/lib/libs/audit-engine/registry/context.types.d.ts +6 -0
  16. package/lib/libs/audit-engine/registry/definitions.d.ts +73 -44
  17. package/lib/libs/audit-engine/registry/policies/permissionSets.js +1 -1
  18. package/lib/libs/audit-engine/registry/policies/permissionSets.js.map +1 -1
  19. package/lib/libs/audit-engine/registry/policies/profiles.js +1 -1
  20. package/lib/libs/audit-engine/registry/policies/profiles.js.map +1 -1
  21. package/lib/libs/audit-engine/registry/policies/users.js +1 -1
  22. package/lib/libs/audit-engine/registry/policies/users.js.map +1 -1
  23. package/lib/libs/audit-engine/registry/policy.js +2 -2
  24. package/lib/libs/audit-engine/registry/policy.js.map +1 -1
  25. package/lib/libs/audit-engine/registry/roles/roleManager.d.ts +3 -19
  26. package/lib/libs/audit-engine/registry/roles/roleManager.js +17 -29
  27. package/lib/libs/audit-engine/registry/roles/roleManager.js.map +1 -1
  28. package/lib/libs/audit-engine/registry/roles/roleManager.types.d.ts +21 -3
  29. package/lib/libs/audit-engine/registry/roles/userRole.d.ts +7 -6
  30. package/lib/libs/audit-engine/registry/roles/userRole.js +78 -31
  31. package/lib/libs/audit-engine/registry/roles/userRole.js.map +1 -1
  32. package/lib/libs/audit-engine/registry/rules/enforcePermissionPresets.js +5 -4
  33. package/lib/libs/audit-engine/registry/rules/enforcePermissionPresets.js.map +1 -1
  34. package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnProfileLike.js +3 -3
  35. package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnProfileLike.js.map +1 -1
  36. package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnUser.js +4 -4
  37. package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnUser.js.map +1 -1
  38. package/lib/libs/audit-engine/registry/shape/auditConfigShape.d.ts +71 -42
  39. package/lib/libs/audit-engine/registry/shape/auditConfigShape.js +26 -30
  40. package/lib/libs/audit-engine/registry/shape/auditConfigShape.js.map +1 -1
  41. package/lib/libs/audit-engine/registry/shape/schema.d.ts +77 -43
  42. package/lib/libs/audit-engine/registry/shape/schema.js +22 -20
  43. package/lib/libs/audit-engine/registry/shape/schema.js.map +1 -1
  44. package/lib/libs/audit-engine/registry/shape/shapeValidation.d.ts +3 -0
  45. package/lib/libs/audit-engine/registry/shape/shapeValidation.js +36 -7
  46. package/lib/libs/audit-engine/registry/shape/shapeValidation.js.map +1 -1
  47. package/lib/libs/conf-init/auditConfig.d.ts +1 -0
  48. package/lib/libs/conf-init/auditConfig.js +15 -10
  49. package/lib/libs/conf-init/auditConfig.js.map +1 -1
  50. package/lib/libs/conf-init/defaultClassifications.d.ts +4 -6
  51. package/lib/libs/conf-init/defaultClassifications.js +18 -28
  52. package/lib/libs/conf-init/defaultClassifications.js.map +1 -1
  53. package/lib/libs/conf-init/init.types.d.ts +7 -6
  54. package/lib/libs/conf-init/init.types.js.map +1 -1
  55. package/messages/auditShapeValidation.md +4 -0
  56. package/messages/org.audit.run.md +4 -0
  57. package/messages/rules.enforceClassificationPresets.md +4 -8
  58. package/oclif.manifest.json +1 -1
  59. package/package.json +1 -1
  60. package/lib/libs/audit-engine/registry/helpers/permissionsScanning.d.ts +0 -37
  61. package/lib/libs/audit-engine/registry/helpers/permissionsScanning.js +0 -81
  62. package/lib/libs/audit-engine/registry/helpers/permissionsScanning.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { RuleRegistry, PolicyDefinitions, } from '../audit-engine/index.js';
2
- import { ClassificationInitDefinitions } from './defaultClassifications.js';
1
+ import { RuleRegistry, PolicyDefinitions } from '../audit-engine/index.js';
2
+ import { InventoryInitialisers, ShapeInitialisers } from './defaultClassifications.js';
3
3
  import { DefaultPolicyDefinitions } from './defaultPolicies.js';
4
4
  /**
5
5
  * Exposes key functionality to load an audit config as static methods. This makes
@@ -13,20 +13,25 @@ export default class AuditConfig {
13
13
  * @param con
14
14
  */
15
15
  static async init(targetCon, opts) {
16
- const conf = { classifications: {}, policies: {}, acceptedRisks: {}, definitions: {} };
17
- for (const [className, classInitDef] of Object.entries(ClassificationInitDefinitions)) {
18
- // eslint-disable-next-line no-await-in-loop
19
- const defaultClassification = await classInitDef.initialiser(targetCon, opts?.preset);
20
- if (defaultClassification) {
21
- conf.classifications[className] = defaultClassification;
22
- }
23
- }
16
+ const conf = { shape: {}, inventory: {}, policies: {}, acceptedRisks: {}, controls: {} };
17
+ conf.shape = await this.initSubtype(ShapeInitialisers, targetCon, opts);
18
+ conf.inventory = await this.initSubtype(InventoryInitialisers, targetCon, opts);
24
19
  for (const policyName of Object.keys(PolicyDefinitions)) {
25
20
  const policy = initPolicyConfig(policyName);
26
21
  conf.policies[policyName] = policy;
27
22
  }
28
23
  return conf;
29
24
  }
25
+ static async initSubtype(initialisable, targetCon, opts) {
26
+ const initPromises = Object.entries(initialisable).map(([, init]) => init(targetCon, opts?.preset));
27
+ const inits = await Promise.all(initPromises);
28
+ const result = {};
29
+ const keys = Object.keys(initialisable);
30
+ for (const initEntry of keys) {
31
+ result[initEntry] = inits.at(keys.indexOf(initEntry));
32
+ }
33
+ return result;
34
+ }
30
35
  }
31
36
  export function initPolicyConfig(policyName) {
32
37
  const def = PolicyDefinitions[policyName];
@@ -1 +1 @@
1
- {"version":3,"file":"auditConfig.js","sourceRoot":"","sources":["../../../src/libs/conf-init/auditConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,YAAY,EAGZ,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAYhE;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAqB,EAAE,IAAuB;QACrE,MAAM,IAAI,GAAmB,EAAE,eAAe,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QACvG,KAAK,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,EAAE,CAAC;YACtF,4CAA4C;YAC5C,MAAM,qBAAqB,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACtF,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,IAAI,CAAC,eAAe,CAAC,SAA4B,CAAC,GAAG,qBAA4B,CAAC;YACpF,CAAC;QACH,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAsB,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,UAAsB,CAAC,GAAG,MAAa,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAqB,UAAa;IAChE,MAAM,GAAG,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC3D,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;YACzB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,IAAI,wBAAwB,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,wBAAwB,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"auditConfig.js","sourceRoot":"","sources":["../../../src/libs/conf-init/auditConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,YAAY,EAA0B,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEnH,OAAO,EAAe,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAYhE;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAqB,EAAE,IAAuB;QACrE,MAAM,IAAI,GAAmB,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACzG,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAChF,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAsB,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,UAAsB,CAAC,GAAG,MAAa,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,WAAW,CAC9B,aAA0C,EAC1C,SAAqB,EACrB,IAAuB;QAEvB,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxC,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAqB,UAAa;IAChE,MAAM,GAAG,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC3D,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;YACzB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,IAAI,wBAAwB,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,wBAAwB,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,8 +1,6 @@
1
1
  import { Connection } from '@salesforce/core';
2
- import { Classifications } from '../audit-engine/index.js';
2
+ import { Inventories, Shapes } from '../audit-engine/registry/definitions.js';
3
3
  import { AuditInitPresets } from './init.types.js';
4
- type ClassificationDefinition = {
5
- initialiser: (con: Connection, preset?: AuditInitPresets) => unknown;
6
- };
7
- export declare const ClassificationInitDefinitions: Record<Classifications, ClassificationDefinition>;
8
- export {};
4
+ export type Initialiser = (con: Connection, preset?: AuditInitPresets) => Promise<unknown>;
5
+ export declare const ShapeInitialisers: Record<Shapes, Initialiser>;
6
+ export declare const InventoryInitialisers: Record<Inventories, Initialiser>;
@@ -1,22 +1,14 @@
1
1
  import { PermissionRiskLevel, UserPrivilegeLevel } from '../audit-engine/index.js';
2
2
  import { OrgDescribe, PermissionSets, Profiles, Users } from '../../salesforce/index.js';
3
3
  import { loadPreset } from './presets.js';
4
- export const ClassificationInitDefinitions = {
5
- userPermissions: {
6
- initialiser: initUserPermissions,
7
- },
8
- customPermissions: {
9
- initialiser: initCustomPermissions,
10
- },
11
- profiles: {
12
- initialiser: initProfiles,
13
- },
14
- permissionSets: {
15
- initialiser: initPermissionSets,
16
- },
17
- users: {
18
- initialiser: initUsers,
19
- },
4
+ export const ShapeInitialisers = {
5
+ userPermissions: initUserPermissions,
6
+ customPermissions: initCustomPermissions,
7
+ };
8
+ export const InventoryInitialisers = {
9
+ profiles: initProfiles,
10
+ permissionSets: initPermissionSets,
11
+ users: initUsers,
20
12
  };
21
13
  async function initUserPermissions(con, preset) {
22
14
  const orgManager = await OrgDescribe.create(con);
@@ -24,8 +16,8 @@ async function initUserPermissions(con, preset) {
24
16
  const presConfig = loadPreset(preset);
25
17
  const perms = presConfig.classifyUserPermissions(userPerms);
26
18
  perms.sort(classificationSorter);
27
- const result = { permissions: {} };
28
- perms.forEach((perm) => (result.permissions[perm.name] = {
19
+ const result = {};
20
+ perms.forEach((perm) => (result[perm.name] = {
29
21
  label: perm.label,
30
22
  classification: perm.classification,
31
23
  reason: perm.reason,
@@ -33,7 +25,7 @@ async function initUserPermissions(con, preset) {
33
25
  return result;
34
26
  }
35
27
  async function initCustomPermissions(con) {
36
- const result = { permissions: {} };
28
+ const result = {};
37
29
  const orgManager = await OrgDescribe.create(con);
38
30
  const customPerms = orgManager.getCustomPermissions();
39
31
  if (customPerms.length === 0) {
@@ -43,7 +35,7 @@ async function initCustomPermissions(con) {
43
35
  ...cp,
44
36
  classification: PermissionRiskLevel.UNKNOWN,
45
37
  }));
46
- perms.forEach((perm) => (result.permissions[perm.name] = {
38
+ perms.forEach((perm) => (result[perm.name] = {
47
39
  label: perm.label,
48
40
  classification: perm.classification,
49
41
  }));
@@ -52,29 +44,27 @@ async function initCustomPermissions(con) {
52
44
  async function initProfiles(targetOrgCon) {
53
45
  const profilesRepo = new Profiles(targetOrgCon);
54
46
  const profiles = await profilesRepo.resolve();
55
- const content = { profiles: {} };
47
+ const content = {};
56
48
  for (const profileName of profiles.keys()) {
57
- content.profiles[profileName] = { role: UserPrivilegeLevel.UNKNOWN };
49
+ content[profileName] = { role: UserPrivilegeLevel.UNKNOWN };
58
50
  }
59
51
  return content;
60
52
  }
61
53
  async function initPermissionSets(targetOrgCon) {
62
54
  const permsetsRepo = new PermissionSets(targetOrgCon);
63
55
  const permsets = await permsetsRepo.resolve({ isCustomOnly: true });
64
- const content = { permissionSets: {} };
56
+ const content = {};
65
57
  for (const permsetName of permsets.keys()) {
66
- content.permissionSets[permsetName] = { role: UserPrivilegeLevel.UNKNOWN };
58
+ content[permsetName] = { role: UserPrivilegeLevel.UNKNOWN };
67
59
  }
68
60
  return content;
69
61
  }
70
62
  async function initUsers(targetOrgCon) {
71
63
  const usersRepo = new Users(targetOrgCon);
72
64
  const users = await usersRepo.resolve();
73
- const content = {
74
- users: {},
75
- };
65
+ const content = {};
76
66
  for (const username of users.keys())
77
- content.users[username] = { role: UserPrivilegeLevel.STANDARD_USER };
67
+ content[username] = { role: UserPrivilegeLevel.STANDARD_USER };
78
68
  return content;
79
69
  }
80
70
  function resolveRiskLevelOrdinalValue(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAc1C,MAAM,CAAC,MAAM,6BAA6B,GAAsD;IAC9F,eAAe,EAAE;QACf,WAAW,EAAE,mBAAmB;KACjC;IACD,iBAAiB,EAAE;QACjB,WAAW,EAAE,qBAAqB;KACnC;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,YAAY;KAC1B;IACD,cAAc,EAAE;QACd,WAAW,EAAE,kBAAkB;KAChC;IACD,KAAK,EAAE;QACL,WAAW,EAAE,SAAS;KACvB;CACF,CAAC;AAEF,KAAK,UAAU,mBAAmB,CAAC,GAAe,EAAE,MAAyB;IAC3E,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,MAAM,MAAM,GAA8B,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC9D,KAAK,CAAC,OAAO,CACX,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CACL,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,GAAe;IAClD,MAAM,MAAM,GAA8B,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC9D,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,UAAU,CAAC,oBAAoB,EAAE,CAAC;IACtD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACrC,GAAG,EAAE;QACL,cAAc,EAAE,mBAAmB,CAAC,OAAO;KAC5C,CAAC,CAAC,CAAC;IACJ,KAAK,CAAC,OAAO,CACX,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CACL,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,YAAwB;IAClD,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,OAAO,GAA2B,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzD,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,YAAwB;IACxD,MAAM,YAAY,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC/D,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,YAAwB;IAC/C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;IACxC,MAAM,OAAO,GAAwB;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;IACF,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;QAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,aAAa,EAAE,CAAC;IAC1G,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAa;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAgC,EAAE,CAAgC,EAAU,EAAE,CAC1G,4BAA4B,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,15 @@
1
1
  import z from 'zod';
2
2
  import { AuditConfigShape } from '../audit-engine/index.js';
3
- type AuditClassifications = (typeof AuditConfigShape)['classifications']['files'];
4
- export type PermissionClassifications = z.infer<AuditClassifications['userPermissions']['schema']>;
5
- export type NamedPermissionClassification = PermissionClassifications['permissions']['string'] & {
3
+ type Shapes = (typeof AuditConfigShape)['shape']['files'];
4
+ type Inventories = (typeof AuditConfigShape)['inventory']['files'];
5
+ export type PermissionClassifications = z.infer<Shapes['userPermissions']['schema']>;
6
+ export type NamedPermissionClassification = PermissionClassifications['string'] & {
6
7
  name: string;
7
8
  };
8
9
  export type UnclassifiedPerm = Omit<NamedPermissionClassification, 'classification'>;
9
- export type ProfileClassifications = z.infer<AuditClassifications['profiles']['schema']>;
10
- export type PermsetClassifications = z.infer<AuditClassifications['permissionSets']['schema']>;
11
- export type UserClassifications = z.infer<AuditClassifications['users']['schema']>;
10
+ export type ProfileClassifications = z.infer<Inventories['profiles']['schema']>;
11
+ export type PermsetClassifications = z.infer<Inventories['permissionSets']['schema']>;
12
+ export type UserClassifications = z.infer<Inventories['users']['schema']>;
12
13
  export declare enum AuditInitPresets {
13
14
  strict = "strict",
14
15
  loose = "loose",
@@ -1 +1 @@
1
- {"version":3,"file":"init.types.js","sourceRoot":"","sources":["../../../src/libs/conf-init/init.types.ts"],"names":[],"mappings":"AAYA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,mCAAe,CAAA;IACf,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B"}
1
+ {"version":3,"file":"init.types.js","sourceRoot":"","sources":["../../../src/libs/conf-init/init.types.ts"],"names":[],"mappings":"AAaA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,mCAAe,CAAA;IACf,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B"}
@@ -2,6 +2,10 @@
2
2
 
3
3
  %s is not a valid role for audit config.
4
4
 
5
+ # PermissionDoesNotExistOnOrg
6
+
7
+ Permission does not exist on Org.
8
+
5
9
  # FailedToParseAuditConfig
6
10
 
7
11
  Failed to parse audit config at location %s: %s (%s).
@@ -64,6 +64,10 @@ The "Permission Sets" policy requires at least userPermissions to be initialised
64
64
 
65
65
  The "Profiles" policy requires a corresponding classification to be initialised.
66
66
 
67
+ # error.DirectoryDoesNotExistOrIsEmpty
68
+
69
+ %s does not exist or the directory is empty.
70
+
67
71
  # error.InvalidConfigFileSchema
68
72
 
69
73
  Failed to parse %s: %s.
@@ -6,6 +6,10 @@ Duplicate role identifier after normalization found: %s was already defined, %s
6
6
 
7
7
  Tried to access a role that does not exist: %s.
8
8
 
9
+ # RoleReferencesPermissionThatDoesNotExist
10
+
11
+ Role %s references permission control %s that does not exist.
12
+
9
13
  # violations.classification-preset-mismatch
10
14
 
11
15
  Permission is classified as "%s" and not allowed in role "%s".
@@ -22,14 +26,6 @@ Permission classified as UNKNOWN. Update classification to LOW or higher to reso
22
26
 
23
27
  Permission is assigned, but was not found in classification. Refresh or add manually.
24
28
 
25
- # warnings.permission-not-classified-in-profile
26
-
27
- Profile assigns the permission, but it was not found in classification. Refresh or add manually.
28
-
29
- # warnings.permission-not-classified-in-permission-set
30
-
31
- PermissionSet assigns the permission, but it was not found in classification. Refresh or add manually.
32
-
33
29
  # error.failed-to-resolve-role
34
30
 
35
31
  The assigned role "%s" was not valid for this audit. Check your role definitions.
@@ -278,5 +278,5 @@
278
278
  ]
279
279
  }
280
280
  },
281
- "version": "0.19.3"
281
+ "version": "0.20.0"
282
282
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@j-schreiber/sf-cli-security-audit",
3
3
  "description": "Salesforce CLI plugin to automate highly configurable security audits",
4
- "version": "0.19.3",
4
+ "version": "0.20.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/j-schreiber/js-sf-cli-security-audit"
@@ -1,37 +0,0 @@
1
- import { Profile } from '@jsforce/jsforce-node/lib/api/metadata.js';
2
- import { PolicyRuleViolation, RuleComponentMessage } from '../result.types.js';
3
- import { AuditRunConfig } from '../definitions.js';
4
- import { PermissionClassifications } from '../shape/schema.js';
5
- export type ResolvedProfileLike = {
6
- name: string;
7
- role: string;
8
- metadata: PartialProfileLike;
9
- };
10
- export type ScanResult = {
11
- violations: PolicyRuleViolation[];
12
- warnings: RuleComponentMessage[];
13
- };
14
- export type PartialProfileLike = Pick<Profile, 'userPermissions' | 'customPermissions'>;
15
- type PermissionsListKey = keyof PartialProfileLike;
16
- /**
17
- * Moves the "name" from the classifications map to object prop
18
- */
19
- type NamedPermissionClassification = PermissionClassifications['string'] & {
20
- name: string;
21
- };
22
- /**
23
- * Scan userPermissions and customPermissions of a profile or permission set and
24
- * get a unified scan result with violations (risk level not allowed) and warnings
25
- * (risk level not classified)
26
- *
27
- * @param profileLike
28
- * @param auditRun
29
- * @param rootIdentifier Optional root identifier for messages to prepend.
30
- * @returns
31
- */
32
- export declare function scanProfileLike(profileLike: ResolvedProfileLike, auditRun: AuditRunConfig, rootIdentifier?: string[]): ScanResult;
33
- export declare function scanPermissions(profile: ResolvedProfileLike, permissionListName: PermissionsListKey, auditRun: AuditRunConfig, rootIdentifier?: string[]): ScanResult;
34
- export declare function resolvePresetOrdinalValue(value: string): number;
35
- export declare function permissionAllowedInPreset(permClassification: string, preset: string): boolean;
36
- export declare const classificationSorter: (a: NamedPermissionClassification, b: NamedPermissionClassification) => number;
37
- export {};
@@ -1,81 +0,0 @@
1
- import { Messages } from '@salesforce/core';
2
- import { PermissionRiskLevel, UserPrivilegeLevel } from '../shape/schema.js';
3
- Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
4
- const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
5
- /**
6
- * Scan userPermissions and customPermissions of a profile or permission set and
7
- * get a unified scan result with violations (risk level not allowed) and warnings
8
- * (risk level not classified)
9
- *
10
- * @param profileLike
11
- * @param auditRun
12
- * @param rootIdentifier Optional root identifier for messages to prepend.
13
- * @returns
14
- */
15
- export function scanProfileLike(profileLike, auditRun, rootIdentifier) {
16
- if (!profileLike.metadata) {
17
- return { violations: [], warnings: [] };
18
- }
19
- const userPermsResult = scanPermissions(profileLike, 'userPermissions', auditRun, rootIdentifier);
20
- const customPermsResult = scanPermissions(profileLike, 'customPermissions', auditRun, rootIdentifier);
21
- userPermsResult.violations.push(...customPermsResult.violations);
22
- userPermsResult.warnings.push(...customPermsResult.warnings);
23
- return userPermsResult;
24
- }
25
- export function scanPermissions(profile, permissionListName, auditRun, rootIdentifier) {
26
- const result = { warnings: [], violations: [] };
27
- for (const perm of profile.metadata[permissionListName]) {
28
- const identifier = rootIdentifier ? [...rootIdentifier, profile.name, perm.name] : [profile.name, perm.name];
29
- const permClassification = resolvePerm(perm.name, auditRun, permissionListName);
30
- if (permClassification) {
31
- if (permClassification.classification === PermissionRiskLevel.BLOCKED) {
32
- result.violations.push({
33
- identifier,
34
- message: messages.getMessage('violations.permission-is-blocked'),
35
- });
36
- }
37
- else if (!permissionAllowedInPreset(permClassification.classification, profile.role)) {
38
- result.violations.push({
39
- identifier,
40
- message: messages.getMessage('violations.classification-preset-mismatch', [
41
- permClassification.classification,
42
- profile.role,
43
- ]),
44
- });
45
- }
46
- else if (permClassification.classification === PermissionRiskLevel.UNKNOWN) {
47
- result.warnings.push({
48
- identifier,
49
- message: messages.getMessage('warnings.permission-unknown'),
50
- });
51
- }
52
- }
53
- else {
54
- result.warnings.push({
55
- identifier,
56
- message: messages.getMessage('warnings.permission-not-classified'),
57
- });
58
- }
59
- }
60
- return result;
61
- }
62
- export function resolvePresetOrdinalValue(value) {
63
- return Object.keys(UserPrivilegeLevel).indexOf(value.toUpperCase().replace(' ', '_'));
64
- }
65
- export function permissionAllowedInPreset(permClassification, preset) {
66
- // this works, as long as we are mindful when adding new risk levels and presets
67
- const invertedPermValue = Object.keys(PermissionRiskLevel).length - resolveRiskLevelOrdinalValue(permClassification);
68
- const invertedPresetValue = Object.keys(UserPrivilegeLevel).length - resolvePresetOrdinalValue(preset);
69
- return invertedPresetValue >= invertedPermValue;
70
- }
71
- function resolveRiskLevelOrdinalValue(value) {
72
- return Object.keys(PermissionRiskLevel).indexOf(value.toUpperCase());
73
- }
74
- export const classificationSorter = (a, b) => resolveRiskLevelOrdinalValue(a.classification) - resolveRiskLevelOrdinalValue(b.classification);
75
- function resolvePerm(permName, auditRun, type) {
76
- return nameClassification(permName, auditRun.classifications[type]?.permissions[permName]);
77
- }
78
- function nameClassification(permName, perm) {
79
- return perm ? { name: permName, ...perm } : undefined;
80
- }
81
- //# sourceMappingURL=permissionsScanning.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"permissionsScanning.js","sourceRoot":"","sources":["../../../../../src/libs/audit-engine/registry/helpers/permissionsScanning.ts"],"names":[],"mappings":"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"}