@mcpg-dev/pulumi-policy

中文文档
0.1.0-beta.45发布于 2026/11/02Apache-2.0TypeScriptCommonJS构建来源已验证

Pulumi CrossGuard policy pack mirroring MCPG operator admission rules.

原始使用文档
文档目录7 节
  1. Quick start
  2. Rules
  3. Validator library
  4. Configuration
  5. Build and test
  6. Licence
  7. See also

@mcpg/pulumi-policy

A Pulumi CrossGuard policy pack that enforces the MCPG Kubernetes operator's admission rules at pulumi preview, before anything reaches a cluster. It inspects the mcpg.dev custom resources a program declares — gateways, plugins, plugin sets, revocation lists, clusters, routes, tenants and plugin mirrors — and reports the violations the operator's admission webhook would return, locally and with no API-server round trip.

Quick start

The pack is referenced at preview/update time rather than imported into your program:

npm i --save-dev @mcpg/pulumi-policy
pulumi preview --policy-pack node_modules/@mcpg/pulumi-policy

A violation is printed as [<rule-id>] <message> — for example [gateway.workloadIdentity.oneOf] workloadIdentity must be exactly one of aws|gcp|azure|spiffe. The rule id is stable, and is the same identifier the MCPG Terraform provider's plan-time validators emit.

main points at bin/index.js, so a source checkout has to be compiled before Pulumi can load it:

npm install && npm run build   # tsc → bin/

Rules

KindWhat it checks
MCPGGatewayspec.image present; replicas ≥ 1 when set; at most one of workloadIdentity.{aws,gcp,azure,spiffe}; a present ingress block carries a non-empty ingressClassName, at least one host, and non-empty paths per host.
MCPGPluginpluginId non-empty and reverse-DNS; version non-empty; pluginClass is a known plugin class; oci.image carries a registry component and a tag or digest; the artifact is digest-pinned or carries a cosign identity; trust.signingKeyRef.secretName present (Ed25519 signing is the mandatory baseline); a cosign block has a non-empty, anchored certificateIdentityRegexp and an oidcIssuer; an SLSA block sets configMapName, sourceUri and sourceTag.
MCPGPluginSetentries non-empty; each entry has a reverse-DNS id and a pluginRef.name; ids unique; capabilityGrants keys name a declared entry and grant a non-empty capability list.
MCPGRevocationListversion == 1; every artifactSha256 is 64 hex characters; every revocation carries a reason; no duplicate hashes.
MCPGClusterthe single_node backend takes no config; every other backend requires one; a plaintext coordinator address (redis://, or NATS with tls.require_tls: false) is rejected unless config.allow_insecure_transport: true; credentialRefs entries carry name + secretName and unique names.
MCPGRoutegatewayRef.name non-empty; match.tools lists at least one tool; tool ids non-empty and unique; no empty entry in identityChain / policyChain / auditChain.
MCPGTenantnamespaces non-empty, with entries non-empty and unique; each allowedPlugins entry sets name or registryPrefix; quota fields are non-negative; identityAttribute.key non-empty when that block is set.
MCPGPluginMirrorendpoint.service.{namespace,name,port} set; upstream.registry present and shaped like a registry host; upstream.namespace present; auth.secretRef.secretName present when auth is set.

Two behaviours exist specifically so the preview verdict matches the cluster's:

  • A certificateIdentityRegexp using lookahead, lookbehind or a back-reference is rejected even though JavaScript would compile it, because the operator compiles the pattern with an RE2-style engine that will not.
  • SHA-256 hashes are accepted in either case, and duplicate detection is case-insensitive, matching the operator's lowercase-then-deduplicate behaviour.

Cross-resource and client-backed admission checks are deliberately not mirrored: the per-tenant replica cap and plugin allowlist need cluster state, and image.tag is filled in by the mutating webhook, so enforcing it at preview would false-reject a program that relies on defaulting. Treat the pack as a high-coverage local gate, not a guarantee of admission acceptance.

Validator library

The rules live in src/validators.ts as pure functions with no Pulumi runtime dependency, which is what lets the same logic back both the policy pack and a cross-tool contract test:

  • validateByType(type, spec) — dispatch by Pulumi type token.
  • validateGatewaySpec, validatePluginSpec, validatePluginSetSpec, validateRevocationListSpec, validateClusterSpec, validateRouteSpec, validateTenantSpec, validatePluginMirrorSpec — one per kind, each returning Finding[] ({ rule, message }); an empty array means accept.
  • isSha256Hex, isAnchoredRegexp, countWorkloadIdentities, findDuplicates — the shared predicates.

The MCPG Terraform provider ships a Go port of these same functions, and a shared fixture corpus asserts both sides return identical verdicts, so a rule relaxed on one side fails the build.

Configuration

The pack takes no configuration. It registers one policy, mcpg-admission-mirror, declared at enforcementLevel: "mandatory", so a violation blocks the update instead of emitting an advisory.

Resources are dispatched on the Pulumi type-token suffix (…:MCPGGateway, …:MCPGPlugin, …) and read from props.spec. Any resource whose token matches no rule set yields no findings, so the pack is safe to apply across a whole stack.

Build and test

npm run build                       # tsc → bin/
node --test bin/validators.test.js  # unit tests over the pure validators

Inside the MCPG workspace, from the repo root:

pnpm --filter ./iac/pulumi/policy exec tsc -b --noEmit   # tsc --noEmit
pnpm --filter ./iac/pulumi/policy test        # builds, then runs the validator tests

Licence

Apache-2.0.

See also

版本与发布记录

@mcpg-dev/pulumi-policy 共发布 30 个版本,首次发布于 2026/08/13;过去 12 个月发布了 30 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.0-beta.45latest2026/11/021 天前
0.1.0-beta.442026/11/012 天前
0.1.0-beta.432026/10/303 天前
0.1.0-beta.422026/10/2410 天前
0.1.0-beta.412026/10/1915 天前
0.1.0-beta.402026/10/1816 天前

其他发布通道:canary → 0.1.0-canary.732,beta → 0.1.0-beta.13。

关于 @mcpg-dev/pulumi-policy 的常见问题

@mcpg-dev/pulumi-policy 是什么?

Pulumi CrossGuard策略包镜像MCPG运营商准入规则。

如何安装 @mcpg-dev/pulumi-policy?

在项目目录运行 npm install @mcpg-dev/pulumi-policy,或使用 pnpm add / yarn add / bun add。

@mcpg-dev/pulumi-policy 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@mcpg-dev/pulumi-policy 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@mcpg-dev/pulumi-policy 可以商用吗?

@mcpg-dev/pulumi-policy 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@mcpg-dev/pulumi-policy 还在维护吗?

最新版本 0.1.0-beta.45 发布于 2026/11/02(1 天前);至今共发布 30 个版本,其中过去 12 个月发布了 30 个;首次发布于 2026/08/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。