@ploaness/governance 1.1.0 → 1.3.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/dist/a11y-hit-target.d.ts.map +1 -1
- package/dist/a11y-hit-target.js +1 -21
- package/dist/a11y-hit-target.js.map +1 -1
- package/dist/a11y-incomplete.d.ts.map +1 -1
- package/dist/a11y-incomplete.js +1 -18
- package/dist/a11y-incomplete.js.map +1 -1
- package/dist/access-boundary.d.ts +43 -1
- package/dist/access-boundary.d.ts.map +1 -1
- package/dist/access-boundary.js +146 -5
- package/dist/access-boundary.js.map +1 -1
- package/dist/admin-view-coverage.d.ts.map +1 -1
- package/dist/admin-view-coverage.js +1 -17
- package/dist/admin-view-coverage.js.map +1 -1
- package/dist/asset-policy.d.ts.map +1 -1
- package/dist/asset-policy.js +1 -23
- package/dist/asset-policy.js.map +1 -1
- package/dist/axe-coverage.d.ts +3 -4
- package/dist/axe-coverage.d.ts.map +1 -1
- package/dist/axe-coverage.js +18 -51
- package/dist/axe-coverage.js.map +1 -1
- package/dist/blocklist-entries.d.ts +36 -0
- package/dist/blocklist-entries.d.ts.map +1 -0
- package/dist/blocklist-entries.js +338 -0
- package/dist/blocklist-entries.js.map +1 -0
- package/dist/blocklist.d.ts +91 -0
- package/dist/blocklist.d.ts.map +1 -0
- package/dist/blocklist.js +187 -0
- package/dist/blocklist.js.map +1 -0
- package/dist/checkov-check.d.ts +9 -0
- package/dist/checkov-check.d.ts.map +1 -0
- package/dist/checkov-check.js +4 -0
- package/dist/checkov-check.js.map +1 -0
- package/dist/checkov-checks-aws.d.ts +4 -0
- package/dist/checkov-checks-aws.d.ts.map +1 -0
- package/dist/checkov-checks-aws.js +93 -0
- package/dist/checkov-checks-aws.js.map +1 -0
- package/dist/checkov-checks-azure.d.ts +4 -0
- package/dist/checkov-checks-azure.d.ts.map +1 -0
- package/dist/checkov-checks-azure.js +32 -0
- package/dist/checkov-checks-azure.js.map +1 -0
- package/dist/checkov-checks-google.d.ts +6 -0
- package/dist/checkov-checks-google.d.ts.map +1 -0
- package/dist/checkov-checks-google.js +53 -0
- package/dist/checkov-checks-google.js.map +1 -0
- package/dist/checkov-policy.d.ts +63 -0
- package/dist/checkov-policy.d.ts.map +1 -0
- package/dist/checkov-policy.js +105 -0
- package/dist/checkov-policy.js.map +1 -0
- package/dist/container-failure.d.ts.map +1 -1
- package/dist/container-failure.js +1 -18
- package/dist/container-failure.js.map +1 -1
- package/dist/container-files.d.ts +16 -0
- package/dist/container-files.d.ts.map +1 -1
- package/dist/container-files.js +23 -8
- package/dist/container-files.js.map +1 -1
- package/dist/container-images.d.ts +43 -0
- package/dist/container-images.d.ts.map +1 -0
- package/dist/container-images.js +157 -0
- package/dist/container-images.js.map +1 -0
- package/dist/dependency-freshness.d.ts +8 -0
- package/dist/dependency-freshness.d.ts.map +1 -1
- package/dist/dependency-freshness.js +2 -18
- package/dist/dependency-freshness.js.map +1 -1
- package/dist/doc-blocks.d.ts.map +1 -1
- package/dist/doc-blocks.js +1 -13
- package/dist/doc-blocks.js.map +1 -1
- package/dist/editorconfig-policy.d.ts +7 -0
- package/dist/editorconfig-policy.d.ts.map +1 -1
- package/dist/editorconfig-policy.js +19 -12
- package/dist/editorconfig-policy.js.map +1 -1
- package/dist/environment-coherence.d.ts +59 -5
- package/dist/environment-coherence.d.ts.map +1 -1
- package/dist/environment-coherence.js +107 -27
- package/dist/environment-coherence.js.map +1 -1
- package/dist/environment-files.d.ts.map +1 -1
- package/dist/environment-files.js +1 -19
- package/dist/environment-files.js.map +1 -1
- package/dist/file-roles.d.ts +7 -2
- package/dist/file-roles.d.ts.map +1 -1
- package/dist/file-roles.js +10 -9
- package/dist/file-roles.js.map +1 -1
- package/dist/freshness-repair.d.ts +82 -0
- package/dist/freshness-repair.d.ts.map +1 -0
- package/dist/freshness-repair.js +91 -0
- package/dist/freshness-repair.js.map +1 -0
- package/dist/generated-denial.d.ts.map +1 -1
- package/dist/generated-denial.js +1 -9
- package/dist/generated-denial.js.map +1 -1
- package/dist/generated-drift.d.ts.map +1 -1
- package/dist/generated-drift.js +1 -12
- package/dist/generated-drift.js.map +1 -1
- package/dist/harness-package.d.ts +13 -0
- package/dist/harness-package.d.ts.map +1 -0
- package/dist/harness-package.js +20 -0
- package/dist/harness-package.js.map +1 -0
- package/dist/history-policy.d.ts.map +1 -1
- package/dist/history-policy.js +1 -7
- package/dist/history-policy.js.map +1 -1
- package/dist/image-assets.d.ts.map +1 -1
- package/dist/image-assets.js +1 -10
- package/dist/image-assets.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/install-policy.d.ts +21 -0
- package/dist/install-policy.d.ts.map +1 -1
- package/dist/install-policy.js +53 -1
- package/dist/install-policy.js.map +1 -1
- package/dist/jsx-accessibility-scope.d.ts +17 -0
- package/dist/jsx-accessibility-scope.d.ts.map +1 -0
- package/dist/jsx-accessibility-scope.js +36 -0
- package/dist/jsx-accessibility-scope.js.map +1 -0
- package/dist/jsx-accessibility.d.ts +13 -0
- package/dist/jsx-accessibility.d.ts.map +1 -0
- package/dist/jsx-accessibility.js +188 -0
- package/dist/jsx-accessibility.js.map +1 -0
- package/dist/network-policy.d.ts.map +1 -1
- package/dist/network-policy.js +1 -12
- package/dist/network-policy.js.map +1 -1
- package/dist/oxlint-policy.d.ts +16 -0
- package/dist/oxlint-policy.d.ts.map +1 -0
- package/dist/oxlint-policy.js +28 -0
- package/dist/oxlint-policy.js.map +1 -0
- package/dist/oxlint-report.d.ts +29 -0
- package/dist/oxlint-report.d.ts.map +1 -0
- package/dist/oxlint-report.js +84 -0
- package/dist/oxlint-report.js.map +1 -0
- package/dist/oxlint-scope.d.ts +13 -0
- package/dist/oxlint-scope.d.ts.map +1 -0
- package/dist/oxlint-scope.js +46 -0
- package/dist/oxlint-scope.js.map +1 -0
- package/dist/oxlint-suppressions.d.ts +17 -0
- package/dist/oxlint-suppressions.d.ts.map +1 -0
- package/dist/oxlint-suppressions.js +72 -0
- package/dist/oxlint-suppressions.js.map +1 -0
- package/dist/paired-assets.d.ts.map +1 -1
- package/dist/paired-assets.js.map +1 -1
- package/dist/payload-access.d.ts +6 -0
- package/dist/payload-access.d.ts.map +1 -1
- package/dist/payload-access.js +166 -9
- package/dist/payload-access.js.map +1 -1
- package/dist/payload-bootstrap.d.ts +52 -0
- package/dist/payload-bootstrap.d.ts.map +1 -0
- package/dist/payload-bootstrap.js +195 -0
- package/dist/payload-bootstrap.js.map +1 -0
- package/dist/payload-configs.d.ts +0 -1
- package/dist/payload-configs.d.ts.map +1 -1
- package/dist/payload-configs.js +36 -17
- package/dist/payload-configs.js.map +1 -1
- package/dist/payload-database.d.ts +80 -0
- package/dist/payload-database.d.ts.map +1 -0
- package/dist/payload-database.js +164 -0
- package/dist/payload-database.js.map +1 -0
- package/dist/payload-defaults.d.ts +128 -0
- package/dist/payload-defaults.d.ts.map +1 -0
- package/dist/payload-defaults.js +295 -0
- package/dist/payload-defaults.js.map +1 -0
- package/dist/payload-policy.d.ts +21 -0
- package/dist/payload-policy.d.ts.map +1 -1
- package/dist/payload-policy.js +92 -43
- package/dist/payload-policy.js.map +1 -1
- package/dist/relationship-cleanup.d.ts.map +1 -1
- package/dist/relationship-cleanup.js +16 -16
- package/dist/relationship-cleanup.js.map +1 -1
- package/dist/release-age.d.ts.map +1 -1
- package/dist/release-age.js +1 -16
- package/dist/release-age.js.map +1 -1
- package/dist/request-limits.d.ts.map +1 -1
- package/dist/request-limits.js +1 -11
- package/dist/request-limits.js.map +1 -1
- package/dist/route-map.d.ts.map +1 -1
- package/dist/route-map.js +1 -16
- package/dist/route-map.js.map +1 -1
- package/dist/run-plan.d.ts.map +1 -1
- package/dist/run-plan.js +1 -19
- package/dist/run-plan.js.map +1 -1
- package/dist/secret-policy.d.ts.map +1 -1
- package/dist/secret-policy.js +1 -11
- package/dist/secret-policy.js.map +1 -1
- package/dist/settings-layering.d.ts +8 -30
- package/dist/settings-layering.d.ts.map +1 -1
- package/dist/settings-layering.js +19 -48
- package/dist/settings-layering.js.map +1 -1
- package/dist/settings.d.ts +9 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/shell-files.d.ts +45 -0
- package/dist/shell-files.d.ts.map +1 -0
- package/dist/shell-files.js +105 -0
- package/dist/shell-files.js.map +1 -0
- package/dist/source-security.d.ts +10 -0
- package/dist/source-security.d.ts.map +1 -1
- package/dist/source-security.js +88 -1
- package/dist/source-security.js.map +1 -1
- package/dist/source-text.d.ts +2 -0
- package/dist/source-text.d.ts.map +1 -1
- package/dist/source-text.js +7 -16
- package/dist/source-text.js.map +1 -1
- package/dist/terraform-files.d.ts +29 -0
- package/dist/terraform-files.d.ts.map +1 -0
- package/dist/terraform-files.js +50 -0
- package/dist/terraform-files.js.map +1 -0
- package/dist/terraform-policy.d.ts +13 -0
- package/dist/terraform-policy.d.ts.map +1 -0
- package/dist/terraform-policy.js +261 -0
- package/dist/terraform-policy.js.map +1 -0
- package/dist/terraform-providers.d.ts +28 -0
- package/dist/terraform-providers.d.ts.map +1 -0
- package/dist/terraform-providers.js +68 -0
- package/dist/terraform-providers.js.map +1 -0
- package/dist/toolchain-pins.d.ts +1 -1
- package/dist/toolchain-pins.d.ts.map +1 -1
- package/dist/toolchain-pins.js +11 -21
- package/dist/toolchain-pins.js.map +1 -1
- package/dist/version-policy.d.ts +7 -8
- package/dist/version-policy.d.ts.map +1 -1
- package/dist/version-policy.js +15 -26
- package/dist/version-policy.js.map +1 -1
- package/dist/vulnerability-policy.d.ts.map +1 -1
- package/dist/vulnerability-policy.js +1 -11
- package/dist/vulnerability-policy.js.map +1 -1
- package/dist/wiring-policy.d.ts.map +1 -1
- package/dist/wiring-policy.js +4 -1
- package/dist/wiring-policy.js.map +1 -1
- package/dist/wiring-violation.d.ts.map +1 -1
- package/dist/wiring-violation.js +1 -6
- package/dist/wiring-violation.js.map +1 -1
- package/dist/workspace-policy.d.ts.map +1 -1
- package/dist/workspace-policy.js +3 -9
- package/dist/workspace-policy.js.map +1 -1
- package/dist/yaml-blocks.d.ts +10 -0
- package/dist/yaml-blocks.d.ts.map +1 -1
- package/dist/yaml-blocks.js +20 -0
- package/dist/yaml-blocks.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// Infrastructure defects a text reader can decide on its own, and only those.
|
|
2
|
+
//
|
|
3
|
+
// Every rule here owns a question the analyzer beside it does not answer. Where checkov has a check,
|
|
4
|
+
// checkov keeps it: one semantic rule has one owner, and a second opinion written as a regular
|
|
5
|
+
// expression would be the weaker of the two. So `AdministratorAccess`, wildcard IAM actions and a
|
|
6
|
+
// publicly reachable database are absent from this file deliberately - they are enabled as curated
|
|
7
|
+
// checks instead, where the resource graph is understood rather than guessed at from one line.
|
|
8
|
+
//
|
|
9
|
+
// `0.0.0.0/0` is read in exactly one place: the standalone ingress rule resource, whose TYPE names its
|
|
10
|
+
// direction. Everywhere else text cannot decide it. The same address is correct on egress and fatal on
|
|
11
|
+
// ingress, and an `ingress` block or an `aws_security_group_rule` carries its direction in a nested
|
|
12
|
+
// block or a sibling attribute that a line reader cannot tie to the address - so those forms stay
|
|
13
|
+
// with the analyzer, which knows which side of the rule it is looking at. The standalone resource is
|
|
14
|
+
// this file's because the analyzer does not read its idiomatic spelling at all, and its own SSH and RDP
|
|
15
|
+
// checks read a rule naming another security group as its source as open to the world.
|
|
16
|
+
import { stripComments } from './source-text.js';
|
|
17
|
+
const FIRST_LINE = 1;
|
|
18
|
+
// An argument assigned one literal value, bare or quoted, on its own line. Terraform accepts both
|
|
19
|
+
// spellings of a boolean, and a quoted string is what the other values are.
|
|
20
|
+
const assigned = (attribute, value) => new RegExp(String.raw `^[ \t]*${attribute}[ \t]*=[ \t]*"?${value}"?(?:[ \t]|$)`);
|
|
21
|
+
// The Owner definition has one id in every Azure tenant, and a role assignment may name it by id
|
|
22
|
+
// rather than by name.
|
|
23
|
+
const AZURE_OWNER_DEFINITION = '8e3af657-a8ff-443c-a75c-2fe8c4bcb635';
|
|
24
|
+
// Each rule refuses an explicit literal and never an absence, which is what keeps every one of them
|
|
25
|
+
// free of false positives: a value that arrives through a variable or a reference never matches. The
|
|
26
|
+
// first two arguments exist only where they destroy data, and checkov ships no check for either. The
|
|
27
|
+
// last two stand in for checks that fail the rubric - `CKV_GCP_6` rejects the correct
|
|
28
|
+
// `ENCRYPTED_ONLY`, `CKV_AZURE_3` and `CKV_AZURE_91` read only the argument names azurerm retired,
|
|
29
|
+
// and every project-role check on Google Cloud also flags `viewer` or a documented deploy role,
|
|
30
|
+
// while Azure has no check for an Owner assignment at all. A checkov check that fails the rubric
|
|
31
|
+
// returns its question to text. The patterns are built once here rather than per line, so the scan
|
|
32
|
+
// is one pass over the text.
|
|
33
|
+
const FLAG_RULES = [
|
|
34
|
+
{
|
|
35
|
+
patterns: [assigned('force_destroy', 'true')],
|
|
36
|
+
rule: 'no-force-destroy',
|
|
37
|
+
reason: 'force_destroy lets a destroy remove a bucket or repository that still holds objects, so a ' +
|
|
38
|
+
'replacement-forcing edit deletes the data rather than failing - remove it, and empty the ' +
|
|
39
|
+
'store deliberately when it is genuinely meant to go',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
patterns: [assigned('skip_final_snapshot', 'true')],
|
|
43
|
+
rule: 'no-skipped-final-snapshot',
|
|
44
|
+
reason: 'skip_final_snapshot leaves a deleted database with nothing to restore from, and a destroy ' +
|
|
45
|
+
'that was never meant to reach production is exactly when that snapshot is wanted - remove it ' +
|
|
46
|
+
'and let the final snapshot be taken',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
patterns: [
|
|
50
|
+
assigned('role', 'roles/owner'),
|
|
51
|
+
assigned('role', 'roles/editor'),
|
|
52
|
+
assigned('role_definition_name', 'Owner'),
|
|
53
|
+
new RegExp(String.raw `^[ \t]*role_definition_id[ \t]*=[ \t]*"[^"]*${AZURE_OWNER_DEFINITION}"`),
|
|
54
|
+
],
|
|
55
|
+
rule: 'no-administrative-role-grant',
|
|
56
|
+
reason: 'an administrative role is granted outright, which is every permission on everything in its ' +
|
|
57
|
+
'scope - grant the specific roles the principal needs, and no more',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
patterns: [
|
|
61
|
+
assigned('ssl_mode', 'ALLOW_UNENCRYPTED_AND_ENCRYPTED'),
|
|
62
|
+
assigned('require_ssl', 'false'),
|
|
63
|
+
assigned('https_traffic_only_enabled', 'false'),
|
|
64
|
+
assigned('enable_https_traffic_only', 'false'),
|
|
65
|
+
assigned('non_ssl_port_enabled', 'true'),
|
|
66
|
+
assigned('enable_non_ssl_port', 'true'),
|
|
67
|
+
],
|
|
68
|
+
rule: 'no-unencrypted-transport',
|
|
69
|
+
reason: 'the service explicitly accepts unencrypted connections - remove the argument or set its ' +
|
|
70
|
+
'encrypted-only value; every client the harness governs speaks TLS',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
// A quoted assignment, whatever it names. WHICH names hold a credential is decided below rather than
|
|
74
|
+
// inside the pattern: one alternation covering every spelling was unreadable and past the complexity
|
|
75
|
+
// the lint budget allows, and it is the name's segments that carry the meaning anyway.
|
|
76
|
+
const QUOTED_ASSIGNMENT = /^[ \t]*(?<name>\w+)[ \t]*=[ \t]*"(?<value>[^"]*)"/;
|
|
77
|
+
// Read by the last `_`-segment of the name, the way the credential guard in `source-security.ts` reads
|
|
78
|
+
// an identifier. `key` alone is excluded: an S3 object's `key` is a path, and reading it as a
|
|
79
|
+
// credential would report every upload in the tree - so only a QUALIFIED key counts.
|
|
80
|
+
const CREDENTIAL_WORDS = new Set([
|
|
81
|
+
'password',
|
|
82
|
+
'passphrase',
|
|
83
|
+
'secret',
|
|
84
|
+
'token',
|
|
85
|
+
'credential',
|
|
86
|
+
'credentials',
|
|
87
|
+
]);
|
|
88
|
+
const QUALIFIED_KEYS = new Set([
|
|
89
|
+
'api',
|
|
90
|
+
'access',
|
|
91
|
+
'secret',
|
|
92
|
+
'private',
|
|
93
|
+
'encryption',
|
|
94
|
+
]);
|
|
95
|
+
// A secret's CONTENT argument is named the other way round: `secret_string`, `secret_data` and
|
|
96
|
+
// `secret_binary` are what a secret-store version holds, so the first segment carries the meaning and
|
|
97
|
+
// the last says what shape the content takes. `secret_id` and `secret_arn` name a secret rather than
|
|
98
|
+
// hold one, and stay outside.
|
|
99
|
+
const SECRET_CONTENT = new Set(['string', 'data', 'binary', 'value']);
|
|
100
|
+
const PENULTIMATE = -2;
|
|
101
|
+
const isCredentialName = (name) => {
|
|
102
|
+
const segments = name.toLowerCase().split('_');
|
|
103
|
+
const first = segments.at(0) ?? '';
|
|
104
|
+
const last = segments.at(-1) ?? '';
|
|
105
|
+
if (last === 'key') {
|
|
106
|
+
return QUALIFIED_KEYS.has(segments.at(PENULTIMATE) ?? '');
|
|
107
|
+
}
|
|
108
|
+
return CREDENTIAL_WORDS.has(last) || (first === 'secret' && SECRET_CONTENT.has(last));
|
|
109
|
+
};
|
|
110
|
+
// What a placeholder looks like once punctuation and case stop mattering. An angle-bracketed value is
|
|
111
|
+
// the other conventional spelling, and it needs no vocabulary.
|
|
112
|
+
const PLACEHOLDER_VALUES = new Set([
|
|
113
|
+
'REPLACEME',
|
|
114
|
+
'CHANGEME',
|
|
115
|
+
'TODO',
|
|
116
|
+
'FIXME',
|
|
117
|
+
'XXX',
|
|
118
|
+
'PLACEHOLDER',
|
|
119
|
+
'TBD',
|
|
120
|
+
'YOURVALUEHERE',
|
|
121
|
+
]);
|
|
122
|
+
const isPlaceholder = (value) => {
|
|
123
|
+
if (value.startsWith('<') && value.endsWith('>')) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return PLACEHOLDER_VALUES.has(value.toUpperCase().replaceAll(/[^A-Z0-9]/g, ''));
|
|
127
|
+
};
|
|
128
|
+
// An analyzer's own inline skip. Without this the curated checks are advisory: one comment turns the
|
|
129
|
+
// flagship check off and the run still passes. gitleaks cannot see a placeholder either - it carries no
|
|
130
|
+
// entropy - which is why the value rule above is here rather than left to the secret scan.
|
|
131
|
+
const ANALYZER_SUPPRESSION = /#[ \t]*(?<analyzer>checkov:skip=|tfsec:ignore:|trivy:ignore:)/;
|
|
132
|
+
const flagViolations = (code) => code.split('\n').flatMap((line, index) => FLAG_RULES.filter((flag) => flag.patterns.some((pattern) => pattern.test(line))).map((flag) => ({
|
|
133
|
+
line: index + FIRST_LINE,
|
|
134
|
+
rule: flag.rule,
|
|
135
|
+
reason: flag.reason,
|
|
136
|
+
})));
|
|
137
|
+
// The attribute a line leaves as a placeholder, or nothing. Separated from the walk below so each reads
|
|
138
|
+
// as the one question it asks.
|
|
139
|
+
const placeholderNameIn = (line) => {
|
|
140
|
+
const found = QUOTED_ASSIGNMENT.exec(line);
|
|
141
|
+
if (found === null) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
const name = found.groups?.['name'] ?? '';
|
|
145
|
+
const value = found.groups?.['value'] ?? '';
|
|
146
|
+
return isCredentialName(name) && isPlaceholder(value) ? name : undefined;
|
|
147
|
+
};
|
|
148
|
+
const placeholderViolations = (code) => code.split('\n').flatMap((line, index) => {
|
|
149
|
+
const name = placeholderNameIn(line);
|
|
150
|
+
return name === undefined
|
|
151
|
+
? []
|
|
152
|
+
: [
|
|
153
|
+
{
|
|
154
|
+
line: index + FIRST_LINE,
|
|
155
|
+
rule: 'no-placeholder-secret',
|
|
156
|
+
reason: `${name} is set to a placeholder, so whatever it guards is guarded by a value written ` +
|
|
157
|
+
'into the repository - supply it from a secret store, and let the configuration name ' +
|
|
158
|
+
'the reference rather than the value',
|
|
159
|
+
},
|
|
160
|
+
];
|
|
161
|
+
});
|
|
162
|
+
// Read from the RAW text, unlike every rule above: a comment is this rule's subject rather than
|
|
163
|
+
// something to see past.
|
|
164
|
+
const suppressionViolations = (source) => source.split('\n').flatMap((line, index) => {
|
|
165
|
+
const analyzer = ANALYZER_SUPPRESSION.exec(line)?.groups?.['analyzer'];
|
|
166
|
+
return analyzer === undefined
|
|
167
|
+
? []
|
|
168
|
+
: [
|
|
169
|
+
{
|
|
170
|
+
line: index + FIRST_LINE,
|
|
171
|
+
rule: 'no-analyzer-suppression',
|
|
172
|
+
reason: `"${analyzer}" turns off a check this harness enabled, from inside the file the check ` +
|
|
173
|
+
'judges - repair what the analyzer found, because a gate a project can switch off is ' +
|
|
174
|
+
'not a gate',
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
});
|
|
178
|
+
// The rule resource is read from its header to the next line that closes or opens a top-level block.
|
|
179
|
+
// Formatted HCL closes a resource at column 0; unformatted HCL over-reads at worst the blank lines
|
|
180
|
+
// before the next block, never the next block's attributes.
|
|
181
|
+
const INGRESS_RULE_HEADER = /^[ \t]*resource[ \t]+"aws_vpc_security_group_ingress_rule"/;
|
|
182
|
+
const BLOCK_BOUNDARY = /^(?:\}|(?:resource|data|module|variable|output|locals|provider|terraform)\b)/;
|
|
183
|
+
const ANY_ADDRESS = /^[ \t]*cidr_ipv[46][ \t]*=[ \t]*"(?:0\.0\.0\.0\/0|::\/0)"/;
|
|
184
|
+
const EVERY_PROTOCOL = /^[ \t]*ip_protocol[ \t]*=[ \t]*"?-1"?/;
|
|
185
|
+
const PORT_EDGE = /^[ \t]*(?<edge>from_port|to_port)[ \t]*=[ \t]*(?<port>\d+)/;
|
|
186
|
+
const SSH_PORT = 22;
|
|
187
|
+
const RDP_PORT = 3389;
|
|
188
|
+
const LAST_PORT = 65_535;
|
|
189
|
+
const ingressRulesIn = (lines) => lines.flatMap((line, index) => {
|
|
190
|
+
if (!INGRESS_RULE_HEADER.test(line)) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const rest = lines.slice(index + 1);
|
|
194
|
+
const end = rest.findIndex((candidate) => BLOCK_BOUNDARY.test(candidate));
|
|
195
|
+
return [{ line: index + FIRST_LINE, body: end === -1 ? rest : rest.slice(0, end) }];
|
|
196
|
+
});
|
|
197
|
+
const portRangeOf = (body) => {
|
|
198
|
+
const edges = new Map(body.flatMap((line) => {
|
|
199
|
+
const found = PORT_EDGE.exec(line);
|
|
200
|
+
return found === null
|
|
201
|
+
? []
|
|
202
|
+
: [[found.groups?.['edge'] ?? '', Number(found.groups?.['port'] ?? '')]];
|
|
203
|
+
}));
|
|
204
|
+
const from = edges.get('from_port');
|
|
205
|
+
const to = edges.get('to_port');
|
|
206
|
+
return from === undefined || to === undefined ? undefined : { from, to };
|
|
207
|
+
};
|
|
208
|
+
const coversPort = (range, port) => range.from <= port && port <= range.to;
|
|
209
|
+
// What a port range exposes when its source is every address, or nothing when its ports are ones a
|
|
210
|
+
// public site legitimately opens.
|
|
211
|
+
const exposureOfRange = (range) => {
|
|
212
|
+
if (range.from === 0 && range.to === LAST_PORT) {
|
|
213
|
+
return 'every port';
|
|
214
|
+
}
|
|
215
|
+
if (coversPort(range, SSH_PORT)) {
|
|
216
|
+
return 'SSH';
|
|
217
|
+
}
|
|
218
|
+
return coversPort(range, RDP_PORT) ? 'RDP' : undefined;
|
|
219
|
+
};
|
|
220
|
+
const exposureOf = (body) => {
|
|
221
|
+
if (!body.some((line) => ANY_ADDRESS.test(line))) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
if (body.some((line) => EVERY_PROTOCOL.test(line))) {
|
|
225
|
+
return 'every port';
|
|
226
|
+
}
|
|
227
|
+
const range = portRangeOf(body);
|
|
228
|
+
return range === undefined ? undefined : exposureOfRange(range);
|
|
229
|
+
};
|
|
230
|
+
const openIngressViolations = (code) => ingressRulesIn(code.split('\n')).flatMap((rule) => {
|
|
231
|
+
const exposure = exposureOf(rule.body);
|
|
232
|
+
return exposure === undefined
|
|
233
|
+
? []
|
|
234
|
+
: [
|
|
235
|
+
{
|
|
236
|
+
line: rule.line,
|
|
237
|
+
rule: 'no-open-ingress',
|
|
238
|
+
reason: `an ingress rule admits ${exposure} from the whole internet - name the security ` +
|
|
239
|
+
'group or address range that needs it as the source',
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
});
|
|
243
|
+
/**
|
|
244
|
+
* Report every infrastructure defect a text reader can decide.
|
|
245
|
+
* @param source the file's text, as tracked.
|
|
246
|
+
* @returns one violation per defect, ordered by the line it sits on.
|
|
247
|
+
*/
|
|
248
|
+
export const findTerraformViolations = (source) => {
|
|
249
|
+
// `stripComments` covers the `//` and `/* */` forms HCL shares with the languages it was written
|
|
250
|
+
// for. It does NOT read `#`, which is HCL's own spelling - what keeps `# force_destroy = true` out
|
|
251
|
+
// of the value rules is that each pattern is anchored at the attribute, so a leading `#` cannot
|
|
252
|
+
// match. The suppression rule reads the raw text instead, because the comment is its subject.
|
|
253
|
+
const code = stripComments(source);
|
|
254
|
+
return [
|
|
255
|
+
...flagViolations(code),
|
|
256
|
+
...placeholderViolations(code),
|
|
257
|
+
...openIngressViolations(code),
|
|
258
|
+
...suppressionViolations(source),
|
|
259
|
+
].toSorted((left, right) => left.line - right.line);
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=terraform-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-policy.js","sourceRoot":"","sources":["../src/terraform-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** One line that names a provider: a resource, a data source, or a provider block. */
|
|
2
|
+
export interface ProviderDeclaration {
|
|
3
|
+
readonly line: number;
|
|
4
|
+
readonly provider: string;
|
|
5
|
+
/** What the line declares, as a finding names it: the resource type, or `provider "name"`. */
|
|
6
|
+
readonly subject: string;
|
|
7
|
+
readonly kind: 'resource' | 'data' | 'provider';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Every line of a source that names a provider.
|
|
11
|
+
* @param source the file's text, as tracked.
|
|
12
|
+
* @returns the declarations, ordered by the line they sit on.
|
|
13
|
+
*/
|
|
14
|
+
export declare const providerDeclarationsIn: (source: string) => readonly ProviderDeclaration[];
|
|
15
|
+
/**
|
|
16
|
+
* The providers a set of declarations names.
|
|
17
|
+
* @param declarations declarations from one or many sources.
|
|
18
|
+
* @returns each provider once, ordered so a report reads the same on every machine.
|
|
19
|
+
*/
|
|
20
|
+
export declare const providersOf: (declarations: readonly ProviderDeclaration[]) => readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* How many resources and data sources the declarations carry - what an analyzer has to judge. A
|
|
23
|
+
* provider block configures a provider and declares nothing it could check.
|
|
24
|
+
* @param declarations declarations from one or many sources.
|
|
25
|
+
* @returns the count of resource and data declarations.
|
|
26
|
+
*/
|
|
27
|
+
export declare const resourceCountOf: (declarations: readonly ProviderDeclaration[]) => number;
|
|
28
|
+
//# sourceMappingURL=terraform-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-providers.d.ts","sourceRoot":"","sources":["../src/terraform-providers.ts"],"names":[],"mappings":"AAUA,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU,CAAA;CAChD;AA6CD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,KAAG,SAAS,mBAAmB,EAKnF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,cAAc,SAAS,mBAAmB,EAAE,KAAG,SAAS,MAAM,EAKV,CAAA;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,cAAc,SAAS,mBAAmB,EAAE,KAAG,MAGrE,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Which providers an OpenTofu or Terraform source declares, read from block headers alone.
|
|
2
|
+
//
|
|
3
|
+
// The resource type is the key, because it is what the analyzer's own catalogue binds a check to:
|
|
4
|
+
// `aws_iam_role` belongs to `aws` whatever local name a `required_providers` block gives the provider.
|
|
5
|
+
// That block is deliberately not read. Modules inherit it from their caller, so it sits in a minority
|
|
6
|
+
// of files; its `source = "..."` line cannot be told from a module's without block parsing; and a
|
|
7
|
+
// provider declared there with no resource in the tree leaves the analyzer nothing to judge anyway.
|
|
8
|
+
// Nothing here parses HCL structure - this stays a line reader, like the policy beside it.
|
|
9
|
+
import { lineOf, stripComments } from './source-text.js';
|
|
10
|
+
// Anchored at the start of a line so HCL's own `#` comment, which `stripComments` does not read, cannot
|
|
11
|
+
// match; a `//` or `/* */` comment is blanked before the scan (see terraform-policy.ts).
|
|
12
|
+
const RESOURCE_HEADER = /^[ \t]*(?<kind>resource|data)[ \t]+"(?<type>[a-z][a-z0-9_]*)"/gm;
|
|
13
|
+
const PROVIDER_HEADER = /^[ \t]*provider[ \t]+"(?<name>[a-z][a-z0-9-]*)"/gm;
|
|
14
|
+
// A provider whose resources carry another provider's prefix. `google-beta` declares `google_*`
|
|
15
|
+
// resources, so its block names the provider the resource types already name.
|
|
16
|
+
const PROVIDER_ALIASES = new Map([['google-beta', 'google']]);
|
|
17
|
+
const providerOfType = (type) => {
|
|
18
|
+
const separator = type.indexOf('_');
|
|
19
|
+
return separator === -1 ? type : type.slice(0, separator);
|
|
20
|
+
};
|
|
21
|
+
// A matched header always carries its groups; the fallback satisfies the type checker, not a case.
|
|
22
|
+
const groupOf = (found, group) => found[group] ?? '';
|
|
23
|
+
const KIND_GROUP = 1;
|
|
24
|
+
const TYPE_GROUP = 2;
|
|
25
|
+
const NAME_GROUP = 1;
|
|
26
|
+
const resourceDeclarations = (code) => [...code.matchAll(RESOURCE_HEADER)].map((found) => {
|
|
27
|
+
const type = groupOf(found, TYPE_GROUP);
|
|
28
|
+
return {
|
|
29
|
+
line: lineOf(code, found.index),
|
|
30
|
+
provider: providerOfType(type),
|
|
31
|
+
subject: type,
|
|
32
|
+
kind: groupOf(found, KIND_GROUP) === 'data' ? 'data' : 'resource',
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
const providerBlocks = (code) => [...code.matchAll(PROVIDER_HEADER)].map((found) => {
|
|
36
|
+
const name = groupOf(found, NAME_GROUP);
|
|
37
|
+
return {
|
|
38
|
+
line: lineOf(code, found.index),
|
|
39
|
+
provider: PROVIDER_ALIASES.get(name) ?? name,
|
|
40
|
+
subject: `provider "${name}"`,
|
|
41
|
+
kind: 'provider',
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Every line of a source that names a provider.
|
|
46
|
+
* @param source the file's text, as tracked.
|
|
47
|
+
* @returns the declarations, ordered by the line they sit on.
|
|
48
|
+
*/
|
|
49
|
+
export const providerDeclarationsIn = (source) => {
|
|
50
|
+
const code = stripComments(source);
|
|
51
|
+
return [...resourceDeclarations(code), ...providerBlocks(code)].toSorted((left, right) => left.line - right.line);
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The providers a set of declarations names.
|
|
55
|
+
* @param declarations declarations from one or many sources.
|
|
56
|
+
* @returns each provider once, ordered so a report reads the same on every machine.
|
|
57
|
+
*/
|
|
58
|
+
export const providersOf = (declarations) => [
|
|
59
|
+
...new Set(declarations.map((declaration) => declaration.provider)),
|
|
60
|
+
].toSorted((left, right) => left.localeCompare(right));
|
|
61
|
+
/**
|
|
62
|
+
* How many resources and data sources the declarations carry - what an analyzer has to judge. A
|
|
63
|
+
* provider block configures a provider and declares nothing it could check.
|
|
64
|
+
* @param declarations declarations from one or many sources.
|
|
65
|
+
* @returns the count of resource and data declarations.
|
|
66
|
+
*/
|
|
67
|
+
export const resourceCountOf = (declarations) => declarations.filter((declaration) => declaration.kind !== 'provider').length;
|
|
68
|
+
//# sourceMappingURL=terraform-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-providers.js","sourceRoot":"","sources":["../src/terraform-providers.ts"],"names":[],"mappings":"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"}
|
package/dist/toolchain-pins.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** An analyzer ploaness runs in a container rather than installing from the registry. */
|
|
2
|
-
export type ContainerTool = 'gitleaks' | 'hadolint' | 'actionlint' | 'shellcheck';
|
|
2
|
+
export type ContainerTool = 'gitleaks' | 'hadolint' | 'actionlint' | 'shellcheck' | 'checkov';
|
|
3
3
|
/** The exact image each containerised analyzer runs, by digest. */
|
|
4
4
|
export declare const CONTAINER_IMAGES: Readonly<Record<ContainerTool, string>>;
|
|
5
5
|
/** Matches a reference that names image bytes AND the release they are, and only such a reference. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolchain-pins.d.ts","sourceRoot":"","sources":["../src/toolchain-pins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toolchain-pins.d.ts","sourceRoot":"","sources":["../src/toolchain-pins.ts"],"names":[],"mappings":"AAGA,yFAAyF;AACzF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAA;AAE7F,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAmBpE,CAAA;AAED,sGAAsG;AACtG,eAAO,MAAM,aAAa,EAAE,MACsC,CAAA;AAElE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,SAAS,MAAM,EAOxF,CAAA;AAOL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAG3E,CAAA;AAOD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,gBAAgB,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAG/E,CAAA;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GACpC,WAAW,MAAM,GAAG,SAAS,EAC7B,UAAU,MAAM,GAAG,SAAS,KAC3B,SAAS,MAAM,EAajB,CAAA"}
|
package/dist/toolchain-pins.js
CHANGED
|
@@ -1,30 +1,20 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Pinned by digest rather than by tag. A tag - `latest` most obviously, but a version tag too - is a
|
|
4
|
-
// mutable reference: the registry can repoint it at new bytes, and the same repository would then reach
|
|
5
|
-
// a different verdict on a different day. A digest names the bytes, so it is the only form that makes
|
|
6
|
-
// "an upstream release cannot change a verdict while the repository does not change" literally true.
|
|
7
|
-
//
|
|
8
|
-
// The tag is written too, and it is not decoration. A digest alone says nothing about which release it
|
|
9
|
-
// is, so the version used to live in a comment beside it - unreadable to anything but a person, which
|
|
10
|
-
// is why nothing reported when a newer image existed. `<repo>:<tag>@sha256:<digest>` states both: docker
|
|
11
|
-
// resolves the digest and ignores the tag, and the freshness check reads the tag to ask the registry
|
|
12
|
-
// what is newer. A bare tag is still rejected; the spec requires both halves.
|
|
13
|
-
//
|
|
14
|
-
// To move a pin, read the new digest with `docker buildx imagetools inspect <repo>:<tag>`.
|
|
15
|
-
//
|
|
16
|
-
// Two of the four tags below are not the versions their comments used to claim. The hadolint pin was
|
|
17
|
-
// commented `2.14.0` and is the bytes of `v2.15.1`; the actionlint pin was commented `1.7.7` and is
|
|
18
|
-
// `1.7.12`. Nothing could have caught that while the version was prose, which is the whole argument for
|
|
19
|
-
// writing it where a check can read it.
|
|
1
|
+
// Analyzer image tags support freshness reporting; immutable digests identify the bytes executed.
|
|
2
|
+
// Update both with docker buildx imagetools inspect <repository>:<tag>.
|
|
20
3
|
/** The exact image each containerised analyzer runs, by digest. */
|
|
21
4
|
export const CONTAINER_IMAGES = {
|
|
22
5
|
gitleaks: 'zricethezav/gitleaks:v8.30.1@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f',
|
|
23
6
|
hadolint: 'hadolint/hadolint:v2.15.1@sha256:32dac94127fd60b7b7e3fbfc65e1383b9b5e25c9bfd7b8536de7a539fe68a12d',
|
|
24
7
|
actionlint: 'rhysd/actionlint:1.7.12@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667',
|
|
25
|
-
//
|
|
26
|
-
//
|
|
8
|
+
// A project's operational scripts are code it runs against its own database and its own deployments,
|
|
9
|
+
// and the standard makes a check a repository implements itself into its source code. The `shell`
|
|
10
|
+
// gate reads both: a consumer's scripts, and the ones this verification command is written in.
|
|
27
11
|
shellcheck: 'koalaman/shellcheck:v0.11.0@sha256:61862eba1fcf09a484ebcc6feea46f1782532571a34ed51fedf90dd25f925a8d',
|
|
12
|
+
// The infrastructure gate enables named checks rather than a category, and a `--check` id that does
|
|
13
|
+
// not exist matches nothing and raises no error. The digest is what makes that audit durable: the
|
|
14
|
+
// catalogue cannot change underneath it, so the enabled ids stay the ones somebody confirmed with
|
|
15
|
+
// `--list`. The provider standings beside the catalogue rest on the same listing: which providers
|
|
16
|
+
// the image has no check for at all. Re-confirm both whenever this pin moves.
|
|
17
|
+
checkov: 'bridgecrew/checkov:3.3.17@sha256:41c4701c6a56d8952e5aba7a420f871c8b70b57da94eb4f142dcdf7295bb0be3',
|
|
28
18
|
};
|
|
29
19
|
/** Matches a reference that names image bytes AND the release they are, and only such a reference. */
|
|
30
20
|
export const DIGEST_PINNED = /^[a-z0-9][a-z0-9._/-]*:[A-Za-z0-9][\w.-]*@sha256:[0-9a-f]{64}$/;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolchain-pins.js","sourceRoot":"","sources":["../src/toolchain-pins.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"toolchain-pins.js","sourceRoot":"","sources":["../src/toolchain-pins.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,wEAAwE;AAKxE,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAA4C;IACvE,QAAQ,EACN,sGAAsG;IACxG,QAAQ,EACN,mGAAmG;IACrG,UAAU,EACR,iGAAiG;IACnG,qGAAqG;IACrG,kGAAkG;IAClG,+FAA+F;IAC/F,UAAU,EACR,qGAAqG;IACvG,oGAAoG;IACpG,kGAAkG;IAClG,kGAAkG;IAClG,kGAAkG;IAClG,8EAA8E;IAC9E,OAAO,EACL,mGAAmG;CACtG,CAAA;AAED,sGAAsG;AACtG,MAAM,CAAC,MAAM,aAAa,GACxB,gEAAgE,CAAA;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAwC,EAAqB,EAAE,CAChG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;KACnB,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAA4B,EAAW,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KAC7F,GAAG,CACF,CAAC,CAAC,IAAI,EAAE,SAAS,CAA4B,EAAU,EAAE,CACvD,GAAG,IAAI,UAAU,SAAS,yDAAyD;IACnF,wCAAwC,CAC3C,CAAA;AAEL,0FAA0F;AAC1F,wGAAwG;AACxG,sGAAsG;AACtG,MAAM,aAAa,GAAW,OAAO,CAAA;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,WAA+B,EAAsB,EAAE;IACtF,MAAM,KAAK,GAA2B,aAAa,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;IAC3E,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACtD,CAAC,CAAA;AAED,oGAAoG;AACpG,iGAAiG;AACjG,0DAA0D;AAC1D,MAAM,cAAc,GAAW,4BAA4B,CAAA;AAE3D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,cAAkC,EAAsB,EAAE;IAC1F,MAAM,KAAK,GAA2B,cAAc,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,CAAA;IAC/E,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC,CAAA;AAED,qGAAqG;AACrG,oGAAoG;AACpG,MAAM,eAAe,GAAW,qBAAqB,CAAA;AAErD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,SAA6B,EAC7B,QAA4B,EACT,EAAE;IACrB,MAAM,KAAK,GAA2B,eAAe,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;IAC3E,MAAM,OAAO,GAAuB,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9C,gGAAgG;IAChG,oGAAoG;IACpG,8FAA8F;IAC9F,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5E,OAAO,EAAE,CAAA;IACX,CAAC;IACD,OAAO;QACL,QAAQ,OAAO,mDAAmD,QAAQ,IAAI;YAC5E,0FAA0F;KAC7F,CAAA;AACH,CAAC,CAAA"}
|
package/dist/version-policy.d.ts
CHANGED
|
@@ -8,18 +8,17 @@ import type { WiringViolation } from './wiring-violation.js';
|
|
|
8
8
|
* @returns `missing`, or the value in quotes.
|
|
9
9
|
*/
|
|
10
10
|
export declare const describeFound: (found: string | undefined) => string;
|
|
11
|
-
/** The meta package a governed project declares, and the root of everything it inherits from ploaness. */
|
|
12
|
-
export declare const HARNESS_PACKAGE: string;
|
|
13
11
|
/**
|
|
14
|
-
* Whether a package
|
|
12
|
+
* Whether a package is one Payload publishes alongside itself, and so must carry the pinned `payload`
|
|
13
|
+
* version.
|
|
15
14
|
*
|
|
16
|
-
* Exported because the
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* Exported because the freshness report asks the same question from the other side: a `@payloadcms/*`
|
|
16
|
+
* update is not the project's to take, since this rule holds the declaration to the pin. Two copies of
|
|
17
|
+
* the scope literal would be two rules that stop agreeing about which packages that is.
|
|
19
18
|
* @param packageName the declared name.
|
|
20
|
-
* @returns true for
|
|
19
|
+
* @returns true for anything under Payload's scope.
|
|
21
20
|
*/
|
|
22
|
-
export declare const
|
|
21
|
+
export declare const isPayloadFamilyPackage: (packageName: string) => boolean;
|
|
23
22
|
/**
|
|
24
23
|
* The package whose presence makes a project a Payload application.
|
|
25
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-policy.d.ts","sourceRoot":"","sources":["../src/version-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version-policy.d.ts","sourceRoot":"","sources":["../src/version-policy.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAc5D;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MACV,CAAA;AAiNhD;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,KAAG,OACtB,CAAA;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,MAAkB,CAAA;AAEhD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,MAAe,CAAA;AAmG1C,gGAAgG;AAChG,MAAM,WAAW,uBAAuB;IACtC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACnD,8EAA8E;IAC9E,QAAQ,CAAC,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAA;IACnD,uDAAuD;IACvD,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1D,yFAAyF;IACzF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACjE;AAED,+EAA+E;AAC/E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACnD,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACtC,mGAAmG;IACnG,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5C;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,GAC1C,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,uBAAuB,KAC9B,SAAS,eAAe,EAc1B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,GACvC,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,oBAAoB,KAC3B,SAAS,eAAe,EAM1B,CAAA;AAED,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACnD,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3C,QAAQ,CAAC,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAA;IACnD,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAChC,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,aAAa,KACpB,SAAS,eAAe,EAa1B,CAAA"}
|
package/dist/version-policy.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// ploaness with; this judges the numbers beside its dependencies. The two were one file until it passed
|
|
5
|
-
// the size cap, which is the cap doing its job: they answer different questions and share only the
|
|
6
|
-
// helpers below.
|
|
7
|
-
import { findOverrides, OVERRIDE_KEYS } from './install-policy.js';
|
|
1
|
+
// Hold declared package versions and install overrides to the harness-owned version policy.
|
|
2
|
+
import { HARNESS_PACKAGE, isHarnessPackage } from './harness-package.js';
|
|
3
|
+
import { findOverrides, OVERRIDE_KEYS, packageNameOf, } from './install-policy.js';
|
|
8
4
|
import { asOptionalText, asRecord, asStringRecord, declaredDependencies } from './json-shapes.js';
|
|
9
5
|
import { pinnedPnpmVersion } from './toolchain-pins.js';
|
|
10
6
|
// Which block a package is actually declared in. A finding that named `devDependencies` for a package
|
|
@@ -35,18 +31,6 @@ export const describeFound = (found) => found === undefined ? 'missing' : `"${fo
|
|
|
35
31
|
// finding, which is the right time to say what was actually intended.
|
|
36
32
|
const HARNESS_SCOPE = '@ploaness/';
|
|
37
33
|
const LOCAL_ARTEFACT = /^(?:file|link|workspace):/;
|
|
38
|
-
/** The meta package a governed project declares, and the root of everything it inherits from ploaness. */
|
|
39
|
-
export const HARNESS_PACKAGE = 'ploaness';
|
|
40
|
-
/**
|
|
41
|
-
* Whether a package name is one of ploaness's own.
|
|
42
|
-
*
|
|
43
|
-
* Exported because the `deps` gate asks the same question when it walks the manifests a project
|
|
44
|
-
* inherits, and it had no way to ask it but a second copy of the two literals above - which is the
|
|
45
|
-
* shape of drift this repository refuses everywhere else.
|
|
46
|
-
* @param packageName the declared name.
|
|
47
|
-
* @returns true for `ploaness` and for anything under its scope.
|
|
48
|
-
*/
|
|
49
|
-
export const isHarnessPackage = (packageName) => packageName === HARNESS_PACKAGE || packageName.startsWith(HARNESS_SCOPE);
|
|
50
34
|
const isHarnessTarball = (entry) => isHarnessPackage(entry.packageName) && LOCAL_ARTEFACT.test(entry.specifier);
|
|
51
35
|
const overrideViolation = (entry, expected, declared) => {
|
|
52
36
|
if (isHarnessTarball(entry)) {
|
|
@@ -127,12 +111,6 @@ const checkEngines = (packageJson, required) => {
|
|
|
127
111
|
// version says otherwise; and a package extension, which rewrites a manifest the resolver then obeys.
|
|
128
112
|
// None is visible in the dependency block a reader checks, which is what makes them worth naming - and
|
|
129
113
|
// the list is imported rather than restated, because two copies of it in one gate will not stay equal.
|
|
130
|
-
// A patch is keyed by `name@version`, and a scoped name begins with the same character, so the split is
|
|
131
|
-
// on the last `@` rather than the first.
|
|
132
|
-
const packageNameOf = (key) => {
|
|
133
|
-
const at = key.lastIndexOf('@');
|
|
134
|
-
return at > 0 ? key.slice(0, at) : key;
|
|
135
|
-
};
|
|
136
114
|
const escapeEntries = (packageJson) => OVERRIDE_KEYS.flatMap((key) => [packageJson, asRecord(packageJson['pnpm'])].flatMap((holder) => Object.keys(asRecord(holder[key])).map((entry) => [key, entry])));
|
|
137
115
|
const checkVersionEscapes = (packageJson, expected) => escapeEntries(packageJson)
|
|
138
116
|
.filter(([, entry]) => Object.hasOwn(expected, packageNameOf(entry ?? '')))
|
|
@@ -190,6 +168,17 @@ const checkExactVersions = (packageJson) => Object.entries(declaredDependencies(
|
|
|
190
168
|
// list, so a project adding `@payloadcms/plugin-form-builder` is covered by the rule that already
|
|
191
169
|
// exists instead of by an entry somebody has to remember.
|
|
192
170
|
const PAYLOAD_SCOPE = '@payloadcms/';
|
|
171
|
+
/**
|
|
172
|
+
* Whether a package is one Payload publishes alongside itself, and so must carry the pinned `payload`
|
|
173
|
+
* version.
|
|
174
|
+
*
|
|
175
|
+
* Exported because the freshness report asks the same question from the other side: a `@payloadcms/*`
|
|
176
|
+
* update is not the project's to take, since this rule holds the declaration to the pin. Two copies of
|
|
177
|
+
* the scope literal would be two rules that stop agreeing about which packages that is.
|
|
178
|
+
* @param packageName the declared name.
|
|
179
|
+
* @returns true for anything under Payload's scope.
|
|
180
|
+
*/
|
|
181
|
+
export const isPayloadFamilyPackage = (packageName) => packageName.startsWith(PAYLOAD_SCOPE);
|
|
193
182
|
/**
|
|
194
183
|
* The package whose presence makes a project a Payload application.
|
|
195
184
|
*
|
|
@@ -211,7 +200,7 @@ const checkPayloadFamily = (packageJson, payloadVersion) => {
|
|
|
211
200
|
return [];
|
|
212
201
|
}
|
|
213
202
|
return Object.entries(declaredDependencies(packageJson))
|
|
214
|
-
.filter(([name, version]) => name
|
|
203
|
+
.filter(([name, version]) => isPayloadFamilyPackage(name) && version !== payloadVersion)
|
|
215
204
|
.map(([name, version]) => ({
|
|
216
205
|
location: `package.json ${name}`,
|
|
217
206
|
reason: `is "${version}" but payload is pinned at "${payloadVersion}"; ` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-policy.js","sourceRoot":"","sources":["../src/version-policy.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"version-policy.js","sourceRoot":"","sources":["../src/version-policy.ts"],"names":[],"mappings":"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"}
|