sql server hub / hardening guide

SQL Serverhardening guide

SQL Server hardening is the work of reducing unnecessary access, exposed connection paths, weak key handling, missing audit coverage, and unsupported builds.

Use this guide to check logins, service accounts, roles, permissions, endpoints, linked servers, credentials, certificates, encryption, auditing, and patch posture with concrete SQL Server output.

Guide

Guide~11 min readUpdated 19 Apr 2026

Share

LinkedInXEmail
  1. 01What SQL Server hardening is
  2. 02SQL Server hardening baseline checklist
  3. 03SQL Server hardening with CIS Benchmark
  4. 04SQL Server hardening starts with logins and service accounts
  5. 05SQL Server hardening for sysadmin and server roles
  6. 06SQL Server hardening for server-level permissions
  7. 07SQL Server hardening for database access and ownership
  8. 08SQL Server hardening for surface area
  9. 09SQL Server hardening for linked servers and credentials
  10. 10SQL Server hardening for encryption, certificates, and keys
  11. 11SQL Server hardening audit checks
  12. 12SQL Server hardening and patch status
  13. 13What not to change during hardening
  14. 14When to request a SQL Server health audit

What SQL Server hardening is

SQL Server hardening is the process of reducing avoidable access, exposed features, weak configuration, and missing review paths on a SQL Server instance. It covers the Database Engine, the Windows or cloud environment around it, SQL Agent behavior, linked access, encryption material, audit output, and patch state.

A useful hardening review looks at how people, applications, services, jobs, linked servers, certificates, audits, and patching all fit together. The goal is to make the instance harder to misuse while keeping production work, backups, restores, monitoring, and support access working.

The safest hardening work starts with inventory and classification. Decide what is required, what is excessive, what is unknown, and what needs a planned change window before turning settings off or removing permissions.

SQL Server hardening baseline checklist

A hardening baseline should say what exists before anyone starts removing access or turning settings off. That baseline should include identity, privilege, database ownership, surface area, external access, encryption, auditing, patch level, backups, and monitoring.

The useful output is not a pass/fail screenshot. It is a controlled change list: what to remove, what to keep, what to test first, what needs an exception, and what must be monitored after the change.

Run these checks from an account with enough metadata visibility. Some server views require `VIEW SERVER STATE` on older SQL Server versions or `VIEW SERVER SECURITY STATE` on newer versions, and low-privilege accounts can return partial results that look cleaner than the instance really is.

Hardening areaBaseline question
Instance and versionWhich SQL Server version, edition, patch level, HA features, and platform constraints shape the review?
IdentityWhich SQL logins, Windows groups, service accounts, vendor accounts, and application identities still need access?
PrivilegeWhich server roles, database roles, ownership chains, explicit grants, and impersonation paths are broader than needed?
Surface areaWhich endpoints, linked servers, external execution features, credentials, and connection paths are still required?
Protection and reviewCan encryption, certificate backup, auditing, patch posture, backups, monitoring, and restore access support production work?

Too many sysadmins

Risk: Every sysadmin can bypass normal permission boundaries, change security settings, read data, and alter jobs.

Check first: Review fixed server role membership, Windows group membership, job ownership, and break-glass access.

Do not: Do not remove a sysadmin account only because it looks old.

Safer path: Move routine work to narrower roles, keep one documented emergency path, and test jobs before removing access.

Old vendor or support login

Risk: A forgotten login can keep privileged access long after the support agreement or project ended.

Check first: Check disabled state, last password change, server permissions, database roles, and whether the login owns jobs or objects.

Do not: Do not disable it during business hours without a rollback path.

Safer path: Confirm ownership, disable first when safe, monitor for failures, then remove after a retention period.

Service account with broad permissions

Risk: A service account with sysadmin or db_owner can turn an application bug into broad database access.

Check first: Map the service, application, jobs, proxies, linked servers, credentials, and required stored procedures.

Do not: Do not swap service accounts without checking SPNs, file access, backup paths, and restart behavior.

Safer path: Create a least-privilege role, test the application path, then remove broad access in a controlled change.

Linked server using stored credentials

Risk: Stored remote credentials can give SQL Server access to another system even when local access looks clean.

Check first: Review linked server mappings, RPC out, data access, remote name, provider, and the owner of the remote account.

Do not: Do not drop the linked server until jobs, reports, ETL, and vendor integrations are checked.

