fix: 隔离 Sub2Rank PaC 执行身份

This commit is contained in:
Codex
2026-07-13 08:12:47 +02:00
parent 18ac5d33ba
commit f99aefafbf
12 changed files with 201 additions and 11 deletions
@@ -159,6 +159,7 @@ interface PacConsumer {
required: true;
markerValue: string;
executionServiceAccountName: string;
manageExecutionServiceAccount: boolean;
gitOps: { repoUrl: string; targetRevision: string };
} | null;
repositoryRef: string;
@@ -271,6 +272,9 @@ export async function runPlatformInfraPipelinesAsCodeCommand(config: UniDeskConf
namespace: consumer.namespace,
pipeline: consumer.pipeline,
pipelineRunPrefix: consumer.pipelineRunPrefix,
argoNamespace: consumer.argoNamespace,
argoApplication: consumer.argoApplication,
argoBootstrap: consumer.argoBootstrap,
deliveryProvenance: consumer.deliveryProvenance === null ? null : {
markerAnnotation: pac.deliveryProvenance.markerAnnotation,
markerValue: consumer.deliveryProvenance.markerValue,
@@ -528,6 +532,9 @@ function parseConsumerDeliveryProvenance(value: Record<string, unknown>, path: s
required: true,
markerValue: y.stringField(value, "markerValue", path),
executionServiceAccountName: y.kubernetesNameField(value, "executionServiceAccountName", path),
manageExecutionServiceAccount: value.manageExecutionServiceAccount === undefined
? false
: y.booleanField(value, "manageExecutionServiceAccount", path),
gitOps: {
repoUrl: urlField(gitOps, "repoUrl", `${path}.gitOps`),
targetRevision: y.stringField(gitOps, "targetRevision", `${path}.gitOps`),
@@ -756,6 +763,7 @@ function validateConfig(config: PacConfig): void {
}
const consumerIds = new Set<string>();
const markerValues = new Set<string>();
const reservedServiceAccounts = new Set<string>();
for (const consumer of config.consumers) {
if (consumerIds.has(consumer.id)) throw new Error(`${configLabel}.consumers id must be unique: ${consumer.id}`);
consumerIds.add(consumer.id);
@@ -765,6 +773,14 @@ function validateConfig(config: PacConfig): void {
if (consumer.sourceArtifact === null) throw new Error(`${configLabel}.consumers.${consumer.id}.deliveryProvenance requires sourceArtifact ownership`);
if (markerValues.has(consumer.deliveryProvenance.markerValue)) throw new Error(`${configLabel}.consumers deliveryProvenance.markerValue must be unique: ${consumer.deliveryProvenance.markerValue}`);
markerValues.add(consumer.deliveryProvenance.markerValue);
if (consumer.deliveryProvenance.executionServiceAccountName === "default") {
throw new Error(`${configLabel}.consumers.${consumer.id}.deliveryProvenance.executionServiceAccountName must not reserve the shared default ServiceAccount`);
}
const serviceAccountKey = `${consumer.node.toLowerCase()}\u0000${consumer.deliveryProvenance.executionServiceAccountName}`;
if (reservedServiceAccounts.has(serviceAccountKey)) {
throw new Error(`${configLabel}.consumers deliveryProvenance.executionServiceAccountName must be unique per target: ${consumer.deliveryProvenance.executionServiceAccountName}`);
}
reservedServiceAccounts.add(serviceAccountKey);
if (repository.params.service_account !== consumer.deliveryProvenance.executionServiceAccountName) {
throw new Error(`${configLabel}.consumers.${consumer.id}.deliveryProvenance.executionServiceAccountName must match repository params.service_account`);
}
@@ -1229,6 +1245,7 @@ function remoteScript(action: "apply" | "status" | "history" | "debug-step", pac
UNIDESK_PAC_DELIVERY_PROVENANCE_REQUIRED: consumer.deliveryProvenance?.required === true ? "1" : "0",
UNIDESK_PAC_CONSUMER_RBAC_MANIFEST_B64: Buffer.from(renderPacConsumerRbacDesiredFragment(target.id), "utf8").toString("base64"),
UNIDESK_PAC_CONSUMER_RBAC_CONFIG_SHA256: rbacIdentity.configSha256,
UNIDESK_PAC_MANAGED_EXECUTION_SERVICE_ACCOUNTS_JSON: JSON.stringify(rbacIdentity.executionServiceAccounts),
UNIDESK_PAC_ADMISSION_POLICY_NAME: admissionIdentity.policyName,
UNIDESK_PAC_ADMISSION_BINDING_NAME: admissionIdentity.bindingName,
UNIDESK_PAC_ADMISSION_VERSION: admissionIdentity.version,
@@ -1272,6 +1289,7 @@ function historyConsumerConfig(pac: PacConfig, consumer: PacConsumer): Record<st
bindingName: admissionIdentity.bindingName,
configSha256: admissionIdentity.configSha256,
rbacConfigSha256: rbacIdentity.configSha256,
managedExecutionServiceAccounts: rbacIdentity.executionServiceAccounts,
markerAnnotation: pac.deliveryProvenance.markerAnnotation,
markerValue: consumer.deliveryProvenance.markerValue,
executionServiceAccountName: consumer.deliveryProvenance.executionServiceAccountName,