{"id":13880897,"url":"https://github.com/cdklabs/construct-hub","last_synced_at":"2026-05-25T03:09:16.289Z","repository":{"id":37801460,"uuid":"360088782","full_name":"cdklabs/construct-hub","owner":"cdklabs","description":"AWS CDK construct library that can be used to deploy instances of the Construct Hub in any AWS Account.","archived":false,"fork":false,"pushed_at":"2026-01-26T22:28:06.000Z","size":38811,"stargazers_count":230,"open_issues_count":33,"forks_count":28,"subscribers_count":15,"default_branch":"main","last_synced_at":"2026-01-27T09:45:04.711Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://constructs.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdklabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-04-21T08:25:35.000Z","updated_at":"2026-01-26T22:21:45.000Z","dependencies_parsed_at":"2024-02-29T01:26:22.729Z","dependency_job_id":"8c917ffa-323e-4e16-9cd5-29430011de64","html_url":"https://github.com/cdklabs/construct-hub","commit_stats":{"total_commits":946,"total_committers":32,"mean_commits":29.5625,"dds":0.4756871035940803,"last_synced_commit":"af62e997df1c479d937834f91d9215a340e8fa9c"},"previous_names":[],"tags_count":1072,"template":false,"template_full_name":"amazon-archives/__template_Apache-2.0","purl":"pkg:github/cdklabs/construct-hub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Fconstruct-hub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Fconstruct-hub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Fconstruct-hub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Fconstruct-hub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdklabs","download_url":"https://codeload.github.com/cdklabs/construct-hub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdklabs%2Fconstruct-hub/sbom","scorecard":{"id":269839,"data":{"date":"2025-08-11","repo":{"name":"github.com/cdklabs/construct-hub","commit":"f5b1ae7209e4a7e66a9784fae25aea1c9a4372cd"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.7,"checks":[{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":5,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/auto-queue.yml:16","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/build.yml:12","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/build.yml:65","Info: jobLevel 'contents' permission set to 'read': .github/workflows/build.yml:96","Info: jobLevel 'contents' permission set to 'read': .github/workflows/release.yml:92","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yml:16","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yml:68","Warn: jobLevel 'actions' permission set to 'write': .github/workflows/update-vpc-acl-allow-lists.yml:11","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/update-vpc-acl-allow-lists.yml:12","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:11","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:43","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-dev-deps-main.yml:13","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-dev-deps-main.yml:47","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-main.yml:13","Info: jobLevel 'contents' permission set to 'read': .github/workflows/upgrade-main.yml:47","Warn: no topLevel permission defined: .github/workflows/auto-approve.yml:1","Warn: no topLevel permission defined: .github/workflows/auto-queue.yml:1","Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/pull-request-lint.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/update-vpc-acl-allow-lists.yml:1","Warn: no topLevel permission defined: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:1","Warn: no topLevel permission defined: .github/workflows/upgrade-dev-deps-main.yml:1","Warn: no topLevel permission defined: .github/workflows/upgrade-main.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/auto-approve.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/auto-approve.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/auto-queue.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/auto-queue.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:69: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:99: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:103: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:111: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull-request-lint.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/pull-request-lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:95: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:99: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:107: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/update-vpc-acl-allow-lists.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/update-vpc-acl-allow-lists.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/update-vpc-acl-allow-lists.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/update-vpc-acl-allow-lists.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/update-vpc-acl-allow-lists.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/update-vpc-acl-allow-lists.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/upgrade-cdklabs-projen-project-types-main.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-cdklabs-projen-project-types-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-dev-deps-main.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-dev-deps-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/upgrade-main.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/cdklabs/construct-hub/upgrade-main.yml/main?enable=pin","Info:   0 out of  34 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/cdklabs/.github/SECURITY.md:1","Info: Found linked content: github.com/cdklabs/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/cdklabs/.github/SECURITY.md:1","Info: Found text in security policy: github.com/cdklabs/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-qc59-cxj2-c2w4"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T13:04:37.594Z","repository_id":37801460,"created_at":"2025-08-17T13:04:37.594Z","updated_at":"2025-08-17T13:04:37.594Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28924096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T22:32:35.345Z","status":"ssl_error","status_checked_at":"2026-01-30T22:32:31.927Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T08:03:36.996Z","updated_at":"2026-01-31T00:14:59.427Z","avatar_url":"https://github.com/cdklabs.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","others"],"sub_categories":[],"readme":"# Construct Hub\n\nThis project maintains a [AWS Cloud Development Kit][aws-cdk] construct library\nthat can be used to deploy instances of the Construct Hub in any AWS Account.\n\nThis software backs the public instance of the\n[ConstructHub](https://constructs.dev), and can be used to deploy a self-hosted\ninstance with personalized configuration.\n\n[aws-cdk]: https://github.com/aws/aws-cdk\n\n## :question: Getting Started\n\n\u003e [!WARNING]\n\u003e\n\u003e ### Disclaimer\n\u003e\n\u003e The [public instance of ConstructHub](https://constructs.dev) is Generally Available.\n\u003e\n\u003e Self-hosted ConstructHub instances are however in active development and\n\u003e should be considered *experimental*. Breaking changes to the public API of\n\u003e this package are expected to be released without prior notice, and the\n\u003e infrastructure and operational posture of ConstructHub instances may also\n\u003e significantly change.\n\u003e\n\u003e You are welcome to deploy self-hosted instances of ConstructHub for evaluation\n\u003e purposes, and we welcome any feedback (good or bad) from your experience in\n\u003e doing so.\n\n\u003e [!IMPORTANT]\n\u003e\n\u003e ### 💰 Cost of running Construct Hub\n\u003e\n\u003e If you opt to use Construct Hub for processing your CDK packages,\n\u003e you will be subject to charges based on the number of packages processed by Construct Hub.\n\u003e To minimize these charges, you can implement package filters for relevant sources\n\u003e and exclude public NPM packages from the processing list.\n\n### Quick Start\n\nOnce you have installed the `construct-hub` library in your project, the\nsimplest way to get started is to create an instance of the `ConstructHub`\nconstruct:\n\n```ts nofixture\nimport { App, Stack } from 'aws-cdk-lib/core';\nimport { ConstructHub } from 'construct-hub';\n\n// The usual... you might have used `cdk init app` instead!\nconst app = new App();\nconst stack = new Stack(app, 'StackName', { /* ... */ });\n\n// Now to business!\nnew ConstructHub(stack, 'ConstructHub');\n```\n\n### Personalization\n\n#### Using a custom domain name\n\nIn order to use a custom domain for your ConstructHub instance instead of the\ndefault CloudFront domain name, specify the `domain` property with the following\nelements:\n\n| Attribute                      | Description                                                                                       |\n| ------------------------------ | ------------------------------------------------------------------------------------------------- |\n| `zone`                         | A Route53 Hosted Zone, where DNS records will be added.                                           |\n| `cert`                         | An Amazon Certificate Manager certificate, which must be in the `us-east-1` region.               |\n| `monitorCertificateExpiration` | Set to `false` if you do not want an alarm to be created when the certificate is close to expiry. |\n\nYour self-hosted ConstructHub instance will be served from the root of the\nprovided `zone`, so the certificate must match this name.\n\n#### Alternate package sources\n\nBy default, ConstructHub has a single package source configured: the public\n`npmjs.com` registry. Self-hosted instances typically should list packages from\nalternate sources, either in addition to packages from `npmjs.com`, or instead\nof those.\n\nThe `packageSources` property can be used to replace the default set of package\nsources configured on the instance. ConstructHub provides `IPackageSource`\nimplementations for the public `npmjs.com` registry as well as for private\nCodeArtifact repositories:\n\n```ts nofixture\nimport * as codeartifact from 'aws-cdk-lib/aws-codeartifact';\nimport { App, Stack } from 'aws-cdk-lib/core';\nimport { sources, ConstructHub } from 'construct-hub';\n\n// The usual... you might have used `cdk init app` instead!\nconst app = new App();\nconst stack = new Stack(app, 'StackName', { /* ... */ });\n\n// Now to business!\nconst repository = new codeartifact.CfnRepository(stack, 'Repository', {\n  domainName: 'my-domain',\n  repositoryName: 'my-repo',\n  // ....\n});\nnew ConstructHub(stack, 'ConstructHub', {\n  packageSources: [\n    new sources.NpmJs(), // Remove if you do NOT want npmjs.com packages\n    new sources.CodeArtifact({ repository }),\n  ],\n});\n```\n\nYou may also implement a custom `IPackageSource` if you want to index packages\nfrom alternate locations. In this case, the component you provide will be\nresponsible for sending notifications to an SQS Queue about newly discovered\npackages. You may refer to the [sources.NpmJs] and [sources.CodeArtifact]\nimplementations as a reference for hos this can be done.\n\nBy default, download counts of NPM packages will be fetched periodically from\nNPM's public API by a Lambda. Since this is not desirable if you are using a\nprivate package registry, this is automatically disabled if you specify your own\nvalue for `packageSources`. (But this can be re-enabled through the\n`fetchPackageStats` property if needed).\n\n[sources.NpmJs]: src/package-sources/npmjs.ts\n[sources.CodeArtifact]: src/package-sources/code-artifact.ts\n\n#### Package deny list\n\nCertain packages may be undesirable to show in your self-hosted ConstructHub\ninstance. In order to prevent a package from ever being listed in construct hub,\nthe `denyList` property can be configured with a set of `DenyListRule` objects\nthat specify which package or package versions should never be lested:\n\n```ts nofixture\nimport { App, Stack } from 'aws-cdk-lib/core';\nimport { ConstructHub } from 'construct-hub';\n\n// The usual... you might have used `cdk init app` instead!\nconst app = new App();\nconst stack = new Stack(app, 'StackName', { /* ... */ });\n\n// Now to business!\nnew ConstructHub(stack, 'ConstructHub', {\n  denyList: [\n    // Denying _all_ versions of the \"sneaky-hackery\" package\n    { packageName: 'sneaky-hackery', reason: 'Mines bitcoins wherever it gets installed' },\n    // Denying _a specific_ version of the \"bad-release\" package\n    { packageName: 'bad-release', version: '1.2.3', reason: 'CVE-####-#####' },\n  ],\n});\n```\n\n#### Redirecting from additional domains\n\nYou can add additional domains that will be redirected to your primary Construct\nHub domain:\n\n```ts\nimport * as r53 from 'aws-cdk-lib/aws-route53';\n\nconst myDomainZone = r53.HostedZone.fromHostedZoneAttributes(this, 'MyDomainZone', {\n  hostedZoneId: 'AZ1234',\n  zoneName: 'my.domain.com',\n});\n\nnew ConstructHub(this, 'ConstructHub', {\n  additionalDomains: [ { hostedZone: myDomainZone } ]\n});\n```\n\nThis will set up full domain redirect using Amazon S3 and Amazon CloudFront. All\nrequests will be redirected to your primary Construct Hub domain.\n\n#### Decrease deployment footprint\n\nBy default, ConstructHub executes the documentation rendering process in the\ncontext of isolated subnets. This is a defense-in-depth mechanism to mitigate\nthe risks associated with downloading aribtrary (un-trusted) *npm packages* and\ntheir dependency closures.\n\nThis layer of security implies the creation of a number of resources that can\nincrease the operating cost of your self-hosted instance: several VPC endpoints\nare created, an internal CodeArtifact repository needs to be provisioned, etc...\n\nWhile we generally recommend leaving these features enabled, if your self-hosted\nConstructHub instance only indexes *trusted* packages (as could be the case for\nan instance that does not list packages from the public `npmjs.com` registry),\nyou may set the `isolateLambdas` setting to `false`.\n\n## :gear: Operating a self-hosted instance\n\n1. [Application Overview](./docs/application-overview.md) provides a high-level\n   description of the components that make a ConstructHub instance. This is a\n   great starting point for people who consider operating a self-hosted instance\n   of ConstructHub; and for new operators on-boarding the platform.\n\n1. [Operator Runbook](./docs/operator-runbook.md) is a series of diagnostics and\n   troubleshooting guides indended for operators to have a quick and easy way to\n   navigate a ConstructHub instance when they are reacting to an alarm or bug\n   report.\n\n### :baby_chick: Deployment Canaries\n\nConstruct Hub provides several built-in validation mechanisms to make sure the\ndeployment of your instance is continuously operating as expected.\n\nThese mechanisms come in the form of canary testers that are part of the\nConstructHub deployment stack. Each canary runs periodically and performs a\ndifferent check, triggering a different CloudWatch alarm in case it detects a\nfailure.\n\nWe recommend that you use staged deployments, and block promotions to the\nproduction stage in case any preivous stage triggers an alarm within a specific\ntimeframe.\n\n#### Discovery Canary\n\nWhen configuring an `NpmJs` package source, a package discovery canary can be\nenabled using the `enableCanary` property (and optionally configured using the\n`canaryPackage` and `canarySla` properties). This feature is activated by\ndefault and monitors availability of releases of the `construct-hub-probe` npm\npackage in the ConstructHub instance.\n\nProbe packages, such as `construct-hub-probe` are published frequently (e.g:\nevery 3 hours or more frequently), and can be used to ensure the ConstructHub\ninstance correctly discovers, indexes and represents those packages.\n\nIf a different package or SLA should be used, you can configure the `NpmJs`\npackage source manually like so:\n\n```ts nofixture\nimport * as codeartifact from 'aws-cdk-lib/aws-codeartifact';\nimport { App, Duration, Stack } from 'aws-cdk-lib/core';\nimport { sources, ConstructHub } from 'construct-hub';\n\nconst app = new App();\nconst stack = new Stack(app, 'StackName', { /* ... */ });\n\nnew ConstructHub(stack, 'ConstructHub', {\n  // ...\n  packageSources: [\n    // ...\n    new sources.NpmJs({\n      enableCanary: true, // This is the default\n      canaryPackage: '@acme/my-constructhub-probe',\n      canarySla: Duration.minutes(30),\n    }),\n    // ...\n  ],\n  // ...\n});\n```\n\nIn case the new package isn't fully available in the predefined SLA, a\n**high severity** CloudWatch alarm will trigger, which will in turn trigger\nthe configured action for low severity alarms.\n\n\u003e See [Monitoring \u0026 Alarms](./docs/application-overview.md#monitoring--alarming)\n\nThe operator runbook contains [instructions](./docs/operator-runbook.md) on how\nto diagnose and mitigate the root cause of the failure.\n\n### :nail_care: Customizing the frontend\n\nThere are a number of customizations available in order to make your private\nconstruct hub better tailored to your organization.\n\n#### Package Tags\n\nConfiguring package tags allows you to compute additional labels to be applied\nto packages. These can be used to indicate to users which packages are owned by\ntrusted organizations, or any other arbitrary conditions, and can be referenced\nwhile searching.\n\nFor example:\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  packageTags: [{\n    id: 'official',\n    condition: TagCondition.field('name').eq('construct-hub'),\n    keyword: {\n      label: 'Official',\n      color: '#00FF00',\n    },\n    highlight: {\n      label: 'Vended by AWS',\n      color: '#00FF00',\n    }\n  }]\n});\n```\n\nThe above example will result in packages with the `name` of `construct-hub` to\nreceive the `Official` tag, which is colored green and displayed amongst the\nlist of keywords. Additionally the `highlight` key shows this as a highlighted\nitem on the package's card.\n\nThe `searchFilter` key can also be used to show tags as search filters grouped\ntogether.\n\n```ts\nconst authorsGroup = new PackageTagGroup(\"authors\", {\n  label: \"Authors\",\n  tooltip: \"Information about the authors filter\",\n  filterType: FilterType.checkbox(),\n});\n\nconst isAws = TagCondition.field('name').eq('construct-hub');\nnew ConstructHub(this, \"ConstructHub\", {\n  packageTags: [{\n    id: 'AWS',\n    condition: isAws,\n    searchFilter: {\n      group: authorsGroup,\n      display: 'AWS',\n    },\n  }, {\n    id: 'Community',\n    condition: TagCondition.not(isAws),\n    searchFilter: {\n      group: authorsGroup,\n      display: 'AWS',\n    },\n  }]\n});\n```\n\nThe above will show a list of `Authors` filters on the search results page\nwith a checkbox for each `AWS` and `Community` packages, allowing users to\nfilter results by the presence of these tags.\n\nCombinations of conditions are also supported:\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  packageTags: [{\n    id: 'official',\n    keyword: {\n      label: 'Official',\n      color: '#00FF00',\n    },\n    condition: TagCondition.or(\n      TagCondition.field('name').eq('construct-hub'),\n      TagCondition.field('name').eq('construct-hub-webapp'),\n    ),\n  }]\n});\n```\n\nYou can assert against any value within package json including nested ones.\n\n```ts\nTagCondition.field('constructHub', 'nested', 'key').eq('value');\n\n// checks the following:\n// packageJson?.constructHub?.nested?.key === value;\n```\n\nYou can also assert that a string occurs at least a certain number of times\nwithin the package's README.\n\n```ts\nTagCondition.readme().includes('ECS');\nTagCondition.readme().includes('fargate', { atLeast: 3, caseSensitive: false });\n```\n\n#### Package Links\n\nConfiguring package links allows you to replace the `Repository`, `License`,\nand `Registry` links on the package details page with whatever you choose.\n\nFor example:\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  packageLinks: [{\n    linkLabel: 'Service Level Agreement',\n    configKey: 'SLA',\n  }, {\n    linkLabel: 'Contact',\n    configKey: 'Contact',\n    linkText: 'Email Me!',\n    allowedDomains: ['me.com'],\n  }]\n});\n```\n\nThis would allow publishers to add the following to their package.json:\n\n```json\n\"constructHub\": {\n  \"packageLinks\": {\n    \"SLA\": \"https://support.mypackage.com\",\n    \"Contact\": \"me.com/contact\"\n  }\n}\n```\n\nThen the links on the corresponding package page would show these items as\nconfigured.\n\n### RSS/ATOM feeds for recent packages\n\nConstruct hub automatically generates RSS/ATOM feed showing the list of latest\n100 packages added. The generated feed can be configured to get release notes from\nGitHub by configuring it with [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).\nThe access token has to be stored in AWS Secretsmanager and should be passed to `feedConfiguration`\n\nFor example:\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  feedConfiguration: {\n      githubTokenSecret: secretsmanager.Secret.fromSecretCompleteArn(this, 'GitHubToken', '\u003carn:aws:secretsmanager:us-east-2:11111111111:secret:releaseNotesFetcherGitHubToken-abCd1\u003e'),\n      feedDescription: 'Latest Constructs in the construct hub',\n      feedTitle: 'Latest constructs',\n    }\n  }\n);\n```\n\n#### Home Page\n\nThe home page is divided into sections, each with a header and list of packages.\nCurrently, for a given section you can display either the most recently updated\npackages, or a curated list of packages.\n\nFor example:\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  featuredPackages: {\n    sections: [\n      {\n        name: \"Recently updated\",\n        showLastUpdated: 4\n      },\n      {\n        name: \"From the AWS CDK\",\n        showPackages: [\n          {\n            name: \"@aws-cdk/core\"\n          },\n          {\n            name: \"@aws-cdk/aws-s3\",\n            comment: \"One of the most popular AWS CDK libraries!\"\n          },\n          {\n            name: \"@aws-cdk/aws-lambda\"\n          },\n          {\n            name: \"@aws-cdk/pipelines\",\n            comment: \"The pipelines L3 construct library abstracts away many of the details of managing software deployment within AWS.\"\n          }\n        ]\n      }\n    ]\n  }\n});\n```\n\n#### Browse Categories\n\nThe Construct Hub home page includes a section that displays a set of buttons\nthat represent browsing categories (e.g. \"Databases\", \"Monitoring\",\n\"Serverless\", etc).\n\nYou can use the `categories` option to configure these categories. Each category\nis defined by a `title` and a `url`, which will be the link associated with the\nbutton.\n\n```ts\nnew ConstructHub(this, \"ConstructHub\", {\n  categories: [\n    { title: 'Databases', url: '?keywords=databases' },\n    { title: 'Monitoring', url: '?q=monitoring' },\n    { title: 'Partners', url: '?tags=aws-partner' }\n  ]\n});\n```\n\n#### Feature Flags\n\nFeature flags for the web app can be used to enable or disable experimental\nfeatures. These can be customized through the `featureFlags` property - for\nmore information about the available flags, check the documentation for\n\u003chttps://github.com/cdklabs/construct-hub-webapp/\u003e.\n\n#### AppRegistry\n\nBy default, an AppRegistry application will be created that is associated\nwith the stack you put the `ConstructHub` construct in.\n\n### Re-processing specific packages\n\nIn some cases, you might need to re-generate the documentation for a given\npackage version. This is useful, for example, in a CI/CD pipeline, to make\nsure there are no regressions before releasing a new version to production.\n\nTo re-process a specific package, start the execution of the state machine\ncalled `ReprocessDocumentationPerPackage` with the following input:\n\n```json\n{\n  \"Prefix\": \"data/\u003cpackage-name\u003e/v\u003cpackage-version\u003e\"\n}\n```\n\n## :raised_hand: Contributing\n\nIf you are looking to contribute to this project, but don't know where to start,\nhave a look at our [contributing guide](CONTRIBUTING.md)!\n\n## :cop: Security\n\nSee [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more\ninformation.\n\n## :balance_scale: License\n\nThis project is licensed under the Apache-2.0 License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdklabs%2Fconstruct-hub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdklabs%2Fconstruct-hub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdklabs%2Fconstruct-hub/lists"}