Safer path: Replace broad mappings with named mappings, rotate remote credentials, and document who owns the dependency.

TDE enabled but certificate backup missing

Risk: The database may be encrypted but not recoverable on another instance if certificate and private key backups are missing.

Check first: Review certificate expiry, private-key backup date, encryptor type, and restore access for the backup location.

Do not: Do not rotate or drop certificates before restore testing.

Safer path: Back up the certificate and private key securely, test restore access, then plan certificate rotation if needed.

Auditing enabled but nobody reviews the output

Risk: Audit events consume storage and create a false sense of control when nobody reviews failures or privileged changes.

Check first: Review audit target, enabled state, failure behavior, audited actions, retention, ownership, and alerting.

Do not: Do not add noisy audit actions before deciding who reads them.

Safer path: Capture the events that matter, route exceptions to an owner, and define retention before expanding coverage.

How to check SQL Server version and feature context

Reads SQL Server version and platform context before judging hardening posture.

SELECT
    SERVERPROPERTY('ServerName') AS server_name,
    SERVERPROPERTY('MachineName') AS machine_name,
    SERVERPROPERTY('Edition') AS edition,
    SERVERPROPERTY('ProductVersion') AS product_version,
    SERVERPROPERTY('ProductLevel') AS product_level,
    SERVERPROPERTY('ProductUpdateLevel') AS product_update_level,
    SERVERPROPERTY('ProductUpdateReference') AS product_update_reference,
    SERVERPROPERTY('IsClustered') AS is_clustered,
    SERVERPROPERTY('IsHadrEnabled') AS is_hadr_enabled;

ProductVersion and ProductUpdateLevel show the current build and servicing level. Edition can affect feature availability and encryption/audit choices. IsClustered and IsHadrEnabled help identify HA paths that need separate checks. Use this with the update guide when the instance is unsupported or far behind.

SQL Server hardening with CIS Benchmark

The CIS Benchmark for Microsoft SQL Server is a configuration baseline maintained by the Center for Internet Security. It gives auditors, DBAs, and security reviewers a shared checklist for SQL Server settings that are commonly misconfigured or left too permissive.

Use the benchmark as a review baseline, not as an automatic change script. Some recommendations can affect legacy applications, SQL Agent jobs, linked servers, monitoring accounts, high-availability features, or restore procedures. The best use is to record the benchmark version, run the checks for the installed SQL Server version, classify exceptions, then change one controlled group at a time.

The version matters. SQL Server 2025, 2022, 2019, 2017, and 2016 have separate CIS Benchmark documents, and the checks are not always identical. Do not copy a control from one major version into another without checking whether the setting, feature, or default behavior exists there.

SQL Server 2025

CIS Microsoft SQL Server 2025 Benchmark v1.0.0. Use this for new SQL Server 2025 builds and early production reviews. Check the version-specific controls before carrying older hardening assumptions into new surface-area features.

SQL Server 2019

CIS Microsoft SQL Server 2019 Benchmark v1.5.2. Use this for SQL Server 2019 estates. It is common to find older audit-tool content pinned to earlier 2019 benchmark versions, so record the exact benchmark version used.

What the SQL Server CIS Benchmark covers

The exact controls vary by benchmark version, but the SQL Server benchmark usually covers the same broad review areas. Use these areas to organize the work before opening tickets or changing settings.

Patch level and platform shape

CIS starts with whether the SQL Server build is current enough for the organization and whether the server is shaped like a database server, not a general-purpose application box. That matters because access cleanup does not help much if the instance is unsupported or exposed through old platform choices.

Surface area and network exposure

The benchmark checks whether unnecessary protocols, endpoints, browser exposure, remote access behavior, and feature switches are enabled. These are not just security preferences; they affect how applications connect, how clustered or HA setups behave, and what must be restarted after a change.

Authentication and login handling

CIS covers SQL authenticated logins, password policy and expiration flags, local Windows groups, old accounts, guest access, and whether login behavior matches the intended identity model. This is where many old vendor, support, and application accounts show up.

Roles, permissions, and ownership

The benchmark reviews sysadmin, server roles, database ownership, trustworthy database settings, cross-database ownership behavior, public role permissions, and high-risk grants. It is useful because it catches privilege paths that are not obvious from a sysadmin-only review.

Auditing and traceability

