One question I often get from DBAs and developers is: “Why do I see NT AUTHORITY\SYSTEM or LOCAL SERVICE in my SQL logs making schema or metadata changes?”
At first glance, this can look suspicious. Did the operating system just change my database? Is this a security risk? Let’s break it down.
What’s Actually Happening
When SQL Server services (the Database Engine or SQL Agent) run under built-in Windows accounts like Local System, Local Service, or Network Service, any automated tasks they execute — such as:
- Auto Update / Auto Create Statistics
- Index maintenance jobs
- Backups or restores triggered by Agent jobs
- Even schema changes scripted by a deployment tool
…will show up in SQL Server as having been performed by that service account.
So if your UPDATE STATISTICS operations are running under Local System, the audit trail shows NT AUTHORITY\SYSTEM as the actor.
Is This a Security Issue?
Technically, not always.
It doesn’t necessarily mean that someone hacked your server. SQL is simply attributing the change to the account running the service.
But practically, yes.
Relying on these generic built-in accounts is not a best practice for several reasons:
- Over-privileged accounts: Local System has broad rights on the OS. If SQL Server is compromised, the attacker gets powerful system access.
- Lack of accountability: You can’t distinguish whether the action came from a scheduled job, an auto-stats update, or a manual operation.
- Auditing blind spots: Security teams need meaningful principals in logs — not just “SYSTEM.”
- Poor compliance fit: Regulations (SOX, HIPAA, PCI) often require traceable accounts.
Microsoft’s Guidance
Microsoft’s official documentation is clear:
- “Always run SQL Server services by using the lowest possible user rights. Use a Managed Service Account (MSA), group-Managed Service Account (gMSA), or virtual account when possible.”
— Configure Windows Service Accounts and Permissions - Local System and Local Service are not recommended for SQL Server or SQL Agent in most cases. They either have too many privileges (Local System) or too few for clustered/distributed operations (Local Service).
Best Practices
1. Use Dedicated Service Accounts
- For standalone servers, use a virtual account or Managed Service Account (MSA).
- For clustered or multi-server deployments, use a gMSA or domain account.
- Never use Local System, Local Service, or
saas catch-all accounts.
2. Apply Least Privilege
- Grant only what’s required: NTFS rights to data/log/backup folders,
Log on as a servicerights, and the SQL roles the account needs. - Don’t grant local admin unless absolutely required.
3. Separate Accounts per Service
- SQL Server Engine, SQL Agent, SSIS, and Reporting Services should each have their own accounts.
- That way, if one is compromised, the others aren’t automatically exposed.
4. Fix Job Ownership
- Check current job owners:
SELECT j.name, SUSER_SNAME(j.owner_sid) AS JobOwner
FROM msdb.dbo.sysjobs j;
- Reassign jobs to controlled accounts, not SYSTEM or
sa.
5. Audit Meaningfully
- Use SQL Server Audit or Extended Events to track schema changes:
CREATE SERVER AUDIT Audit_DDL_Changes
TO FILE (FILEPATH = 'C:\SQLAudit\DDLChanges\');
GO
CREATE SERVER AUDIT SPECIFICATION AuditSpec_DDL
FOR SERVER AUDIT Audit_DDL_Changes
ADD (SCHEMA_OBJECT_CHANGE_GROUP)
WITH (STATE = ON);
GO
ALTER SERVER AUDIT Audit_DDL_Changes WITH (STATE = ON);
- This ensures you see which principal actually made changes, not just SYSTEM.
6. Configure Accounts with Configuration Manager
Always change SQL service accounts through SQL Server Configuration Manager, not Services.msc. This ensures SPNs, registry rights, and file permissions are updated correctly.
Scripts to Check Your Current Setup
See what accounts your SQL services are using:
SELECT servicename, service_account
FROM sys.dm_server_services;
Check auto-stats settings:
SELECT name, is_auto_create_stats_on, is_auto_update_stats_on
FROM sys.databases;
Find jobs owned by built-in accounts:
SELECT j.name, SUSER_SNAME(j.owner_sid) AS JobOwner
FROM msdb.dbo.sysjobs j
WHERE SUSER_SNAME(j.owner_sid) IN ('NT AUTHORITY\SYSTEM','NT AUTHORITY\LOCAL SERVICE');
Final Thoughts
If you see NT AUTHORITY\SYSTEM in your logs, don’t panic. It usually means SQL Server or Agent is running under a built-in account and is performing maintenance tasks.
But it’s not best practice. For accountability, security, and compliance, switch to managed service accounts, apply least privilege, and audit with meaningful identities.
In short:
- Avoid built-in accounts for SQL services.
- Use domain MSAs/gMSAs or virtual accounts.
- Audit and assign jobs to proper accounts.
This ensures your logs tell the right story, your environment follows Microsoft’s recommendations, and you reduce risk from over-privileged service accounts.
Discover more from SQLYARD
Subscribe to get the latest posts sent to your email.


