@intentius/chant 0.13.1 → 0.15.1
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/audit/catalog.d.ts +45 -5
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/proof.d.ts +3 -0
- package/dist/audit/proof.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +4 -1
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts +3 -0
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts +8 -2
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts +37 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts.map +1 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts +48 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts.map +1 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +41 -0
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +39 -0
- package/dist/cli/handlers/components.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts +3 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts +4 -2
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts +49 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +35 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +22 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/lexicon-regen.d.ts +110 -0
- package/dist/codegen/lexicon-regen.d.ts.map +1 -0
- package/dist/codegen/pinned-upgrade.d.ts +153 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -0
- package/dist/codegen/rolling-upgrade.d.ts +138 -0
- package/dist/codegen/rolling-upgrade.d.ts.map +1 -0
- package/dist/codegen/surface-snapshot.d.ts +173 -0
- package/dist/codegen/surface-snapshot.d.ts.map +1 -0
- package/dist/codegen/version-bump.d.ts +21 -0
- package/dist/codegen/version-bump.d.ts.map +1 -0
- package/dist/components/auto-release.d.ts +93 -0
- package/dist/components/auto-release.d.ts.map +1 -0
- package/dist/components/builders.d.ts +37 -0
- package/dist/components/builders.d.ts.map +1 -0
- package/dist/components/capability-plugin-loader.d.ts +111 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -0
- package/dist/components/capability-plugin-schema.d.ts +24 -0
- package/dist/components/capability-plugin-schema.d.ts.map +1 -0
- package/dist/components/capability-plugin.d.ts +85 -0
- package/dist/components/capability-plugin.d.ts.map +1 -0
- package/dist/components/capability.d.ts +89 -0
- package/dist/components/capability.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +204 -0
- package/dist/components/cli-support.d.ts.map +1 -0
- package/dist/components/component.d.ts +179 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/config-defaults.d.ts +41 -0
- package/dist/components/config-defaults.d.ts.map +1 -0
- package/dist/components/discover.d.ts +60 -0
- package/dist/components/discover.d.ts.map +1 -0
- package/dist/components/driver-output.d.ts +20 -0
- package/dist/components/driver-output.d.ts.map +1 -0
- package/dist/components/driver.d.ts +209 -0
- package/dist/components/driver.d.ts.map +1 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/manifest-persistence.d.ts +79 -0
- package/dist/components/manifest-persistence.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +27 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts +22 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts.map +1 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts +37 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts.map +1 -0
- package/dist/components/pilots/lambda.pilot.d.ts +35 -0
- package/dist/components/pilots/lambda.pilot.d.ts.map +1 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts +17 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts.map +1 -0
- package/dist/components/pilots/project.d.ts +13 -0
- package/dist/components/pilots/project.d.ts.map +1 -0
- package/dist/components/presets/ecs-fargate.d.ts +59 -0
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -0
- package/dist/components/presets/index.d.ts +29 -0
- package/dist/components/presets/index.d.ts.map +1 -0
- package/dist/components/presets/lambda.d.ts +35 -0
- package/dist/components/presets/lambda.d.ts.map +1 -0
- package/dist/components/presets/single-host-compose.d.ts +43 -0
- package/dist/components/presets/single-host-compose.d.ts.map +1 -0
- package/dist/components/registry.d.ts +29 -0
- package/dist/components/registry.d.ts.map +1 -0
- package/dist/components/starter-plugin.d.ts +51 -0
- package/dist/components/starter-plugin.d.ts.map +1 -0
- package/dist/components/temporal-codegen-loader.d.ts +27 -0
- package/dist/components/temporal-codegen-loader.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts +35 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts +45 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts +33 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/bom-writer.d.ts +155 -0
- package/dist/components/verbs/bom-writer.d.ts.map +1 -0
- package/dist/components/verbs/build-archive.d.ts +205 -0
- package/dist/components/verbs/build-archive.d.ts.map +1 -0
- package/dist/components/verbs/build.d.ts +150 -0
- package/dist/components/verbs/build.d.ts.map +1 -0
- package/dist/components/verbs/cloud-executor.d.ts +88 -0
- package/dist/components/verbs/cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/component-bom.d.ts +103 -0
- package/dist/components/verbs/component-bom.d.ts.map +1 -0
- package/dist/components/verbs/index.d.ts +49 -0
- package/dist/components/verbs/index.d.ts.map +1 -0
- package/dist/components/verbs/license-policy.d.ts +56 -0
- package/dist/components/verbs/license-policy.d.ts.map +1 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts +81 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/process-runner.d.ts +64 -0
- package/dist/components/verbs/process-runner.d.ts.map +1 -0
- package/dist/components/verbs/reproducibility.d.ts +80 -0
- package/dist/components/verbs/reproducibility.d.ts.map +1 -0
- package/dist/components/verbs/sbom-generator.d.ts +157 -0
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/sbom.d.ts +79 -0
- package/dist/components/verbs/sbom.d.ts.map +1 -0
- package/dist/components/verbs/shell.d.ts +35 -0
- package/dist/components/verbs/shell.d.ts.map +1 -0
- package/dist/components/verbs/sign.d.ts +222 -0
- package/dist/components/verbs/sign.d.ts.map +1 -0
- package/dist/components/verbs/stub.d.ts +18 -0
- package/dist/components/verbs/stub.d.ts.map +1 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts +51 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/verify.d.ts +106 -0
- package/dist/components/verbs/verify.d.ts.map +1 -0
- package/dist/components/verbs/vex.d.ts +65 -0
- package/dist/components/verbs/vex.d.ts.map +1 -0
- package/dist/components/verbs/vuln-gate.d.ts +91 -0
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -0
- package/dist/components/verbs/vuln-scan.d.ts +116 -0
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -0
- package/dist/components/verbs/wait-verify.d.ts +85 -0
- package/dist/components/verbs/wait-verify.d.ts.map +1 -0
- package/dist/config.d.ts +205 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon.d.ts +78 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts +121 -0
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -0
- package/dist/lifecycle/build-ledger.d.ts +225 -0
- package/dist/lifecycle/build-ledger.d.ts.map +1 -0
- package/dist/lifecycle/git.d.ts +84 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +5 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/oras-referrer-lookup.d.ts +41 -0
- package/dist/lifecycle/oras-referrer-lookup.d.ts.map +1 -0
- package/dist/lifecycle/release-ledger.d.ts +122 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -0
- package/dist/lifecycle/status.d.ts +150 -0
- package/dist/lifecycle/status.d.ts.map +1 -0
- package/dist/lint/component-checks.d.ts +95 -0
- package/dist/lint/component-checks.d.ts.map +1 -0
- package/dist/lint/engine.d.ts +23 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/presets/strict.json +8 -1
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts +20 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts +28 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +39 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +37 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts +43 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts +22 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts +33 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts.map +1 -0
- package/dist/lint/rules/comp/index.d.ts +18 -0
- package/dist/lint/rules/comp/index.d.ts.map +1 -0
- package/dist/lint/rules/comp/support.d.ts +71 -0
- package/dist/lint/rules/comp/support.d.ts.map +1 -0
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts +11 -6
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/activity-runtime.d.ts +24 -0
- package/dist/op/activity-runtime.d.ts.map +1 -0
- package/dist/op/builders.d.ts +59 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/ownership.d.ts +20 -14
- package/dist/ownership.d.ts.map +1 -1
- package/package.json +14 -1
- package/src/audit/catalog.test.ts +74 -22
- package/src/audit/catalog.ts +74 -471
- package/src/audit/proof.ts +4 -2
- package/src/audit/report-html.test.ts +14 -7
- package/src/audit/report-model.ts +20 -9
- package/src/audit/report.test.ts +36 -13
- package/src/audit/report.ts +2 -0
- package/src/audit/rules-doc.test.ts +8 -6
- package/src/audit/rules-doc.ts +13 -5
- package/src/cli/commands/audit.ts +23 -18
- package/src/cli/commands/component-lint.test.ts +158 -0
- package/src/cli/commands/doctor.test.ts +116 -2
- package/src/cli/commands/doctor.ts +46 -0
- package/src/cli/commands/lexicon-rolling-upgrade.ts +198 -0
- package/src/cli/commands/lexicon-surface-diff.test.ts +104 -0
- package/src/cli/commands/lexicon-surface-diff.ts +185 -0
- package/src/cli/commands/lint.ts +142 -1
- package/src/cli/commands/pinned-upgrade.ts +204 -0
- package/src/cli/handlers/build.ts +58 -1
- package/src/cli/handlers/components.test.ts +504 -0
- package/src/cli/handlers/components.ts +404 -0
- package/src/cli/handlers/dev.ts +60 -1
- package/src/cli/handlers/graph.ts +47 -2
- package/src/cli/handlers/misc.ts +45 -1
- package/src/cli/handlers/run.test.ts +967 -3
- package/src/cli/handlers/run.ts +618 -11
- package/src/cli/main.test.ts +66 -0
- package/src/cli/main.ts +105 -2
- package/src/cli/registry.ts +35 -0
- package/src/codegen/fetch.test.ts +84 -3
- package/src/codegen/fetch.ts +76 -2
- package/src/codegen/lexicon-regen.test.ts +298 -0
- package/src/codegen/lexicon-regen.ts +545 -0
- package/src/codegen/pinned-upgrade.test.ts +399 -0
- package/src/codegen/pinned-upgrade.ts +423 -0
- package/src/codegen/rolling-upgrade.test.ts +333 -0
- package/src/codegen/rolling-upgrade.ts +320 -0
- package/src/codegen/surface-snapshot.test.ts +461 -0
- package/src/codegen/surface-snapshot.ts +546 -0
- package/src/codegen/version-bump.test.ts +47 -0
- package/src/codegen/version-bump.ts +39 -0
- package/src/components/README.md +130 -0
- package/src/components/SPRAWL-VALIDATION.md +181 -0
- package/src/components/__fixtures__/alb-ecs-service.json +51 -0
- package/src/components/__fixtures__/dynamodb-infra.json +32 -0
- package/src/components/__fixtures__/emr-job-consumer.json +26 -0
- package/src/components/__fixtures__/jar-lib-producer.json +16 -0
- package/src/components/__fixtures__/lambda-image-processor.json +28 -0
- package/src/components/__fixtures__/neo4j-fanout.json +34 -0
- package/src/components/__fixtures__/single-host-compose.json +29 -0
- package/src/components/auto-release.test.ts +217 -0
- package/src/components/auto-release.ts +216 -0
- package/src/components/builders.test.ts +45 -0
- package/src/components/builders.ts +71 -0
- package/src/components/capability-plugin-loader.ts +218 -0
- package/src/components/capability-plugin-schema.ts +56 -0
- package/src/components/capability-plugin.test.ts +235 -0
- package/src/components/capability-plugin.ts +108 -0
- package/src/components/capability.ts +117 -0
- package/src/components/cli-support.test.ts +579 -0
- package/src/components/cli-support.ts +481 -0
- package/src/components/component-schema.test.ts +265 -0
- package/src/components/component.schema.json +235 -0
- package/src/components/component.test.ts +251 -0
- package/src/components/component.ts +255 -0
- package/src/components/config-defaults.test.ts +263 -0
- package/src/components/config-defaults.ts +145 -0
- package/src/components/discover.test.ts +352 -0
- package/src/components/discover.ts +167 -0
- package/src/components/driver-output.ts +71 -0
- package/src/components/driver.test.ts +638 -0
- package/src/components/driver.ts +690 -0
- package/src/components/index.ts +113 -0
- package/src/components/manifest-persistence.test.ts +152 -0
- package/src/components/manifest-persistence.ts +164 -0
- package/src/components/pilots/README.md +33 -0
- package/src/components/pilots/alb-ecs.pilot.ts +63 -0
- package/src/components/pilots/dynamodb.pilot.ts +59 -0
- package/src/components/pilots/jar-emr.pilot.ts +69 -0
- package/src/components/pilots/lambda.pilot.ts +55 -0
- package/src/components/pilots/neo4j-fanout.pilot.ts +92 -0
- package/src/components/pilots/pilots-lint-clean.test.ts +78 -0
- package/src/components/pilots/pilots.test.ts +126 -0
- package/src/components/pilots/project.ts +13 -0
- package/src/components/presets/comp007-reduction.test.ts +122 -0
- package/src/components/presets/ecs-fargate.test.ts +84 -0
- package/src/components/presets/ecs-fargate.ts +103 -0
- package/src/components/presets/index.ts +32 -0
- package/src/components/presets/lambda.test.ts +35 -0
- package/src/components/presets/lambda.ts +53 -0
- package/src/components/presets/single-host-compose.test.ts +65 -0
- package/src/components/presets/single-host-compose.ts +64 -0
- package/src/components/registry.test.ts +112 -0
- package/src/components/registry.ts +37 -0
- package/src/components/starter-plugin.ts +105 -0
- package/src/components/temporal-codegen-loader.ts +41 -0
- package/src/components/verbs/__fixtures__/package-lock.json +45 -0
- package/src/components/verbs/__fixtures__/pom.xml +37 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-1.5.schema.json +3800 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-spdx-license.schema.json +621 -0
- package/src/components/verbs/__fixtures__/schemas/jsf-0.82.schema.json +240 -0
- package/src/components/verbs/__fixtures__/schemas/spdx-2.3.schema.json +740 -0
- package/src/components/verbs/__tests__/mock-cloud-executor.ts +102 -0
- package/src/components/verbs/__tests__/mock-process-runner.ts +79 -0
- package/src/components/verbs/__tests__/mock-sbom-generator.ts +85 -0
- package/src/components/verbs/bom-writer.test.ts +331 -0
- package/src/components/verbs/bom-writer.ts +386 -0
- package/src/components/verbs/build-archive.test.ts +251 -0
- package/src/components/verbs/build-archive.ts +296 -0
- package/src/components/verbs/build.test.ts +222 -0
- package/src/components/verbs/build.ts +252 -0
- package/src/components/verbs/cloud-executor.ts +181 -0
- package/src/components/verbs/component-bom.test.ts +219 -0
- package/src/components/verbs/component-bom.ts +189 -0
- package/src/components/verbs/index.ts +49 -0
- package/src/components/verbs/license-policy.ts +115 -0
- package/src/components/verbs/lockfile-sbom-generator.test.ts +195 -0
- package/src/components/verbs/lockfile-sbom-generator.ts +236 -0
- package/src/components/verbs/process-runner.test.ts +79 -0
- package/src/components/verbs/process-runner.ts +113 -0
- package/src/components/verbs/reproducibility.test.ts +24 -0
- package/src/components/verbs/reproducibility.ts +100 -0
- package/src/components/verbs/sbom-generator.test.ts +96 -0
- package/src/components/verbs/sbom-generator.ts +209 -0
- package/src/components/verbs/sbom.test.ts +184 -0
- package/src/components/verbs/sbom.ts +152 -0
- package/src/components/verbs/shell.test.ts +36 -0
- package/src/components/verbs/shell.ts +51 -0
- package/src/components/verbs/sign.test.ts +210 -0
- package/src/components/verbs/sign.ts +350 -0
- package/src/components/verbs/stub.ts +34 -0
- package/src/components/verbs/tool-sbom-generator.test.ts +194 -0
- package/src/components/verbs/tool-sbom-generator.ts +192 -0
- package/src/components/verbs/verify.test.ts +159 -0
- package/src/components/verbs/verify.ts +179 -0
- package/src/components/verbs/vex.ts +182 -0
- package/src/components/verbs/vuln-gate.test.ts +201 -0
- package/src/components/verbs/vuln-gate.ts +170 -0
- package/src/components/verbs/vuln-scan.test.ts +145 -0
- package/src/components/verbs/vuln-scan.ts +266 -0
- package/src/components/verbs/wait-verify.test.ts +111 -0
- package/src/components/verbs/wait-verify.ts +171 -0
- package/src/config.test.ts +74 -1
- package/src/config.ts +219 -0
- package/src/index.ts +32 -0
- package/src/lexicon.ts +88 -0
- package/src/lifecycle/build-ledger-store.test.ts +217 -0
- package/src/lifecycle/build-ledger-store.ts +165 -0
- package/src/lifecycle/build-ledger.test.ts +349 -0
- package/src/lifecycle/build-ledger.ts +305 -0
- package/src/lifecycle/git.test.ts +118 -0
- package/src/lifecycle/git.ts +149 -14
- package/src/lifecycle/index.ts +5 -0
- package/src/lifecycle/oras-referrer-lookup.test.ts +116 -0
- package/src/lifecycle/oras-referrer-lookup.ts +110 -0
- package/src/lifecycle/release-ledger.test.ts +209 -0
- package/src/lifecycle/release-ledger.ts +185 -0
- package/src/lifecycle/status.test.ts +330 -0
- package/src/lifecycle/status.ts +278 -0
- package/src/lint/component-checks.ts +148 -0
- package/src/lint/config.test.ts +21 -0
- package/src/lint/engine.ts +11 -2
- package/src/lint/presets/relaxed.json +8 -1
- package/src/lint/presets/strict.json +8 -1
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.ts +27 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.ts +19 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.ts +20 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.ts +18 -0
- package/src/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.ts +12 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.ts +18 -0
- package/src/lint/rules/comp/comp.test.ts +378 -0
- package/src/lint/rules/comp/comp001-publishes-never-applies.ts +78 -0
- package/src/lint/rules/comp/comp002-dangling-wiring-ref.ts +94 -0
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +115 -0
- package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +66 -0
- package/src/lint/rules/comp/comp005-capability-kind-is-noun.ts +113 -0
- package/src/lint/rules/comp/comp006-shell-needs-reason.ts +55 -0
- package/src/lint/rules/comp/comp007-composition-sprawl.ts +71 -0
- package/src/lint/rules/comp/index.ts +37 -0
- package/src/lint/rules/comp/support.ts +173 -0
- package/src/lsp/lexicon-providers.test.ts +55 -0
- package/src/lsp/lexicon-providers.ts +13 -3
- package/src/op/activity-registry.test.ts +38 -0
- package/src/op/activity-registry.ts +31 -12
- package/src/op/activity-runtime.ts +73 -0
- package/src/op/builders.ts +99 -0
- package/src/op/index.ts +3 -1
- package/src/ownership.test.ts +24 -26
- package/src/ownership.ts +26 -38
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sign` capability — keyless cosign signing + SLSA provenance attestation
|
|
3
|
+
* (#622, epic #551 follow-up to #610's referrer-attach path and #614's
|
|
4
|
+
* reproducibility/provenance material). The companion gate is
|
|
5
|
+
* `./verify.ts`'s `verify` capability.
|
|
6
|
+
*
|
|
7
|
+
* **Beginner footgun #1 neutralized: sign the digest, never a tag.** `input`
|
|
8
|
+
* requires an already-resolved `sha256:` image reference (typically wired
|
|
9
|
+
* from a prior publish step, `"@Publish.uri"`, which is itself
|
|
10
|
+
* `repo@sha256:...` — see ./publish.ts) — never a bare tag. A tag is mutable;
|
|
11
|
+
* signing one says nothing about which bytes were actually signed by the
|
|
12
|
+
* time someone pulls it. `assertDigestRef` below throws before ever shelling
|
|
13
|
+
* out if a caller passes a tag-only reference.
|
|
14
|
+
*
|
|
15
|
+
* **Beginner footgun #2 neutralized: keyless by default.** Sign via cosign's
|
|
16
|
+
* keyless flow (a short-lived Fulcio cert bound to an OIDC identity, logged
|
|
17
|
+
* to the public Rekor transparency log) — `cosign sign --yes <ref>` with no
|
|
18
|
+
* `--key`. There is no private key file for a first-timer to generate, lose,
|
|
19
|
+
* leak, or forget to rotate. Key-based signing (`input.key`) is an opt-in
|
|
20
|
+
* override for teams with an existing KMS/file-based key policy, never the
|
|
21
|
+
* default — see `buildSignArgs`/`buildAttestArgs` below: `--key` is added
|
|
22
|
+
* only when `input.key` is explicitly supplied, and it is the *only* thing
|
|
23
|
+
* that changes about the invocation (still by digest, still attached the
|
|
24
|
+
* same way).
|
|
25
|
+
*
|
|
26
|
+
* **SLSA provenance.** `attestProvenance` builds an in-toto
|
|
27
|
+
* `https://slsa.dev/provenance/v1` statement from the same
|
|
28
|
+
* `ProvenanceLink`/`ArtifactReproducibility` material #614's
|
|
29
|
+
* ./reproducibility.ts already records per build-archive entry (source ref,
|
|
30
|
+
* artifact digest) plus a builder id and timestamp, then signs+attaches it
|
|
31
|
+
* via `cosign attest` (keyless by the same default). This reuses #614's
|
|
32
|
+
* provenance model rather than inventing a second one — the in-toto
|
|
33
|
+
* statement's `predicate.buildDefinition.resolvedDependencies` /
|
|
34
|
+
* `.internalParameters` are populated from the same source-ref/digest link a
|
|
35
|
+
* build archive entry already carries.
|
|
36
|
+
*
|
|
37
|
+
* Both `sign` and `attestProvenance` shell out to `cosign` through the
|
|
38
|
+
* injectable `ProcessRunner` (./process-runner.ts) — mirroring
|
|
39
|
+
* ./tool-sbom-generator.ts and ./publish.ts's referrer-attach step exactly:
|
|
40
|
+
* `requireTool` throws `ToolNotAvailableError` with an actionable message if
|
|
41
|
+
* `cosign` is absent, and no test here ever spawns a real process or talks
|
|
42
|
+
* to Rekor/Fulcio.
|
|
43
|
+
*/
|
|
44
|
+
import type { Capability } from "../capability.js";
|
|
45
|
+
import { type ProcessRunner } from "./process-runner.js";
|
|
46
|
+
import type { ProvenanceLink } from "./reproducibility.js";
|
|
47
|
+
/**
|
|
48
|
+
* Thrown when a `sign`/`attest` input's image reference has no `@sha256:...`
|
|
49
|
+
* digest — refusing to sign a mutable tag (beginner footgun #1) rather than
|
|
50
|
+
* silently signing whatever the tag happens to resolve to right now.
|
|
51
|
+
*/
|
|
52
|
+
export declare class SignTargetNotDigestError extends Error {
|
|
53
|
+
readonly ref: string;
|
|
54
|
+
readonly verb: "sign" | "attest";
|
|
55
|
+
constructor(ref: string, verb: "sign" | "attest");
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* cosign keyless signing config. Keyless is the default story this whole
|
|
59
|
+
* module encodes — every field here is optional because `cosign sign --yes`
|
|
60
|
+
* with no flags at all already does the right thing in CI (ambient OIDC from
|
|
61
|
+
* the CI provider's own token, e.g. GitHub Actions' `id-token: write`).
|
|
62
|
+
* `identityToken`/`oidcIssuer`/`oidcClientId` are the explicit overrides for
|
|
63
|
+
* environments without ambient OIDC detection.
|
|
64
|
+
*/
|
|
65
|
+
export interface KeylessSigningConfig {
|
|
66
|
+
/** Explicit OIDC identity token, when the environment has no ambient CI OIDC cosign can auto-detect. */
|
|
67
|
+
identityToken?: string;
|
|
68
|
+
/** OIDC issuer URL override (`cosign sign --oidc-issuer`). */
|
|
69
|
+
oidcIssuer?: string;
|
|
70
|
+
/** OIDC client id override (`cosign sign --oidc-client-id`). */
|
|
71
|
+
oidcClientId?: string;
|
|
72
|
+
/** Fulcio URL override, for a private Sigstore instance. */
|
|
73
|
+
fulcioUrl?: string;
|
|
74
|
+
/** Rekor URL override, for a private transparency log. */
|
|
75
|
+
rekorUrl?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Key-based signing override config — opt-in, never the default (see this
|
|
79
|
+
* module's doc comment). Supplying `input.key` on `sign`/`attestProvenance`
|
|
80
|
+
* switches the invocation to `cosign sign --key <key>` instead of the keyless
|
|
81
|
+
* flow; every other part of the invocation (digest-only target, referrer
|
|
82
|
+
* attach) is unchanged.
|
|
83
|
+
*/
|
|
84
|
+
export interface KeyBasedSigningConfig {
|
|
85
|
+
/** Key reference cosign accepts: a local path, `kms://...`, `k8s://...`, `azurekms://...`, `awskms://...`, etc. An encrypted key file's password is not accepted here — `ProcessRunner.run` (./process-runner.ts) has no env-var passthrough today, and interpolating a secret into the shell command string would leak it into process listings/logs; supply an unencrypted key reference (e.g. a KMS URI) or export `COSIGN_PASSWORD` in the calling process's own environment instead. */
|
|
86
|
+
key: string;
|
|
87
|
+
}
|
|
88
|
+
export interface SignInput {
|
|
89
|
+
/** Digest-qualified image reference to sign, e.g. `"123.dkr.ecr.us-east-1.amazonaws.com/search@sha256:abc..."` — typically wired from a prior publish step's `"@Publish.uri"`. Never a bare tag; see `SignTargetNotDigestError`. */
|
|
90
|
+
imageRef: string;
|
|
91
|
+
/** Keyless signing config (OIDC identity + Rekor/Fulcio overrides). Default: cosign's own ambient keyless detection, no explicit config needed. Ignored when `key` is supplied. */
|
|
92
|
+
keyless?: KeylessSigningConfig;
|
|
93
|
+
/** Opt-in key-based override — supply to sign with a private/KMS key instead of the keyless default. Not the default; see this module's doc comment. */
|
|
94
|
+
key?: KeyBasedSigningConfig;
|
|
95
|
+
/** Annotations to attach to the signature (`cosign sign -a k=v`), e.g. build metadata. */
|
|
96
|
+
annotations?: Record<string, string>;
|
|
97
|
+
}
|
|
98
|
+
export interface SignOutput {
|
|
99
|
+
/** The digest-qualified reference that was signed — echoed back for downstream wiring (e.g. into `attestProvenance`/`verify`). */
|
|
100
|
+
imageRef: string;
|
|
101
|
+
/** True once `cosign sign` completed without error. */
|
|
102
|
+
signed: true;
|
|
103
|
+
/** `"keyless"` or `"key"`, reflecting which flow actually ran. */
|
|
104
|
+
method: "keyless" | "key";
|
|
105
|
+
}
|
|
106
|
+
/** Build the `cosign sign` argv (as a shell command string) for `input` — factored out so tests can assert on the exact invocation without needing a full mock run. */
|
|
107
|
+
export declare function buildSignArgs(input: SignInput): string;
|
|
108
|
+
/**
|
|
109
|
+
* Sign an artifact by digest via keyless cosign (default) or an opt-in
|
|
110
|
+
* key-based override, and attach the signature as an OCI referrer on that
|
|
111
|
+
* digest — `cosign sign` itself performs the attach (cosign's signatures are
|
|
112
|
+
* always stored as registry referrers/the legacy tag convention; no separate
|
|
113
|
+
* `oras attach` step is needed the way SBOM/BOM referrer attach in
|
|
114
|
+
* ./publish.ts requires one, since cosign natively pushes to the registry).
|
|
115
|
+
* Refuses to run at all against a non-digest reference (`SignTargetNotDigestError`)
|
|
116
|
+
* — sign is never invoked for a tag, by construction, before any process is spawned.
|
|
117
|
+
*
|
|
118
|
+
* No rollback: an already-signed, content-addressed image's signature is
|
|
119
|
+
* immutable evidence sitting in the registry — nothing to compensate, the
|
|
120
|
+
* same opt-out `publish-image`/`generate-sbom` already take for
|
|
121
|
+
* no-mutable-remote-state operations.
|
|
122
|
+
*/
|
|
123
|
+
export declare function createSignCapability(processRunner?: ProcessRunner): Capability<SignInput, SignOutput>;
|
|
124
|
+
/** Default `sign` capability, backed by the real `ProcessRunner`. */
|
|
125
|
+
export declare const signCapability: Capability<SignInput, SignOutput>;
|
|
126
|
+
/** Minimal in-toto `https://slsa.dev/provenance/v1` predicate — the fields this module can honestly populate from #614's `ProvenanceLink` material, not a full SLSA Level 3+ builder identity/hermeticity claim. */
|
|
127
|
+
export interface SlsaProvenancePredicate {
|
|
128
|
+
buildDefinition: {
|
|
129
|
+
buildType: string;
|
|
130
|
+
externalParameters: Record<string, unknown>;
|
|
131
|
+
internalParameters?: Record<string, unknown>;
|
|
132
|
+
resolvedDependencies?: Array<{
|
|
133
|
+
uri: string;
|
|
134
|
+
digest?: Record<string, string>;
|
|
135
|
+
}>;
|
|
136
|
+
};
|
|
137
|
+
runDetails: {
|
|
138
|
+
builder: {
|
|
139
|
+
id: string;
|
|
140
|
+
};
|
|
141
|
+
metadata?: {
|
|
142
|
+
invocationId?: string;
|
|
143
|
+
startedOn?: string;
|
|
144
|
+
finishedOn?: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** The full in-toto statement wrapping the SLSA predicate — what `cosign attest` signs+attaches. */
|
|
149
|
+
export interface InTotoProvenanceStatement {
|
|
150
|
+
_type: "https://in-toto.io/Statement/v1";
|
|
151
|
+
predicateType: "https://slsa.dev/provenance/v1";
|
|
152
|
+
subject: Array<{
|
|
153
|
+
name: string;
|
|
154
|
+
digest: {
|
|
155
|
+
sha256: string;
|
|
156
|
+
};
|
|
157
|
+
}>;
|
|
158
|
+
predicate: SlsaProvenancePredicate;
|
|
159
|
+
}
|
|
160
|
+
export interface BuildProvenanceStatementInput {
|
|
161
|
+
/** The digest-qualified artifact reference this provenance describes (subject). */
|
|
162
|
+
imageRef: string;
|
|
163
|
+
/** Source -> output link, reused from #614 (./reproducibility.ts) rather than re-deriving a second source-of-truth for "what commit produced this." */
|
|
164
|
+
provenance: ProvenanceLink;
|
|
165
|
+
/** Builder identity URI, e.g. a CI run URL or `"https://github.com/actions/runner"`. */
|
|
166
|
+
builderId: string;
|
|
167
|
+
/** Build type identifier (an arbitrary URI naming the recipe kind, e.g. `"https://chant.dev/build-archive/v1"`). Defaults to a chant-generic build type. */
|
|
168
|
+
buildType?: string;
|
|
169
|
+
/** ISO-8601 timestamp of the build's completion. Defaults to `new Date().toISOString()`. */
|
|
170
|
+
finishedOn?: string;
|
|
171
|
+
/** CI invocation/run id, when available (e.g. a GitHub Actions run id). */
|
|
172
|
+
invocationId?: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build an in-toto SLSA provenance statement for `input.imageRef`, reusing
|
|
176
|
+
* #614's `ProvenanceLink` (source ref -> artifact digest) as the statement's
|
|
177
|
+
* `resolvedDependencies`/`internalParameters` material — the honest subset
|
|
178
|
+
* chant can actually attest to (which source commit, which builder, when),
|
|
179
|
+
* matching ./reproducibility.ts's "honesty over convenience" stance rather
|
|
180
|
+
* than fabricating a stronger provenance claim than the build system backs.
|
|
181
|
+
*/
|
|
182
|
+
export declare function buildProvenanceStatement(input: BuildProvenanceStatementInput): InTotoProvenanceStatement;
|
|
183
|
+
export interface AttestProvenanceInput extends BuildProvenanceStatementInput {
|
|
184
|
+
/** Keyless signing config, same shape/default as `SignInput.keyless`. */
|
|
185
|
+
keyless?: KeylessSigningConfig;
|
|
186
|
+
/** Opt-in key-based override, same shape/default as `SignInput.key`. */
|
|
187
|
+
key?: KeyBasedSigningConfig;
|
|
188
|
+
}
|
|
189
|
+
export interface AttestProvenanceOutput {
|
|
190
|
+
/** The digest-qualified reference the provenance was attested for. */
|
|
191
|
+
imageRef: string;
|
|
192
|
+
/** The in-toto statement that was signed+attached (returned for inspection/logging/tests). */
|
|
193
|
+
statement: InTotoProvenanceStatement;
|
|
194
|
+
/** True once `cosign attest` completed without error. */
|
|
195
|
+
attested: true;
|
|
196
|
+
/** `"keyless"` or `"key"`, reflecting which flow actually ran. */
|
|
197
|
+
method: "keyless" | "key";
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Build the `cosign attest` argv (as a shell command string) for a
|
|
201
|
+
* predicate-type/payload pair. Factored out (like `buildSignArgs`) so tests
|
|
202
|
+
* can assert on the exact invocation. `--predicate` reads from a scratch
|
|
203
|
+
* file path (`cosign attest` does not accept the payload on stdin any more
|
|
204
|
+
* reliably than `oras attach` does — see ./publish.ts's `attachOneReferrer`
|
|
205
|
+
* for the same scratch-file convention) — the caller passes the path already
|
|
206
|
+
* written.
|
|
207
|
+
*/
|
|
208
|
+
export declare function buildAttestArgs(input: AttestProvenanceInput, predicatePath: string): string;
|
|
209
|
+
/**
|
|
210
|
+
* Build an in-toto SLSA provenance statement for a digest-qualified artifact
|
|
211
|
+
* (reusing #614's `ProvenanceLink` material) and sign+attach it via keyless
|
|
212
|
+
* `cosign attest` (default) or an opt-in key-based override — attached as a
|
|
213
|
+
* referrer alongside the signature (`sign`) and SBOM (`generate-sbom`) on
|
|
214
|
+
* the same digest. Refuses a non-digest `imageRef` the same way `sign` does.
|
|
215
|
+
*
|
|
216
|
+
* No rollback: same reasoning as `sign` — an attached, content-addressed
|
|
217
|
+
* attestation is immutable evidence, nothing to compensate.
|
|
218
|
+
*/
|
|
219
|
+
export declare function createAttestProvenanceCapability(processRunner?: ProcessRunner): Capability<AttestProvenanceInput, AttestProvenanceOutput>;
|
|
220
|
+
/** Default `attest-provenance` capability, backed by the real `ProcessRunner`. */
|
|
221
|
+
export declare const attestProvenanceCapability: Capability<AttestProvenanceInput, AttestProvenanceOutput>;
|
|
222
|
+
//# sourceMappingURL=sign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/sign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper for building typed capability stubs.
|
|
3
|
+
*
|
|
4
|
+
* A stub is fully typed (`kind`, `In`, `Out`) so compositions can wire
|
|
5
|
+
* output -> input and lint can check the graph, but `run`/`rollback` throw
|
|
6
|
+
* `CapabilityNotImplementedError` — no cloud calls, no side effects. Cloud
|
|
7
|
+
* implementations land in a later phase (epic #551).
|
|
8
|
+
*/
|
|
9
|
+
import type { Capability } from "../capability.js";
|
|
10
|
+
/**
|
|
11
|
+
* Build a stub `Capability<In, Out>` for `kind`. `supportsRollback` also
|
|
12
|
+
* attaches a `rollback` that throws the same error, so compositions can
|
|
13
|
+
* already reference `rollback` in typed code ahead of the real implementation.
|
|
14
|
+
*/
|
|
15
|
+
export declare function stubCapability<In, Out>(kind: string, opts?: {
|
|
16
|
+
rollback?: boolean;
|
|
17
|
+
}): Capability<In, Out>;
|
|
18
|
+
//# sourceMappingURL=stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/stub.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,GAAG,EACpC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,CAarB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real, deep-scan `SbomGenerator` backend (#610, epic #551's "deep external
|
|
3
|
+
* tool" half of the SBOM story — the counterpart to ./lockfile-sbom-generator.ts's
|
|
4
|
+
* hermetic, zero-dependency default from #613). Shells out to whichever
|
|
5
|
+
* external scanner fits the artifact type, through the injectable
|
|
6
|
+
* `ProcessRunner` (./process-runner.ts, itself mirroring
|
|
7
|
+
* ./cloud-executor.ts's `CloudExecutor` pattern):
|
|
8
|
+
*
|
|
9
|
+
* - `image` -> `docker buildx build --sbom=true` (BuildKit's native SPDX
|
|
10
|
+
* attestation) when a Dockerfile build context is available, otherwise a
|
|
11
|
+
* `syft <tarball>` scan of the already-built OCI-layout tarball;
|
|
12
|
+
* - `jar` -> `syft`, or `cyclonedx-maven` when the jar's project directory
|
|
13
|
+
* carries a `pom.xml` (a more Maven-native scan than a bytecode-level jar
|
|
14
|
+
* scan);
|
|
15
|
+
* - `zip` -> `syft <zip>`;
|
|
16
|
+
* - `dir` -> `syft <dir>`, falling back to `cdxgen <dir>` when `syft` is
|
|
17
|
+
* unavailable (`cdxgen`'s "wnat's on disk" mode covers ecosystems syft
|
|
18
|
+
* might not have detected).
|
|
19
|
+
*
|
|
20
|
+
* Every method resolves the specific tool it needs, checks availability via
|
|
21
|
+
* `ProcessRunner.available` first, and throws `ToolNotAvailableError`
|
|
22
|
+
* (./process-runner.ts) with an actionable install hint if the tool is
|
|
23
|
+
* missing — never a silent empty SBOM. Tests inject `MockProcessRunner`
|
|
24
|
+
* (./__tests__/mock-process-runner.ts) and assert on the constructed command
|
|
25
|
+
* line + parsed output; nothing here ever spawns a real process.
|
|
26
|
+
*
|
|
27
|
+
* This backend is **not** the process-wide default (see
|
|
28
|
+
* ./sbom-generator.ts's `notImplementedSbomGenerator` and
|
|
29
|
+
* ./lockfile-sbom-generator.ts's `lockfileSbomGenerator` module docs for why):
|
|
30
|
+
* a project opts in explicitly by constructing
|
|
31
|
+
* `createGenerateSbomCapability(createToolSbomGenerator())` when it wants the
|
|
32
|
+
* deeper, external-tool-backed scan (e.g. to see an image's base-layer OS
|
|
33
|
+
* packages, which no lockfile read can see).
|
|
34
|
+
*/
|
|
35
|
+
import { type SbomGenerator } from "./sbom-generator.js";
|
|
36
|
+
import { type ProcessRunner } from "./process-runner.js";
|
|
37
|
+
export interface ToolSbomGeneratorOptions {
|
|
38
|
+
/** Injected process boundary. Defaults to the real, `child_process`-backed runner. */
|
|
39
|
+
runner?: ProcessRunner;
|
|
40
|
+
/** Directory `syft`/`cdxgen`/`cyclonedx-maven` write their output file into before this backend reads it back. Defaults to `node:os`'s tmpdir via each call's own scratch path — see `scratchPath`. */
|
|
41
|
+
workDir?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build a real, deep-scan `SbomGenerator` backend. Every method shells out
|
|
45
|
+
* through `options.runner` (default: the real `ProcessRunner`); tests should
|
|
46
|
+
* always pass a `MockProcessRunner` instead.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createToolSbomGenerator(options?: ToolSbomGeneratorOptions): SbomGenerator;
|
|
49
|
+
/** Process-wide, real-tool-backed `SbomGenerator`, ready to inject wherever a project opts into the deep-scan path over ./lockfile-sbom-generator.ts's hermetic default. Never constructed by a test. */
|
|
50
|
+
export declare const toolSbomGenerator: SbomGenerator;
|
|
51
|
+
//# sourceMappingURL=tool-sbom-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-sbom-generator.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/tool-sbom-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAwC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAW5F,MAAM,WAAW,wBAAwB;IACvC,sFAAsF;IACtF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,uMAAuM;IACvM,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B,GAAG,aAAa,CAiG7F;AAED,yMAAyM;AACzM,eAAO,MAAM,iBAAiB,EAAE,aAAyC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `verify` capability — the deploy-time signature/provenance gate (#622,
|
|
3
|
+
* epic #551 follow-up to ./sign.ts's keyless signing + SLSA attestation).
|
|
4
|
+
* Mirrors `../../lint/policy.ts`'s `policyGate` shape: a step that runs
|
|
5
|
+
* `cosign verify` (+ `cosign verify-attestation` for provenance) against a
|
|
6
|
+
* configured identity policy and **throws** on any failure, so composing it
|
|
7
|
+
* before an apply phase fails the deploy the same way a thrown capability
|
|
8
|
+
* error already halts `driver.ts`'s step execution — no new failure
|
|
9
|
+
* mechanism, no gate-signal/human-approval semantics (that is `Gate`,
|
|
10
|
+
* ../component.ts, a different, durable-runtime-only concept). `verify` is a
|
|
11
|
+
* synchronous, local-executor-safe capability, exactly like `health-gate`
|
|
12
|
+
* (./wait-verify.ts).
|
|
13
|
+
*
|
|
14
|
+
* **Beginner-safe default policy.** The minimum an identity policy must
|
|
15
|
+
* declare is `expectedIssuer` + `expectedIdentity` (the OIDC issuer/identity
|
|
16
|
+
* that must have signed) — "signature present + from the expected identity."
|
|
17
|
+
* There is no "verify but accept any identity" mode: an identity-less verify
|
|
18
|
+
* would defeat the point of keyless signing (anyone's Rekor-logged signature
|
|
19
|
+
* would pass), so `IdentityPolicy` requires both fields, not an optional
|
|
20
|
+
* pair a beginner could forget to set.
|
|
21
|
+
*
|
|
22
|
+
* Routes `cosign verify`/`cosign verify-attestation` through the injectable
|
|
23
|
+
* `ProcessRunner` (./process-runner.ts), mirroring every other #610/#622
|
|
24
|
+
* real backend: `requireTool` throws `ToolNotAvailableError` if `cosign` is
|
|
25
|
+
* absent (a missing verifier is a hard stop, never a silent pass — the
|
|
26
|
+
* opposite failure mode from ./publish.ts's best-effort referrer attach,
|
|
27
|
+
* because skipping verification on a missing tool would silently let an
|
|
28
|
+
* unsigned/wrongly-signed artifact through the gate).
|
|
29
|
+
*/
|
|
30
|
+
import type { Capability } from "../capability.js";
|
|
31
|
+
import { type ProcessRunner } from "./process-runner.js";
|
|
32
|
+
/**
|
|
33
|
+
* The configured identity an artifact's signature/provenance must match —
|
|
34
|
+
* "beginner-safe default" per #622: signature present + from the expected
|
|
35
|
+
* identity, nothing more exotic required out of the box. Both fields are
|
|
36
|
+
* required (see this module's doc comment for why an identity-less verify
|
|
37
|
+
* is not offered).
|
|
38
|
+
*/
|
|
39
|
+
export interface IdentityPolicy {
|
|
40
|
+
/** Expected OIDC issuer, e.g. `"https://token.actions.githubusercontent.com"` for GitHub Actions keyless signing. Passed to `cosign verify --certificate-oidc-issuer`. */
|
|
41
|
+
expectedIssuer: string;
|
|
42
|
+
/**
|
|
43
|
+
* Expected signer identity. For keyless CI signing this is typically the
|
|
44
|
+
* workflow identity URI cosign embeds in the Fulcio cert (e.g.
|
|
45
|
+
* `"https://github.com/my-org/my-repo/.github/workflows/release.yml@refs/heads/main"`).
|
|
46
|
+
* Passed to `cosign verify --certificate-identity`. Supports the same
|
|
47
|
+
* `--certificate-identity-regexp` escape hatch via `identityIsRegexp`
|
|
48
|
+
* below, for teams whose identity varies by branch/tag and want one policy
|
|
49
|
+
* to match a pattern rather than enumerating every literal ref.
|
|
50
|
+
*/
|
|
51
|
+
expectedIdentity: string;
|
|
52
|
+
/** Treat `expectedIdentity` as a regexp (`cosign verify --certificate-identity-regexp`) instead of a literal match. Default: false. */
|
|
53
|
+
identityIsRegexp?: boolean;
|
|
54
|
+
/** Optional key-based override — verify against a public key instead of the keyless identity policy, mirroring ./sign.ts's opt-in key-based override. Not the default. */
|
|
55
|
+
key?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface VerifyInput {
|
|
58
|
+
/** Digest-qualified image reference to verify, e.g. `"@Publish.uri"`/`"@Sign.imageRef"`. */
|
|
59
|
+
imageRef: string;
|
|
60
|
+
/** The identity policy the signature must satisfy. */
|
|
61
|
+
policy: IdentityPolicy;
|
|
62
|
+
/** Also verify the SLSA provenance attestation (`cosign verify-attestation --type slsaprovenance1`) alongside the signature. Default: true — both #622 outputs are expected present once `sign`+`attest-provenance` have run. */
|
|
63
|
+
requireProvenance?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface VerifyOutput {
|
|
66
|
+
/** True once every requested check (signature, and provenance if requested) passed. Always `true` when returned — a failure throws instead, so a caller never has to remember to check this field; it exists for symmetry with other capability outputs and for logging. */
|
|
67
|
+
verified: true;
|
|
68
|
+
/** Which checks actually ran and passed. */
|
|
69
|
+
checked: Array<"signature" | "provenance">;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Thrown when `cosign verify`/`cosign verify-attestation` rejects — wrong
|
|
73
|
+
* identity, missing signature, tampered artifact, or any other verification
|
|
74
|
+
* failure `cosign` itself reports. Distinct from `ToolNotAvailableError` so a
|
|
75
|
+
* caller (and a test) can tell "cosign said no" apart from "cosign isn't
|
|
76
|
+
* installed." Carries `reason` (cosign's own stderr/message) for whoever is
|
|
77
|
+
* debugging a failed gate.
|
|
78
|
+
*/
|
|
79
|
+
export declare class VerificationFailedError extends Error {
|
|
80
|
+
readonly imageRef: string;
|
|
81
|
+
readonly check: "signature" | "provenance";
|
|
82
|
+
readonly reason: string;
|
|
83
|
+
constructor(imageRef: string, check: "signature" | "provenance", reason: string);
|
|
84
|
+
}
|
|
85
|
+
/** Build the `cosign verify` argv (as a shell command string) for `input` — factored out so tests can assert on the exact invocation. */
|
|
86
|
+
export declare function buildVerifySignatureArgs(input: VerifyInput): string;
|
|
87
|
+
/** Build the `cosign verify-attestation` argv (as a shell command string) for `input`. */
|
|
88
|
+
export declare function buildVerifyAttestationArgs(input: VerifyInput): string;
|
|
89
|
+
/**
|
|
90
|
+
* Gate a deploy on `cosign verify` (signature) + `cosign verify-attestation`
|
|
91
|
+
* (SLSA provenance, unless `requireProvenance: false`) against `input.policy`
|
|
92
|
+
* — the digest-anchored counterpart to `../../lint/policy.ts`'s
|
|
93
|
+
* organizational-policy `policyGate`. Throws `VerificationFailedError` on any
|
|
94
|
+
* failed check, which halts the composition the same way any other thrown
|
|
95
|
+
* capability error does (see ../driver.ts) — no separate "gate" plumbing
|
|
96
|
+
* needed; a `verify` step composed before an `Apply` phase blocks that phase
|
|
97
|
+
* from ever running on verification failure.
|
|
98
|
+
*
|
|
99
|
+
* No rollback: verification is read-only observation of already-published
|
|
100
|
+
* evidence, nothing to compensate — same reasoning as `health-gate`/`wait-*`
|
|
101
|
+
* (./wait-verify.ts).
|
|
102
|
+
*/
|
|
103
|
+
export declare function createVerifyCapability(processRunner?: ProcessRunner): Capability<VerifyInput, VerifyOutput>;
|
|
104
|
+
/** Default `verify` capability, backed by the real `ProcessRunner`. */
|
|
105
|
+
export declare const verifyCapability: Capability<VerifyInput, VerifyOutput>;
|
|
106
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAwC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAI5F;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,0KAA0K;IAC1K,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,uIAAuI;IACvI,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0KAA0K;IAC1K,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,MAAM,WAAW,WAAW;IAC1B,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,MAAM,EAAE,cAAc,CAAC;IACvB,iOAAiO;IACjO,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,4QAA4Q;IAC5Q,QAAQ,EAAE,IAAI,CAAC;IACf,4CAA4C;IAC5C,OAAO,EAAE,KAAK,CAAC,WAAW,GAAG,YAAY,CAAC,CAAC;CAC5C;AAED;;;;;;;GAOG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aAE9B,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,WAAW,GAAG,YAAY;aACjC,MAAM,EAAE,MAAM;gBAFd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,WAAW,GAAG,YAAY,EACjC,MAAM,EAAE,MAAM;CAKjC;AAYD,yIAAyI;AACzI,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAKnE;AAED,0FAA0F;AAC1F,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAKrE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,aAAsC,GACpD,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAmCvC;AAED,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,EAAE,UAAU,CAAC,WAAW,EAAE,YAAY,CAA4B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VEX (Vulnerability Exploitability eXchange) ingestion + suppression (#626).
|
|
3
|
+
* A scanner (./vuln-scan.ts) flags every known CVE in an SBOM, but most aren't
|
|
4
|
+
* actually exploitable in context (unreachable code path, already mitigated,
|
|
5
|
+
* false positive). VEX is where you (or upstream) assert, per CVE, whether it
|
|
6
|
+
* *actually* affects this artifact. Without it a gate is CVE fatigue — 500
|
|
7
|
+
* findings, 5 that matter. This module parses VEX and filters findings, and it
|
|
8
|
+
* **reports** every suppression with its justification — a VEX-suppressed
|
|
9
|
+
* finding is never silently dropped.
|
|
10
|
+
*
|
|
11
|
+
* Two formats: **OpenVEX** (the standalone Sigstore/OpenSSF format) and
|
|
12
|
+
* **CycloneDX**-embedded VEX (`vulnerabilities[].analysis`). Both reduce to the
|
|
13
|
+
* same `VexStatement` shape here.
|
|
14
|
+
*/
|
|
15
|
+
import type { VulnFinding } from "./vuln-scan.js";
|
|
16
|
+
/** VEX status for a CVE against an artifact. `not_affected`/`fixed` suppress a finding; `affected`/`under_investigation` keep it (conservative — an unresolved status must not hide a real vuln). */
|
|
17
|
+
export type VexStatus = "not_affected" | "affected" | "fixed" | "under_investigation";
|
|
18
|
+
/** True for statuses that suppress a matching finding from gating. */
|
|
19
|
+
export declare function suppresses(status: VexStatus): boolean;
|
|
20
|
+
/** One VEX assertion: this CVE has this status for this artifact, with an optional human justification. */
|
|
21
|
+
export interface VexStatement {
|
|
22
|
+
cveId: string;
|
|
23
|
+
status: VexStatus;
|
|
24
|
+
/** Why — e.g. `"vulnerable_code_not_in_execute_path"`, `"component_not_present"`. Surfaced on the suppression report so a reviewer sees the reasoning, never a bare "suppressed." */
|
|
25
|
+
justification?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Parse an OpenVEX JSON document into statements. Unknown statuses / statements missing a vulnerability id are skipped. */
|
|
28
|
+
export declare function parseOpenVex(bytes: string): VexStatement[];
|
|
29
|
+
/** Parse CycloneDX-embedded VEX (`vulnerabilities[].analysis`) into statements. */
|
|
30
|
+
export declare function parseCycloneDxVex(bytes: string): VexStatement[];
|
|
31
|
+
/**
|
|
32
|
+
* Parse a VEX document of either format — dispatched on shape (`statements` ->
|
|
33
|
+
* OpenVEX, `vulnerabilities` -> CycloneDX). A malformed/unparseable document
|
|
34
|
+
* yields NO statements (returns `[]`) rather than throwing: it therefore
|
|
35
|
+
* suppresses nothing, keeping the gate strict (fail-closed) instead of
|
|
36
|
+
* crashing on attacker- or typo-supplied input.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseVexDocument(bytes: string): VexStatement[];
|
|
39
|
+
/** A finding removed from gating by a VEX statement, kept for reporting (never silently dropped). */
|
|
40
|
+
export interface SuppressedFinding {
|
|
41
|
+
finding: VulnFinding;
|
|
42
|
+
status: VexStatus;
|
|
43
|
+
justification?: string;
|
|
44
|
+
}
|
|
45
|
+
/** The result of filtering findings through VEX: what still gates, and what was suppressed (with reasons). */
|
|
46
|
+
export interface VexResult {
|
|
47
|
+
/** Findings that survived VEX — the gate evaluates these. */
|
|
48
|
+
gating: VulnFinding[];
|
|
49
|
+
/** Findings suppressed by a `not_affected`/`fixed` statement, with the statement's justification. */
|
|
50
|
+
suppressed: SuppressedFinding[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Filter `findings` through `statements`. A finding is suppressed only when
|
|
54
|
+
* some statement for its CVE suppresses it (`not_affected`/`fixed`) AND **no**
|
|
55
|
+
* statement for that CVE asserts it is `affected`/`under_investigation`.
|
|
56
|
+
*
|
|
57
|
+
* This is the conservative merge, deliberately NOT "last statement wins":
|
|
58
|
+
* when VEX comes from several sources (repo-local files + referrer-attached),
|
|
59
|
+
* a later `not_affected` must not be able to override an earlier `affected` to
|
|
60
|
+
* unblock a real vulnerability. Merging VEX can only ever make the gate
|
|
61
|
+
* *stricter*, never quietly weaker — so an attacker who can append a statement
|
|
62
|
+
* cannot suppress a finding another source flagged as affected.
|
|
63
|
+
*/
|
|
64
|
+
export declare function applyVex(findings: VulnFinding[], statements: VexStatement[]): VexResult;
|
|
65
|
+
//# sourceMappingURL=vex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vex.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/vex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,qMAAqM;AACrM,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,qBAAqB,CAAC;AAEtF,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAErD;AAED,2GAA2G;AAC3G,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,qLAAqL;IACrL,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA8BD,4HAA4H;AAC5H,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAU1D;AA6BD,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAS/D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAU9D;AAID,qGAAqG;AACrG,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,8GAA8G;AAC9G,MAAM,WAAW,SAAS;IACxB,6DAA6D;IAC7D,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,qGAAqG;IACrG,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,SAAS,CAoBvF"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vuln-gate` capability (#626) — the deploy-time gate that closes the
|
|
3
|
+
* supply-chain loop: scan the SBOM (./vuln-scan.ts) for known CVEs, suppress
|
|
4
|
+
* the ones VEX says don't matter (./vex.ts), check licenses (./license-policy.ts),
|
|
5
|
+
* and **throw** on a policy violation so composing it before an apply phase
|
|
6
|
+
* fails the deploy — the same throw-to-halt mechanism as ./verify.ts and
|
|
7
|
+
* `policyGate` (../../lint/policy.ts). No new gate plumbing.
|
|
8
|
+
*
|
|
9
|
+
* **Beginner-safe default policy:** fail on `severity >= critical AND fixable
|
|
10
|
+
* AND not VEX-suppressed`; findings at/above the warn severity (default
|
|
11
|
+
* `high`) that don't reach the fail bar are reported as warnings, not blocked;
|
|
12
|
+
* license findings are report-only unless `failOnLicense` is set. Everything
|
|
13
|
+
* is configurable via `chant.config.ts`'s `vulnPolicy` section (see
|
|
14
|
+
* ../../config.ts `resolveVulnPolicy`). The intent is that a first-timer who
|
|
15
|
+
* just adds a `vuln-gate` step gets a sensible, non-noisy gate that blocks the
|
|
16
|
+
* genuinely actionable (critical + fixable) and reports the rest.
|
|
17
|
+
*/
|
|
18
|
+
import type { Capability } from "../capability.js";
|
|
19
|
+
import type { SbomDocument } from "./sbom-generator.js";
|
|
20
|
+
import { type Severity, type VulnFinding, type VulnScanner } from "./vuln-scan.js";
|
|
21
|
+
import { type SuppressedFinding } from "./vex.js";
|
|
22
|
+
import { type LicensePolicy, type LicenseViolation } from "./license-policy.js";
|
|
23
|
+
/** The gate's policy. Defaults (per `resolveVulnPolicy`, ../../config.ts) are beginner-safe: fail critical+fixable, warn high, license report-only. */
|
|
24
|
+
export interface VulnPolicy {
|
|
25
|
+
/** Minimum severity that FAILS the gate. Default `"critical"`. */
|
|
26
|
+
failSeverity: Severity;
|
|
27
|
+
/** When true (default), only *fixable* findings at/above `failSeverity` fail the gate — an unfixable finding can't be actioned by upgrading, so it warns instead of blocking. */
|
|
28
|
+
fixableOnly: boolean;
|
|
29
|
+
/** Minimum severity reported as a warning (below `failSeverity`). Default `"high"`. */
|
|
30
|
+
warnSeverity: Severity;
|
|
31
|
+
/** License allow/deny policy. Evaluated always; only *blocks* when `failOnLicense` is true. */
|
|
32
|
+
license?: LicensePolicy;
|
|
33
|
+
/** Block the deploy on a license violation. Default `false` (report-only) — license posture is context-dependent. */
|
|
34
|
+
failOnLicense: boolean;
|
|
35
|
+
/** Block on an `unknown`-severity finding (a scanner that didn't report a severity chant could map). Default `false` — but such a finding is ALWAYS at least warned, never silently dropped, regardless of this flag. Set true for a strict shop that won't ship an unclassifiable finding. */
|
|
36
|
+
failOnUnknownSeverity: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** Beginner-safe defaults, also encoded in `resolveVulnPolicy` (../../config.ts). */
|
|
39
|
+
export declare const DEFAULT_VULN_POLICY: VulnPolicy;
|
|
40
|
+
export interface VulnGateInput {
|
|
41
|
+
/** The artifact's SBOM. Scanned in-place unless `findings` is supplied. */
|
|
42
|
+
sbom: SbomDocument;
|
|
43
|
+
/** Pre-scanned findings (e.g. from a prior `scan-vulnerabilities` step). If omitted, the gate scans `sbom` itself via the injected scanner. */
|
|
44
|
+
findings?: VulnFinding[];
|
|
45
|
+
/** VEX documents (OpenVEX or CycloneDX-embedded), as serialized JSON, applied to suppress findings. */
|
|
46
|
+
vex?: string[];
|
|
47
|
+
/** Policy override; merged over `DEFAULT_VULN_POLICY`. */
|
|
48
|
+
policy?: Partial<VulnPolicy>;
|
|
49
|
+
/** Artifact digest, for reporting. */
|
|
50
|
+
digest?: string;
|
|
51
|
+
}
|
|
52
|
+
/** A finding that fails the gate, with why. */
|
|
53
|
+
export interface BlockingFinding {
|
|
54
|
+
finding: VulnFinding;
|
|
55
|
+
reason: "severity-threshold" | "unknown-severity";
|
|
56
|
+
}
|
|
57
|
+
export interface VulnGateOutput {
|
|
58
|
+
/** Always `true` when returned — a violation throws instead (mirrors ./verify.ts's `verified`). */
|
|
59
|
+
passed: true;
|
|
60
|
+
/** Findings at/above `warnSeverity` that did not reach the fail bar. */
|
|
61
|
+
warnings: VulnFinding[];
|
|
62
|
+
/** Findings suppressed by VEX, with justification (never silently dropped). */
|
|
63
|
+
suppressed: SuppressedFinding[];
|
|
64
|
+
/** License findings — reported even when `failOnLicense` is false. */
|
|
65
|
+
licenseFindings: LicenseViolation[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Thrown when the gate blocks a deploy — carries the blocking findings and any
|
|
69
|
+
* blocking license violations so a reviewer sees exactly what to fix (or VEX).
|
|
70
|
+
* Distinct from a scanner-not-installed error (`VulnScannerNotImplementedError`/
|
|
71
|
+
* `ToolNotAvailableError`) so a caller can tell "policy said no" from "no
|
|
72
|
+
* scanner."
|
|
73
|
+
*/
|
|
74
|
+
export declare class VulnGateFailedError extends Error {
|
|
75
|
+
readonly blocking: BlockingFinding[];
|
|
76
|
+
readonly blockingLicenses: LicenseViolation[];
|
|
77
|
+
constructor(blocking: BlockingFinding[], blockingLicenses: LicenseViolation[]);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build the `vuln-gate` capability. Scans `sbom` (or uses supplied `findings`),
|
|
81
|
+
* applies VEX, evaluates the license policy, and classifies every gating
|
|
82
|
+
* finding: it BLOCKS (throws `VulnGateFailedError`) any finding at/above
|
|
83
|
+
* `failSeverity` that satisfies `fixableOnly`, plus license violations when
|
|
84
|
+
* `failOnLicense`; everything at/above `warnSeverity` below the fail bar is a
|
|
85
|
+
* warning. On a clean pass it returns the warnings/suppressed/license report
|
|
86
|
+
* for logging.
|
|
87
|
+
*/
|
|
88
|
+
export declare function createVulnGateCapability(scanner?: VulnScanner): Capability<VulnGateInput, VulnGateOutput>;
|
|
89
|
+
/** Default `vuln-gate` capability (inject a real/mock scanner, or supply `findings`). */
|
|
90
|
+
export declare const vulnGateCapability: Capability<VulnGateInput, VulnGateOutput>;
|
|
91
|
+
//# sourceMappingURL=vuln-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuln-gate.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/vuln-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAA8B,KAAK,iBAAiB,EAAqB,MAAM,OAAO,CAAC;AAC9F,OAAO,EAAyB,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpG,uJAAuJ;AACvJ,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,YAAY,EAAE,QAAQ,CAAC;IACvB,iLAAiL;IACjL,WAAW,EAAE,OAAO,CAAC;IACrB,uFAAuF;IACvF,YAAY,EAAE,QAAQ,CAAC;IACvB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,qHAAqH;IACrH,aAAa,EAAE,OAAO,CAAC;IACvB,+RAA+R;IAC/R,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,EAAE,UAMjC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,IAAI,EAAE,YAAY,CAAC;IACnB,+IAA+I;IAC/I,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,uGAAuG;IACvG,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,oBAAoB,GAAG,kBAAkB,CAAC;CACnD;AAED,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,MAAM,EAAE,IAAI,CAAC;IACb,wEAAwE;IACxE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,+EAA+E;IAC/E,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,sEAAsE;IACtE,eAAe,EAAE,gBAAgB,EAAE,CAAC;CACrC;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,QAAQ,EAAE,eAAe,EAAE;aAC3B,gBAAgB,EAAE,gBAAgB,EAAE;gBADpC,QAAQ,EAAE,eAAe,EAAE,EAC3B,gBAAgB,EAAE,gBAAgB,EAAE;CAUvD;AASD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,WAAkC,GAC1C,UAAU,CAAC,aAAa,EAAE,cAAc,CAAC,CAyC3C;AAED,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,EAAE,UAAU,CAAC,aAAa,EAAE,cAAc,CAA8B,CAAC"}
|