CIS includes checks for login auditing, audit specifications, privileged activity capture, and whether the audit configuration is actually enabled. The practical question is not only whether auditing exists, but whether important events are retained and reviewed by someone.

Encryption and key material

The benchmark covers network encryption, certificate choices, weak algorithms, TDE, asymmetric and symmetric key strength, and related database encryption settings. Any finding here must be tied to restore testing, because key changes can make recovery harder if the private key handling is weak.

Application-facing risks

Some SQL Server benchmark checks point outside pure DBA configuration, such as SQL injection-resistant application input handling, external execution features, and procedures that can call outside services. These findings usually need application owners, not only a DBA change ticket.

CIS is useful because it makes hardening repeatable. Instead of arguing from memory, the review can say which benchmark version was used, which controls passed, which controls failed, which exceptions were accepted, and what will be checked again later.

The best production workflow is simple: match the benchmark to the SQL Server major version, capture current settings, group findings by risk and dependency, fix the low-dependency items first, and leave risky changes for a planned window with application validation and rollback notes.

SQL Server hardening starts with logins and service accounts

Start with identities. Review SQL Server service accounts, SQL logins, Windows logins, groups, disabled accounts, SQL authentication policy flags, and stale defaults before changing permissions.

How to check SQL Server services and service accounts

Reads SQL Server service status, startup type, service account, startup time, and instant file initialization state.

SELECT
    servicename,
    startup_type_desc,
    status_desc,
    service_account,
    instant_file_initialization_enabled,
    last_startup_time
FROM sys.dm_server_services
ORDER BY servicename;

service_account should be intentional and documented. Disabled or unexpected services may indicate old components still installed. instant_file_initialization_enabled affects data file growth behavior. Do not change service accounts without testing permissions, SPNs, backups, jobs, and restart behavior.

How to inventory SQL Server logins

Lists SQL, Windows, group, external, and application logins with disabled state, policy flags, default database, and credential link.

SELECT
    sp.name AS login_name,
    sp.type_desc,
    sp.is_disabled,
    sp.create_date,
    sp.modify_date,
    sp.default_database_name,
    sl.is_policy_checked,
    sl.is_expiration_checked,
    LOGINPROPERTY(sp.name, 'PasswordLastSetTime') AS password_last_set_time,
    sp.credential_id
FROM sys.server_principals AS sp
LEFT JOIN sys.sql_logins AS sl
    ON sl.principal_id = sp.principal_id
WHERE sp.type IN ('S', 'U', 'G', 'E', 'X')
  AND sp.name NOT LIKE N'##MS_%##'
ORDER BY sp.is_disabled, sp.type_desc, sp.name;

SQL logins with policy checks disabled deserve review. Disabled logins can still show stale access management habits. default_database_name should exist and be reachable. credential_id links the login to stored external access and needs separate review.

SQL Server hardening for sysadmin and server roles

Sysadmin membership is the first privilege check, but not the only one. Fixed server roles and group-based access can still grant broad control that is easy to miss in daily operations.

How to review fixed server role membership

Shows members of fixed server roles, including sysadmin, securityadmin, serveradmin, and other server roles.

SELECT
    role_principal.name AS server_role,
    member_principal.name AS member_name,
    member_principal.type_desc AS member_type,
    member_principal.is_disabled,
    member_principal.default_database_name
FROM sys.server_role_members AS srm
JOIN sys.server_principals AS role_principal
    ON role_principal.principal_id = srm.role_principal_id
JOIN sys.server_principals AS member_principal
    ON member_principal.principal_id = srm.member_principal_id
ORDER BY role_principal.name, member_principal.name;

sysadmin membership should be short, current, and explainable. securityadmin can grant access and should not be treated as harmless. Windows groups need ownership and membership review outside SQL Server. Do not remove a member until job, application, support, and break-glass use are checked.

Role patternWhat to check
Individual sysadmin loginsConfirm named owner, reason, and whether group-based access is cleaner.
Nested Windows groupsVerify group membership and change process outside SQL Server.
Old vendor loginsConfirm whether support access is still required and how it is audited.
Automation accountsCheck job ownership, linked servers, proxies, credentials, and service dependencies.

SQL Server hardening for server-level permissions

Explicit server-level grants can bypass the simpler role view. Review `CONTROL SERVER`, `ALTER ANY LOGIN`, `VIEW SERVER STATE`, endpoint permissions, and other grants beside role membership.

