As a database application vendor, the security and reliability of your software are key competitive differentiators. As a database administrator, your priority is ensuring that hosted databases never expose data or the environment to risk. This checklist is a blueprint for building secure-by-default, resilient database applications - helping you align with ISO 27001 controls while giving enterprise customers confidence in your product against a demanding environment and an evolving threat landscape.
Version 3
Download as PDFThe application should support installation into an existing empty database prepared by the customer's DBA.
The DBA should be able to define the database name and file locations according to the organization's standards. The application setup should then connect to that database and create only the required database-level objects, such as schemas, tables, views, stored procedures, and functions.
This avoids the need for server-level permissions during setup and keeps physical database layout independent from application code.
This is especially important for:
Use CREATE ANY DATABASE as the maximum required server-level permission for database creation, if the customer DBA cannot pre-create the database (D1).
The installer should not require sysadmin or Windows administrator rights. - Requiring sysadmin for database setup is a security red flag and may require a customer-side exception, supervision, and auditing.
Do not require user or application accounts to access SQL Server data folders. - Database files are created by the SQL Server service account; granting file-system access to data folders can allow file corruption or tampering.
Note: Avoid using ##MS_DatabaseManager## as a shortcut. It has a documented unresolved privilege-escalation path. CREATE ANY DATABASE remains the appropriate minimal grant for database deployment.
Any server-level permissions required during setup must be removable after installation completes.
Elevated permissions should be temporary, installation-only, and documented.
The application should run under a dedicated service identity - not under a shared administrator, DBA, user, or developer account.
For Windows-based deployments that connect to SQL Server, the application should ideally support Group Managed Service Accounts (gMSA).
For Azure-based deployments, it should support Managed Identities where applicable.
Do not share the same identity across unrelated applications or environments unless explicitly justified.
The application should prefer Windows Authentication for SQL Server and Managed Identity / Entra ID authentication for Azure-based deployments.
Avoid requiring SQL Authentication unless there is a clear technical reason. If SQL Authentication is required, provide a roadmap for when it can be replaced, or document the technical reason it cannot be.
Requiring SQL Authentication forces customers to enable Mixed Mode Authentication at the SQL Server instance level. That increases the attack surface for every database on the instance and may require the customer to deploy the application on a separate SQL Server instance.
If SQL Authentication is required, SQL credentials must be protected during installation, storage, and runtime use.
When deployment imports data from the file system, use a dedicated folder (network share) and grant the least amount of privileges required.
For BULK INSERT, grant read-only access only to the SQL Server service account. The application account does not need direct file access when SQL Server performs the file read.
For exports, document which component performs the write operation, such as bcp, SSIS, SQL Server, or custom application code.
These controls protect the database during normal application operation. They focus on least privilege, data protection, and avoiding database features that can become privilege-escalation paths if used carelessly.
Application accounts should not require membership in db_owner and should not own the database.
Most applications should run with the read and write permissions on the database granted via the database roles:
For applications that execute stored procedures broadly, grant EXECUTE permission through a dedicated database role rather than directly to the user, following the Login → User → Role → Permission (LURP) model.
Example (T-SQL):
CREATE DATABASE ROLE db_executor; GRANT EXECUTE TO db_executor;
Note: If the application creates or modifies database objects during normal operation, it may require additional permissions such as ALTER on a schema or, in broader cases, db_ddladmin. Avoid db_ddladmin unless necessary. It is still preferable to db_owner, but it grants powerful permissions and should be treated as elevated access.
If the application has separate components, services, modules, or background jobs that access different parts of the database, permissions should be separated by schema where practical.
This lets each process access only the objects it needs.
Example (T-SQL):
GRANT EXECUTE ON SCHEMA::Billing TO app_billing_role; GRANT SELECT, INSERT, UPDATE ON SCHEMA::Orders TO app_order_role;
If the application stores sensitive data, such as PCI data, healthcare data, credentials, secrets, or regulated personal information, use data encryption.
Do not rely on customer-implemented Transparent Data Encryption as a data-protection control. - TDE protects database backup files, but it does not protect against compromised application access or against privileged users with access to the host.
Triggers can become hidden execution paths. If an attacker or overly privileged user can modify a trigger, they may be able to execute code indirectly through normal application activity.
SQL CLR should not be required unless there is a clear technical reason.
If CLR assemblies are used, they must be deployed securely and should not depend on the database TRUSTWORTHY property.
The application should not require the database TRUSTWORTHY property to be set to ON.
TRUSTWORTHY ON enables elevation-of-privilege paths, especially when combined with powerful database ownership, unsafe assemblies, impersonation, or cross-database access.
The application must use safe query construction and parameter handling. Dynamic SQL should never be built by concatenating untrusted input directly into command text.
The application should not require broad access to msdb.
If the application uses SQL Server Agent jobs, Database Mail, SSIS, backup metadata, or other msdb features, the required access must be clearly documented and limited to the minimum necessary permissions.
Ensure the application supports encrypted SQL Server connections using TLS 1.2 or later.
These controls help ensure that the application works correctly during failover, migration, patching, and recovery operations. They focus on HA-aware connectivity, encryption validation, and DBA visibility.
The application should be tested against the SQL Server high-availability patterns customers commonly use, not only against a single standalone test instance.
Always use the customer-provided stable SQL Server endpoint - listener, FCI network name, or DNS alias - and do not switch to a resolved physical node name or IP address.
The application should connect through a stable customer-controlled name, not directly to a physical SQL Server host or IP address.
For Availability Groups, the application must support connecting through the Availability Group listener. A DNS alias pointing to the listener or target SQL Server name gives the customer more flexibility during failover, migration, and consolidation.
For SQL Server clients that support it, include MultiSubnetFailover=True in the connection string.
This improves connection behavior for Availability Groups and Failover Cluster Instances, especially during failover. It is useful even when the current deployment is not multi-subnet, and it has no adverse effect when no Availability Group is used.
Use a current Microsoft-supported SQL Server driver with validated HA behavior, such as Microsoft.Data.SqlClient, Microsoft JDBC Driver for SQL Server, or Microsoft ODBC Driver for SQL Server.
If SQL Server encryption is enforced, certificate validation must work with the exact name the application uses to connect.
A certificate can validate correctly against the server hostname but fail when the application connects through a DNS alias or Availability Group listener. The client validates the name in the connection string, not merely the server it resolves to.
Note: TrustServerCertificate disables certificate validation. It should not be used as a workaround for a name mismatch.
By adopting these standards, you are not just checking compliance boxes - you are making the application safer to deploy, easier to operate, and more credible for enterprise customers who care about least privilege, auditability, high availability, and recovery. This checklist is a practical reference for vendors, DBAs, security administrators, and developers; feedback is welcome.