@oneuptime/common 14.0.1 → 14.0.3
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/Models/DatabaseModels/AlertEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
- package/Models/DatabaseModels/Monitor.ts +48 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Models/DatabaseModels/Runner.ts +5 -4
- package/Models/DatabaseModels/RunnerJob.ts +66 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
- package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
- package/Server/API/AIInvestigationAPI.ts +341 -0
- package/Server/API/AutoRemediationAPI.ts +184 -2
- package/Server/API/CommonAPI.ts +70 -0
- package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
- package/Server/API/MicrosoftTeamsAPI.ts +770 -315
- package/Server/API/MonitorAPI.ts +140 -0
- package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
- package/Server/API/SlackAPI.ts +447 -99
- package/Server/API/StatusPageAPI.ts +146 -26
- package/Server/API/TelemetryAPI.ts +216 -5
- package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
- package/Server/API/WorkflowVariableAPI.ts +156 -0
- package/Server/Infrastructure/GlobalCache.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
- package/Server/Middleware/TelemetryIngest.ts +47 -2
- package/Server/Middleware/UserAuthorization.ts +56 -2
- package/Server/Services/AIAgentService.ts +1 -0
- package/Server/Services/AccessTokenService.ts +121 -48
- package/Server/Services/AlertEpisodeMemberService.ts +9 -0
- package/Server/Services/AlertEpisodeService.ts +14 -1
- package/Server/Services/AlertService.ts +134 -22
- package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
- package/Server/Services/AutoRemediationRuleService.ts +118 -0
- package/Server/Services/BillingService.ts +1 -0
- package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
- package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
- package/Server/Services/IncidentEpisodeService.ts +14 -1
- package/Server/Services/IncidentGroupingEngineService.ts +11 -0
- package/Server/Services/IncidentMemberService.ts +21 -0
- package/Server/Services/IncidentPublicNoteService.ts +63 -0
- package/Server/Services/IncidentService.ts +330 -30
- package/Server/Services/IncidentStateTimelineService.ts +39 -0
- package/Server/Services/IncidentTemplateService.ts +83 -3
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
- package/Server/Services/KubernetesClusterService.ts +1570 -1
- package/Server/Services/LogAggregationService.ts +14 -6
- package/Server/Services/MonitorService.ts +651 -52
- package/Server/Services/MonitorStatusTimelineService.ts +639 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
- package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
- package/Server/Services/OnCallSetupReminderService.ts +1 -0
- package/Server/Services/ProbeService.ts +7 -1
- package/Server/Services/ProjectService.ts +11 -1
- package/Server/Services/RunbookCredentialService.ts +26 -1
- package/Server/Services/RunbookSecretService.ts +36 -0
- package/Server/Services/RunnerJobService.ts +941 -23
- package/Server/Services/RunnerService.ts +439 -6
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
- package/Server/Services/ScheduledMaintenanceService.ts +124 -19
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
- package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
- package/Server/Services/StatusPagePrivateUserService.ts +1 -0
- package/Server/Services/StatusPageService.ts +301 -74
- package/Server/Services/StatusPageSubscriberService.ts +4 -0
- package/Server/Services/TeamMemberService.ts +309 -7
- package/Server/Services/TraceAggregationService.ts +10 -6
- package/Server/Services/UserEmailService.ts +1 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleService.ts +4 -0
- package/Server/Services/UserService.ts +122 -1
- package/Server/Services/WorkflowVariableService.ts +593 -8
- package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
- package/Server/Types/Database/QueryHelper.ts +22 -0
- package/Server/Types/Markdown.ts +502 -27
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
- package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
- package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
- package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
- package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
- package/Server/Utils/PushNotificationUtil.ts +45 -0
- package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
- package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
- package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
- package/Server/Utils/StartServer.ts +4 -3
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
- package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
- package/Server/Utils/UserPermission/UserPermission.ts +16 -0
- package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
- package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
- package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
- package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
- package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
- package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
- package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
- package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
- package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
- package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/Server/Utils/Workspace/Workspace.ts +171 -54
- package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
- package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
- package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
- package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
- package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
- package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
- package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
- package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
- package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
- package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
- package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
- package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +238 -0
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
- package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
- package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
- package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
- package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
- package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
- package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
- package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
- package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
- package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
- package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
- package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
- package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
- package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
- package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
- package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
- package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
- package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
- package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
- package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
- package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
- package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
- package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
- package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
- package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
- package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
- package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
- package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
- package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
- package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
- package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
- package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
- package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
- package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
- package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
- package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
- package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
- package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
- package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
- package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
- package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
- package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
- package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
- package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
- package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
- package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
- package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
- package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
- package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
- package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
- package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
- package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
- package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
- package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
- package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
- package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
- package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
- package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
- package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
- package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
- package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
- package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
- package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
- package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
- package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
- package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
- package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
- package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
- package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
- package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
- package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
- package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
- package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
- package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
- package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
- package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
- package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
- package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
- package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
- package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
- package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
- package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
- package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
- package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
- package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
- package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
- package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
- package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
- package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
- package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
- package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
- package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
- package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
- package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
- package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
- package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
- package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
- package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
- package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
- package/Tests/Server/Types/Markdown.test.ts +1033 -0
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
- package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
- package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
- package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
- package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
- package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
- package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
- package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
- package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
- package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
- package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
- package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
- package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
- package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
- package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
- package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
- package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
- package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
- package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
- package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
- package/Tests/Types/DateUserTimezone.test.ts +177 -4
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
- package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
- package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
- package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
- package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
- package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
- package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
- package/Tests/Types/Timezone.test.ts +5 -0
- package/Tests/Types/TimezoneAlias.test.ts +1034 -0
- package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
- package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
- package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
- package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
- package/Tests/Types/Workflow/Templates.test.ts +79 -4
- package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
- package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
- package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
- package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
- package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
- package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
- package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
- package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
- package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
- package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
- package/Tests/UI/Components/Dropdown.test.tsx +999 -2
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
- package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
- package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
- package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
- package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
- package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
- package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
- package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
- package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
- package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
- package/Tests/UI/Utils/Timezone.test.ts +747 -33
- package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
- package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
- package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
- package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
- package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
- package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
- package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
- package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
- package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
- package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
- package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
- package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
- package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
- package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
- package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
- package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
- package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
- package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
- package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
- package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
- package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
- package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
- package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
- package/Types/Date.ts +121 -7
- package/Types/Email/EmailMessage.ts +8 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Exception/ExceptionMessages.ts +1 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
- package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
- package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
- package/Types/Permission.ts +48 -0
- package/Types/Rum/SessionReplay.ts +80 -8
- package/Types/Rum/SessionReplayApi.ts +44 -1
- package/Types/Rum/UserFlow.ts +187 -0
- package/Types/Rum/WebVitals.ts +52 -0
- package/Types/Runbook/RunbookStepType.ts +10 -0
- package/Types/Runbook/RunnerJobOrigin.ts +15 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
- package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
- package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
- package/Types/Timezone.ts +5 -0
- package/Types/TimezoneAlias.ts +385 -0
- package/Types/Workflow/Templates.ts +3041 -2
- package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
- package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
- package/Typings/Index.d.ts +24 -0
- package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
- package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
- package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
- package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
- package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
- package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
- package/UI/Components/Calendar/Calendar.css +83 -0
- package/UI/Components/Calendar/Calendar.tsx +136 -7
- package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
- package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
- package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
- package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/Dropdown/Dropdown.tsx +58 -9
- package/UI/Components/Forms/Fields/FormField.tsx +49 -14
- package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
- package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
- package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
- package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
- package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
- package/UI/Components/ModelTable/BaseModelTable.tsx +161 -31
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
- package/UI/Components/Page/ModelPage.tsx +59 -3
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
- package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
- package/UI/Utils/PermissionGate.ts +11 -2
- package/UI/Utils/Timezone.ts +69 -28
- package/Utils/AI/InvestigationReport.ts +195 -25
- package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
- package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
- package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
- package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
- package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
- package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
- package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
- package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
- package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
- package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
- package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
- package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
- package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
- package/Utils/Rum/SessionIdentity.ts +44 -0
- package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/Utils/Rum/UserFlow.ts +1527 -0
- package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
- package/Utils/StatusPage/ResourceUptime.ts +99 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
- package/Utils/Telemetry/AttributesJSON.ts +367 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
- package/Utils/Uptime/UptimeUtil.ts +122 -38
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Runner.js +4 -4
- package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +49 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +107 -1
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +322 -78
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +123 -17
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +144 -5
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
- package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
- package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +21 -0
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +1 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +87 -42
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +110 -23
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +1 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentMemberService.js +14 -0
- package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +263 -33
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +33 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +14 -6
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +487 -48
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
- package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +7 -1
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +11 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
- package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
- package/build/dist/Server/Services/RunbookSecretService.js +44 -0
- package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +641 -21
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +344 -5
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +230 -32
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +270 -11
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +10 -6
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +1 -0
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +107 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
- package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +394 -27
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
- package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
- package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +4 -3
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
- package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
- package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
- package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Date.js +97 -7
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
- package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +52 -2
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/Rum/UserFlow.js +115 -0
- package/build/dist/Types/Rum/UserFlow.js.map +1 -0
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
- package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/Timezone.js +5 -0
- package/build/dist/Types/Timezone.js.map +1 -1
- package/build/dist/Types/TimezoneAlias.js +340 -0
- package/build/dist/Types/TimezoneAlias.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2694 -2
- package/build/dist/Types/Workflow/Templates.js.map +1 -1
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +89 -22
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +37 -3
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/Timezone.js +52 -17
- package/build/dist/UI/Utils/Timezone.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +116 -21
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
- package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
- package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/build/dist/Utils/Rum/UserFlow.js +941 -0
- package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
- package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
- package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
- package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
- package/jest.config.json +2 -1
- package/package.json +2 -1
- package/tsconfig.tests.json +36 -0
- package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
- package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
|
@@ -0,0 +1,1525 @@
|
|
|
1
|
+
import KubectlPolicy, {
|
|
2
|
+
KubectlAutoExecutionVerdict,
|
|
3
|
+
KubectlPolicyResult,
|
|
4
|
+
KubectlTokenizeResult,
|
|
5
|
+
normalizeKubectlFlagName,
|
|
6
|
+
} from "../../../Utils/AiRemediation/KubectlPolicy";
|
|
7
|
+
import { KubectlCommandTier } from "../../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
8
|
+
import { AiRemediationCommandPolicyVerdict } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
|
|
9
|
+
import { describe, expect, it } from "@jest/globals";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* Contract under test — what the kubectl policy refuses in EVERY mode, even
|
|
13
|
+
* with a human approving (Denied), beyond the verb and flag basics pinned in
|
|
14
|
+
* KubectlPolicy.test.ts:
|
|
15
|
+
* 1. Changes to who may do what, or to what the API server admits and
|
|
16
|
+
* serves: creating RBAC kinds or ServiceAccounts, set subject, set
|
|
17
|
+
* serviceaccount, auth reconcile, certificate approve/deny, and EVERY
|
|
18
|
+
* write verb (label, annotate, patch, set, scale, rollout, ...; delete
|
|
19
|
+
* through the never-delete list) on roles, cluster roles, their
|
|
20
|
+
* bindings, admission webhook configurations, admission policies and
|
|
21
|
+
* their bindings, APIServices and CRDs, in every spelling kubectl
|
|
22
|
+
* accepts. Reading them stays Read.
|
|
23
|
+
* 2. Wiring identity, privileges, host access, Secrets or a new program into
|
|
24
|
+
* a pod: patch bodies that touch POD_SECURITY_PATCH_KEYS (by key name,
|
|
25
|
+
* in strategic-merge and merge keys, strategic-merge directives and
|
|
26
|
+
* JSON-patch paths, escapes decoded), Pod Security Admission labels on
|
|
27
|
+
* namespaces, set env --from=secret/..., and every create subcommand
|
|
28
|
+
* that starts a workload from an image named in the command (create
|
|
29
|
+
* deployment, create cronjob, create job --image; only `create job NAME
|
|
30
|
+
* --from=cronjob/NAME` stays, as RiskyWrite, and `set image` on an
|
|
31
|
+
* existing workload stays RiskyWrite).
|
|
32
|
+
* 3. A patch body that is not JSON, whatever it says: kubectl decodes any
|
|
33
|
+
* other body as YAML, whose tags, anchors and merge keys can spell a
|
|
34
|
+
* forbidden field that appears nowhere in the text (checked against the
|
|
35
|
+
* pinned kubectl v1.36.4 with `patch --local`: each tagged body below
|
|
36
|
+
* really changed serviceAccountName, hostNetwork or hostPID).
|
|
37
|
+
* 4. Resource categories in any write (all, api-extensions, ...), and every
|
|
38
|
+
* NEVER_DELETE kind in every spelling kubectl accepts.
|
|
39
|
+
* 5. Anything that could run something other than the command we read: the
|
|
40
|
+
* kuberc and plugin verbs, any unknown verb or create/set subcommand
|
|
41
|
+
* (kubectl would run a kubectl-<word> plugin), a verb or subcommand not
|
|
42
|
+
* in lowercase, and a namespace set twice (the last one wins).
|
|
43
|
+
* 6. Every kubectl v1.36 global flag except -n/--namespace,
|
|
44
|
+
* --request-timeout and --match-server-version, in every spelling —
|
|
45
|
+
* "_" for "-" included, because kubectl normalizes it.
|
|
46
|
+
* 7. Property: every command in every Denied table here stays Denied under
|
|
47
|
+
* bypassApproval, under an allowlist entry that is the command itself,
|
|
48
|
+
* and under the broadest valid entry of its shape (every word after the
|
|
49
|
+
* verb a wildcard).
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
function tier(command: string): KubectlCommandTier {
|
|
53
|
+
return KubectlPolicy.evaluateCommand(command).tier;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function reason(command: string): string {
|
|
57
|
+
return KubectlPolicy.evaluateCommand(command).reason;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ---- 1. RBAC, identity and certificates -------------------------------------
|
|
61
|
+
|
|
62
|
+
const DENIED_IDENTITY_AND_RBAC_SHAPES: Array<string> = [
|
|
63
|
+
"kubectl create clusterrolebinding x --clusterrole=cluster-admin --serviceaccount=ns:sa",
|
|
64
|
+
"kubectl create clusterrolebinding x --clusterrole=view --group=system:authenticated",
|
|
65
|
+
"kubectl create rolebinding x --clusterrole=admin --group=system:authenticated -n web",
|
|
66
|
+
"kubectl create rolebinding x --role=r --user=alice -n web",
|
|
67
|
+
"kubectl create role x --verb=* --resource=* -n web",
|
|
68
|
+
"kubectl create role x --verb=get --resource=pods -n web",
|
|
69
|
+
"kubectl create clusterrole x --verb=* --resource=*",
|
|
70
|
+
"kubectl create clusterrole x --aggregation-rule=rbac.example.com/aggregate=true",
|
|
71
|
+
"kubectl create serviceaccount runner -n web",
|
|
72
|
+
"kubectl create sa runner -n web",
|
|
73
|
+
"kubectl create -n web serviceaccount runner",
|
|
74
|
+
"kubectl create rolebinding x --clusterrole=edit --serviceaccount=web:default -n web --dry-run=client -o yaml",
|
|
75
|
+
"kubectl set subject clusterrolebinding view --serviceaccount=web:sa",
|
|
76
|
+
"kubectl set subject rolebinding/admin -n web --group=system:unauthenticated",
|
|
77
|
+
"kubectl set subject rolebinding admin -n web --user=mallory",
|
|
78
|
+
"kubectl set serviceaccount deployment web privileged-sa -n web",
|
|
79
|
+
"kubectl set serviceaccount deployment/web privileged-sa -n prod",
|
|
80
|
+
"kubectl set sa deployment/web privileged-sa -n prod",
|
|
81
|
+
"kubectl set serviceaccount cronjob nightly admin -n web",
|
|
82
|
+
"kubectl auth reconcile -f rbac.yaml",
|
|
83
|
+
"kubectl auth reconcile",
|
|
84
|
+
"kubectl auth reconcile --remove-extra-permissions",
|
|
85
|
+
"kubectl certificate approve csr-1",
|
|
86
|
+
"kubectl certificate deny csr-1",
|
|
87
|
+
"kubectl certificate approve csr-1 --force",
|
|
88
|
+
'kubectl patch clusterrolebinding view -p \'{"roleRef":{"name":"cluster-admin"}}\'',
|
|
89
|
+
'kubectl patch clusterrolebinding view --type=json -p \'[{"op":"add","path":"/subjects/-","value":{"kind":"Group","name":"system:authenticated"}}]\'',
|
|
90
|
+
'kubectl patch clusterrole view --type=json -p \'[{"op":"add","path":"/rules/0/verbs/-","value":"*"}]\'',
|
|
91
|
+
"kubectl patch rolebindings.rbac.authorization.k8s.io x -n web -p '{}'",
|
|
92
|
+
"kubectl patch role/x -n web -p '{\"rules\":[]}'",
|
|
93
|
+
"kubectl patch roles x -n web -p '{}'",
|
|
94
|
+
"kubectl label clusterrole x rbac.authorization.k8s.io/aggregate-to-admin=true",
|
|
95
|
+
"kubectl label clusterrole x rbac.authorization.k8s.io/aggregate-to-view=true --overwrite",
|
|
96
|
+
"kubectl label clusterrole/x rbac.authorization.k8s.io/aggregate-to-edit=true",
|
|
97
|
+
"kubectl label clusterroles.rbac.authorization.k8s.io x rbac.authorization.k8s.io/aggregate-to-view=true",
|
|
98
|
+
/*
|
|
99
|
+
* These three were pinned RiskyWrite before: a plain label or annotation
|
|
100
|
+
* on an RBAC object. Every write verb on an RBAC kind is Denied now — a
|
|
101
|
+
* label on a ClusterRole can aggregate its rules, and none of them is a
|
|
102
|
+
* workload fix.
|
|
103
|
+
*/
|
|
104
|
+
"kubectl label clusterrole x team=a",
|
|
105
|
+
"kubectl annotate rolebinding x -n web owner=sre",
|
|
106
|
+
// Aggregation reads LABELS, but an annotation on a role is still an RBAC write.
|
|
107
|
+
"kubectl annotate clusterrole x rbac.authorization.k8s.io/aggregate-to-admin=true",
|
|
108
|
+
"kubectl delete rolebinding x -n web",
|
|
109
|
+
"kubectl delete role x -n web",
|
|
110
|
+
"kubectl delete roles/x -n web",
|
|
111
|
+
"kubectl delete rolebindings.rbac.authorization.k8s.io x -n web",
|
|
112
|
+
"kubectl delete clusterrolebinding admin",
|
|
113
|
+
"kubectl delete clusterrole/admin",
|
|
114
|
+
// set env --from=secret/... wires a Secret into the workload.
|
|
115
|
+
"kubectl set env deployment/web -n web --from=secret/db-creds",
|
|
116
|
+
"kubectl set env deployment/web -n web --from=secrets/db-creds --prefix=DB_",
|
|
117
|
+
"kubectl set env deployment/web -n web --from=Secret/db-creds",
|
|
118
|
+
// A set subcommand kubectl does not have.
|
|
119
|
+
"kubectl set frobnicate deployment/web -n web",
|
|
120
|
+
"kubectl set",
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
// Neighbours that must keep their tiers: reading RBAC, and plain workload changes.
|
|
124
|
+
const ALLOWED_IDENTITY_NEIGHBOURS: Array<[string, KubectlCommandTier]> = [
|
|
125
|
+
["kubectl get clusterrolebindings -o yaml", KubectlCommandTier.Read],
|
|
126
|
+
["kubectl get roles -n web", KubectlCommandTier.Read],
|
|
127
|
+
["kubectl describe rolebinding x -n web", KubectlCommandTier.Read],
|
|
128
|
+
["kubectl describe clusterrole admin", KubectlCommandTier.Read],
|
|
129
|
+
["kubectl auth can-i --list", KubectlCommandTier.Read],
|
|
130
|
+
["kubectl auth can-i create clusterrolebindings", KubectlCommandTier.Read],
|
|
131
|
+
["kubectl auth whoami", KubectlCommandTier.Read],
|
|
132
|
+
["kubectl get csr", KubectlCommandTier.Read],
|
|
133
|
+
["kubectl get serviceaccounts -n web", KubectlCommandTier.Read],
|
|
134
|
+
// A label key that names a kind is not that kind.
|
|
135
|
+
[
|
|
136
|
+
"kubectl label pod web-1 -n web rolebinding=x",
|
|
137
|
+
KubectlCommandTier.SafeWrite,
|
|
138
|
+
],
|
|
139
|
+
[
|
|
140
|
+
"kubectl label pod web-1 -n web serviceaccount=x",
|
|
141
|
+
KubectlCommandTier.SafeWrite,
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
"kubectl create job x --from=cronjob/y -n web",
|
|
145
|
+
KubectlCommandTier.RiskyWrite,
|
|
146
|
+
],
|
|
147
|
+
/*
|
|
148
|
+
* `create deployment web --image=nginx` used to be pinned RiskyWrite here;
|
|
149
|
+
* it starts a new workload from an image named in the command and is
|
|
150
|
+
* Denied now (see DENIED_IMAGE_WORKLOAD_CREATES). Changing an EXISTING
|
|
151
|
+
* workload's image stays RiskyWrite (set image, below).
|
|
152
|
+
*/
|
|
153
|
+
[
|
|
154
|
+
"kubectl create configmap app --from-literal=a=b -n web",
|
|
155
|
+
KubectlCommandTier.RiskyWrite,
|
|
156
|
+
],
|
|
157
|
+
["kubectl create namespace scratch", KubectlCommandTier.RiskyWrite],
|
|
158
|
+
["kubectl create ns scratch", KubectlCommandTier.RiskyWrite],
|
|
159
|
+
[
|
|
160
|
+
"kubectl create pdb web --selector=app=web --min-available=1 -n web",
|
|
161
|
+
KubectlCommandTier.RiskyWrite,
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"kubectl create cm app --from-literal=a=b -n web",
|
|
165
|
+
KubectlCommandTier.RiskyWrite,
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
"kubectl set image deployment/web web=nginx:1.27 -n web",
|
|
169
|
+
KubectlCommandTier.RiskyWrite,
|
|
170
|
+
],
|
|
171
|
+
[
|
|
172
|
+
"kubectl set resources deployment/web -n web --limits=cpu=1",
|
|
173
|
+
KubectlCommandTier.RiskyWrite,
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"kubectl set env deployment/web -n web LOG_LEVEL=debug",
|
|
177
|
+
KubectlCommandTier.RiskyWrite,
|
|
178
|
+
],
|
|
179
|
+
[
|
|
180
|
+
"kubectl set env deployment/web -n web --from=configmap/app-config",
|
|
181
|
+
KubectlCommandTier.RiskyWrite,
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
"kubectl set selector svc/web app=web -n web",
|
|
185
|
+
KubectlCommandTier.RiskyWrite,
|
|
186
|
+
],
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
/*
|
|
190
|
+
* The cluster-control kinds, each in the spellings kubectl accepts: plural,
|
|
191
|
+
* singular, Kind case, short name and group-qualified (with and without a
|
|
192
|
+
* version). The second element says whether the kind is namespaced.
|
|
193
|
+
*/
|
|
194
|
+
const CLUSTER_CONTROL_KIND_SPELLINGS: Array<[string, boolean]> = [
|
|
195
|
+
["role", true],
|
|
196
|
+
["roles", true],
|
|
197
|
+
["Role", true],
|
|
198
|
+
["roles.rbac.authorization.k8s.io", true],
|
|
199
|
+
["roles.v1.rbac.authorization.k8s.io", true],
|
|
200
|
+
["rolebinding", true],
|
|
201
|
+
["rolebindings", true],
|
|
202
|
+
["RoleBinding", true],
|
|
203
|
+
["rolebindings.rbac.authorization.k8s.io", true],
|
|
204
|
+
["clusterrole", false],
|
|
205
|
+
["clusterroles", false],
|
|
206
|
+
["ClusterRole", false],
|
|
207
|
+
["clusterroles.rbac.authorization.k8s.io", false],
|
|
208
|
+
["clusterrolebinding", false],
|
|
209
|
+
["clusterrolebindings", false],
|
|
210
|
+
["clusterrolebindings.rbac.authorization.k8s.io", false],
|
|
211
|
+
["validatingwebhookconfiguration", false],
|
|
212
|
+
["validatingwebhookconfigurations", false],
|
|
213
|
+
["ValidatingWebhookConfiguration", false],
|
|
214
|
+
["validatingwebhookconfigurations.admissionregistration.k8s.io", false],
|
|
215
|
+
["validatingwebhookconfigurations.v1.admissionregistration.k8s.io", false],
|
|
216
|
+
["mutatingwebhookconfiguration", false],
|
|
217
|
+
["mutatingwebhookconfigurations", false],
|
|
218
|
+
["MutatingWebhookConfiguration", false],
|
|
219
|
+
["mutatingwebhookconfigurations.admissionregistration.k8s.io", false],
|
|
220
|
+
["validatingadmissionpolicy", false],
|
|
221
|
+
["validatingadmissionpolicies", false],
|
|
222
|
+
["validatingadmissionpolicies.admissionregistration.k8s.io", false],
|
|
223
|
+
["validatingadmissionpolicybinding", false],
|
|
224
|
+
["validatingadmissionpolicybindings", false],
|
|
225
|
+
["validatingadmissionpolicybindings.admissionregistration.k8s.io", false],
|
|
226
|
+
["mutatingadmissionpolicy", false],
|
|
227
|
+
["mutatingadmissionpolicies", false],
|
|
228
|
+
["mutatingadmissionpolicies.v1beta1.admissionregistration.k8s.io", false],
|
|
229
|
+
["mutatingadmissionpolicybinding", false],
|
|
230
|
+
["mutatingadmissionpolicybindings", false],
|
|
231
|
+
["apiservice", false],
|
|
232
|
+
["apiservices", false],
|
|
233
|
+
["APIService", false],
|
|
234
|
+
["apiservices.apiregistration.k8s.io", false],
|
|
235
|
+
["apiservices.v1.apiregistration.k8s.io", false],
|
|
236
|
+
["crd", false],
|
|
237
|
+
["crds", false],
|
|
238
|
+
["customresourcedefinition", false],
|
|
239
|
+
["CustomResourceDefinition", false],
|
|
240
|
+
["customresourcedefinitions.apiextensions.k8s.io", false],
|
|
241
|
+
["customresourcedefinitions.v1.apiextensions.k8s.io", false],
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* Every write verb that takes objects, for one object of `kind` (named
|
|
246
|
+
* "KIND NAME" or "KIND/NAME", by selector, by --all, or in a comma list with
|
|
247
|
+
* an ordinary kind). delete is covered by the never-delete table.
|
|
248
|
+
*/
|
|
249
|
+
function clusterControlWrites(
|
|
250
|
+
kind: string,
|
|
251
|
+
namespaced: boolean,
|
|
252
|
+
): Array<string> {
|
|
253
|
+
const ns: string = namespaced ? " -n web" : "";
|
|
254
|
+
return [
|
|
255
|
+
`kubectl label ${kind} x team=a${ns}`,
|
|
256
|
+
`kubectl label ${kind}/x team=a --overwrite${ns}`,
|
|
257
|
+
`kubectl label ${kind} -l app=x team=a${ns}`,
|
|
258
|
+
`kubectl label pod,${kind} x team=a -n web`,
|
|
259
|
+
`kubectl annotate ${kind} x owner=sre${ns}`,
|
|
260
|
+
`kubectl annotate ${kind} --all owner=sre${ns}`,
|
|
261
|
+
`kubectl patch ${kind} x -p '{"metadata":{"labels":{"a":"b"}}}'${ns}`,
|
|
262
|
+
`kubectl patch ${kind}/x --type=merge -p '{"spec":{}}'${ns}`,
|
|
263
|
+
`kubectl patch ${kind} x --type=json -p '[{"op":"replace","path":"/webhooks/0/rules","value":[]}]'${ns}`,
|
|
264
|
+
`kubectl scale ${kind}/x --replicas=1${ns}`,
|
|
265
|
+
`kubectl set env ${kind}/x A=b${ns}`,
|
|
266
|
+
`kubectl set image ${kind}/x c=img:1${ns}`,
|
|
267
|
+
`kubectl set resources ${kind}/x --limits=cpu=1${ns}`,
|
|
268
|
+
`kubectl set selector ${kind}/x app=x${ns}`,
|
|
269
|
+
`kubectl rollout restart ${kind}/x${ns}`,
|
|
270
|
+
`kubectl rollout undo ${kind} x${ns}`,
|
|
271
|
+
`kubectl taint ${kind} x k=v:NoSchedule${ns}`,
|
|
272
|
+
`kubectl expose ${kind} x --port=80${ns}`,
|
|
273
|
+
`kubectl autoscale ${kind} x --min=1 --max=2${ns}`,
|
|
274
|
+
];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// A few of the rows above, for the property tests at the bottom.
|
|
278
|
+
const DENIED_CLUSTER_CONTROL_WRITES: Array<string> = [
|
|
279
|
+
'kubectl patch validatingwebhookconfiguration gatekeeper --type=json -p \'[{"op":"replace","path":"/webhooks/0/rules","value":[]}]\'',
|
|
280
|
+
'kubectl patch validatingwebhookconfigurations.admissionregistration.k8s.io/gatekeeper --type=json -p \'[{"op":"replace","path":"/webhooks/0/failurePolicy","value":"Ignore"}]\'',
|
|
281
|
+
'kubectl patch mutatingwebhookconfiguration istio-sidecar-injector -p \'{"webhooks":[{"name":"x","rules":[]}]}\'',
|
|
282
|
+
'kubectl patch validatingadmissionpolicybinding restricted-pods --type=merge -p \'{"spec":{"validationActions":["Audit"]}}\'',
|
|
283
|
+
'kubectl patch apiservice v1beta1.metrics.k8s.io --type=merge -p \'{"spec":{"service":{"name":"x","namespace":"web"}}}\'',
|
|
284
|
+
'kubectl patch crd certificates.cert-manager.io --type=merge -p \'{"spec":{"conversion":{"strategy":"None"}}}\'',
|
|
285
|
+
"kubectl label validatingwebhookconfiguration gatekeeper a=b",
|
|
286
|
+
"kubectl label mutatingwebhookconfigurations/x a=b",
|
|
287
|
+
"kubectl annotate crd certificates.cert-manager.io a=b",
|
|
288
|
+
"kubectl label clusterrole my-role a=b",
|
|
289
|
+
"kubectl label clusterrolebinding x a=b",
|
|
290
|
+
"kubectl label role/x -n web a=b",
|
|
291
|
+
"kubectl label rolebinding x -n web a=b",
|
|
292
|
+
"kubectl patch validatingwebhookconfiguration -l app=gatekeeper -p '{}'",
|
|
293
|
+
"kubectl label rolebinding x -n kube-system a=b",
|
|
294
|
+
];
|
|
295
|
+
|
|
296
|
+
// Reading the same kinds stays Read: an investigation needs to see them.
|
|
297
|
+
const CLUSTER_CONTROL_READS: Array<string> = [
|
|
298
|
+
"kubectl get validatingwebhookconfiguration gatekeeper -o yaml",
|
|
299
|
+
"kubectl get validatingwebhookconfigurations",
|
|
300
|
+
"kubectl describe apiservice v1beta1.metrics.k8s.io",
|
|
301
|
+
"kubectl get crd certificates.cert-manager.io -o yaml",
|
|
302
|
+
"kubectl get validatingadmissionpolicybindings",
|
|
303
|
+
"kubectl describe mutatingwebhookconfiguration istio-sidecar-injector",
|
|
304
|
+
"kubectl get clusterroles",
|
|
305
|
+
"kubectl describe rolebinding x -n web",
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
// Neighbours: the same verbs on ordinary kinds keep their tiers.
|
|
309
|
+
const CLUSTER_CONTROL_NEIGHBOURS: Array<[string, KubectlCommandTier]> = [
|
|
310
|
+
["kubectl label pod web-1 -n web team=a", KubectlCommandTier.SafeWrite],
|
|
311
|
+
["kubectl label ns web team=a", KubectlCommandTier.RiskyWrite],
|
|
312
|
+
[
|
|
313
|
+
"kubectl annotate svc web -n web example.com/owner=sre",
|
|
314
|
+
KubectlCommandTier.RiskyWrite,
|
|
315
|
+
],
|
|
316
|
+
[
|
|
317
|
+
'kubectl patch deployment web -n web -p \'{"spec":{"replicas":2}}\'',
|
|
318
|
+
KubectlCommandTier.RiskyWrite,
|
|
319
|
+
],
|
|
320
|
+
[
|
|
321
|
+
'kubectl patch certificates.cert-manager.io web -n web --type=merge -p \'{"spec":{"renewBefore":"48h"}}\'',
|
|
322
|
+
KubectlCommandTier.RiskyWrite,
|
|
323
|
+
],
|
|
324
|
+
[
|
|
325
|
+
"kubectl label pod web-1 -n web validatingwebhookconfiguration=x",
|
|
326
|
+
KubectlCommandTier.SafeWrite,
|
|
327
|
+
],
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
// ---- 2. Running a different program or identity ------------------------------
|
|
331
|
+
|
|
332
|
+
const DENIED_CREATE_JOB_SHAPES: Array<string> = [
|
|
333
|
+
"kubectl create job pwn --image=evil/img -n kube-system",
|
|
334
|
+
"kubectl create job x --image=busybox -n web",
|
|
335
|
+
"kubectl create job x --image=busybox -n web -- sh -c 'cat /var/run/secrets/*'",
|
|
336
|
+
"kubectl create job x --from=cronjob/y --image=busybox -n web",
|
|
337
|
+
"kubectl create job x -n web",
|
|
338
|
+
"kubectl create job x --from=deployment/web -n web",
|
|
339
|
+
"kubectl create job x --from=cronjob/ -n web",
|
|
340
|
+
"kubectl create job x --from=cronjob -n web",
|
|
341
|
+
"kubectl create job x --from=cronjobs.example.com/y -n web",
|
|
342
|
+
"kubectl create job x --from=cronjob/y --from=cronjob/z -n web",
|
|
343
|
+
"kubectl create job x y --from=cronjob/z -n web",
|
|
344
|
+
"kubectl create job x --from=cronjob/y -n web -- sh",
|
|
345
|
+
];
|
|
346
|
+
|
|
347
|
+
/*
|
|
348
|
+
* Every create subcommand that makes a pod template, with an image named in
|
|
349
|
+
* the command or a program after `--`: a new program in the cluster, the
|
|
350
|
+
* same thing `create job --image` and a patch touching command/args are
|
|
351
|
+
* refused for. kubectl requires --image for create deployment and create
|
|
352
|
+
* cronjob (checked against the pinned v1.36.4: `required flag(s) "image" not
|
|
353
|
+
* set`), so both are Denied in every form — with and without a command, in
|
|
354
|
+
* every alias.
|
|
355
|
+
*/
|
|
356
|
+
const DENIED_IMAGE_WORKLOAD_CREATES: Array<string> = [
|
|
357
|
+
"kubectl create deployment web --image=nginx -n web",
|
|
358
|
+
"kubectl create deployment x --image=busybox -n web -- sh -c evil",
|
|
359
|
+
"kubectl create deploy x --image=busybox --replicas=2 -n web -- sh",
|
|
360
|
+
"kubectl create deployment x --image=busybox -r 3 --port=80 -n web",
|
|
361
|
+
"kubectl create deployment x -n web",
|
|
362
|
+
"kubectl create cronjob x --image=busybox --schedule='* * * * *' -n web -- sh -c evil",
|
|
363
|
+
"kubectl create cj x --image=busybox --schedule='* * * * *' -n web -- date",
|
|
364
|
+
"kubectl create cronjob x --image=nginx --schedule='0 * * * *' -n web",
|
|
365
|
+
"kubectl create cronjob x --schedule='0 * * * *' -n web",
|
|
366
|
+
"kubectl create -n web cronjob x --image=nginx --schedule='0 * * * *'",
|
|
367
|
+
"kubectl create deployment x --image=busybox -n web --dry-run=client -o yaml",
|
|
368
|
+
];
|
|
369
|
+
|
|
370
|
+
/*
|
|
371
|
+
* The pod-template create subcommands in every alias kubectl accepts, for
|
|
372
|
+
* the parity test: each one refuses an image named in the command and a
|
|
373
|
+
* program after `--`.
|
|
374
|
+
*/
|
|
375
|
+
const POD_TEMPLATE_CREATE_SUBCOMMANDS: Array<string> = [
|
|
376
|
+
"deployment",
|
|
377
|
+
"deploy",
|
|
378
|
+
"cronjob",
|
|
379
|
+
"cj",
|
|
380
|
+
"job",
|
|
381
|
+
];
|
|
382
|
+
|
|
383
|
+
const ALLOWED_CREATE_JOB_SHAPES: Array<string> = [
|
|
384
|
+
"kubectl create job manual-run --from=cronjob/nightly -n web",
|
|
385
|
+
"kubectl create job manual-run --from=cronjobs/nightly -n web",
|
|
386
|
+
"kubectl create job manual-run --from=cj/nightly -n web",
|
|
387
|
+
"kubectl create job manual-run --from=cronjob.batch/nightly -n web",
|
|
388
|
+
"kubectl create job --from=cronjob/nightly manual-run -n web",
|
|
389
|
+
"kubectl create -n web job manual-run --from=cronjob/nightly",
|
|
390
|
+
"kubectl create job manual-run --from=cronjob/nightly -n web --dry-run=client -o yaml",
|
|
391
|
+
];
|
|
392
|
+
|
|
393
|
+
/*
|
|
394
|
+
* Patch bodies that touch a field that changes which identity, privileges,
|
|
395
|
+
* host access, Secrets or program a pod runs with.
|
|
396
|
+
*/
|
|
397
|
+
const POD_SECURITY_FIELDS: Array<string> = [
|
|
398
|
+
"serviceAccountName",
|
|
399
|
+
"serviceAccount",
|
|
400
|
+
"automountServiceAccountToken",
|
|
401
|
+
"securityContext",
|
|
402
|
+
"privileged",
|
|
403
|
+
"capabilities",
|
|
404
|
+
"hostPath",
|
|
405
|
+
"hostNetwork",
|
|
406
|
+
"hostPID",
|
|
407
|
+
"hostIPC",
|
|
408
|
+
/*
|
|
409
|
+
* The Pod Security Standards baseline's Host Ports control and the
|
|
410
|
+
* isolation fields beside it; they were RiskyWrite (AutoApproved under
|
|
411
|
+
* Bypass approval) until the name check listed them. More shapes in
|
|
412
|
+
* KubectlPolicyPodSecurityBaseline.test.ts.
|
|
413
|
+
*/
|
|
414
|
+
"hostPort",
|
|
415
|
+
"hostUsers",
|
|
416
|
+
"runtimeClassName",
|
|
417
|
+
"shareProcessNamespace",
|
|
418
|
+
"volumes",
|
|
419
|
+
"volumeMounts",
|
|
420
|
+
"initContainers",
|
|
421
|
+
"ephemeralContainers",
|
|
422
|
+
"command",
|
|
423
|
+
"args",
|
|
424
|
+
"envFrom",
|
|
425
|
+
"secretKeyRef",
|
|
426
|
+
"secretRef",
|
|
427
|
+
"secretName",
|
|
428
|
+
];
|
|
429
|
+
|
|
430
|
+
function podTemplatePatch(fragment: string): string {
|
|
431
|
+
return `kubectl patch deployment web -n web -p '{"spec":{"template":{"spec":${fragment}}}}'`;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const DENIED_PATCH_BODIES: Array<string> = [
|
|
435
|
+
// Every forbidden key as a strategic-merge key...
|
|
436
|
+
...POD_SECURITY_FIELDS.map((field: string) => {
|
|
437
|
+
return podTemplatePatch(`{"${field}":true}`);
|
|
438
|
+
}),
|
|
439
|
+
// ... as a merge-patch key ...
|
|
440
|
+
...POD_SECURITY_FIELDS.map((field: string) => {
|
|
441
|
+
return `kubectl patch deployment web -n web --type=merge -p '{"spec":{"template":{"spec":{"${field}":true}}}}'`;
|
|
442
|
+
}),
|
|
443
|
+
// ... as a JSON-patch path segment ...
|
|
444
|
+
...POD_SECURITY_FIELDS.map((field: string) => {
|
|
445
|
+
return `kubectl patch deployment web -n web --type=json -p '[{"op":"add","path":"/spec/template/spec/containers/0/${field}","value":1}]'`;
|
|
446
|
+
}),
|
|
447
|
+
/*
|
|
448
|
+
* ... and as a YAML key. Still Denied, but now because the body is not
|
|
449
|
+
* JSON at all (see NON_JSON_PATCH_BODIES), not because the word was found.
|
|
450
|
+
*/
|
|
451
|
+
...POD_SECURITY_FIELDS.map((field: string) => {
|
|
452
|
+
return `kubectl patch deployment web -n web -p 'spec: {template: {spec: {${field}: x}}}'`;
|
|
453
|
+
}),
|
|
454
|
+
// Nested where a real escalation puts them.
|
|
455
|
+
podTemplatePatch(
|
|
456
|
+
'{"containers":[{"name":"web","securityContext":{"privileged":true}}]}',
|
|
457
|
+
),
|
|
458
|
+
podTemplatePatch(
|
|
459
|
+
'{"volumes":[{"name":"creds","secret":{"secretName":"db-creds"}}]}',
|
|
460
|
+
),
|
|
461
|
+
podTemplatePatch(
|
|
462
|
+
'{"containers":[{"name":"web","env":[{"name":"P","valueFrom":{"secretKeyRef":{"name":"db","key":"p"}}}]}]}',
|
|
463
|
+
),
|
|
464
|
+
podTemplatePatch(
|
|
465
|
+
'{"containers":[{"name":"web","command":["sh","-c","id"]}]}',
|
|
466
|
+
),
|
|
467
|
+
podTemplatePatch('{"hostNetwork":true,"hostPID":true}'),
|
|
468
|
+
'kubectl patch pod web-abc -n prod -p \'{"spec":{"ephemeralContainers":[{"name":"x","image":"busybox"}]}}\'',
|
|
469
|
+
'kubectl patch cronjob nightly -n web -p \'{"spec":{"jobTemplate":{"spec":{"template":{"spec":{"serviceAccountName":"admin"}}}}}}\'',
|
|
470
|
+
'kubectl patch daemonset kube-proxy -n web --type=json -p \'[{"op":"replace","path":"/spec/template/spec/hostNetwork","value":true}]\'',
|
|
471
|
+
'kubectl patch deployment web -n web --type=json -p \'[{"op":"move","from":"/spec/template/spec/initContainers","path":"/spec/x"}]\'',
|
|
472
|
+
// Case does not matter, and neither do escapes: JSON is decoded first.
|
|
473
|
+
podTemplatePatch('{"ServiceAccountName":"admin"}'),
|
|
474
|
+
podTemplatePatch('{"HOSTNETWORK":true}'),
|
|
475
|
+
podTemplatePatch('{"serviceAccount\\u004eame":"admin"}'),
|
|
476
|
+
'kubectl patch deployment web -n web --type=json -p \'[{"op":"add","path":"/spec/template/spec/serviceAccount\\u004eame","value":"admin"}]\'',
|
|
477
|
+
// Strategic-merge directives name the list they edit after the slash.
|
|
478
|
+
podTemplatePatch('{"$setElementOrder/volumes":[{"name":"x"}]}'),
|
|
479
|
+
podTemplatePatch(
|
|
480
|
+
'{"containers":[{"name":"web","$deleteFromPrimitiveList/args":["--safe"]}]}',
|
|
481
|
+
),
|
|
482
|
+
// Pod Security Admission labels, through patch.
|
|
483
|
+
'kubectl patch ns web -p \'{"metadata":{"labels":{"pod-security.kubernetes.io/enforce":"privileged"}}}\'',
|
|
484
|
+
'kubectl patch namespace web --type=json -p \'[{"op":"remove","path":"/metadata/labels/pod-security.kubernetes.io~1enforce"}]\'',
|
|
485
|
+
// Both spellings of the flag.
|
|
486
|
+
'kubectl patch deployment web -n web --patch \'{"spec":{"template":{"spec":{"hostPID":true}}}}\'',
|
|
487
|
+
'kubectl patch deployment web -n web --patch=\'{"spec":{"template":{"spec":{"hostIPC":true}}}}\'',
|
|
488
|
+
// The body kubectl uses is the last one; every body is checked.
|
|
489
|
+
'kubectl patch deployment web -n web -p \'{"spec":{"replicas":2}}\' --patch=\'{"spec":{"template":{"spec":{"hostPID":true}}}}\'',
|
|
490
|
+
];
|
|
491
|
+
|
|
492
|
+
/*
|
|
493
|
+
* ---- 3. Patch bodies that are not JSON ---------------------------------------
|
|
494
|
+
*
|
|
495
|
+
* kubectl sends a body starting with "{" to the API server unchanged and
|
|
496
|
+
* decodes every other body — a JSON patch's "[" included — as YAML 1.1. A
|
|
497
|
+
* YAML tag builds a key or a JSON-patch path out of base64, so the field
|
|
498
|
+
* name appears nowhere in the text: `!!binary c2VydmljZUFjY291bnROYW1l` is
|
|
499
|
+
* serviceAccountName, aG9zdE5ldHdvcms= is hostNetwork, aG9zdFBJRA== is
|
|
500
|
+
* hostPID. The old check scanned a non-JSON body for literal words and tiered
|
|
501
|
+
* these RiskyWrite (AutoApproved under Bypass approval); the pinned kubectl
|
|
502
|
+
* applied every one of them.
|
|
503
|
+
*/
|
|
504
|
+
const TAGGED_YAML_PATCH_BODIES: Array<string> = [
|
|
505
|
+
// strategic merge (the default type)
|
|
506
|
+
"kubectl patch deployment web -n web -p 'spec: {template: {spec: {!!binary c2VydmljZUFjY291bnROYW1l: default}}}'",
|
|
507
|
+
"kubectl patch deployment web -n web --type=strategic -p 'spec: {template: {spec: {!!binary aG9zdE5ldHdvcms=: true}}}'",
|
|
508
|
+
"kubectl patch deployment web -n web -p 'spec: {template: {spec: {? !!binary aG9zdFBJRA== : true}}}'",
|
|
509
|
+
// merge
|
|
510
|
+
"kubectl patch deployment web -n web --type=merge -p 'spec: {template: {spec: {? !!binary aG9zdE5ldHdvcms= : true}}}'",
|
|
511
|
+
"kubectl patch deployment web -n web --type merge -p 'spec: {template: {spec: {!!binary c2VydmljZUFjY291bnROYW1l: default}}}'",
|
|
512
|
+
// json: the path is the tagged value
|
|
513
|
+
"kubectl patch deployment web -n web --type=json -p '[{op: replace, path: !!binary L3NwZWMvdGVtcGxhdGUvc3BlYy9zZXJ2aWNlQWNjb3VudE5hbWU=, value: default}]'",
|
|
514
|
+
"kubectl patch deployment web -n web --type=json -p '[{op: add, path: !!binary L3NwZWMvdGVtcGxhdGUvc3BlYy9ob3N0TmV0d29yaw==, value: true}]'",
|
|
515
|
+
// The verbatim tag form, and a %TAG-free local tag.
|
|
516
|
+
"kubectl patch deployment web -n web -p 'spec: {template: {spec: {!<tag:yaml.org,2002:binary> aG9zdFBJRA==: true}}}'",
|
|
517
|
+
"kubectl patch deployment web -n web --type=merge -p 'spec: {template: {spec: {!<tag:yaml.org,2002:binary> c2VydmljZUFjY291bnROYW1l: default}}}'",
|
|
518
|
+
// A Pod Security Admission label spelled through a tag.
|
|
519
|
+
"kubectl patch ns web -p 'metadata: {labels: {!!binary cG9kLXNlY3VyaXR5Lmt1YmVybmV0ZXMuaW8vZW5mb3JjZQ==: privileged}}'",
|
|
520
|
+
// Anchors, aliases and merge keys.
|
|
521
|
+
"kubectl patch deployment web -n web -p 'spec: {template: {spec: {a: &k hostNetwork, *k : true}}}'",
|
|
522
|
+
"kubectl patch deployment web -n web --type=merge -p 'spec: {<<: {replicas: 4}}'",
|
|
523
|
+
"kubectl patch deployment web -n web --type=json -p '[&op {op: replace, path: /spec/replicas, value: 2}, *op]'",
|
|
524
|
+
];
|
|
525
|
+
|
|
526
|
+
/*
|
|
527
|
+
* Plain YAML with only harmless fields is Denied too, although kubectl
|
|
528
|
+
* would apply it: the policy cannot tell harmless YAML from tagged YAML
|
|
529
|
+
* without decoding YAML exactly as kubectl does, and every patch a fix needs
|
|
530
|
+
* can be written as JSON (the refusal says so). These were RiskyWrite
|
|
531
|
+
* before.
|
|
532
|
+
*/
|
|
533
|
+
const PLAIN_YAML_PATCH_BODIES: Array<string> = [
|
|
534
|
+
"kubectl patch deployment web -n web -p 'spec: {replicas: 2}'",
|
|
535
|
+
"kubectl patch deployment web -n web --type=merge -p 'spec: {replicas: 2}'",
|
|
536
|
+
"kubectl patch deployment web -n web --type=json -p '[{op: replace, path: /spec/replicas, value: 3}]'",
|
|
537
|
+
"kubectl patch cronjob nightly -n web -p 'spec: {suspend: true}'",
|
|
538
|
+
"kubectl patch ns web -p 'metadata: {labels: {pod-security.kubernetes.io/enforce: privileged}}'",
|
|
539
|
+
// A YAML escape, the old check's only refusal besides the word scan.
|
|
540
|
+
"kubectl patch deployment web -n web -p 'spec: {template: {spec: {\"serviceAccount\\x4eame\": admin}}}'",
|
|
541
|
+
// Not a body at all.
|
|
542
|
+
"kubectl patch deployment web -n web -p ''",
|
|
543
|
+
"kubectl patch deployment web -n web -p replicas=2",
|
|
544
|
+
/*
|
|
545
|
+
* Almost JSON: a JSON patch with a trailing comment (kubectl decodes a "["
|
|
546
|
+
* body as YAML and would apply it), and a trailing comma.
|
|
547
|
+
*/
|
|
548
|
+
'kubectl patch deployment web -n web --type=json -p \'[{"op":"replace","path":"/spec/replicas","value":3}] # c\'',
|
|
549
|
+
'kubectl patch deployment web -n web -p \'{"spec":{"replicas":2},}\'',
|
|
550
|
+
];
|
|
551
|
+
|
|
552
|
+
const NON_JSON_PATCH_BODIES: Array<string> = [
|
|
553
|
+
...TAGGED_YAML_PATCH_BODIES,
|
|
554
|
+
...PLAIN_YAML_PATCH_BODIES,
|
|
555
|
+
];
|
|
556
|
+
|
|
557
|
+
/*
|
|
558
|
+
* Negative controls: JSON bodies that change only what a fix changes stay
|
|
559
|
+
* RiskyWrite — and so still run under Bypass approval or a matching
|
|
560
|
+
* allowlist entry.
|
|
561
|
+
*/
|
|
562
|
+
const ALLOWED_PATCH_BODIES: Array<string> = [
|
|
563
|
+
'kubectl patch deployment web -n web -p \'{"spec":{"replicas":2}}\'',
|
|
564
|
+
'kubectl patch deployment web -n web --type=merge -p \'{"spec":{"replicas":2}}\'',
|
|
565
|
+
podTemplatePatch(
|
|
566
|
+
'{"containers":[{"name":"web","resources":{"limits":{"memory":"1Gi"}}}]}',
|
|
567
|
+
),
|
|
568
|
+
podTemplatePatch('{"containers":[{"name":"web","image":"nginx:1.27"}]}'),
|
|
569
|
+
podTemplatePatch(
|
|
570
|
+
'{"containers":[{"name":"web","env":[{"name":"LOG_LEVEL","value":"debug"}]}]}',
|
|
571
|
+
),
|
|
572
|
+
'kubectl patch deployment web -n web -p \'{"spec":{"template":{"metadata":{"annotations":{"kubectl.kubernetes.io/restartedAt":"2026-09-22T00:00:00Z"}}}}}\'',
|
|
573
|
+
// A forbidden word as a VALUE is just text in a JSON body.
|
|
574
|
+
'kubectl patch deployment web -n web -p \'{"metadata":{"annotations":{"note":"fixed command args volumes"}}}\'',
|
|
575
|
+
'kubectl patch deployment web -n web -p \'{"metadata":{"annotations":{"path":"/spec/command"}}}\'',
|
|
576
|
+
// YAML syntax inside a JSON string is only text, to JSON and YAML alike.
|
|
577
|
+
'kubectl patch deployment web -n web -p \'{"metadata":{"annotations":{"note":"!!binary c2VydmljZUFjY291bnROYW1l &a *a <<"}}}\'',
|
|
578
|
+
'kubectl patch deployment web -n web --type=json -p \'[{"op":"replace","path":"/spec/replicas","value":3}]\'',
|
|
579
|
+
'kubectl patch deployment web -n web --type=json -p \'[ {"op":"replace","path":"/spec/replicas","value":3} ]\'',
|
|
580
|
+
'kubectl patch cronjob nightly -n web -p \'{"spec":{"suspend":true}}\'',
|
|
581
|
+
'kubectl patch hpa web -n web -p \'{"spec":{"minReplicas":3}}\'',
|
|
582
|
+
'kubectl patch pdb web -n web -p \'{"spec":{"minAvailable":1}}\'',
|
|
583
|
+
"kubectl patch deployment web -n web -p '{}'",
|
|
584
|
+
];
|
|
585
|
+
|
|
586
|
+
// Allowlist entries an operator could write for patches (all valid, none broad).
|
|
587
|
+
const PATCH_ALLOWLIST_ENTRIES: Array<string> = [
|
|
588
|
+
"kubectl patch deployment web -n web -p *",
|
|
589
|
+
"kubectl patch deployment web -n web --type=merge -p *",
|
|
590
|
+
"kubectl patch deployment web -n web --type=json -p *",
|
|
591
|
+
"kubectl patch deployment web -n web --type=strategic -p *",
|
|
592
|
+
"kubectl patch deployment web -n web --type merge -p *",
|
|
593
|
+
];
|
|
594
|
+
|
|
595
|
+
// ---- 4. Categories and never-delete kinds, in every spelling ---------------------
|
|
596
|
+
|
|
597
|
+
const DENIED_CATEGORY_WRITES: Array<string> = [
|
|
598
|
+
"kubectl delete api-extensions -l app.kubernetes.io/instance=cert-manager",
|
|
599
|
+
"kubectl delete api-extensions -l '!x'",
|
|
600
|
+
"kubectl delete api-extensions foo",
|
|
601
|
+
"kubectl delete api-extensions/foo",
|
|
602
|
+
"kubectl delete API-Extensions -l app=x",
|
|
603
|
+
"kubectl delete pods,api-extensions -l app=x",
|
|
604
|
+
"kubectl delete api-extensions,pods -l app=x",
|
|
605
|
+
"kubectl delete deployments,api-extensions -l app=x -n web",
|
|
606
|
+
"kubectl delete all -l app=web -n web",
|
|
607
|
+
"kubectl delete all web -n web",
|
|
608
|
+
"kubectl delete all --all -n web",
|
|
609
|
+
"kubectl delete ALL -l app=web -n web",
|
|
610
|
+
"kubectl delete managed -l crossplane.io/claim-name=db",
|
|
611
|
+
"kubectl delete crossplane -l x=y",
|
|
612
|
+
"kubectl delete gateway-api -l x=y -n web",
|
|
613
|
+
"kubectl delete cert-manager -l x=y -n web",
|
|
614
|
+
"kubectl delete knative -l x=y -n web",
|
|
615
|
+
"kubectl label api-extensions -l x=y a=b",
|
|
616
|
+
"kubectl label all -l app=web a=b -n web",
|
|
617
|
+
"kubectl annotate all -n web --all a=b",
|
|
618
|
+
"kubectl patch all web -n web -p '{}'",
|
|
619
|
+
"kubectl rollout restart all -n web",
|
|
620
|
+
"kubectl rollout undo all/web -n web",
|
|
621
|
+
"kubectl scale all --all --replicas=1 -n web",
|
|
622
|
+
"kubectl set image all web=nginx -n web",
|
|
623
|
+
];
|
|
624
|
+
|
|
625
|
+
// Reading a category is fine.
|
|
626
|
+
const ALLOWED_CATEGORY_READS: Array<string> = [
|
|
627
|
+
"kubectl get all -n web",
|
|
628
|
+
"kubectl get api-extensions",
|
|
629
|
+
"kubectl get all -A",
|
|
630
|
+
"kubectl describe all -n web",
|
|
631
|
+
];
|
|
632
|
+
|
|
633
|
+
/*
|
|
634
|
+
* Every NEVER_DELETE kind, in the spellings kubectl accepts: plural,
|
|
635
|
+
* singular, short name, Kind case, group-qualified, TYPE/NAME, comma lists,
|
|
636
|
+
* and behind optional-value flags.
|
|
637
|
+
*/
|
|
638
|
+
const DENIED_NEVER_DELETE_SPELLINGS: Array<string> = [
|
|
639
|
+
"kubectl delete namespace prod",
|
|
640
|
+
"kubectl delete namespaces prod",
|
|
641
|
+
"kubectl delete ns prod",
|
|
642
|
+
"kubectl delete Namespace prod",
|
|
643
|
+
"kubectl delete namespaces.v1. prod",
|
|
644
|
+
"kubectl delete ns/prod",
|
|
645
|
+
"kubectl delete node worker-1",
|
|
646
|
+
"kubectl delete nodes worker-1",
|
|
647
|
+
"kubectl delete no worker-1",
|
|
648
|
+
"kubectl delete node/worker-1",
|
|
649
|
+
"kubectl delete pv data-1",
|
|
650
|
+
"kubectl delete persistentvolumes data-1",
|
|
651
|
+
"kubectl delete PersistentVolume data-1",
|
|
652
|
+
"kubectl delete pvc data-0 -n web",
|
|
653
|
+
"kubectl delete persistentvolumeclaims data-0 -n web",
|
|
654
|
+
"kubectl delete persistentvolumeclaim/data-0 -n web",
|
|
655
|
+
"kubectl delete crd certificates.cert-manager.io",
|
|
656
|
+
"kubectl delete crds certificates.cert-manager.io",
|
|
657
|
+
"kubectl delete CustomResourceDefinition certificates.cert-manager.io",
|
|
658
|
+
"kubectl delete customresourcedefinitions.apiextensions.k8s.io certificates.cert-manager.io",
|
|
659
|
+
"kubectl delete customresourcedefinitions.v1.apiextensions.k8s.io/certificates.cert-manager.io",
|
|
660
|
+
"kubectl delete clusterrole admin",
|
|
661
|
+
"kubectl delete clusterroles.rbac.authorization.k8s.io admin",
|
|
662
|
+
"kubectl delete clusterrolebinding admin",
|
|
663
|
+
"kubectl delete clusterrolebindings/admin",
|
|
664
|
+
"kubectl delete role x -n web",
|
|
665
|
+
"kubectl delete rolebinding x -n web",
|
|
666
|
+
"kubectl delete sc standard",
|
|
667
|
+
"kubectl delete storageclasses.storage.k8s.io standard",
|
|
668
|
+
"kubectl delete secret db -n web",
|
|
669
|
+
"kubectl delete secrets.v1. db -n web",
|
|
670
|
+
"kubectl delete pc high",
|
|
671
|
+
"kubectl delete priorityclasses.scheduling.k8s.io high",
|
|
672
|
+
"kubectl delete apiservice v1beta1.metrics.k8s.io",
|
|
673
|
+
"kubectl delete apiservices.apiregistration.k8s.io v1beta1.metrics.k8s.io",
|
|
674
|
+
"kubectl delete mutatingwebhookconfiguration istio-sidecar-injector",
|
|
675
|
+
"kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io x",
|
|
676
|
+
"kubectl delete validatingwebhookconfiguration gatekeeper",
|
|
677
|
+
"kubectl delete validatingwebhookconfigurations/gatekeeper",
|
|
678
|
+
"kubectl delete validatingadmissionpolicy p",
|
|
679
|
+
"kubectl delete validatingadmissionpolicies.admissionregistration.k8s.io p",
|
|
680
|
+
"kubectl delete validatingadmissionpolicybindings foo",
|
|
681
|
+
"kubectl delete mutatingadmissionpolicy p",
|
|
682
|
+
"kubectl delete mutatingadmissionpolicybindings/p",
|
|
683
|
+
"kubectl delete csr csr-1",
|
|
684
|
+
"kubectl delete certificatesigningrequests csr-1",
|
|
685
|
+
"kubectl delete pod,ns web-1 prod -n web",
|
|
686
|
+
"kubectl delete deployment,crd web x -n web",
|
|
687
|
+
"kubectl delete --cascade=orphan crd x",
|
|
688
|
+
"kubectl delete --cascade node worker-1",
|
|
689
|
+
"kubectl delete -n web --dry-run=server pvc data-0",
|
|
690
|
+
];
|
|
691
|
+
|
|
692
|
+
// ---- 5. Verbs and subcommands kubectl would not run as written --------------------
|
|
693
|
+
|
|
694
|
+
const DENIED_VERB_SHAPES: Array<string> = [
|
|
695
|
+
"kubectl kuberc view",
|
|
696
|
+
"kubectl kuberc set --section defaults --command get --option output=wide",
|
|
697
|
+
"kubectl plugin list",
|
|
698
|
+
"kubectl frobnicate pods",
|
|
699
|
+
"kubectl get-pods",
|
|
700
|
+
"kubectl pods",
|
|
701
|
+
"kubectl node-shell worker-1",
|
|
702
|
+
"kubectl krew install x",
|
|
703
|
+
"kubectl ctx prod",
|
|
704
|
+
"kubectl whoami",
|
|
705
|
+
// cobra matches commands case-sensitively; kubectl would look for a plugin.
|
|
706
|
+
"kubectl Get pods",
|
|
707
|
+
"kubectl GET pods -n web",
|
|
708
|
+
"kubectl Describe pod x",
|
|
709
|
+
"kubectl Delete pod web-1 -n web",
|
|
710
|
+
"kubectl Rollout restart deployment/web -n web",
|
|
711
|
+
"kubectl rollout Restart deployment/web -n web",
|
|
712
|
+
"kubectl rollout STATUS deployment/web -n web",
|
|
713
|
+
"kubectl set Image deployment/web web=nginx -n web",
|
|
714
|
+
"kubectl create Job x --from=cronjob/y -n web",
|
|
715
|
+
"kubectl create ConfigMap x --from-literal=a=b -n web",
|
|
716
|
+
"kubectl auth Can-I get pods",
|
|
717
|
+
"kubectl top Pod -n web",
|
|
718
|
+
"kubectl cluster-info Dump",
|
|
719
|
+
// create subcommands kubectl does not have (kubectl-create-<name> plugins).
|
|
720
|
+
"kubectl create frobnicate x -n web",
|
|
721
|
+
"kubectl create deployments web --image=nginx -n web",
|
|
722
|
+
"kubectl create secrets generic x --from-literal=a=b -n web",
|
|
723
|
+
"kubectl create pod x -n web",
|
|
724
|
+
"kubectl create",
|
|
725
|
+
// A namespace set twice (pflag keeps the last one).
|
|
726
|
+
"kubectl get pods -n a -n b",
|
|
727
|
+
"kubectl -n a get pods --namespace=b",
|
|
728
|
+
"kubectl get pods -na --namespace b",
|
|
729
|
+
"kubectl -n web get pods -n kube-system",
|
|
730
|
+
"kubectl -n web patch deployment web -p '{}' -n kube-system",
|
|
731
|
+
"kubectl patch deployment web -n web -p '{}' --namespace=kube-system",
|
|
732
|
+
"kubectl scale deployment web --replicas=1 -n prod -n kube-system",
|
|
733
|
+
"kubectl delete pod web-1 -n web -nkube-system",
|
|
734
|
+
"kubectl get pods -n web -n web",
|
|
735
|
+
];
|
|
736
|
+
|
|
737
|
+
// ---- 6. Global flags ------------------------------------------------------------
|
|
738
|
+
|
|
739
|
+
/*
|
|
740
|
+
* kubectl v1.36.4's global flags. Every one may change which credentials,
|
|
741
|
+
* identity or cluster kubectl uses, write a file on the Runner, or log
|
|
742
|
+
* request bodies — except these four, which the policy allows.
|
|
743
|
+
*/
|
|
744
|
+
const ALLOWED_GLOBAL_FLAGS: Array<string> = [
|
|
745
|
+
"n",
|
|
746
|
+
"namespace",
|
|
747
|
+
"request-timeout",
|
|
748
|
+
"match-server-version",
|
|
749
|
+
];
|
|
750
|
+
|
|
751
|
+
const KUBECTL_1_36_GLOBAL_FLAGS: Array<string> = [
|
|
752
|
+
"as",
|
|
753
|
+
"as-group",
|
|
754
|
+
"as-uid",
|
|
755
|
+
"as-user-extra",
|
|
756
|
+
"cache-dir",
|
|
757
|
+
"certificate-authority",
|
|
758
|
+
"client-certificate",
|
|
759
|
+
"client-key",
|
|
760
|
+
"cluster",
|
|
761
|
+
"context",
|
|
762
|
+
"disable-compression",
|
|
763
|
+
"insecure-skip-tls-verify",
|
|
764
|
+
"kubeconfig",
|
|
765
|
+
"kuberc",
|
|
766
|
+
"log-flush-frequency",
|
|
767
|
+
"match-server-version",
|
|
768
|
+
"n",
|
|
769
|
+
"namespace",
|
|
770
|
+
"password",
|
|
771
|
+
"profile",
|
|
772
|
+
"profile-output",
|
|
773
|
+
"request-timeout",
|
|
774
|
+
"s",
|
|
775
|
+
"server",
|
|
776
|
+
"tls-server-name",
|
|
777
|
+
"token",
|
|
778
|
+
"user",
|
|
779
|
+
"username",
|
|
780
|
+
"v",
|
|
781
|
+
"vmodule",
|
|
782
|
+
"warnings-as-errors",
|
|
783
|
+
];
|
|
784
|
+
|
|
785
|
+
const DENIED_GLOBAL_FLAGS: Array<string> = KUBECTL_1_36_GLOBAL_FLAGS.filter(
|
|
786
|
+
(flag: string) => {
|
|
787
|
+
return !ALLOWED_GLOBAL_FLAGS.includes(flag);
|
|
788
|
+
},
|
|
789
|
+
);
|
|
790
|
+
|
|
791
|
+
function flagSpellings(flag: string): Array<string> {
|
|
792
|
+
const dash: string = flag.length === 1 ? `-${flag}` : `--${flag}`;
|
|
793
|
+
const spellings: Array<string> = [
|
|
794
|
+
`kubectl get pods ${dash}=x`,
|
|
795
|
+
`kubectl get pods ${dash} x`,
|
|
796
|
+
`kubectl get pods -n web ${dash}=x`,
|
|
797
|
+
`kubectl delete pod web-1 -n web ${dash}=x`,
|
|
798
|
+
`kubectl rollout restart deployment/web -n web ${dash}=x`,
|
|
799
|
+
];
|
|
800
|
+
if (flag.length > 1) {
|
|
801
|
+
spellings.push(`kubectl ${dash}=x get pods`);
|
|
802
|
+
}
|
|
803
|
+
if (flag.includes("-")) {
|
|
804
|
+
// kubectl reads "_" as "-" in a long flag name.
|
|
805
|
+
const underscored: string = `--${flag.replace(/-/g, "_")}`;
|
|
806
|
+
spellings.push(`kubectl get pods ${underscored}=x`);
|
|
807
|
+
spellings.push(`kubectl get pods ${underscored} x`);
|
|
808
|
+
spellings.push(
|
|
809
|
+
`kubectl scale deployment/web --replicas=2 -n web ${underscored}=x`,
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
if (flag.length === 1) {
|
|
813
|
+
// Hidden in a short-flag cluster.
|
|
814
|
+
spellings.push(`kubectl get pods -A${flag} x`);
|
|
815
|
+
}
|
|
816
|
+
return spellings;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
const DENIED_GLOBAL_FLAG_SHAPES: Array<string> = DENIED_GLOBAL_FLAGS.flatMap(
|
|
820
|
+
(flag: string) => {
|
|
821
|
+
return flagSpellings(flag);
|
|
822
|
+
},
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
const ALLOWED_GLOBAL_FLAG_SHAPES: Array<[string, KubectlCommandTier]> = [
|
|
826
|
+
["kubectl get pods -n web", KubectlCommandTier.Read],
|
|
827
|
+
["kubectl get pods --namespace=web", KubectlCommandTier.Read],
|
|
828
|
+
["kubectl get pods --request-timeout=30s -n web", KubectlCommandTier.Read],
|
|
829
|
+
["kubectl get pods --request_timeout=30s -n web", KubectlCommandTier.Read],
|
|
830
|
+
["kubectl get pods --match-server-version -n web", KubectlCommandTier.Read],
|
|
831
|
+
["kubectl get pods --match_server_version -n web", KubectlCommandTier.Read],
|
|
832
|
+
[
|
|
833
|
+
"kubectl --request-timeout=5s -n web delete pod web-1",
|
|
834
|
+
KubectlCommandTier.SafeWrite,
|
|
835
|
+
],
|
|
836
|
+
["kubectl get pods --all_namespaces", KubectlCommandTier.Read],
|
|
837
|
+
[
|
|
838
|
+
"kubectl get pods --field_selector=status.phase=Pending",
|
|
839
|
+
KubectlCommandTier.Read,
|
|
840
|
+
],
|
|
841
|
+
[
|
|
842
|
+
"kubectl scale deployment web --replicas=2 --current_replicas=1 -n web",
|
|
843
|
+
KubectlCommandTier.SafeWrite,
|
|
844
|
+
],
|
|
845
|
+
];
|
|
846
|
+
|
|
847
|
+
// ---- Every Denied table, for the property tests -----------------------------------
|
|
848
|
+
|
|
849
|
+
const ALL_DENIED_COMMANDS: Array<string> = [
|
|
850
|
+
...DENIED_IDENTITY_AND_RBAC_SHAPES,
|
|
851
|
+
...DENIED_CLUSTER_CONTROL_WRITES,
|
|
852
|
+
...DENIED_CREATE_JOB_SHAPES,
|
|
853
|
+
...DENIED_IMAGE_WORKLOAD_CREATES,
|
|
854
|
+
...DENIED_PATCH_BODIES,
|
|
855
|
+
...NON_JSON_PATCH_BODIES,
|
|
856
|
+
...DENIED_CATEGORY_WRITES,
|
|
857
|
+
...DENIED_NEVER_DELETE_SPELLINGS,
|
|
858
|
+
...DENIED_VERB_SHAPES,
|
|
859
|
+
...DENIED_GLOBAL_FLAG_SHAPES,
|
|
860
|
+
];
|
|
861
|
+
|
|
862
|
+
/*
|
|
863
|
+
* The broadest allowlist entry of a command's shape: the verb (and a
|
|
864
|
+
* subcommand) kept, every flag spelled as written with any "=value" globbed,
|
|
865
|
+
* and every other word a wildcard. It is a valid entry whenever the verb is
|
|
866
|
+
* one OneUptime AI may run, and it matches the command whenever no word has
|
|
867
|
+
* a space in it.
|
|
868
|
+
*/
|
|
869
|
+
function broadestShapeOf(command: string): string {
|
|
870
|
+
const args: Array<string> = KubectlPolicy.tokenize(command).args || [];
|
|
871
|
+
const keep: number = [
|
|
872
|
+
"rollout",
|
|
873
|
+
"set",
|
|
874
|
+
"create",
|
|
875
|
+
"auth",
|
|
876
|
+
"cluster-info",
|
|
877
|
+
"top",
|
|
878
|
+
].includes(args[0] || "")
|
|
879
|
+
? 2
|
|
880
|
+
: 1;
|
|
881
|
+
return [
|
|
882
|
+
"kubectl",
|
|
883
|
+
...args.map((arg: string, index: number) => {
|
|
884
|
+
if (index < keep) {
|
|
885
|
+
return arg;
|
|
886
|
+
}
|
|
887
|
+
if (arg.startsWith("-") && arg !== "-") {
|
|
888
|
+
return arg.includes("=") ? `${arg.slice(0, arg.indexOf("="))}=*` : arg;
|
|
889
|
+
}
|
|
890
|
+
return "*";
|
|
891
|
+
}),
|
|
892
|
+
].join(" ");
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
describe("KubectlPolicy denials", () => {
|
|
896
|
+
describe("changes to who may do what are Denied", () => {
|
|
897
|
+
it.each(DENIED_IDENTITY_AND_RBAC_SHAPES)("denies %s", (command: string) => {
|
|
898
|
+
const result: KubectlPolicyResult =
|
|
899
|
+
KubectlPolicy.evaluateCommand(command);
|
|
900
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
901
|
+
expect(result.reason.length).toBeGreaterThan(0);
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
it.each(ALLOWED_IDENTITY_NEIGHBOURS)(
|
|
905
|
+
"keeps %s at %s",
|
|
906
|
+
(command: string, expected: KubectlCommandTier) => {
|
|
907
|
+
expect(tier(command)).toBe(expected);
|
|
908
|
+
},
|
|
909
|
+
);
|
|
910
|
+
|
|
911
|
+
it("explains an RBAC grant as a privilege grant", () => {
|
|
912
|
+
expect(
|
|
913
|
+
reason(
|
|
914
|
+
"kubectl create clusterrolebinding x --clusterrole=cluster-admin --serviceaccount=ns:sa",
|
|
915
|
+
),
|
|
916
|
+
).toContain("privilege grant");
|
|
917
|
+
expect(
|
|
918
|
+
reason(
|
|
919
|
+
"kubectl set subject clusterrolebinding view --serviceaccount=web:sa",
|
|
920
|
+
),
|
|
921
|
+
).toContain("privilege grant");
|
|
922
|
+
expect(
|
|
923
|
+
reason(
|
|
924
|
+
'kubectl patch clusterrolebinding view -p \'{"roleRef":{"name":"cluster-admin"}}\'',
|
|
925
|
+
),
|
|
926
|
+
).toContain("clusterrolebinding objects is never allowed");
|
|
927
|
+
expect(
|
|
928
|
+
reason("kubectl set serviceaccount deployment web sa -n web"),
|
|
929
|
+
).toContain("identity");
|
|
930
|
+
expect(
|
|
931
|
+
reason(
|
|
932
|
+
"kubectl label clusterrole x rbac.authorization.k8s.io/aggregate-to-admin=true",
|
|
933
|
+
),
|
|
934
|
+
).toContain("admin/edit/view");
|
|
935
|
+
expect(
|
|
936
|
+
KubectlPolicy.evaluateCommand("kubectl create sa x -n web").verb,
|
|
937
|
+
).toBe("create serviceaccount");
|
|
938
|
+
});
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
describe("every write to an RBAC, admission or API-extension kind is Denied", () => {
|
|
942
|
+
it.each(CLUSTER_CONTROL_KIND_SPELLINGS)(
|
|
943
|
+
"denies every write verb on %s, and nothing lifts it",
|
|
944
|
+
(kind: string, namespaced: boolean) => {
|
|
945
|
+
for (const command of clusterControlWrites(kind, namespaced)) {
|
|
946
|
+
const result: KubectlPolicyResult =
|
|
947
|
+
KubectlPolicy.evaluateCommand(command);
|
|
948
|
+
expect({ command, tier: result.tier }).toEqual({
|
|
949
|
+
command,
|
|
950
|
+
tier: KubectlCommandTier.Denied,
|
|
951
|
+
});
|
|
952
|
+
expect(result.reason).toContain("is never allowed for OneUptime AI");
|
|
953
|
+
|
|
954
|
+
const verdict: KubectlAutoExecutionVerdict =
|
|
955
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
956
|
+
command,
|
|
957
|
+
allowlistPatterns: [command, broadestShapeOf(command)],
|
|
958
|
+
bypassApproval: true,
|
|
959
|
+
});
|
|
960
|
+
expect({ command, verdict: verdict.verdict }).toEqual({
|
|
961
|
+
command,
|
|
962
|
+
verdict: AiRemediationCommandPolicyVerdict.Denied,
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
// Deleting one is refused by the never-delete list.
|
|
967
|
+
expect(
|
|
968
|
+
tier(`kubectl delete ${kind} x${namespaced ? " -n web" : ""}`),
|
|
969
|
+
).toBe(KubectlCommandTier.Denied);
|
|
970
|
+
// Reading one stays Read.
|
|
971
|
+
expect(tier(`kubectl get ${kind} x -o yaml`)).toBe(
|
|
972
|
+
KubectlCommandTier.Read,
|
|
973
|
+
);
|
|
974
|
+
expect(tier(`kubectl describe ${kind}/x`)).toBe(
|
|
975
|
+
KubectlCommandTier.Read,
|
|
976
|
+
);
|
|
977
|
+
},
|
|
978
|
+
);
|
|
979
|
+
|
|
980
|
+
it.each(DENIED_CLUSTER_CONTROL_WRITES)("denies %s", (command: string) => {
|
|
981
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
it.each(CLUSTER_CONTROL_READS)("keeps %s Read", (command: string) => {
|
|
985
|
+
expect(tier(command)).toBe(KubectlCommandTier.Read);
|
|
986
|
+
expect(
|
|
987
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
988
|
+
command,
|
|
989
|
+
allowlistPatterns: [],
|
|
990
|
+
}).verdict,
|
|
991
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
992
|
+
});
|
|
993
|
+
|
|
994
|
+
it.each(CLUSTER_CONTROL_NEIGHBOURS)(
|
|
995
|
+
"keeps the neighbour %s at %s",
|
|
996
|
+
(command: string, expected: KubectlCommandTier) => {
|
|
997
|
+
expect(tier(command)).toBe(expected);
|
|
998
|
+
},
|
|
999
|
+
);
|
|
1000
|
+
|
|
1001
|
+
it("says what an admission or API-extension change does, and who makes it", () => {
|
|
1002
|
+
const text: string = reason(
|
|
1003
|
+
'kubectl patch validatingadmissionpolicybinding restricted-pods --type=merge -p \'{"spec":{"validationActions":["Audit"]}}\'',
|
|
1004
|
+
);
|
|
1005
|
+
expect(text).toContain(
|
|
1006
|
+
"validatingadmissionpolicybinding objects is never allowed",
|
|
1007
|
+
);
|
|
1008
|
+
expect(text).toContain("what the API server admits and serves");
|
|
1009
|
+
expect(text).toContain("a human makes that change");
|
|
1010
|
+
expect(
|
|
1011
|
+
KubectlPolicy.evaluateCommand(
|
|
1012
|
+
"kubectl label apiservices.apiregistration.k8s.io/v1beta1.metrics.k8s.io a=b",
|
|
1013
|
+
).verb,
|
|
1014
|
+
).toBe("label apiservice");
|
|
1015
|
+
expect(reason("kubectl annotate rolebinding x -n web a=b")).toContain(
|
|
1016
|
+
"privilege grant",
|
|
1017
|
+
);
|
|
1018
|
+
});
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
describe("create job only re-runs an existing CronJob", () => {
|
|
1022
|
+
it.each(DENIED_CREATE_JOB_SHAPES)("denies %s", (command: string) => {
|
|
1023
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
it.each(ALLOWED_CREATE_JOB_SHAPES)(
|
|
1027
|
+
"keeps %s RiskyWrite",
|
|
1028
|
+
(command: string) => {
|
|
1029
|
+
expect(tier(command)).toBe(KubectlCommandTier.RiskyWrite);
|
|
1030
|
+
},
|
|
1031
|
+
);
|
|
1032
|
+
|
|
1033
|
+
it("says what to write instead", () => {
|
|
1034
|
+
expect(reason("kubectl create job x --image=busybox -n web")).toContain(
|
|
1035
|
+
"--from=cronjob/NAME",
|
|
1036
|
+
);
|
|
1037
|
+
expect(reason("kubectl create job x -n web")).toContain(
|
|
1038
|
+
"--from=cronjob/NAME",
|
|
1039
|
+
);
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
describe("no create subcommand starts a workload from an image named in the command", () => {
|
|
1044
|
+
it.each(DENIED_IMAGE_WORKLOAD_CREATES)("denies %s", (command: string) => {
|
|
1045
|
+
const result: KubectlPolicyResult =
|
|
1046
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1047
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1048
|
+
expect(result.verb).toMatch(/^create (deployment|cronjob)$/);
|
|
1049
|
+
// It says why (a new program running an image) and what to do instead.
|
|
1050
|
+
expect(result.reason).toContain("image");
|
|
1051
|
+
expect(result.reason).toContain("new program");
|
|
1052
|
+
expect(result.reason).toContain("--from=cronjob/NAME");
|
|
1053
|
+
expect(
|
|
1054
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1055
|
+
command,
|
|
1056
|
+
allowlistPatterns: [command, broadestShapeOf(command)],
|
|
1057
|
+
bypassApproval: true,
|
|
1058
|
+
}).verdict,
|
|
1059
|
+
).toBe(AiRemediationCommandPolicyVerdict.Denied);
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
it.each(POD_TEMPLATE_CREATE_SUBCOMMANDS)(
|
|
1063
|
+
"create %s: an image in the command or a program after -- is Denied, whatever else it says",
|
|
1064
|
+
(subcommand: string) => {
|
|
1065
|
+
const schedule: string =
|
|
1066
|
+
subcommand === "cronjob" || subcommand === "cj"
|
|
1067
|
+
? " --schedule='*/5 * * * *'"
|
|
1068
|
+
: "";
|
|
1069
|
+
for (const command of [
|
|
1070
|
+
`kubectl create ${subcommand} x --image=busybox${schedule} -n web`,
|
|
1071
|
+
`kubectl create ${subcommand} x --image busybox${schedule} -n web`,
|
|
1072
|
+
`kubectl create ${subcommand} x --image=busybox${schedule} -n web -- sh -c 'id'`,
|
|
1073
|
+
`kubectl create ${subcommand} x --image=registry.example.com/web:1.2.3${schedule} -n web --dry-run=client`,
|
|
1074
|
+
`kubectl create -n web ${subcommand} x --image=busybox${schedule}`,
|
|
1075
|
+
`kubectl create ${subcommand} x --image=busybox${schedule} -n kube-system`,
|
|
1076
|
+
]) {
|
|
1077
|
+
expect({ command, tier: tier(command) }).toEqual({
|
|
1078
|
+
command,
|
|
1079
|
+
tier: KubectlCommandTier.Denied,
|
|
1080
|
+
});
|
|
1081
|
+
expect(
|
|
1082
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1083
|
+
command,
|
|
1084
|
+
allowlistPatterns: [command],
|
|
1085
|
+
bypassApproval: true,
|
|
1086
|
+
}).verdict,
|
|
1087
|
+
).toBe(AiRemediationCommandPolicyVerdict.Denied);
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
);
|
|
1091
|
+
|
|
1092
|
+
it("keeps re-running an existing CronJob, and changing an existing workload's image, RiskyWrite (negative controls)", () => {
|
|
1093
|
+
for (const command of [
|
|
1094
|
+
"kubectl create job x --from=cronjob/y -n web",
|
|
1095
|
+
"kubectl create job manual-run --from=cj/nightly -n web",
|
|
1096
|
+
"kubectl set image deployment/web web=img:2 -n web",
|
|
1097
|
+
"kubectl set image cronjob/nightly job=img:2 -n web",
|
|
1098
|
+
]) {
|
|
1099
|
+
expect({ command, tier: tier(command) }).toEqual({
|
|
1100
|
+
command,
|
|
1101
|
+
tier: KubectlCommandTier.RiskyWrite,
|
|
1102
|
+
});
|
|
1103
|
+
// A human, the allowlist or Bypass approval decides.
|
|
1104
|
+
expect(
|
|
1105
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1106
|
+
command,
|
|
1107
|
+
allowlistPatterns: [],
|
|
1108
|
+
}).verdict,
|
|
1109
|
+
).toBe(AiRemediationCommandPolicyVerdict.RequiresApproval);
|
|
1110
|
+
expect(
|
|
1111
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1112
|
+
command,
|
|
1113
|
+
allowlistPatterns: [command],
|
|
1114
|
+
}).verdict,
|
|
1115
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
1116
|
+
expect(
|
|
1117
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1118
|
+
command,
|
|
1119
|
+
allowlistPatterns: [],
|
|
1120
|
+
bypassApproval: true,
|
|
1121
|
+
}).verdict,
|
|
1122
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// The other create subcommands make no pod template and keep their tier.
|
|
1126
|
+
expect(
|
|
1127
|
+
tier("kubectl create configmap app --from-literal=a=b -n web"),
|
|
1128
|
+
).toBe(KubectlCommandTier.RiskyWrite);
|
|
1129
|
+
expect(
|
|
1130
|
+
tier("kubectl create service clusterip web --tcp=80:8080 -n web"),
|
|
1131
|
+
).toBe(KubectlCommandTier.RiskyWrite);
|
|
1132
|
+
});
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
describe("patch bodies that change a pod's identity, privileges, host access, Secrets or program are Denied", () => {
|
|
1136
|
+
it("forbids exactly the documented fields", () => {
|
|
1137
|
+
/*
|
|
1138
|
+
* 24 since hostPort, hostUsers, runtimeClassName and
|
|
1139
|
+
* shareProcessNamespace joined the name check (the Pod Security
|
|
1140
|
+
* Standards baseline's Host Ports control and the isolation fields
|
|
1141
|
+
* beside it).
|
|
1142
|
+
*/
|
|
1143
|
+
expect(POD_SECURITY_FIELDS).toHaveLength(24);
|
|
1144
|
+
});
|
|
1145
|
+
|
|
1146
|
+
it.each(DENIED_PATCH_BODIES)("denies %s", (command: string) => {
|
|
1147
|
+
const result: KubectlPolicyResult =
|
|
1148
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1149
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1150
|
+
expect(result.verb).toBe("patch");
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
it.each(ALLOWED_PATCH_BODIES)("keeps %s RiskyWrite", (command: string) => {
|
|
1154
|
+
expect(tier(command)).toBe(KubectlCommandTier.RiskyWrite);
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
it("names the field, decoded", () => {
|
|
1158
|
+
expect(
|
|
1159
|
+
reason(podTemplatePatch('{"serviceAccount\\u004eame":"admin"}')),
|
|
1160
|
+
).toContain("serviceAccountName");
|
|
1161
|
+
expect(reason(podTemplatePatch('{"hostNetwork":true}'))).toContain(
|
|
1162
|
+
"hostNetwork",
|
|
1163
|
+
);
|
|
1164
|
+
expect(
|
|
1165
|
+
reason(
|
|
1166
|
+
'kubectl patch ns web -p \'{"metadata":{"labels":{"pod-security.kubernetes.io/enforce":"privileged"}}}\'',
|
|
1167
|
+
),
|
|
1168
|
+
).toContain("Pod Security Admission");
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
it("denies the same argv when the Runner evaluates it directly", () => {
|
|
1172
|
+
expect(
|
|
1173
|
+
KubectlPolicy.evaluateArgs([
|
|
1174
|
+
"patch",
|
|
1175
|
+
"deployment",
|
|
1176
|
+
"web",
|
|
1177
|
+
"-n",
|
|
1178
|
+
"web",
|
|
1179
|
+
"-p",
|
|
1180
|
+
'{"spec":{"template":{"spec":{"serviceAccountName":"admin"}}}}',
|
|
1181
|
+
]).tier,
|
|
1182
|
+
).toBe(KubectlCommandTier.Denied);
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
it("refuses a body nested deeper than any fix needs", () => {
|
|
1186
|
+
const deep: string = `${"[".repeat(70)}1${"]".repeat(70)}`;
|
|
1187
|
+
const result: KubectlPolicyResult = KubectlPolicy.evaluateArgs([
|
|
1188
|
+
"patch",
|
|
1189
|
+
"deployment",
|
|
1190
|
+
"web",
|
|
1191
|
+
"-n",
|
|
1192
|
+
"web",
|
|
1193
|
+
"--type=json",
|
|
1194
|
+
"-p",
|
|
1195
|
+
deep,
|
|
1196
|
+
]);
|
|
1197
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1198
|
+
expect(result.reason).toContain("nested more than 64 levels deep");
|
|
1199
|
+
// Nested within the bound, the same body is walked and allowed.
|
|
1200
|
+
const shallow: string = `${"[".repeat(10)}1${"]".repeat(10)}`;
|
|
1201
|
+
expect(
|
|
1202
|
+
KubectlPolicy.evaluateArgs([
|
|
1203
|
+
"patch",
|
|
1204
|
+
"deployment",
|
|
1205
|
+
"web",
|
|
1206
|
+
"-n",
|
|
1207
|
+
"web",
|
|
1208
|
+
"--type=json",
|
|
1209
|
+
"-p",
|
|
1210
|
+
shallow,
|
|
1211
|
+
]).tier,
|
|
1212
|
+
).toBe(KubectlCommandTier.RiskyWrite);
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
describe("a patch body that is not JSON is Denied, whatever it spells", () => {
|
|
1217
|
+
it.each(TAGGED_YAML_PATCH_BODIES)(
|
|
1218
|
+
"denies the YAML-tagged body %s",
|
|
1219
|
+
(command: string) => {
|
|
1220
|
+
const result: KubectlPolicyResult =
|
|
1221
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1222
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1223
|
+
expect(result.verb).toBe("patch");
|
|
1224
|
+
expect(result.reason).toContain("not JSON");
|
|
1225
|
+
},
|
|
1226
|
+
);
|
|
1227
|
+
|
|
1228
|
+
it.each(PLAIN_YAML_PATCH_BODIES)(
|
|
1229
|
+
"denies the non-JSON body %s, harmless fields or not",
|
|
1230
|
+
(command: string) => {
|
|
1231
|
+
const result: KubectlPolicyResult =
|
|
1232
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1233
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1234
|
+
expect(result.reason).toContain("not JSON");
|
|
1235
|
+
},
|
|
1236
|
+
);
|
|
1237
|
+
|
|
1238
|
+
it.each(NON_JSON_PATCH_BODIES)(
|
|
1239
|
+
"denies %s in the Runner too, and neither Bypass approval nor any allowlist entry lifts it",
|
|
1240
|
+
(command: string) => {
|
|
1241
|
+
const args: Array<string> = KubectlPolicy.tokenize(command).args!;
|
|
1242
|
+
// The Runner re-evaluates the argv it received, with the same result.
|
|
1243
|
+
expect(KubectlPolicy.evaluateArgs(args).tier).toBe(
|
|
1244
|
+
KubectlCommandTier.Denied,
|
|
1245
|
+
);
|
|
1246
|
+
|
|
1247
|
+
for (const allowlistPatterns of [
|
|
1248
|
+
[],
|
|
1249
|
+
[command],
|
|
1250
|
+
PATCH_ALLOWLIST_ENTRIES,
|
|
1251
|
+
[broadestShapeOf(command)],
|
|
1252
|
+
]) {
|
|
1253
|
+
for (const bypassApproval of [true, false]) {
|
|
1254
|
+
const verdict: KubectlAutoExecutionVerdict =
|
|
1255
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1256
|
+
command,
|
|
1257
|
+
allowlistPatterns,
|
|
1258
|
+
bypassApproval,
|
|
1259
|
+
});
|
|
1260
|
+
expect(verdict.verdict).toBe(
|
|
1261
|
+
AiRemediationCommandPolicyVerdict.Denied,
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
},
|
|
1266
|
+
);
|
|
1267
|
+
|
|
1268
|
+
it("tells the model to write the body as JSON", () => {
|
|
1269
|
+
const text: string = reason(
|
|
1270
|
+
"kubectl patch deployment web -n web -p 'spec: {replicas: 2}'",
|
|
1271
|
+
);
|
|
1272
|
+
expect(text).toContain("write the patch body as JSON");
|
|
1273
|
+
expect(text).toContain("tags, anchors and merge keys");
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
it.each(ALLOWED_PATCH_BODIES)(
|
|
1277
|
+
"negative control: the JSON body %s stays RiskyWrite, and Bypass approval runs it",
|
|
1278
|
+
(command: string) => {
|
|
1279
|
+
expect(tier(command)).toBe(KubectlCommandTier.RiskyWrite);
|
|
1280
|
+
expect(
|
|
1281
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1282
|
+
command,
|
|
1283
|
+
allowlistPatterns: [],
|
|
1284
|
+
bypassApproval: true,
|
|
1285
|
+
}).verdict,
|
|
1286
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
1287
|
+
expect(
|
|
1288
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1289
|
+
command,
|
|
1290
|
+
allowlistPatterns: [],
|
|
1291
|
+
}).verdict,
|
|
1292
|
+
).toBe(AiRemediationCommandPolicyVerdict.RequiresApproval);
|
|
1293
|
+
},
|
|
1294
|
+
);
|
|
1295
|
+
|
|
1296
|
+
it("negative control: the same change written as JSON is Denied for the field it touches, not for its syntax", () => {
|
|
1297
|
+
for (const command of [
|
|
1298
|
+
podTemplatePatch('{"serviceAccountName":"default"}'),
|
|
1299
|
+
`kubectl patch deployment web -n web --type=merge -p '{"spec":{"template":{"spec":{"hostNetwork":true}}}}'`,
|
|
1300
|
+
`kubectl patch deployment web -n web --type=json -p '[{"op":"replace","path":"/spec/template/spec/serviceAccountName","value":"default"}]'`,
|
|
1301
|
+
podTemplatePatch('{"hostPID":true}'),
|
|
1302
|
+
]) {
|
|
1303
|
+
const result: KubectlPolicyResult =
|
|
1304
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1305
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1306
|
+
expect(result.reason).toContain("kubectl patch that touches");
|
|
1307
|
+
expect(result.reason).not.toContain("not JSON");
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
describe("Pod Security Admission labels on namespaces are Denied", () => {
|
|
1313
|
+
it.each([
|
|
1314
|
+
"kubectl label ns web pod-security.kubernetes.io/enforce=privileged --overwrite",
|
|
1315
|
+
"kubectl label namespace web pod-security.kubernetes.io/enforce-",
|
|
1316
|
+
"kubectl label namespaces.v1. prod pod-security.kubernetes.io/warn=baseline",
|
|
1317
|
+
"kubectl label ns/web pod-security.kubernetes.io/audit=privileged",
|
|
1318
|
+
"kubectl label ns --all pod-security.kubernetes.io/enforce=privileged",
|
|
1319
|
+
"kubectl label ns -l team=a pod-security.kubernetes.io/enforce=privileged",
|
|
1320
|
+
"kubectl annotate ns web pod-security.kubernetes.io/enforce=privileged",
|
|
1321
|
+
"kubectl label ns kube-system pod-security.kubernetes.io/enforce=privileged",
|
|
1322
|
+
"kubectl label ns web a=b Pod-Security.Kubernetes.IO/enforce=privileged",
|
|
1323
|
+
])("denies %s", (command: string) => {
|
|
1324
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1325
|
+
expect(reason(command)).toContain("Pod Security Admission");
|
|
1326
|
+
expect(
|
|
1327
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1328
|
+
command,
|
|
1329
|
+
allowlistPatterns: ["*", command],
|
|
1330
|
+
bypassApproval: true,
|
|
1331
|
+
}).verdict,
|
|
1332
|
+
).toBe(AiRemediationCommandPolicyVerdict.Denied);
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
it("keeps other namespace labels RiskyWrite", () => {
|
|
1336
|
+
expect(tier("kubectl label ns web team=a")).toBe(
|
|
1337
|
+
KubectlCommandTier.RiskyWrite,
|
|
1338
|
+
);
|
|
1339
|
+
expect(tier("kubectl label pod web-1 -n web pod-security=x")).toBe(
|
|
1340
|
+
KubectlCommandTier.SafeWrite,
|
|
1341
|
+
);
|
|
1342
|
+
});
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1345
|
+
describe("resource categories are never written", () => {
|
|
1346
|
+
it.each(DENIED_CATEGORY_WRITES)("denies %s", (command: string) => {
|
|
1347
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
it.each(ALLOWED_CATEGORY_READS)("keeps %s Read", (command: string) => {
|
|
1351
|
+
expect(tier(command)).toBe(KubectlCommandTier.Read);
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
it("explains that a category expands into many kinds", () => {
|
|
1355
|
+
const text: string = reason("kubectl delete api-extensions -l app=x");
|
|
1356
|
+
expect(text).toContain('resource category "api-extensions"');
|
|
1357
|
+
expect(text).toContain("CRDs, APIServices and admission webhooks");
|
|
1358
|
+
});
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1361
|
+
describe("never-delete kinds are Denied in every spelling", () => {
|
|
1362
|
+
it.each(DENIED_NEVER_DELETE_SPELLINGS)("denies %s", (command: string) => {
|
|
1363
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
it("keeps a custom resource that merely shares a word RiskyWrite", () => {
|
|
1367
|
+
expect(
|
|
1368
|
+
tier("kubectl delete certificates.cert-manager.io web -n web"),
|
|
1369
|
+
).toBe(KubectlCommandTier.RiskyWrite);
|
|
1370
|
+
expect(tier("kubectl delete configmap app -n web")).toBe(
|
|
1371
|
+
KubectlCommandTier.RiskyWrite,
|
|
1372
|
+
);
|
|
1373
|
+
});
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
describe("verbs and subcommands kubectl would not run as written are Denied", () => {
|
|
1377
|
+
it.each(DENIED_VERB_SHAPES)("denies %s", (command: string) => {
|
|
1378
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1379
|
+
});
|
|
1380
|
+
|
|
1381
|
+
it("says an unknown verb would run a plugin", () => {
|
|
1382
|
+
expect(reason("kubectl frobnicate pods")).toContain(
|
|
1383
|
+
"kubectl-frobnicate plugin",
|
|
1384
|
+
);
|
|
1385
|
+
expect(reason("kubectl Get pods")).toContain("case-sensitively");
|
|
1386
|
+
expect(reason("kubectl create frobnicate x")).toContain(
|
|
1387
|
+
"kubectl-create-frobnicate plugin",
|
|
1388
|
+
);
|
|
1389
|
+
expect(reason("kubectl kuberc view")).toContain(
|
|
1390
|
+
"kubectl kuberc is not allowed",
|
|
1391
|
+
);
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
it("says a repeated namespace is ambiguous and names both values", () => {
|
|
1395
|
+
const text: string = reason("kubectl get pods -n a -n b");
|
|
1396
|
+
expect(text).toContain("more than once");
|
|
1397
|
+
expect(text).toContain('"a"');
|
|
1398
|
+
expect(text).toContain('"b"');
|
|
1399
|
+
});
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
describe("kubectl's global flags", () => {
|
|
1403
|
+
it("lists every v1.36 global flag once, and denies all but four", () => {
|
|
1404
|
+
expect(new Set(KUBECTL_1_36_GLOBAL_FLAGS).size).toBe(
|
|
1405
|
+
KUBECTL_1_36_GLOBAL_FLAGS.length,
|
|
1406
|
+
);
|
|
1407
|
+
expect(DENIED_GLOBAL_FLAGS).toHaveLength(
|
|
1408
|
+
KUBECTL_1_36_GLOBAL_FLAGS.length - ALLOWED_GLOBAL_FLAGS.length,
|
|
1409
|
+
);
|
|
1410
|
+
expect(DENIED_GLOBAL_FLAGS).toEqual(
|
|
1411
|
+
expect.arrayContaining(["as-user-extra", "kuberc", "kubeconfig"]),
|
|
1412
|
+
);
|
|
1413
|
+
});
|
|
1414
|
+
|
|
1415
|
+
it.each(DENIED_GLOBAL_FLAG_SHAPES)("denies %s", (command: string) => {
|
|
1416
|
+
const result: KubectlPolicyResult =
|
|
1417
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1418
|
+
expect(result.tier).toBe(KubectlCommandTier.Denied);
|
|
1419
|
+
// Refused for the flag itself, not for some other reason.
|
|
1420
|
+
expect(result.reason).toMatch(/flag/);
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
it.each(ALLOWED_GLOBAL_FLAG_SHAPES)(
|
|
1424
|
+
"keeps %s at %s",
|
|
1425
|
+
(command: string, expected: KubectlCommandTier) => {
|
|
1426
|
+
expect(tier(command)).toBe(expected);
|
|
1427
|
+
},
|
|
1428
|
+
);
|
|
1429
|
+
|
|
1430
|
+
it("normalizes '_' to '-' in a flag name exactly as kubectl does", () => {
|
|
1431
|
+
expect(normalizeKubectlFlagName("as_group")).toBe("as-group");
|
|
1432
|
+
expect(normalizeKubectlFlagName("insecure_skip_tls_verify")).toBe(
|
|
1433
|
+
"insecure-skip-tls-verify",
|
|
1434
|
+
);
|
|
1435
|
+
expect(normalizeKubectlFlagName("from_file")).toBe("from-file");
|
|
1436
|
+
expect(normalizeKubectlFlagName("namespace")).toBe("namespace");
|
|
1437
|
+
expect(normalizeKubectlFlagName("")).toBe("");
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
it("names the flag as it was written", () => {
|
|
1441
|
+
expect(reason("kubectl get pods --as_user_extra=a=b")).toContain(
|
|
1442
|
+
"--as_user_extra",
|
|
1443
|
+
);
|
|
1444
|
+
expect(reason("kubectl get pods --as-user-extra=a=b")).toContain(
|
|
1445
|
+
"cluster access it was given",
|
|
1446
|
+
);
|
|
1447
|
+
});
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1450
|
+
describe("property: nothing lifts a Denied command", () => {
|
|
1451
|
+
it.each(ALL_DENIED_COMMANDS)(
|
|
1452
|
+
"keeps %s Denied under bypass and a permissive allowlist",
|
|
1453
|
+
(command: string) => {
|
|
1454
|
+
expect(tier(command)).toBe(KubectlCommandTier.Denied);
|
|
1455
|
+
/*
|
|
1456
|
+
* ["*"] and ["kubectl *"] used to be the permissive entries here;
|
|
1457
|
+
* a wildcard verb is no longer a valid entry (the matcher skips it),
|
|
1458
|
+
* so the broadest VALID entry of the command's own shape stands in.
|
|
1459
|
+
*/
|
|
1460
|
+
for (const allowlistPatterns of [
|
|
1461
|
+
[broadestShapeOf(command)],
|
|
1462
|
+
[command],
|
|
1463
|
+
[command, broadestShapeOf(command)],
|
|
1464
|
+
[],
|
|
1465
|
+
]) {
|
|
1466
|
+
for (const bypassApproval of [true, false, undefined]) {
|
|
1467
|
+
const verdict: KubectlAutoExecutionVerdict =
|
|
1468
|
+
KubectlPolicy.evaluateForAutoExecution({
|
|
1469
|
+
command,
|
|
1470
|
+
allowlistPatterns,
|
|
1471
|
+
bypassApproval,
|
|
1472
|
+
});
|
|
1473
|
+
expect(verdict.verdict).toBe(
|
|
1474
|
+
AiRemediationCommandPolicyVerdict.Denied,
|
|
1475
|
+
);
|
|
1476
|
+
expect(verdict.tier).toBe(KubectlCommandTier.Denied);
|
|
1477
|
+
expect(verdict.reason).toContain(
|
|
1478
|
+
"cannot run even with human approval",
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
);
|
|
1484
|
+
});
|
|
1485
|
+
|
|
1486
|
+
describe("evaluateCommand and evaluateArgs agree on every table above", () => {
|
|
1487
|
+
const allCommands: Array<string> = [
|
|
1488
|
+
...ALL_DENIED_COMMANDS,
|
|
1489
|
+
...ALLOWED_IDENTITY_NEIGHBOURS.map(
|
|
1490
|
+
([command]: [string, KubectlCommandTier]) => {
|
|
1491
|
+
return command;
|
|
1492
|
+
},
|
|
1493
|
+
),
|
|
1494
|
+
...ALLOWED_CREATE_JOB_SHAPES,
|
|
1495
|
+
...ALLOWED_PATCH_BODIES,
|
|
1496
|
+
...CLUSTER_CONTROL_READS,
|
|
1497
|
+
...CLUSTER_CONTROL_NEIGHBOURS.map(
|
|
1498
|
+
([command]: [string, KubectlCommandTier]) => {
|
|
1499
|
+
return command;
|
|
1500
|
+
},
|
|
1501
|
+
),
|
|
1502
|
+
...ALLOWED_CATEGORY_READS,
|
|
1503
|
+
...ALLOWED_GLOBAL_FLAG_SHAPES.map(
|
|
1504
|
+
([command]: [string, KubectlCommandTier]) => {
|
|
1505
|
+
return command;
|
|
1506
|
+
},
|
|
1507
|
+
),
|
|
1508
|
+
];
|
|
1509
|
+
|
|
1510
|
+
it.each(allCommands)(
|
|
1511
|
+
"returns the same verdict for %s",
|
|
1512
|
+
(command: string) => {
|
|
1513
|
+
const tokenized: KubectlTokenizeResult =
|
|
1514
|
+
KubectlPolicy.tokenize(command);
|
|
1515
|
+
expect(tokenized.args).toBeDefined();
|
|
1516
|
+
const viaCommand: KubectlPolicyResult =
|
|
1517
|
+
KubectlPolicy.evaluateCommand(command);
|
|
1518
|
+
expect(KubectlPolicy.evaluateArgs(tokenized.args!)).toEqual(viaCommand);
|
|
1519
|
+
expect(KubectlPolicy.tokenize(viaCommand.displayCommand).args).toEqual(
|
|
1520
|
+
tokenized.args,
|
|
1521
|
+
);
|
|
1522
|
+
},
|
|
1523
|
+
);
|
|
1524
|
+
});
|
|
1525
|
+
});
|