How to review explicit server permissions

Lists explicit server-level permissions granted, denied, or revoked for server principals.

SELECT
    grantee.name AS grantee_name,
    grantee.type_desc AS grantee_type,
    permission.state_desc,
    permission.permission_name,
    permission.class_desc,
    grantor.name AS grantor_name
FROM sys.server_permissions AS permission
JOIN sys.server_principals AS grantee
    ON grantee.principal_id = permission.grantee_principal_id
LEFT JOIN sys.server_principals AS grantor
    ON grantor.principal_id = permission.grantor_principal_id
ORDER BY grantee.name, permission.class_desc, permission.permission_name;

CONTROL SERVER is close to full instance control. ALTER ANY LOGIN and ALTER ANY SERVER ROLE affect access management. VIEW SERVER STATE may be required for monitoring but should still be deliberate. DENY entries can be intentional; check before removing them.

Permission or roleWhy it deserves review
CONTROL SERVERClose to full instance control. Treat it with the same care as sysadmin.
ALTER ANY LOGINAllows login changes and can become an access-management bypass.
ALTER ANY SERVER ROLECan change server role membership, including sensitive operational roles.
IMPERSONATECan let one principal act as another and bypass the visible access model.
UNSAFE ASSEMBLYAllows high-risk CLR behavior and should have a current technical reason.
Broad ALTER or CONTROLCan allow schema, permission, or object changes beyond the normal application path.
db_ownerDatabase-level owner access; review it beside application needs, jobs, and deployment process.

SQL Server hardening for database access and ownership

Database hardening should separate role membership, explicit permissions, database ownership, and risky database options. Run these checks inside each important user database, then review ownership and database-level options across the instance.

How to review database role membership

Run inside a selected database to list users and database role membership.

USE [YourDatabase];

SELECT
    DB_NAME() AS database_name,
    role_principal.name AS database_role,
    member_principal.name AS member_name,
    member_principal.type_desc AS member_type,
    member_principal.authentication_type_desc,
    member_principal.create_date,
    member_principal.modify_date
FROM sys.database_role_members AS drm
JOIN sys.database_principals AS role_principal
    ON role_principal.principal_id = drm.role_principal_id
JOIN sys.database_principals AS member_principal
    ON member_principal.principal_id = drm.member_principal_id
ORDER BY role_principal.name, member_principal.name;

db_owner membership should be small and tied to a real support reason. application users should usually not need broad owner-level access. authentication_type_desc helps distinguish mapped logins, contained users, and external identities. Repeat this on critical databases, not only one sample database.

How to review explicit database permissions

Run inside a selected database to review explicit database permissions outside role membership.

USE [YourDatabase];

SELECT
    DB_NAME() AS database_name,
    grantee.name AS grantee_name,
    grantee.type_desc AS grantee_type,
    permission.state_desc,
    permission.permission_name,
    permission.class_desc,
    OBJECT_SCHEMA_NAME(permission.major_id) AS object_schema,
    OBJECT_NAME(permission.major_id) AS object_name,
    grantor.name AS grantor_name
FROM sys.database_permissions AS permission
JOIN sys.database_principals AS grantee
    ON grantee.principal_id = permission.grantee_principal_id
LEFT JOIN sys.database_principals AS grantor
    ON grantor.principal_id = permission.grantor_principal_id
WHERE grantee.name NOT IN (N'public', N'guest', N'INFORMATION_SCHEMA', N'sys')
ORDER BY grantee.name, permission.class_desc, permission.permission_name;

Explicit GRANT and DENY entries can override what role membership suggests. Object-level permissions should match the application or support model. Deny permissions may protect sensitive objects; do not remove them casually. Check high-risk permissions such as ALTER, CONTROL, IMPERSONATE, and EXECUTE.

How to review database owners and security options

Lists database owner, containment, TRUSTWORTHY, cross-database ownership chaining, Service Broker, encryption state, and access mode.

SELECT
    d.name AS database_name,
    SUSER_SNAME(d.owner_sid) AS database_owner,
    d.containment_desc,
    d.is_trustworthy_on,
    d.is_db_chaining_on,
    d.is_broker_enabled,
    d.is_encrypted,
    d.state_desc,
    d.user_access_desc
