aws-delivlib 13.5.19 → 13.6.2
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 +30 -0
- package/cdk.out/tree.json +391 -391
- package/lib/custom-resource-handlers/src/certificate-signing-request.tsbuildinfo +1 -1
- package/lib/custom-resource-handlers/src/pgp-secret.tsbuildinfo +1 -1
- package/lib/custom-resource-handlers/src/private-key.tsbuildinfo +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/index.ts +1 -0
- package/lib/package-integrity/handler/JSONStream.d.ts +29 -0
- package/lib/package-integrity/handler/integrity.d.ts +103 -0
- package/lib/package-integrity/handler/integrity.js +238 -0
- package/lib/package-integrity/handler/integrity.ts +316 -0
- package/lib/package-integrity/handler/repository.d.ts +81 -0
- package/lib/package-integrity/handler/repository.js +111 -0
- package/lib/package-integrity/handler/repository.ts +185 -0
- package/lib/package-integrity/handler/validate.bundle.js +604234 -0
- package/lib/package-integrity/handler/validate.d.ts +2 -0
- package/lib/package-integrity/handler/validate.js +37 -0
- package/lib/package-integrity/handler/validate.sh +5 -0
- package/lib/package-integrity/handler/validate.ts +41 -0
- package/lib/package-integrity/index.d.ts +1 -0
- package/lib/package-integrity/index.js +14 -0
- package/lib/package-integrity/index.ts +1 -0
- package/lib/package-integrity/integrity.d.ts +64 -0
- package/lib/package-integrity/integrity.js +64 -0
- package/lib/package-integrity/integrity.ts +112 -0
- package/package.json +17 -9
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const integrity_1 = require("./integrity");
|
|
5
|
+
const repository_1 = require("./repository");
|
|
6
|
+
function requiredEnv(name) {
|
|
7
|
+
const value = process.env[name];
|
|
8
|
+
if (value)
|
|
9
|
+
return value;
|
|
10
|
+
throw new Error(`${name} env variable is required`);
|
|
11
|
+
}
|
|
12
|
+
function optionalEnv(name, defaultValue) {
|
|
13
|
+
var _a;
|
|
14
|
+
return (_a = process.env[name]) !== null && _a !== void 0 ? _a : defaultValue;
|
|
15
|
+
}
|
|
16
|
+
const GITHUB_REPOSITORY = requiredEnv('GITHUB_REPOSITORY');
|
|
17
|
+
const GITHUB_TOKEN_ARN = optionalEnv('GITHUB_TOKEN_ARN');
|
|
18
|
+
const TAG_PREFIX = optionalEnv('TAG_PREFIX');
|
|
19
|
+
const PACK_TASK = optionalEnv('PACK_TASK');
|
|
20
|
+
async function main() {
|
|
21
|
+
const repo = await repository_1.Repository.fromGitHub({
|
|
22
|
+
githubTokenSecretArn: GITHUB_TOKEN_ARN,
|
|
23
|
+
slug: GITHUB_REPOSITORY,
|
|
24
|
+
tagPrefix: TAG_PREFIX,
|
|
25
|
+
});
|
|
26
|
+
const integrity = new integrity_1.RepositoryIntegrity({
|
|
27
|
+
repository: repo,
|
|
28
|
+
packCommand: PACK_TASK,
|
|
29
|
+
});
|
|
30
|
+
await integrity.validate();
|
|
31
|
+
}
|
|
32
|
+
main()
|
|
33
|
+
.catch(e => {
|
|
34
|
+
console.log(`Error: ${e.message}`);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2YWxpZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwyQ0FBa0Q7QUFDbEQsNkNBQTBDO0FBRTFDLFNBQVMsV0FBVyxDQUFDLElBQVk7SUFDL0IsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxJQUFJLEtBQUs7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsSUFBSSwyQkFBMkIsQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxJQUFZLEVBQUUsWUFBcUI7O0lBQ3RELE9BQU8sTUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxtQ0FBSSxZQUFZLENBQUM7QUFDM0MsQ0FBQztBQUVELE1BQU0saUJBQWlCLEdBQUcsV0FBVyxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDM0QsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUN6RCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDN0MsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRTNDLEtBQUssVUFBVSxJQUFJO0lBRWpCLE1BQU0sSUFBSSxHQUFHLE1BQU0sdUJBQVUsQ0FBQyxVQUFVLENBQUM7UUFDdkMsb0JBQW9CLEVBQUUsZ0JBQWdCO1FBQ3RDLElBQUksRUFBRSxpQkFBaUI7UUFDdkIsU0FBUyxFQUFFLFVBQVU7S0FDdEIsQ0FBQyxDQUFDO0lBRUgsTUFBTSxTQUFTLEdBQUcsSUFBSSwrQkFBbUIsQ0FBQztRQUN4QyxVQUFVLEVBQUUsSUFBSTtRQUNoQixXQUFXLEVBQUUsU0FBUztLQUN2QixDQUFDLENBQUM7SUFFSCxNQUFNLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUU3QixDQUFDO0FBRUQsSUFBSSxFQUFFO0tBQ0gsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ25DLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuaW1wb3J0IHsgUmVwb3NpdG9yeUludGVncml0eSB9IGZyb20gJy4vaW50ZWdyaXR5JztcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcnknO1xuXG5mdW5jdGlvbiByZXF1aXJlZEVudihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W25hbWVdO1xuICBpZiAodmFsdWUpIHJldHVybiB2YWx1ZTtcbiAgdGhyb3cgbmV3IEVycm9yKGAke25hbWV9IGVudiB2YXJpYWJsZSBpcyByZXF1aXJlZGApO1xufVxuXG5mdW5jdGlvbiBvcHRpb25hbEVudihuYW1lOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IHN0cmluZykge1xuICByZXR1cm4gcHJvY2Vzcy5lbnZbbmFtZV0gPz8gZGVmYXVsdFZhbHVlO1xufVxuXG5jb25zdCBHSVRIVUJfUkVQT1NJVE9SWSA9IHJlcXVpcmVkRW52KCdHSVRIVUJfUkVQT1NJVE9SWScpO1xuY29uc3QgR0lUSFVCX1RPS0VOX0FSTiA9IG9wdGlvbmFsRW52KCdHSVRIVUJfVE9LRU5fQVJOJyk7XG5jb25zdCBUQUdfUFJFRklYID0gb3B0aW9uYWxFbnYoJ1RBR19QUkVGSVgnKTtcbmNvbnN0IFBBQ0tfVEFTSyA9IG9wdGlvbmFsRW52KCdQQUNLX1RBU0snKTtcblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcblxuICBjb25zdCByZXBvID0gYXdhaXQgUmVwb3NpdG9yeS5mcm9tR2l0SHViKHtcbiAgICBnaXRodWJUb2tlblNlY3JldEFybjogR0lUSFVCX1RPS0VOX0FSTixcbiAgICBzbHVnOiBHSVRIVUJfUkVQT1NJVE9SWSxcbiAgICB0YWdQcmVmaXg6IFRBR19QUkVGSVgsXG4gIH0pO1xuXG4gIGNvbnN0IGludGVncml0eSA9IG5ldyBSZXBvc2l0b3J5SW50ZWdyaXR5KHtcbiAgICByZXBvc2l0b3J5OiByZXBvLFxuICAgIHBhY2tDb21tYW5kOiBQQUNLX1RBU0ssXG4gIH0pO1xuXG4gIGF3YWl0IGludGVncml0eS52YWxpZGF0ZSgpO1xuXG59XG5cbm1haW4oKVxuICAuY2F0Y2goZSA9PiB7XG4gICAgY29uc29sZS5sb2coYEVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICBwcm9jZXNzLmV4aXRDb2RlID0gMTtcbiAgfSk7XG4iXX0=
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { RepositoryIntegrity } from './integrity';
|
|
3
|
+
import { Repository } from './repository';
|
|
4
|
+
|
|
5
|
+
function requiredEnv(name: string): string {
|
|
6
|
+
const value = process.env[name];
|
|
7
|
+
if (value) return value;
|
|
8
|
+
throw new Error(`${name} env variable is required`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function optionalEnv(name: string, defaultValue?: string) {
|
|
12
|
+
return process.env[name] ?? defaultValue;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const GITHUB_REPOSITORY = requiredEnv('GITHUB_REPOSITORY');
|
|
16
|
+
const GITHUB_TOKEN_ARN = optionalEnv('GITHUB_TOKEN_ARN');
|
|
17
|
+
const TAG_PREFIX = optionalEnv('TAG_PREFIX');
|
|
18
|
+
const PACK_TASK = optionalEnv('PACK_TASK');
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
|
|
22
|
+
const repo = await Repository.fromGitHub({
|
|
23
|
+
githubTokenSecretArn: GITHUB_TOKEN_ARN,
|
|
24
|
+
slug: GITHUB_REPOSITORY,
|
|
25
|
+
tagPrefix: TAG_PREFIX,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const integrity = new RepositoryIntegrity({
|
|
29
|
+
repository: repo,
|
|
30
|
+
packCommand: PACK_TASK,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await integrity.validate();
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main()
|
|
38
|
+
.catch(e => {
|
|
39
|
+
console.log(`Error: ${e.message}`);
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './integrity';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./integrity"), exports);
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSw4Q0FBNEIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2ludGVncml0eSc7Il19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './integrity';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Construct, aws_cloudwatch as cloudwatch, aws_events as events, aws_secretsmanager as sm } from 'monocdk';
|
|
2
|
+
import { ShellPlatform } from '../shellable';
|
|
3
|
+
/**
|
|
4
|
+
* Properties for `PackageIntegrityValidation`.
|
|
5
|
+
*/
|
|
6
|
+
export interface PackageIntegrityValidationProps {
|
|
7
|
+
/**
|
|
8
|
+
* The repository slug of the package (i.e cdklabs/jsii-docgen)
|
|
9
|
+
*/
|
|
10
|
+
readonly repository: string;
|
|
11
|
+
/**
|
|
12
|
+
* Secret containing a github token.
|
|
13
|
+
*/
|
|
14
|
+
readonly githubTokenSecret?: sm.ISecret;
|
|
15
|
+
/**
|
|
16
|
+
* The build platform to use. This platform should contain all necessary tools to package the artifacts
|
|
17
|
+
* in the repository. Note that by default, this also means running the tests.
|
|
18
|
+
*
|
|
19
|
+
* @default ShellPlatform.LinuxUbuntu
|
|
20
|
+
*/
|
|
21
|
+
readonly buildPlatform?: ShellPlatform;
|
|
22
|
+
/**
|
|
23
|
+
* Run the validation on a schedule.
|
|
24
|
+
*
|
|
25
|
+
* @default - once a day.
|
|
26
|
+
*/
|
|
27
|
+
readonly schedule?: events.Schedule;
|
|
28
|
+
/**
|
|
29
|
+
* Wether or not the environment should be privileged, necessary to run container images.
|
|
30
|
+
*
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
readonly privileged?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Tag prefix for this specific validation. Only needed for repositories that either release
|
|
36
|
+
* multiple packages or multiple major versions.
|
|
37
|
+
*
|
|
38
|
+
* @default - no prefix
|
|
39
|
+
*/
|
|
40
|
+
readonly tagPrefix?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The projen task that produces the local artifacts.
|
|
43
|
+
*
|
|
44
|
+
* @default 'release'
|
|
45
|
+
*/
|
|
46
|
+
readonly packTask?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Perform periodic integrity checks on published packages based on the
|
|
50
|
+
* source code of the package. Currently supports only GitHub hosted packages.
|
|
51
|
+
*
|
|
52
|
+
* The check is done by downloading the published artifact, building the source code, and comparing the two.
|
|
53
|
+
* If they differ, it means that of the following was compromised:
|
|
54
|
+
*
|
|
55
|
+
* - The publishing platform (for example GitHub runners)
|
|
56
|
+
* - The artifact storage (for example npmjs.com)
|
|
57
|
+
*/
|
|
58
|
+
export declare class PackageIntegrityValidation extends Construct {
|
|
59
|
+
/**
|
|
60
|
+
* The alarm that will trigger if the validation fails.
|
|
61
|
+
*/
|
|
62
|
+
readonly failureAlarm: cloudwatch.Alarm;
|
|
63
|
+
constructor(scope: Construct, id: string, props: PackageIntegrityValidationProps);
|
|
64
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.PackageIntegrityValidation = void 0;
|
|
23
|
+
const path = __importStar(require("path"));
|
|
24
|
+
const monocdk_1 = require("monocdk");
|
|
25
|
+
const shellable_1 = require("../shellable");
|
|
26
|
+
/**
|
|
27
|
+
* Perform periodic integrity checks on published packages based on the
|
|
28
|
+
* source code of the package. Currently supports only GitHub hosted packages.
|
|
29
|
+
*
|
|
30
|
+
* The check is done by downloading the published artifact, building the source code, and comparing the two.
|
|
31
|
+
* If they differ, it means that of the following was compromised:
|
|
32
|
+
*
|
|
33
|
+
* - The publishing platform (for example GitHub runners)
|
|
34
|
+
* - The artifact storage (for example npmjs.com)
|
|
35
|
+
*/
|
|
36
|
+
class PackageIntegrityValidation extends monocdk_1.Construct {
|
|
37
|
+
constructor(scope, id, props) {
|
|
38
|
+
var _a, _b, _c, _d, _e;
|
|
39
|
+
super(scope, id);
|
|
40
|
+
const shellable = new shellable_1.Shellable(this, 'Default', {
|
|
41
|
+
scriptDirectory: path.join(__dirname, 'handler'),
|
|
42
|
+
entrypoint: 'validate.sh',
|
|
43
|
+
privileged: (_a = props.privileged) !== null && _a !== void 0 ? _a : false,
|
|
44
|
+
platform: (_b = props.buildPlatform) !== null && _b !== void 0 ? _b : shellable_1.ShellPlatform.LinuxUbuntu,
|
|
45
|
+
environment: {
|
|
46
|
+
GITHUB_REPOSITORY: props.repository,
|
|
47
|
+
TAG_PREFIX: (_c = props.tagPrefix) !== null && _c !== void 0 ? _c : '',
|
|
48
|
+
GITHUB_TOKEN_ARN: (_d = props.githubTokenSecret) === null || _d === void 0 ? void 0 : _d.secretArn,
|
|
49
|
+
PACK_TASK: props.packTask,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (props.githubTokenSecret) {
|
|
53
|
+
const grant = props.githubTokenSecret.grantRead(shellable.role);
|
|
54
|
+
grant.assertSuccess();
|
|
55
|
+
}
|
|
56
|
+
new monocdk_1.aws_events.Rule(this, 'ScheduledTrigger', {
|
|
57
|
+
schedule: (_e = props.schedule) !== null && _e !== void 0 ? _e : monocdk_1.aws_events.Schedule.rate(monocdk_1.Duration.days(1)),
|
|
58
|
+
targets: [new monocdk_1.aws_events_targets.CodeBuildProject(shellable.project)],
|
|
59
|
+
});
|
|
60
|
+
this.failureAlarm = shellable.alarm;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.PackageIntegrityValidation = PackageIntegrityValidation;
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWdyaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW50ZWdyaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IscUNBT2lCO0FBQ2pCLDRDQUF3RDtBQXdEeEQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSwwQkFBMkIsU0FBUSxtQkFBUztJQU92RCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXNDOztRQUM5RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sU0FBUyxHQUFHLElBQUkscUJBQVMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQy9DLGVBQWUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7WUFDaEQsVUFBVSxFQUFFLGFBQWE7WUFDekIsVUFBVSxFQUFFLE1BQUEsS0FBSyxDQUFDLFVBQVUsbUNBQUksS0FBSztZQUNyQyxRQUFRLEVBQUUsTUFBQSxLQUFLLENBQUMsYUFBYSxtQ0FBSSx5QkFBYSxDQUFDLFdBQVc7WUFDMUQsV0FBVyxFQUFFO2dCQUNYLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxVQUFVO2dCQUNuQyxVQUFVLEVBQUUsTUFBQSxLQUFLLENBQUMsU0FBUyxtQ0FBSSxFQUFFO2dCQUNqQyxnQkFBZ0IsRUFBRSxNQUFBLEtBQUssQ0FBQyxpQkFBaUIsMENBQUUsU0FBUztnQkFDcEQsU0FBUyxFQUFFLEtBQUssQ0FBQyxRQUFRO2FBQzFCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxLQUFLLENBQUMsaUJBQWlCLEVBQUU7WUFDM0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDaEUsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxvQkFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDeEMsUUFBUSxFQUFFLE1BQUEsS0FBSyxDQUFDLFFBQVEsbUNBQUksb0JBQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLE9BQU8sRUFBRSxDQUFDLElBQUksNEJBQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDM0QsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDO0lBRXRDLENBQUM7Q0FDRjtBQXBDRCxnRUFvQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0LFxuICBhd3NfY2xvdWR3YXRjaCBhcyBjbG91ZHdhdGNoLFxuICBhd3NfZXZlbnRzIGFzIGV2ZW50cyxcbiAgYXdzX2V2ZW50c190YXJnZXRzIGFzIHRhcmdldHMsXG4gIGF3c19zZWNyZXRzbWFuYWdlciBhcyBzbSxcbiAgRHVyYXRpb24sXG59IGZyb20gJ21vbm9jZGsnO1xuaW1wb3J0IHsgU2hlbGxhYmxlLCBTaGVsbFBsYXRmb3JtIH0gZnJvbSAnLi4vc2hlbGxhYmxlJztcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBgUGFja2FnZUludGVncml0eVZhbGlkYXRpb25gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhY2thZ2VJbnRlZ3JpdHlWYWxpZGF0aW9uUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgcmVwb3NpdG9yeSBzbHVnIG9mIHRoZSBwYWNrYWdlIChpLmUgY2RrbGFicy9qc2lpLWRvY2dlbilcbiAgICovXG4gIHJlYWRvbmx5IHJlcG9zaXRvcnk6IHN0cmluZztcblxuICAvKipcbiAgICogU2VjcmV0IGNvbnRhaW5pbmcgYSBnaXRodWIgdG9rZW4uXG4gICAqL1xuICByZWFkb25seSBnaXRodWJUb2tlblNlY3JldD86IHNtLklTZWNyZXQ7XG5cbiAgLyoqXG4gICAqIFRoZSBidWlsZCBwbGF0Zm9ybSB0byB1c2UuIFRoaXMgcGxhdGZvcm0gc2hvdWxkIGNvbnRhaW4gYWxsIG5lY2Vzc2FyeSB0b29scyB0byBwYWNrYWdlIHRoZSBhcnRpZmFjdHNcbiAgICogaW4gdGhlIHJlcG9zaXRvcnkuIE5vdGUgdGhhdCBieSBkZWZhdWx0LCB0aGlzIGFsc28gbWVhbnMgcnVubmluZyB0aGUgdGVzdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFNoZWxsUGxhdGZvcm0uTGludXhVYnVudHVcbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkUGxhdGZvcm0/OiBTaGVsbFBsYXRmb3JtO1xuXG4gIC8qKlxuICAgKiBSdW4gdGhlIHZhbGlkYXRpb24gb24gYSBzY2hlZHVsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBvbmNlIGEgZGF5LlxuICAgKi9cbiAgcmVhZG9ubHkgc2NoZWR1bGU/OiBldmVudHMuU2NoZWR1bGU7XG5cbiAgLyoqXG4gICAqIFdldGhlciBvciBub3QgdGhlIGVudmlyb25tZW50IHNob3VsZCBiZSBwcml2aWxlZ2VkLCBuZWNlc3NhcnkgdG8gcnVuIGNvbnRhaW5lciBpbWFnZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBwcml2aWxlZ2VkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGFnIHByZWZpeCBmb3IgdGhpcyBzcGVjaWZpYyB2YWxpZGF0aW9uLiBPbmx5IG5lZWRlZCBmb3IgcmVwb3NpdG9yaWVzIHRoYXQgZWl0aGVyIHJlbGVhc2VcbiAgICogbXVsdGlwbGUgcGFja2FnZXMgb3IgbXVsdGlwbGUgbWFqb3IgdmVyc2lvbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcHJlZml4XG4gICAqL1xuICByZWFkb25seSB0YWdQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwcm9qZW4gdGFzayB0aGF0IHByb2R1Y2VzIHRoZSBsb2NhbCBhcnRpZmFjdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdyZWxlYXNlJ1xuICAgKi9cbiAgcmVhZG9ubHkgcGFja1Rhc2s/OiBzdHJpbmc7XG5cbn1cblxuLyoqXG4gKiBQZXJmb3JtIHBlcmlvZGljIGludGVncml0eSBjaGVja3Mgb24gcHVibGlzaGVkIHBhY2thZ2VzIGJhc2VkIG9uIHRoZVxuICogc291cmNlIGNvZGUgb2YgdGhlIHBhY2thZ2UuIEN1cnJlbnRseSBzdXBwb3J0cyBvbmx5IEdpdEh1YiBob3N0ZWQgcGFja2FnZXMuXG4gKlxuICogVGhlIGNoZWNrIGlzIGRvbmUgYnkgZG93bmxvYWRpbmcgdGhlIHB1Ymxpc2hlZCBhcnRpZmFjdCwgYnVpbGRpbmcgdGhlIHNvdXJjZSBjb2RlLCBhbmQgY29tcGFyaW5nIHRoZSB0d28uXG4gKiBJZiB0aGV5IGRpZmZlciwgaXQgbWVhbnMgdGhhdCBvZiB0aGUgZm9sbG93aW5nIHdhcyBjb21wcm9taXNlZDpcbiAqXG4gKiAtIFRoZSBwdWJsaXNoaW5nIHBsYXRmb3JtIChmb3IgZXhhbXBsZSBHaXRIdWIgcnVubmVycylcbiAqIC0gVGhlIGFydGlmYWN0IHN0b3JhZ2UgKGZvciBleGFtcGxlIG5wbWpzLmNvbSlcbiAqL1xuZXhwb3J0IGNsYXNzIFBhY2thZ2VJbnRlZ3JpdHlWYWxpZGF0aW9uIGV4dGVuZHMgQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogVGhlIGFsYXJtIHRoYXQgd2lsbCB0cmlnZ2VyIGlmIHRoZSB2YWxpZGF0aW9uIGZhaWxzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGZhaWx1cmVBbGFybTogY2xvdWR3YXRjaC5BbGFybTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogUGFja2FnZUludGVncml0eVZhbGlkYXRpb25Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBzaGVsbGFibGUgPSBuZXcgU2hlbGxhYmxlKHRoaXMsICdEZWZhdWx0Jywge1xuICAgICAgc2NyaXB0RGlyZWN0b3J5OiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnaGFuZGxlcicpLFxuICAgICAgZW50cnlwb2ludDogJ3ZhbGlkYXRlLnNoJyxcbiAgICAgIHByaXZpbGVnZWQ6IHByb3BzLnByaXZpbGVnZWQgPz8gZmFsc2UsXG4gICAgICBwbGF0Zm9ybTogcHJvcHMuYnVpbGRQbGF0Zm9ybSA/PyBTaGVsbFBsYXRmb3JtLkxpbnV4VWJ1bnR1LFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgR0lUSFVCX1JFUE9TSVRPUlk6IHByb3BzLnJlcG9zaXRvcnksXG4gICAgICAgIFRBR19QUkVGSVg6IHByb3BzLnRhZ1ByZWZpeCA/PyAnJyxcbiAgICAgICAgR0lUSFVCX1RPS0VOX0FSTjogcHJvcHMuZ2l0aHViVG9rZW5TZWNyZXQ/LnNlY3JldEFybixcbiAgICAgICAgUEFDS19UQVNLOiBwcm9wcy5wYWNrVGFzayxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuZ2l0aHViVG9rZW5TZWNyZXQpIHtcbiAgICAgIGNvbnN0IGdyYW50ID0gcHJvcHMuZ2l0aHViVG9rZW5TZWNyZXQuZ3JhbnRSZWFkKHNoZWxsYWJsZS5yb2xlKTtcbiAgICAgIGdyYW50LmFzc2VydFN1Y2Nlc3MoKTtcbiAgICB9XG5cbiAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgJ1NjaGVkdWxlZFRyaWdnZXInLCB7XG4gICAgICBzY2hlZHVsZTogcHJvcHMuc2NoZWR1bGUgPz8gZXZlbnRzLlNjaGVkdWxlLnJhdGUoRHVyYXRpb24uZGF5cygxKSksXG4gICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuQ29kZUJ1aWxkUHJvamVjdChzaGVsbGFibGUucHJvamVjdCldLFxuICAgIH0pO1xuXG4gICAgdGhpcy5mYWlsdXJlQWxhcm0gPSBzaGVsbGFibGUuYWxhcm07XG5cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import {
|
|
3
|
+
Construct,
|
|
4
|
+
aws_cloudwatch as cloudwatch,
|
|
5
|
+
aws_events as events,
|
|
6
|
+
aws_events_targets as targets,
|
|
7
|
+
aws_secretsmanager as sm,
|
|
8
|
+
Duration,
|
|
9
|
+
} from 'monocdk';
|
|
10
|
+
import { Shellable, ShellPlatform } from '../shellable';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Properties for `PackageIntegrityValidation`.
|
|
14
|
+
*/
|
|
15
|
+
export interface PackageIntegrityValidationProps {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The repository slug of the package (i.e cdklabs/jsii-docgen)
|
|
19
|
+
*/
|
|
20
|
+
readonly repository: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Secret containing a github token.
|
|
24
|
+
*/
|
|
25
|
+
readonly githubTokenSecret?: sm.ISecret;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The build platform to use. This platform should contain all necessary tools to package the artifacts
|
|
29
|
+
* in the repository. Note that by default, this also means running the tests.
|
|
30
|
+
*
|
|
31
|
+
* @default ShellPlatform.LinuxUbuntu
|
|
32
|
+
*/
|
|
33
|
+
readonly buildPlatform?: ShellPlatform;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Run the validation on a schedule.
|
|
37
|
+
*
|
|
38
|
+
* @default - once a day.
|
|
39
|
+
*/
|
|
40
|
+
readonly schedule?: events.Schedule;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Wether or not the environment should be privileged, necessary to run container images.
|
|
44
|
+
*
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
readonly privileged?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Tag prefix for this specific validation. Only needed for repositories that either release
|
|
51
|
+
* multiple packages or multiple major versions.
|
|
52
|
+
*
|
|
53
|
+
* @default - no prefix
|
|
54
|
+
*/
|
|
55
|
+
readonly tagPrefix?: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The projen task that produces the local artifacts.
|
|
59
|
+
*
|
|
60
|
+
* @default 'release'
|
|
61
|
+
*/
|
|
62
|
+
readonly packTask?: string;
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Perform periodic integrity checks on published packages based on the
|
|
68
|
+
* source code of the package. Currently supports only GitHub hosted packages.
|
|
69
|
+
*
|
|
70
|
+
* The check is done by downloading the published artifact, building the source code, and comparing the two.
|
|
71
|
+
* If they differ, it means that of the following was compromised:
|
|
72
|
+
*
|
|
73
|
+
* - The publishing platform (for example GitHub runners)
|
|
74
|
+
* - The artifact storage (for example npmjs.com)
|
|
75
|
+
*/
|
|
76
|
+
export class PackageIntegrityValidation extends Construct {
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The alarm that will trigger if the validation fails.
|
|
80
|
+
*/
|
|
81
|
+
public readonly failureAlarm: cloudwatch.Alarm;
|
|
82
|
+
|
|
83
|
+
constructor(scope: Construct, id: string, props: PackageIntegrityValidationProps) {
|
|
84
|
+
super(scope, id);
|
|
85
|
+
|
|
86
|
+
const shellable = new Shellable(this, 'Default', {
|
|
87
|
+
scriptDirectory: path.join(__dirname, 'handler'),
|
|
88
|
+
entrypoint: 'validate.sh',
|
|
89
|
+
privileged: props.privileged ?? false,
|
|
90
|
+
platform: props.buildPlatform ?? ShellPlatform.LinuxUbuntu,
|
|
91
|
+
environment: {
|
|
92
|
+
GITHUB_REPOSITORY: props.repository,
|
|
93
|
+
TAG_PREFIX: props.tagPrefix ?? '',
|
|
94
|
+
GITHUB_TOKEN_ARN: props.githubTokenSecret?.secretArn,
|
|
95
|
+
PACK_TASK: props.packTask,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (props.githubTokenSecret) {
|
|
100
|
+
const grant = props.githubTokenSecret.grantRead(shellable.role);
|
|
101
|
+
grant.assertSuccess();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
new events.Rule(this, 'ScheduledTrigger', {
|
|
105
|
+
schedule: props.schedule ?? events.Schedule.rate(Duration.days(1)),
|
|
106
|
+
targets: [new targets.CodeBuildProject(shellable.project)],
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
this.failureAlarm = shellable.alarm;
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
}
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "npx projen build",
|
|
10
10
|
"bump": "npx projen bump",
|
|
11
|
+
"bundle:package-integrity": "npx projen bundle:package-integrity",
|
|
11
12
|
"clobber": "npx projen clobber",
|
|
12
13
|
"compile": "npx projen compile",
|
|
13
14
|
"compile:custom-resource-handlers": "npx projen compile:custom-resource-handlers",
|
|
@@ -36,36 +37,43 @@
|
|
|
36
37
|
"organization": false
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@monocdk-experiment/assert": "^1.
|
|
40
|
+
"@monocdk-experiment/assert": "^1.146.0",
|
|
41
|
+
"@types/adm-zip": "^0.4.34",
|
|
40
42
|
"@types/aws-lambda": "^8.10.92",
|
|
43
|
+
"@types/fs-extra": "^9.0.13",
|
|
41
44
|
"@types/jest": "^27.4.1",
|
|
42
45
|
"@types/node": "^12",
|
|
46
|
+
"@types/tar": "^6.1.1",
|
|
43
47
|
"@typescript-eslint/eslint-plugin": "^5",
|
|
44
48
|
"@typescript-eslint/parser": "^5",
|
|
45
|
-
"
|
|
46
|
-
"aws-
|
|
47
|
-
"
|
|
49
|
+
"adm-zip": "^0.5.9",
|
|
50
|
+
"aws-cdk": "^1.146.0",
|
|
51
|
+
"aws-sdk": "^2.1082.0",
|
|
52
|
+
"constructs": "^3.3.227",
|
|
48
53
|
"esbuild": "^0.14.23",
|
|
49
54
|
"eslint": "^8",
|
|
50
55
|
"eslint-import-resolver-node": "^0.3.6",
|
|
51
56
|
"eslint-import-resolver-typescript": "^2.5.0",
|
|
52
57
|
"eslint-plugin-import": "^2.25.4",
|
|
58
|
+
"fs-extra": "^10.0.1",
|
|
53
59
|
"jest": "^27.5.1",
|
|
54
60
|
"jest-create-mock-instance": "^2.0.0",
|
|
55
61
|
"jest-junit": "^13",
|
|
56
62
|
"json-schema": "^0.4.0",
|
|
57
|
-
"
|
|
63
|
+
"JSONStream": "^1.3.5",
|
|
64
|
+
"monocdk": "^1.146.0",
|
|
58
65
|
"node-ical": "^0.14.1",
|
|
59
66
|
"npm-check-updates": "^12",
|
|
60
|
-
"projen": "^0.52.
|
|
67
|
+
"projen": "^0.52.48",
|
|
61
68
|
"rrule": "^2.6.8",
|
|
62
69
|
"standard-version": "^9",
|
|
70
|
+
"tar": "^6.1.11",
|
|
63
71
|
"ts-jest": "^27.1.3",
|
|
64
72
|
"typescript": "~4.5.5"
|
|
65
73
|
},
|
|
66
74
|
"peerDependencies": {
|
|
67
|
-
"constructs": "^3.3.
|
|
68
|
-
"monocdk": "^1.
|
|
75
|
+
"constructs": "^3.3.227",
|
|
76
|
+
"monocdk": "^1.146.0"
|
|
69
77
|
},
|
|
70
78
|
"dependencies": {
|
|
71
79
|
"changelog-parser": "^2.8.0"
|
|
@@ -78,7 +86,7 @@
|
|
|
78
86
|
],
|
|
79
87
|
"main": "lib/index.js",
|
|
80
88
|
"license": "Apache-2.0",
|
|
81
|
-
"version": "13.
|
|
89
|
+
"version": "13.6.2",
|
|
82
90
|
"jest": {
|
|
83
91
|
"testMatch": [
|
|
84
92
|
"**/lib/__tests__/**/?(*.)+(spec|test).js?(x)"
|