Some checks are pending
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2019-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2022-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2025-latest) (push) Blocked by required conditions
CI / Build og unit tests (push) Waiting to run
- Managed Instance reports 12.0.2000.8 but is evergreen: treated as the newest engine with all capabilities; new SelfManagedInfrastructure capability so backup, CHECKDB, files, tempdb, memory, patch level and lifecycle rules report 'handled by Azure' instead of false findings - Microsoft Entra ID login (managed identity, service principal, default credential chain) via SqlConnection.AccessTokenCallback - Least-privilege script recognizes Managed Instance; deadlock collector falls back to the ring buffer when event files cannot be read - Web UI shows the right release for Managed Instance - README and installation docs: notifications and Managed Instance - Catalog test: 61 rules with unique, well-formed ids Integration suite green on SQL Server 2017 and 2022. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
108 lines
4.8 KiB
Transact-SQL
108 lines
4.8 KiB
Transact-SQL
/*
|
|
SQLInsight Pro: least-privilege rettigheder til agentens login
|
|
================================================================
|
|
|
|
Giver agenten præcis de rettigheder, den skal bruge for at overvåge instansen. Aldrig sysadmin.
|
|
Scriptet kan køres igen uden skade, fx efter en opgradering eller når der er oprettet nye databaser.
|
|
|
|
Understøtter SQL Server 2005 og nyere. SQL Server 2000 har ikke VIEW SERVER STATE: se docs/legacy-versions.md.
|
|
|
|
Forudsætning: login'et findes allerede, fx
|
|
CREATE LOGIN [DOMÆNE\svc-sqlinsight$] FROM WINDOWS; -- gMSA (anbefalet)
|
|
CREATE LOGIN [sqlinsight-agent] FROM EXTERNAL PROVIDER; -- Azure SQL Managed Instance (Entra ID)
|
|
|
|
Hvad der gives, og hvorfor:
|
|
Server
|
|
2005-2019: VIEW SERVER STATE DMV'er: waits, sessions, plan cache, I/O
|
|
2022+: VIEW SERVER PERFORMANCE STATE samme, mere granulært
|
|
VIEW SERVER SECURITY STATE sikkerheds-DMV'er (fx audit, certifikater)
|
|
Alle: VIEW ANY DEFINITION metadata (indexes, statistikker). Giver IKKE adgang til data.
|
|
2014+: CONNECT ANY DATABASE kan åbne alle databaser (nuværende og fremtidige). Giver IKKE adgang til data.
|
|
Databaser (kun før 2014): en bruger uden rettigheder i hver online database, så DMV'er og Query Store kan læses.
|
|
msdb: SELECT på backup-, restore-, job- og suspect_pages-tabeller. Intet andet.
|
|
|
|
Hvad der IKKE gives: adgang til tabeldata, skriverettigheder, xp_cmdshell eller sysadmin.
|
|
*/
|
|
SET NOCOUNT ON;
|
|
|
|
DECLARE @LoginName sysname;
|
|
SET @LoginName = N'DOMÆNE\svc-sqlinsight$'; -- <== ret til agentens login
|
|
|
|
DECLARE @Major int;
|
|
DECLARE @Sql nvarchar(max);
|
|
DECLARE @Quoted nvarchar(300);
|
|
SET @Major = CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(128)), 4) AS int);
|
|
/* Azure SQL Managed Instance reports 12.x but runs the newest engine. Use the broad, universally supported permissions. */
|
|
IF CAST(SERVERPROPERTY('EngineEdition') AS int) = 8 SET @Major = 15;
|
|
SET @Quoted = QUOTENAME(@LoginName);
|
|
|
|
IF @Major < 9
|
|
BEGIN
|
|
RAISERROR(N'SQL Server 2000 understøttes ikke af dette script. Se docs/legacy-versions.md.', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = @LoginName)
|
|
BEGIN
|
|
RAISERROR(N'Login %s findes ikke. Opret det først.', 16, 1, @LoginName);
|
|
RETURN;
|
|
END;
|
|
|
|
IF IS_SRVROLEMEMBER(N'sysadmin', @LoginName) = 1
|
|
PRINT N'ADVARSEL: ' + @LoginName + N' er sysadmin. Agenten har ikke brug for det; fjern rollen.';
|
|
|
|
/* Server-rettigheder */
|
|
IF @Major >= 16
|
|
SET @Sql = N'GRANT VIEW SERVER PERFORMANCE STATE TO ' + @Quoted + N'; GRANT VIEW SERVER SECURITY STATE TO ' + @Quoted + N';';
|
|
ELSE
|
|
SET @Sql = N'GRANT VIEW SERVER STATE TO ' + @Quoted + N';';
|
|
EXEC (@Sql);
|
|
|
|
SET @Sql = N'GRANT VIEW ANY DEFINITION TO ' + @Quoted + N';';
|
|
EXEC (@Sql);
|
|
|
|
IF @Major >= 12
|
|
BEGIN
|
|
SET @Sql = N'GRANT CONNECT ANY DATABASE TO ' + @Quoted + N';';
|
|
EXEC (@Sql);
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
/* Før 2014: en bruger uden rettigheder i hver online database. Kør scriptet igen, når der oprettes nye. */
|
|
DECLARE @Db sysname;
|
|
DECLARE db_cursor CURSOR LOCAL FAST_FORWARD FOR
|
|
SELECT name FROM sys.databases
|
|
WHERE state = 0 AND name NOT IN (N'master', N'tempdb', N'model', N'msdb') AND is_read_only = 0;
|
|
OPEN db_cursor;
|
|
FETCH NEXT FROM db_cursor INTO @Db;
|
|
WHILE @@FETCH_STATUS = 0
|
|
BEGIN
|
|
SET @Sql = N'USE ' + QUOTENAME(@Db) + N';
|
|
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE sid = SUSER_SID(' + QUOTENAME(@LoginName, '''') + N'))
|
|
CREATE USER ' + @Quoted + N' FOR LOGIN ' + @Quoted + N';';
|
|
EXEC (@Sql);
|
|
FETCH NEXT FROM db_cursor INTO @Db;
|
|
END;
|
|
CLOSE db_cursor;
|
|
DEALLOCATE db_cursor;
|
|
END;
|
|
|
|
/* msdb: backup-historik, jobs og suspect pages */
|
|
SET @Sql = N'USE msdb;
|
|
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE sid = SUSER_SID(' + QUOTENAME(@LoginName, '''') + N'))
|
|
CREATE USER ' + @Quoted + N' FOR LOGIN ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.backupset TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.backupmediafamily TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.backupmediaset TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.restorehistory TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.suspect_pages TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysjobs TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysjobsteps TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysjobhistory TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysjobactivity TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysjobschedules TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.sysschedules TO ' + @Quoted + N';
|
|
GRANT SELECT ON dbo.syscategories TO ' + @Quoted + N';';
|
|
EXEC (@Sql);
|
|
|
|
PRINT N'Rettigheder givet til ' + @LoginName + N'.';
|