FROM sys.databases AS d
WHERE d.database_id > 4
ORDER BY d.name;

Database owner should be intentional; avoid leaving important databases owned by personal accounts. TRUSTWORTHY and cross-database ownership chaining deserve a clear technical reason. Containment affects authentication and should match the application model. is_encrypted shows whether TDE is active, but certificate backup still needs a separate check.

SQL Server hardening for surface area

Surface-area hardening is about removing optional ways to run code, reach outside SQL Server, or expose administrative access. The risky part is that some old jobs, reports, ETL flows, and vendor tools may still depend on those features.

Check the current setting first, then decide whether it is required, who owns it, and how to test the application path after a change. Do not disable a feature only because the name looks dangerous.

How to check SQL Server surface-area settings

Reviews common optional features and advanced settings that can expand what SQL Server can execute or expose.

SELECT
    name,
    value,
    value_in_use,
    is_dynamic,
    is_advanced,
    description
FROM sys.configurations
WHERE name IN (
    N'Ad Hoc Distributed Queries',
    N'clr enabled',
    N'clr strict security',
    N'cross db ownership chaining',
    N'Database Mail XPs',
    N'external scripts enabled',
    N'Ole Automation Procedures',
    N'remote access',
    N'remote admin connections',
    N'scan for startup procs',
    N'xp_cmdshell'
)
ORDER BY name;

xp_cmdshell, Ole Automation Procedures, external scripts, and Ad Hoc Distributed Queries should usually be off unless there is a documented reason. clr strict security should normally stay enabled when CLR is used. remote admin connections may be useful for emergency access, but it still needs an access decision. Database Mail XPs and linked access are not automatically wrong; check jobs, alerting, reporting, and ETL dependencies first.

SQL Server hardening for linked servers and credentials

Linked servers, credentials, database-scoped credentials, endpoints, SQL Agent proxies, and old firewall exceptions are where SQL Server hardening crosses into other systems. Each external path needs an owner, a current reason, and a test plan before it is changed.

How to inventory endpoints

Lists SQL Server endpoints, endpoint state, protocol, TCP port, and IP binding.

SELECT
    e.name AS endpoint_name,
    e.type_desc,
    e.protocol_desc,
    e.state_desc,
    e.is_admin_endpoint,
    te.port,
    te.ip_address
FROM sys.endpoints AS e
LEFT JOIN sys.tcp_endpoints AS te
    ON te.endpoint_id = e.endpoint_id
ORDER BY e.type_desc, e.name;

STARTED endpoints should have a current business or HA reason. TCP port and IP binding help validate expected connection paths. Admin endpoints and mirroring endpoints deserve separate access review. Endpoint changes can affect applications, AGs, mirroring, and administration.

How to inventory linked servers

Lists linked servers, provider details, data access settings, RPC-out settings, and linked-login mappings.

SELECT
    s.name AS linked_server_name,
    s.product,
    s.provider,
    s.data_source,
    s.is_linked,
    s.is_remote_login_enabled,
    s.is_rpc_out_enabled,
    s.is_data_access_enabled,
    local_principal.name AS local_principal_name,
    ll.uses_self_credential,
    ll.remote_name
FROM sys.servers AS s
LEFT JOIN sys.linked_logins AS ll
    ON ll.server_id = s.server_id
LEFT JOIN sys.server_principals AS local_principal
    ON local_principal.principal_id = ll.local_principal_id
WHERE s.is_linked = 1
ORDER BY s.name, local_principal.name;

is_rpc_out_enabled and is_data_access_enabled show what the linked server can do. uses_self_credential shows whether local credentials flow to the remote server. remote_name shows stored remote login mapping when one is configured. Check jobs, reports, ETL, and vendor integrations before changing linked server access.

How to inventory credentials

Lists SQL Server credentials and credential identities for stored external access.

SELECT
    name AS credential_name,
    credential_identity,
    create_date,
    modify_date,
    target_type,
    target_id
FROM sys.credentials
ORDER BY name;

credential_identity shows the external identity SQL Server can use. Credentials may support backups, proxies, external scripts, or cloud/storage access. Old credentials should be checked against jobs and proxies before removal. Credential rotation needs coordination with the external system.

How to inventory database-scoped credentials

Run inside a selected database to list credentials used by database-scoped external access.

USE [YourDatabase];

