/** Authenticated Plugin Package management transport boundary. */ import type { ApprovalRequestRecord, DecideApprovalRequestResult, } from '@qinglong/runtime-core/approved-action'; import { pluginPackageInstallRecoveryAction, type PluginPackageInstallActionInput, type PluginPackageInstallInventoryItem, } from '@qinglong/runtime-core/plugin-package-install'; import type { InspectPluginPackageInstallResult, ProposePluginPackageInstallResult, } from '@qinglong/runtime-core/plugin-package-management'; import type { PluginPackageInstallProposal } from '@qinglong/runtime-core/plugin-package-proposal'; import type { PluginPackageLifecyclePlan } from '@qinglong/runtime-core/plugin-package-lifecycle-plan'; import type { PluginPackageSecretBindingAssignment } from '@qinglong/runtime-core/plugin-package-secret-binding'; import type { PluginPackageSecretBindingApprovalPlan } from '@qinglong/runtime-core/plugin-package-secret-binding-approval-plan'; import type { PluginPackageSecretBindingTransitionApprovalPlan } from '@qinglong/runtime-core/plugin-package-secret-binding-transition-approval-plan'; import { normalizeSecurityPrincipal, type SecurityPrincipal, } from '@qinglong/runtime-core/security'; import type { ClusterPluginPackageManagementService } from './pluginPackageManagement'; import type { ClusterPluginPackageLifecycleManagementService } from '../lifecycle/pluginPackageLifecycleManagement'; import type { ClusterPluginPackagePublisherTrustManagementService, InspectClusterPluginPackagePublisherRevocationResult, InspectClusterPluginPackagePublisherTrustTransitionResult, } from '../publisher/pluginPackagePublisherTrustManagement'; import type { ClusterPluginPackageSecretBindingManagementService } from '../secret-binding/pluginPackageSecretBindingManagement'; import type { ClusterPluginPackageSecretBindingTransitionManagementService } from '../secret-binding/pluginPackageSecretBindingTransitionManagement'; const STRONG_CLUSTER_ASSURANCES = new Set(['multi_factor', 'hardware']); export interface ClusterPluginPackageManagementAuthentication { authenticate(): Promise | null>; } export interface ProposeClusterPluginPackageCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.propose'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly proposalAuditEventId: string; readonly approvalAuditEventId: string; readonly actionInput: PluginPackageInstallActionInput; }; } export interface DecideClusterPluginPackageCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.decide'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly expectedVersion: number; readonly decisionId: string; readonly auditEventId: string; readonly decision: 'approved' | 'rejected'; readonly reasonCode: string; }; } export interface InspectClusterPluginPackageCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.inspect'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly inspectionId: string; }; } export interface ProposeClusterPluginPackageLifecycleCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.lifecycle.propose'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly approvalAuditEventId: string; }; } export interface DecideClusterPluginPackageLifecycleCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.lifecycle.decide'; readonly request: DecideClusterPluginPackageCommand['request']; } export interface InspectClusterPluginPackageLifecycleCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.lifecycle.inspect'; readonly request: InspectClusterPluginPackageCommand['request']; } export interface InspectClusterPluginPackageInstallationCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.installation.inspect'; readonly request: { readonly projectId: string; readonly packageName: string; readonly inspectionId: string; }; } export interface ListClusterPluginPackageInstallationsCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.installation.list'; readonly request: { readonly projectId: string; readonly limit: number; readonly after?: Readonly<{ packageName: string }>; readonly inspectionId: string; }; } export interface ProposeClusterPluginPackagePublisherRevocationCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-revocation.propose'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly proposalAuditEventId: string; readonly approvalAuditEventId: string; readonly publisher: string; readonly keyId: string; readonly authorizationMode: 'dual_control' | 'break_glass'; readonly reasonCode: | 'suspected_key_compromise' | 'confirmed_key_compromise'; }; } export interface DecideClusterPluginPackagePublisherRevocationCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-revocation.decide'; readonly request: DecideClusterPluginPackageCommand['request']; } export interface InspectClusterPluginPackagePublisherRevocationCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-revocation.inspect'; readonly request: InspectClusterPluginPackageCommand['request']; } export interface ProposeClusterPluginPackagePublisherTrustTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-trust-transition.propose'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly proposalAuditEventId: string; readonly approvalAuditEventId: string; readonly mode: 'overlap_add' | 'safe_retire'; readonly publisher: string; readonly keyId: string; }; } export interface DecideClusterPluginPackagePublisherTrustTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-trust-transition.decide'; readonly request: DecideClusterPluginPackageCommand['request']; } export interface InspectClusterPluginPackagePublisherTrustTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.publisher-trust-transition.inspect'; readonly request: InspectClusterPluginPackageCommand['request']; } export interface PlanClusterPluginPackageSecretBindingCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.plan'; readonly request: { readonly actionRef: string; readonly projectId: string; readonly packageName: string; readonly assignments: readonly Readonly[]; }; } export interface ProposeClusterPluginPackageSecretBindingCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.propose'; readonly request: { readonly actionRef: string; readonly approvalRequestId: string; readonly approvalAuditEventId: string; }; } export interface DecideClusterPluginPackageSecretBindingCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.decide'; readonly request: DecideClusterPluginPackageCommand['request']; } export interface InspectClusterPluginPackageSecretBindingCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.inspect'; readonly request: InspectClusterPluginPackageCommand['request']; } export interface PlanClusterPluginPackageSecretBindingTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.transition.plan'; readonly request: PlanClusterPluginPackageSecretBindingCommand['request']; } export interface ProposeClusterPluginPackageSecretBindingTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.transition.propose'; readonly request: ProposeClusterPluginPackageSecretBindingCommand['request']; } export interface DecideClusterPluginPackageSecretBindingTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.transition.decide'; readonly request: DecideClusterPluginPackageSecretBindingCommand['request']; } export interface InspectClusterPluginPackageSecretBindingTransitionCommand { readonly schemaVersion: 1; readonly operation: 'plugin-package.secret-binding.transition.inspect'; readonly request: InspectClusterPluginPackageSecretBindingCommand['request']; } export type ClusterPluginPackageManagementCommand = | ProposeClusterPluginPackageCommand | DecideClusterPluginPackageCommand | InspectClusterPluginPackageCommand | ProposeClusterPluginPackageLifecycleCommand | DecideClusterPluginPackageLifecycleCommand | InspectClusterPluginPackageLifecycleCommand | InspectClusterPluginPackageInstallationCommand | ListClusterPluginPackageInstallationsCommand | ProposeClusterPluginPackagePublisherRevocationCommand | DecideClusterPluginPackagePublisherRevocationCommand | InspectClusterPluginPackagePublisherRevocationCommand | ProposeClusterPluginPackagePublisherTrustTransitionCommand | DecideClusterPluginPackagePublisherTrustTransitionCommand | InspectClusterPluginPackagePublisherTrustTransitionCommand | PlanClusterPluginPackageSecretBindingCommand | ProposeClusterPluginPackageSecretBindingCommand | DecideClusterPluginPackageSecretBindingCommand | InspectClusterPluginPackageSecretBindingCommand | PlanClusterPluginPackageSecretBindingTransitionCommand | ProposeClusterPluginPackageSecretBindingTransitionCommand | DecideClusterPluginPackageSecretBindingTransitionCommand | InspectClusterPluginPackageSecretBindingTransitionCommand; export type ClusterPluginPackageManagementTransportResult = | Readonly<{ schemaVersion: 1; operation: 'plugin-package.propose'; proposalStatus: 'created' | 'existing'; approvalStatus: 'created' | 'existing'; proposal: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.inspect'; proposal: ReturnType | null; approval: ReturnType | null; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.installation.inspect'; installation: ReturnType | null; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.installation.list'; installations: readonly ReturnType[]; truncated: boolean; next: Readonly<{ packageName: string }> | null; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.lifecycle.propose'; approvalStatus: 'created' | 'existing'; plan: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.lifecycle.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.lifecycle.inspect'; plan: ReturnType | null; approval: ReturnType | null; stale: boolean; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-revocation.propose'; proposalStatus: 'created' | 'existing'; approvalStatus: 'created' | 'existing'; proposal: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-revocation.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-revocation.inspect'; proposal: ReturnType | null; approval: ReturnType | null; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-trust-transition.propose'; proposalStatus: 'created' | 'existing'; approvalStatus: 'created' | 'existing'; proposal: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-trust-transition.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.publisher-trust-transition.inspect'; proposal: ReturnType< typeof publisherTrustTransitionProposalSummary > | null; approval: ReturnType | null; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.plan'; status: 'created' | 'existing'; plan: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.propose'; approvalStatus: 'created' | 'existing'; plan: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.inspect'; plan: ReturnType | null; approval: ReturnType | null; stale: boolean; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.transition.plan'; status: 'created' | 'existing'; plan: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.transition.propose'; approvalStatus: 'created' | 'existing'; plan: ReturnType; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.transition.decide'; status: 'decided' | 'existing'; approval: ReturnType; }> | Readonly<{ schemaVersion: 1; operation: 'plugin-package.secret-binding.transition.inspect'; plan: ReturnType | null; approval: ReturnType | null; stale: boolean; }>; export interface ClusterPluginPackageManagementTransport { execute( command: unknown, authentication: ClusterPluginPackageManagementAuthentication, ): Promise>; } export interface ClusterPluginPackageManagementTransportOptions { readonly service: ClusterPluginPackageManagementService; readonly lifecycle?: ClusterPluginPackageLifecycleManagementService; readonly publisherTrust?: ClusterPluginPackagePublisherTrustManagementService; readonly secretBinding?: ClusterPluginPackageSecretBindingManagementService; readonly secretBindingTransition?: ClusterPluginPackageSecretBindingTransitionManagementService; readonly now?: () => number; } export class ClusterPluginPackageManagementTransportConfigurationError extends TypeError { readonly code = 'CLUSTER_PLUGIN_PACKAGE_TRANSPORT_CONFIGURATION_INVALID'; constructor(message: string) { super( `Cluster Plugin Package transport configuration is invalid: ${message}`, ); this.name = 'ClusterPluginPackageManagementTransportConfigurationError'; } } export class ClusterPluginPackageManagementTransportRequestError extends TypeError { readonly code = 'CLUSTER_PLUGIN_PACKAGE_TRANSPORT_REQUEST_INVALID'; constructor(message: string) { super(`Cluster Plugin Package transport request is invalid: ${message}`); this.name = 'ClusterPluginPackageManagementTransportRequestError'; } } export class ClusterPluginPackageManagementTransportAuthenticationError extends Error { readonly code = 'CLUSTER_PLUGIN_PACKAGE_TRANSPORT_AUTHENTICATION_REQUIRED'; constructor() { super('Cluster Plugin Package transport requires a strong User principal'); this.name = 'ClusterPluginPackageManagementTransportAuthenticationError'; } } export class ClusterPluginPackageManagementTransportUnavailableError extends Error { readonly code = 'CLUSTER_PLUGIN_PACKAGE_TRANSPORT_UNAVAILABLE'; constructor(readonly cause?: unknown) { super('Cluster Plugin Package transport is unavailable'); this.name = 'ClusterPluginPackageManagementTransportUnavailableError'; } } function exactObject( value: unknown, expectedKeys: readonly string[], label: string, ): asserts value is Record { if (!value || typeof value !== 'object' || Array.isArray(value)) { throw new ClusterPluginPackageManagementTransportRequestError( `${label} must be an object`, ); } const actual = Object.keys(value).sort(); const expected = [...expectedKeys].sort(); if ( actual.length !== expected.length || actual.some((key, index) => key !== expected[index]) ) { throw new ClusterPluginPackageManagementTransportRequestError( `${label} shape is invalid`, ); } } export function normalizeClusterPluginPackageManagementCommand( value: unknown, ): Readonly { exactObject(value, ['schemaVersion', 'operation', 'request'], 'command'); if (value.schemaVersion !== 1) { throw new ClusterPluginPackageManagementTransportRequestError( 'schemaVersion is invalid', ); } switch (value.operation) { case 'plugin-package.propose': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'proposalAuditEventId', 'approvalAuditEventId', 'actionInput', ], 'proposal request', ); break; case 'plugin-package.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'decision request', ); break; case 'plugin-package.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'inspection request', ); break; case 'plugin-package.lifecycle.propose': exactObject( value.request, ['actionRef', 'approvalAuditEventId', 'approvalRequestId'], 'lifecycle proposal request', ); break; case 'plugin-package.lifecycle.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'lifecycle decision request', ); break; case 'plugin-package.lifecycle.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'lifecycle inspection request', ); break; case 'plugin-package.installation.inspect': exactObject( value.request, ['inspectionId', 'packageName', 'projectId'], 'installation inspection request', ); break; case 'plugin-package.installation.list': { const hasAfter = !!value.request && typeof value.request === 'object' && !Array.isArray(value.request) && Object.hasOwn(value.request, 'after'); exactObject( value.request, ['inspectionId', 'limit', 'projectId', ...(hasAfter ? ['after'] : [])], 'installation list request', ); if (hasAfter) { exactObject( value.request.after, ['packageName'], 'installation list cursor', ); } break; } case 'plugin-package.publisher-revocation.propose': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'proposalAuditEventId', 'approvalAuditEventId', 'publisher', 'keyId', 'authorizationMode', 'reasonCode', ], 'publisher revocation proposal request', ); break; case 'plugin-package.publisher-revocation.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'publisher revocation decision request', ); break; case 'plugin-package.publisher-revocation.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'publisher revocation inspection request', ); break; case 'plugin-package.publisher-trust-transition.propose': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'proposalAuditEventId', 'approvalAuditEventId', 'mode', 'publisher', 'keyId', ], 'publisher trust transition proposal request', ); break; case 'plugin-package.publisher-trust-transition.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'publisher trust transition decision request', ); break; case 'plugin-package.publisher-trust-transition.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'publisher trust transition inspection request', ); break; case 'plugin-package.secret-binding.plan': exactObject( value.request, ['actionRef', 'assignments', 'packageName', 'projectId'], 'Secret binding plan request', ); if (!Array.isArray(value.request.assignments)) { throw new ClusterPluginPackageManagementTransportRequestError( 'Secret binding assignments are invalid', ); } for (const assignment of value.request.assignments) { exactObject(assignment, ['name', 'secretRef'], 'Secret binding assignment'); } break; case 'plugin-package.secret-binding.propose': exactObject( value.request, ['actionRef', 'approvalAuditEventId', 'approvalRequestId'], 'Secret binding proposal request', ); break; case 'plugin-package.secret-binding.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'Secret binding decision request', ); break; case 'plugin-package.secret-binding.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'Secret binding inspection request', ); break; case 'plugin-package.secret-binding.transition.plan': exactObject( value.request, ['actionRef', 'assignments', 'packageName', 'projectId'], 'Secret transition plan request', ); if (!Array.isArray(value.request.assignments)) { throw new ClusterPluginPackageManagementTransportRequestError( 'Secret transition assignments are invalid', ); } for (const assignment of value.request.assignments) { exactObject( assignment, ['name', 'secretRef'], 'Secret transition assignment', ); } break; case 'plugin-package.secret-binding.transition.propose': exactObject( value.request, ['actionRef', 'approvalAuditEventId', 'approvalRequestId'], 'Secret transition proposal request', ); break; case 'plugin-package.secret-binding.transition.decide': exactObject( value.request, [ 'actionRef', 'approvalRequestId', 'expectedVersion', 'decisionId', 'auditEventId', 'decision', 'reasonCode', ], 'Secret transition decision request', ); break; case 'plugin-package.secret-binding.transition.inspect': exactObject( value.request, ['actionRef', 'approvalRequestId', 'inspectionId'], 'Secret transition inspection request', ); break; default: throw new ClusterPluginPackageManagementTransportRequestError( 'operation is not publicly available', ); } return Object.freeze( value as unknown as ClusterPluginPackageManagementCommand, ); } function proposalSummary(proposal: Readonly) { return Object.freeze({ actionRef: proposal.actionRef, projectId: proposal.projectId, packageName: proposal.actionInput.manifest.metadata.name, packageVersion: proposal.actionInput.manifest.metadata.version, operation: proposal.actionInput.plan.operation, sourceKind: proposal.actionInput.source.kind, architecture: proposal.actionInput.architecture, deploymentProfile: proposal.actionInput.deploymentProfile, targetGeneration: proposal.actionInput.targetGeneration, actionDigest: proposal.actionDigest, previewDigest: proposal.previewDigest, proposalDigest: proposal.proposalDigest, createdAtMs: proposal.createdAtMs, }); } function installationSummary( item: Readonly, ) { const { record, quarantine } = item; return Object.freeze({ installationId: record.installationId, projectId: record.projectId, packageName: record.packageName, packageVersion: record.packageVersion, operation: record.operation, state: record.state, targetGeneration: record.targetGeneration, activeLockDigest: record.activeLockDigest, previousActiveLockDigest: record.previousActiveLockDigest, recoveryAction: pluginPackageInstallRecoveryAction(record), availability: quarantine ? ('quarantined' as const) : record.state === 'active' ? ('active' as const) : ('not_active' as const), quarantineReason: quarantine?.reasonCode ?? null, quarantineAuthorizationMode: quarantine?.authorizationMode ?? null, quarantineEventDigest: quarantine?.eventDigest ?? null, quarantinedAtMs: quarantine?.occurredAtMs ?? null, withdrawalStatus: quarantine?.capabilityStatus ?? null, withdrawalReceiptDigest: quarantine?.receiptDigest ?? null, withdrawalCommittedAtMs: quarantine?.committedAtMs ?? null, failureReason: record.failure?.reason ?? null, failedFrom: record.failure?.failedFrom ?? null, failedAtMs: record.failure?.failedAtMs ?? null, version: record.version, createdAtMs: record.createdAtMs, updatedAtMs: record.updatedAtMs, recordDigest: record.recordDigest, }); } function approvalSummary(approval: Readonly) { return Object.freeze({ id: approval.id, projectId: approval.projectId, version: approval.version, state: approval.state, risk: approval.risk, decisionMode: approval.decisionMode, requestedAtMs: approval.requestedAtMs, expiresAtMs: approval.expiresAtMs, decision: approval.decision, decisionReasonCode: approval.decisionReasonCode, decidedAtMs: approval.decidedAtMs, dispatchId: approval.dispatchId, consumedAtMs: approval.consumedAtMs, actionDigest: approval.action.actionDigest, previewDigest: approval.action.previewDigest, }); } function lifecyclePlanSummary( plan: Readonly, ) { return Object.freeze({ actionRef: plan.actionRef, planDigest: plan.planDigest, plannedAtMs: plan.plannedAtMs, expiresAtMs: plan.expiresAtMs, action: plan.impact.action, projectId: plan.impact.target.projectId, packageName: plan.impact.target.packageName, installationId: plan.impact.target.installationId, lockDigest: plan.impact.target.lockDigest, installVersion: plan.impact.target.installVersion, installRecordDigest: plan.impact.target.installRecordDigest, expected: plan.impact.expected, generationDigest: plan.impact.generationDigest, materializedRevisionDigest: plan.impact.materializedRevisionDigest, currentToolSnapshotDigest: plan.impact.currentToolSnapshotDigest, taskIds: plan.impact.taskIds, resourceCounts: plan.impact.resourceCounts, referenceGraphDigest: plan.impact.referenceGraphDigest, blockingReferences: plan.impact.blockingReferences, impactDigest: plan.impact.impactDigest, }); } function secretBindingPlanSummary( plan: Readonly, ) { return Object.freeze({ actionRef: plan.actionRef, projectId: plan.bindingPlan.target.projectId, packageName: plan.bindingPlan.target.packageName, installationId: plan.bindingPlan.target.installationId, generation: plan.bindingPlan.target.generation, generationDigest: plan.bindingPlan.target.generationDigest, lockDigest: plan.bindingPlan.target.lockDigest, manifestDigest: plan.bindingPlan.target.manifestDigest, entries: plan.bindingPlan.entries, plannedAtMs: plan.bindingPlan.plannedAtMs, expiresAtMs: plan.expiresAtMs, planDigest: plan.bindingPlan.planDigest, approvalPlanDigest: plan.approvalPlanDigest, }); } function secretBindingTransitionPlanSummary( plan: Readonly, ) { const transition = plan.transitionPlan; return Object.freeze({ actionRef: plan.actionRef, approvalPlanDigest: plan.approvalPlanDigest, plannedAtMs: plan.plannedAtMs, expiresAtMs: plan.expiresAtMs, kind: transition.kind, transitionDigest: transition.transitionDigest, projectId: transition.nextTarget.projectId, packageName: transition.nextTarget.packageName, previousInstallationId: transition.previousTarget.installationId, previousGeneration: transition.previousTarget.generation, previousGenerationDigest: transition.previousTarget.generationDigest, previousActiveLockDigest: transition.previousActiveLockDigest, previousAttemptGeneration: transition.previousAttemptGeneration, nextInstallationId: transition.nextTarget.installationId, nextGeneration: transition.nextTarget.generation, nextGenerationDigest: transition.nextTarget.generationDigest, nextLockDigest: transition.nextTarget.lockDigest, nextManifestDigest: transition.nextTarget.manifestDigest, changes: transition.changes, }); } function publisherRevocationProposalSummary( proposal: NonNullable< InspectClusterPluginPackagePublisherRevocationResult['proposal'] >, ) { return Object.freeze({ actionRef: proposal.actionRef, projectId: proposal.projectId, trustAuthorityId: proposal.actionInput.trustAuthorityId, trustGeneration: proposal.actionInput.trustGeneration, publisher: proposal.actionInput.publisher, keyId: proposal.actionInput.keyId, previousTrustDigest: proposal.actionInput.previousTrustDigest, currentTrustDigest: proposal.actionInput.currentTrustDigest, authorizationMode: proposal.actionInput.authorizationMode, reasonCode: proposal.actionInput.reasonCode, actionDigest: proposal.actionDigest, previewDigest: proposal.previewDigest, proposalDigest: proposal.proposalDigest, createdAtMs: proposal.createdAtMs, }); } function publisherTrustTransitionProposalSummary( proposal: NonNullable< InspectClusterPluginPackagePublisherTrustTransitionResult['proposal'] >, ) { return Object.freeze({ actionRef: proposal.actionRef, projectId: proposal.projectId, trustAuthorityId: proposal.actionInput.trustAuthorityId, trustGeneration: proposal.actionInput.trustGeneration, mode: proposal.actionInput.mode, publisher: proposal.actionInput.publisher, keyId: proposal.actionInput.keyId, previousTrustDigest: proposal.actionInput.previousTrustDigest, currentTrustDigest: proposal.actionInput.currentTrustDigest, actionDigest: proposal.actionDigest, previewDigest: proposal.previewDigest, proposalDigest: proposal.proposalDigest, createdAtMs: proposal.createdAtMs, }); } function exactDecisionReplay( current: Readonly<{ approvalRequest: Readonly | null; }>, command: Readonly< | DecideClusterPluginPackageCommand | DecideClusterPluginPackageLifecycleCommand | DecideClusterPluginPackagePublisherRevocationCommand | DecideClusterPluginPackagePublisherTrustTransitionCommand | DecideClusterPluginPackageSecretBindingCommand | DecideClusterPluginPackageSecretBindingTransitionCommand >, principal: Readonly, ): Readonly | null { const approval = current.approvalRequest; if ( approval?.action.actionRef !== command.request.actionRef || approval.decisionId !== command.request.decisionId || approval.decision !== command.request.decision || approval.decisionReasonCode !== command.request.reasonCode || approval.decidedBy?.type !== principal.subject.type || approval.decidedBy.id !== principal.subject.id ) { return null; } return Object.freeze({ status: 'existing' as const, request: approval, }); } export function createClusterPluginPackageManagementTransport( options: ClusterPluginPackageManagementTransportOptions, ): Readonly { if ( !options || typeof options !== 'object' || Array.isArray(options) || Object.keys(options).some( (key) => key !== 'service' && key !== 'lifecycle' && key !== 'publisherTrust' && key !== 'secretBinding' && key !== 'secretBindingTransition' && key !== 'now', ) || !options.service || typeof options.service.propose !== 'function' || typeof options.service.decide !== 'function' || typeof options.service.inspect !== 'function' || typeof options.service.inspectAuthorized !== 'function' || typeof options.service.inspectInstallationAuthorized !== 'function' || typeof options.service.listInstallationsAuthorized !== 'function' || (options.lifecycle !== undefined && (!options.lifecycle || typeof options.lifecycle.propose !== 'function' || typeof options.lifecycle.decide !== 'function' || typeof options.lifecycle.inspectAuthorized !== 'function')) || (options.publisherTrust !== undefined && (!options.publisherTrust || typeof options.publisherTrust.propose !== 'function' || typeof options.publisherTrust.inspect !== 'function' || typeof options.publisherTrust.inspectAuthorized !== 'function')) || (options.secretBinding !== undefined && (!options.secretBinding || typeof options.secretBinding.plan !== 'function' || typeof options.secretBinding.propose !== 'function' || typeof options.secretBinding.decide !== 'function' || typeof options.secretBinding.inspectAuthorized !== 'function')) || (options.secretBindingTransition !== undefined && (!options.secretBindingTransition || typeof options.secretBindingTransition.plan !== 'function' || typeof options.secretBindingTransition.propose !== 'function' || typeof options.secretBindingTransition.decide !== 'function' || typeof options.secretBindingTransition.inspectAuthorized !== 'function')) || (options.now !== undefined && typeof options.now !== 'function') ) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'options are invalid', ); } const now = options.now ?? Date.now; return Object.freeze({ async execute( commandValue: unknown, authentication: ClusterPluginPackageManagementAuthentication, ): Promise> { const command = normalizeClusterPluginPackageManagementCommand(commandValue); if ( !authentication || typeof authentication !== 'object' || Array.isArray(authentication) || Object.keys(authentication).some((key) => key !== 'authenticate') || typeof authentication.authenticate !== 'function' ) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'authentication authority is invalid', ); } let candidate: Readonly | null; try { candidate = await authentication.authenticate(); } catch (error) { throw new ClusterPluginPackageManagementTransportUnavailableError( error, ); } const observedAtMs = now(); if (!Number.isSafeInteger(observedAtMs) || observedAtMs < 0) { throw new ClusterPluginPackageManagementTransportUnavailableError(); } let principal: Readonly; try { principal = normalizeSecurityPrincipal( candidate as SecurityPrincipal, observedAtMs, ); } catch { throw new ClusterPluginPackageManagementTransportAuthenticationError(); } if ( principal.subject.type !== 'user' || !STRONG_CLUSTER_ASSURANCES.has(principal.assurance) ) { throw new ClusterPluginPackageManagementTransportAuthenticationError(); } switch (command.operation) { case 'plugin-package.propose': { const current = await options.service.inspect( command.request.actionRef, command.request.approvalRequestId, ); const result: Readonly = await options.service.propose({ ...command.request, requestedAtMs: current.approvalRequest?.requestedAtMs ?? current.proposal?.createdAtMs ?? observedAtMs, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposalStatus: result.proposalStatus, approvalStatus: result.approvalStatus, proposal: proposalSummary(result.proposal), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.decide': { const current = await options.service.inspect( command.request.actionRef, command.request.approvalRequestId, ); const replay = exactDecisionReplay(current, command, principal); const result = replay ?? (await options.service.decide({ approvalRequestId: command.request.approvalRequestId, expectedVersion: command.request.expectedVersion, decisionId: command.request.decisionId, auditEventId: command.request.auditEventId, decision: command.request.decision, reasonCode: command.request.reasonCode, decidedAtMs: observedAtMs, principal, })); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.inspect': { const result = await options.service.inspectAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposal: result.proposal ? proposalSummary(result.proposal) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, }); } case 'plugin-package.installation.inspect': { const record = await options.service.inspectInstallationAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, installation: record ? installationSummary(record) : null, }); } case 'plugin-package.installation.list': { const page = await options.service.listInstallationsAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, installations: Object.freeze(page.items.map(installationSummary)), truncated: page.truncated, next: page.next ?? null, }); } case 'plugin-package.lifecycle.propose': { if (!options.lifecycle) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'lifecycle management is not configured', ); } const result = await options.lifecycle.propose({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, approvalStatus: result.approvalStatus, plan: lifecyclePlanSummary(result.plan), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.lifecycle.decide': { if (!options.lifecycle) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'lifecycle management is not configured', ); } const result = await options.lifecycle.decide({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.lifecycle.inspect': { if (!options.lifecycle) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'lifecycle management is not configured', ); } const result = await options.lifecycle.inspectAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, plan: result.plan ? lifecyclePlanSummary(result.plan) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, stale: result.stale, }); } case 'plugin-package.secret-binding.plan': { if (!options.secretBinding) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret binding management is not configured', ); } const result = await options.secretBinding.plan({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, plan: secretBindingPlanSummary(result.plan), }); } case 'plugin-package.secret-binding.propose': { if (!options.secretBinding) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret binding management is not configured', ); } const result = await options.secretBinding.propose({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, approvalStatus: result.approvalStatus, plan: secretBindingPlanSummary(result.plan), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.secret-binding.decide': { if (!options.secretBinding) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret binding management is not configured', ); } const result = await options.secretBinding.decide({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.secret-binding.inspect': { if (!options.secretBinding) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret binding management is not configured', ); } const result = await options.secretBinding.inspectAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, plan: result.plan ? secretBindingPlanSummary(result.plan) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, stale: result.stale, }); } case 'plugin-package.secret-binding.transition.plan': { if (!options.secretBindingTransition) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret transition management is not configured', ); } const result = await options.secretBindingTransition.plan({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, plan: secretBindingTransitionPlanSummary(result.plan), }); } case 'plugin-package.secret-binding.transition.propose': { if (!options.secretBindingTransition) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret transition management is not configured', ); } const result = await options.secretBindingTransition.propose({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, approvalStatus: result.approvalStatus, plan: secretBindingTransitionPlanSummary(result.plan), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.secret-binding.transition.decide': { if (!options.secretBindingTransition) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret transition management is not configured', ); } const result = await options.secretBindingTransition.decide({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.secret-binding.transition.inspect': { if (!options.secretBindingTransition) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'Secret transition management is not configured', ); } const result = await options.secretBindingTransition.inspectAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, plan: result.plan ? secretBindingTransitionPlanSummary(result.plan) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, stale: result.stale, }); } case 'plugin-package.publisher-revocation.propose': { if (!options.publisherTrust) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const current = await options.publisherTrust.inspect( command.request.actionRef, command.request.approvalRequestId, ); const result = await options.publisherTrust.propose({ ...command.request, requestedAtMs: current.approvalRequest?.requestedAtMs ?? current.proposal?.createdAtMs ?? observedAtMs, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposalStatus: result.proposalStatus, approvalStatus: result.approvalStatus, proposal: publisherRevocationProposalSummary(result.proposal), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.publisher-revocation.decide': { if (!options.publisherTrust) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const current = await options.publisherTrust.inspect( command.request.actionRef, command.request.approvalRequestId, ); if ( !current.proposal || !current.approvalRequest || current.proposal.actionRef !== current.approvalRequest.action.actionRef || current.proposal.actionDigest !== current.approvalRequest.action.actionDigest || current.proposal.previewDigest !== current.approvalRequest.action.previewDigest ) { throw new ClusterPluginPackageManagementTransportRequestError( 'publisher revocation authority does not match', ); } if ( current.proposal.actionInput.authorizationMode === 'break_glass' && principal.assurance !== 'hardware' ) { throw new ClusterPluginPackageManagementTransportAuthenticationError(); } const replay = exactDecisionReplay(current, command, principal); const result = replay ?? (await options.service.decide({ approvalRequestId: command.request.approvalRequestId, expectedVersion: command.request.expectedVersion, decisionId: command.request.decisionId, auditEventId: command.request.auditEventId, decision: command.request.decision, reasonCode: command.request.reasonCode, decidedAtMs: observedAtMs, principal, })); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.publisher-revocation.inspect': { if (!options.publisherTrust) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const result = await options.publisherTrust.inspectAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposal: result.proposal ? publisherRevocationProposalSummary(result.proposal) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, }); } case 'plugin-package.publisher-trust-transition.propose': { if ( !options.publisherTrust || typeof options.publisherTrust.proposeTransition !== 'function' || typeof options.publisherTrust.inspectTransition !== 'function' ) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const current = await options.publisherTrust.inspectTransition( command.request.actionRef, command.request.approvalRequestId, ); const result = await options.publisherTrust.proposeTransition({ ...command.request, requestedAtMs: current.approvalRequest?.requestedAtMs ?? current.proposal?.createdAtMs ?? observedAtMs, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposalStatus: result.proposalStatus, approvalStatus: result.approvalStatus, proposal: publisherTrustTransitionProposalSummary(result.proposal), approval: approvalSummary(result.approvalRequest), }); } case 'plugin-package.publisher-trust-transition.decide': { if ( !options.publisherTrust || typeof options.publisherTrust.inspectTransition !== 'function' ) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const current = await options.publisherTrust.inspectTransition( command.request.actionRef, command.request.approvalRequestId, ); if ( !current.proposal || !current.approvalRequest || current.approvalRequest.decisionMode !== 'separation_of_duty' || current.proposal.actionRef !== current.approvalRequest.action.actionRef || current.proposal.actionDigest !== current.approvalRequest.action.actionDigest || current.proposal.previewDigest !== current.approvalRequest.action.previewDigest ) { throw new ClusterPluginPackageManagementTransportRequestError( 'publisher trust transition authority does not match', ); } const replay = exactDecisionReplay(current, command, principal); const result = replay ?? (await options.service.decide({ approvalRequestId: command.request.approvalRequestId, expectedVersion: command.request.expectedVersion, decisionId: command.request.decisionId, auditEventId: command.request.auditEventId, decision: command.request.decision, reasonCode: command.request.reasonCode, decidedAtMs: observedAtMs, principal, })); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, status: result.status, approval: approvalSummary(result.request), }); } case 'plugin-package.publisher-trust-transition.inspect': { if ( !options.publisherTrust || typeof options.publisherTrust.inspectTransitionAuthorized !== 'function' ) { throw new ClusterPluginPackageManagementTransportConfigurationError( 'publisher trust management is not configured', ); } const result = await options.publisherTrust.inspectTransitionAuthorized({ ...command.request, principal, }); return Object.freeze({ schemaVersion: 1 as const, operation: command.operation, proposal: result.proposal ? publisherTrustTransitionProposalSummary(result.proposal) : null, approval: result.approvalRequest ? approvalSummary(result.approvalRequest) : null, }); } } }, }); }