SQL Server security rests on two separate questions. Authentication answers “is the person connecting really who they claim to be?”. Authorization answers “once inside, what can this person do?”. The two are often confused, yet most of the security gaps we see in the field come from the second question: accounts that authenticate correctly but hold far more permissions than they need.
This article covers SQL Server’s authentication methods, the difference between logins and users, how permissions are granted, and how to apply least privilege in practice.
Do you know who can access what?
Aryasoft maps the permission matrix of your SQL Server environment and fixes excessive permissions according to least privilege.
Authentication: Who Are You?
| Method | How it works | When |
|---|---|---|
| Windows Authentication | Identity is verified by Windows or Active Directory; the password isn’t sent to SQL Server | First choice for users and services in the domain |
| SQL Server Authentication | User name and password are stored and verified in SQL Server | Applications connecting from outside the domain, Linux clients, some third-party software |
| Microsoft Entra ID | Identity is verified by the cloud directory; MFA is supported | Azure SQL and SQL Server environments connected through Azure Arc |
A server accepts either Windows Authentication only, or Windows and SQL Authentication together (Mixed Mode). Use Windows Authentication only where possible: password policy, account lockout and account deactivation are managed centrally. If Mixed Mode is required, enforce the password policy on SQL logins and disable or rename the sa account.
Logins vs Users
- A login is server-level: it represents the right to connect to SQL Server.
- A user is database-level: it’s the login’s counterpart in a specific database.
For a login to access a database, it has to be mapped to a user in that database. The mapping is done by SID, so when a database is restored on another server where a login with the same name was created with a different SID, the user is left “orphaned”, and the login can’t reach the database even though it can connect.
-- Users without a login (orphaned)
SELECT dp.name AS user_name, dp.type_desc, dp.sid
FROM sys.database_principals AS dp
LEFT JOIN sys.server_principals AS sp ON sp.sid = dp.sid
WHERE sp.sid IS NULL
AND dp.type IN ('S', 'U', 'G')
AND dp.authentication_type_desc = N'INSTANCE'
AND dp.name NOT IN (N'dbo', N'guest', N'INFORMATION_SCHEMA', N'sys');
-- Reconnect an orphaned SQL user to an existing login
ALTER USER AppUser WITH LOGIN = AppUser;
Tip
Contained database users authenticate directly inside the database without needing a login. When the database moves to another server or fails over with Always On, there’s no login mapping problem. To use them, enable contained database authentication on the server and configure the database with PARTIAL containment.
Authorization: What Can You Do?
Permissions are granted at two levels:
- Server level: fixed server roles such as sysadmin, securityadmin and serveradmin, and server permissions such as
VIEW SERVER STATEandALTER ANY LOGIN. SQL Server 2022 and later also have new, narrower fixed roles such as ##MS_ServerStateReader##. - Database level: fixed roles such as db_owner, db_datareader and db_datawriter; roles you define yourself; and
GRANT,DENYandREVOKEat schema or object level.
-- A role for the application with only the permissions it needs
CREATE ROLE AppRole;
GRANT SELECT, INSERT, UPDATE ON SCHEMA::Sales TO AppRole;
GRANT EXECUTE ON SCHEMA::Sales TO AppRole;
ALTER ROLE AppRole ADD MEMBER AppUser;
Grant permissions to roles, not people, and to roles at schema level where possible. When a new table or procedure is added, the role’s permissions cover it automatically.
Warning
Giving application accounts sysadmin or db_owner is the security gap we see most often in the field. If the application has a SQL injection flaw, the attacker inherits every permission of the application account; a sysadmin account means access to every database on the server and even to the operating system. Application accounts should only hold the permissions they need, on the schemas they need.
Who Has Which Permissions?
-- sysadmin members
SELECT sp.name, sp.type_desc, sp.is_disabled
FROM sys.server_role_members AS rm
JOIN sys.server_principals AS sp ON sp.principal_id = rm.member_principal_id
WHERE rm.role_principal_id = SUSER_ID(N'sysadmin');
-- db_owner members in this database
SELECT dp.name, dp.type_desc
FROM sys.database_role_members AS rm
JOIN sys.database_principals AS dp ON dp.principal_id = rm.member_principal_id
WHERE rm.role_principal_id = DATABASE_PRINCIPAL_ID(N'db_owner');
Regularly reviewing privileged accounts and documenting the permission matrix is the first step of our security hardening guide. Use SQL Server Audit to record who does what.
Checklist
- Windows Authentication only where possible; password policy enforced in Mixed Mode.
- sa is disabled or renamed.
- sysadmin members are few and chosen deliberately; AD groups rather than individuals.
- Application accounts aren’t sysadmin or db_owner; schema-level role permissions are used.
- Orphaned users are checked regularly.
- The permission matrix is documented and reviewed periodically.
Related Reading
SQL Server Security Consulting
Organize permissions around least privilege
Aryasoft’s senior DBA team maps the permission matrix of your SQL Server environment, reviews privileged accounts and makes application accounts run with only the permissions they need.