SELECT
    name AS database_scoped_credential_name,
    credential_identity,
    create_date,
    modify_date,
    target_type,
    target_id
FROM sys.database_scoped_credentials
ORDER BY name;

Database-scoped credentials can support external tables, external data sources, storage access, and application-facing integration paths. credential_identity may be a user name, managed identity marker, or external access identity depending on platform and feature. Review these separately from server-level credentials; cleaning one does not clean the other. Rotate or remove a database-scoped credential only after checking external data sources, jobs, and application dependencies.

How to inventory SQL Agent proxies

Lists SQL Agent proxies with their credential, allowed principals, and allowed subsystems.

USE msdb;

SELECT
    p.name AS proxy_name,
    p.enabled,
    c.name AS credential_name,
    SUSER_SNAME(pl.sid) AS proxy_principal_name,
    ss.subsystem,
    p.description
FROM dbo.sysproxies AS p
LEFT JOIN sys.credentials AS c
    ON c.credential_id = p.credential_id
LEFT JOIN dbo.sysproxylogin AS pl
    ON pl.proxy_id = p.proxy_id
LEFT JOIN dbo.sysproxysubsystem AS ps
    ON ps.proxy_id = p.proxy_id
LEFT JOIN dbo.syssubsystems AS ss
    ON ss.subsystem_id = ps.subsystem_id
ORDER BY p.name, proxy_principal_name, ss.subsystem;

A proxy lets SQL Agent run selected job steps under a credential instead of the SQL Agent service account. Proxy principals show who can use the proxy; subsystems show which job-step types it can run. Old proxies often survive because one rare job step still depends on them. Do not remove or rotate the credential until proxy users and job steps are mapped.

How to review SQL Agent job owners and proxy use

Lists SQL Agent jobs, job owners, job steps, subsystems, proxies, and proxy credentials.

USE msdb;

SELECT
    j.name AS job_name,
    SUSER_SNAME(j.owner_sid) AS job_owner,
    j.enabled AS job_enabled,
    s.step_id,
    s.step_name,
    s.subsystem,
    p.name AS proxy_name,
    c.name AS credential_name
FROM dbo.sysjobs AS j
LEFT JOIN dbo.sysjobsteps AS s
    ON s.job_id = j.job_id
LEFT JOIN dbo.sysproxies AS p
    ON p.proxy_id = s.proxy_id
LEFT JOIN sys.credentials AS c
    ON c.credential_id = p.credential_id
ORDER BY j.name, s.step_id;

Job owner matters because job execution can inherit owner privileges in ways that are easy to miss. Steps with proxy_name use a stored credential path and need owner, purpose, and rotation review. Disabled jobs can still explain why old logins, proxies, or credentials exist. Review job output and schedules before changing owners, proxies, credentials, or role membership.

SQL Server hardening for encryption, certificates, and keys

Encryption review should separate transport protection, backup encryption, TDE, certificate expiry, private-key backup, and restore access. A protected database is not recoverable if the key material is missing.

How to check certificates and private-key backup

Run in master to list certificates, expiry, private-key encryption type, private-key backup date, and key length.

USE master;

SELECT
    name AS certificate_name,
    subject,
    issuer_name,
    start_date,
    expiry_date,
    pvt_key_encryption_type_desc,
    pvt_key_last_backup_date,
    key_length
FROM sys.certificates
WHERE name NOT LIKE N'##MS_%##'
ORDER BY expiry_date, name;

expiry_date matters for certificates used by endpoints, backup encryption, or TDE. pvt_key_last_backup_date should exist for certificates needed during restore. Certificates with private keys need secure backup and recovery handling. Do not enable encryption until restore access is confirmed.

How to check database encryption state

Lists database encryption state, percent complete, algorithm, key length, and encryptor type.

SELECT
    DB_NAME(dek.database_id) AS database_name,
    dek.encryption_state,
    CASE dek.encryption_state
        WHEN 0 THEN 'No database encryption key'
        WHEN 1 THEN 'Unencrypted'
        WHEN 2 THEN 'Encryption in progress'
        WHEN 3 THEN 'Encrypted'
        WHEN 4 THEN 'Key change in progress'
        WHEN 5 THEN 'Decryption in progress'
        WHEN 6 THEN 'Protection change in progress'
    END AS encryption_state_desc,
    dek.percent_complete,
    dek.key_algorithm,
    dek.key_length,
    dek.encryptor_type
FROM sys.dm_database_encryption_keys AS dek
ORDER BY database_name;

Encrypted databases should show encryption_state_desc as Encrypted. In-progress states need monitoring before maintenance or migration. encryptor_type ties the database encryption key to the certificate or asymmetric key path. Use this with certificate backup checks before any restore or migration plan.

SQL Server hardening audit checks

Auditing should capture the changes and access patterns that matter without filling storage with events nobody reads. Review target, enabled state, failure behavior, actions, retention, and who owns follow-up.

How to check server audit configuration

Lists server audits, server audit specifications, enabled state, target type, failure behavior, and audited actions.

SELECT
    a.name AS audit_name,
    a.is_state_enabled AS audit_enabled,
    a.type_desc AS audit_target_type,
    a.queue_delay,
    a.on_failure_desc,
    sas.name AS server_audit_specification,
    sas.is_state_enabled AS server_spec_enabled,
    sad.audit_action_name,
    sad.audited_result,
    sad.class_desc,
    sad.major_id
FROM sys.server_audits AS a
LEFT JOIN sys.server_audit_specifications AS sas
    ON sas.audit_guid = a.audit_guid
LEFT JOIN sys.server_audit_specification_details AS sad
    ON sad.server_specification_id = sas.server_specification_id
ORDER BY a.name, sas.name, sad.audit_action_name;

audit_enabled and server_spec_enabled must both be checked. on_failure_desc matters because audit target failures can affect production behavior. audit_action_name should match the access and change events the business needs. Audit output needs storage, retention, review ownership, and alert routing.

How to check database audit specifications

Run inside a selected database to list database audit specification state and audited actions.

USE [YourDatabase];

SELECT
    das.name AS database_audit_specification,
    das.is_state_enabled AS database_spec_enabled,
    dad.audit_action_name,
    dad.audited_result,
    dad.class_desc,
    dad.major_id
FROM sys.database_audit_specifications AS das
LEFT JOIN sys.database_audit_specification_details AS dad
    ON dad.database_specification_id = das.database_specification_id
ORDER BY das.name, dad.audit_action_name;

database_spec_enabled shows whether database auditing is active. audit_action_name shows which database-level actions are captured. Object-specific audit entries need object ownership and review purpose. Database audit coverage should match sensitive data and privileged operations.

SQL Server hardening and patch status

Access cleanup does not cancel out unsupported builds, unpatched instances, unsafe features, or missing monitoring. Hardening should include version context and a practical patch path.

CheckWhy it matters
SQL Server buildShows whether the instance is current enough for support and security expectations.
Unsupported versionsChange the urgency and the upgrade path.
Unsafe featuresFeatures such as broad external execution or old provider paths need separate review.
Monitoring and backupsHardening changes need recovery and alerting in case access cleanup breaks something.

What not to change during hardening

1

Do not remove permissions before confirming owner, job, application, and rollback impact.

2

Do not treat sysadmin cleanup as the whole hardening job.

3

Do not disable SQL logins or service accounts from one inventory query alone.

4

Do not disable xp_cmdshell, CLR, Database Mail, linked servers, or external scripts until dependent jobs and applications are known.

5

Do not enable encryption without confirming certificate and key backup plus restore access.

6

Do not enable auditing without checking storage, retention, review ownership, and alert routing.

7

Do not remove endpoints or linked servers because an old application may still need them; verify the dependency.

8

Do not combine hardening with unrelated cleanup during the same production change.

9

Do not call the environment hardened while backups, patch posture, monitoring, and restore access are still weak.

When to request a SQL Server health audit

Request a health audit when access has grown over time, privileged roles are hard to explain, encryption or audit settings are unclear, or security work needs to happen without breaking production jobs and applications.

Send version output, service accounts, login inventory, sysadmin membership, explicit permissions, endpoint and linked-server lists, credential list, certificate and TDE state, audit configuration, monitoring output, and the main production constraint.

Next step

If access cleanup needs findings, priorities, and a change path, use the SQL Server health audit page or request the audit above.

Next useful reads: the SQL Server monitoring guide for login failures and permission-change visibility, the SQL Server update guide for patch planning, the latest updates tracker for servicing context, the SQL Server health check guide for broader review, the SQL Server backup guide for key and restore concerns, and the SQL Server failover guide for HA exposure.