Azure SQL and Managed Identity

Azure SQL has a close relationship with Azure Storage. Features like Polybase, backups, extended events and more make use of Azure Storage.

On Azure SQL Database, probably the most common use is Extended Events. When we create a file target, we need to point to the Azure Storage URL where the file will be stored.

Using Keys

In order to access Azure Storage, we need to control the authentication. The most common way is to use credentials, creating a credential with the storage SAS key

. Graphical user interface, text, application, email

Description automatically generated

Once we generate the SAS key, we create the credential object inside our database. For this we have Database Scoped a new feature introduced exactly for these situations, allowing us to create the credential inside the database, instead of at server level.

The statement to create the credential would be like this:

CREATE DATABASE scoped credential
[https://dummystorageaccount.blob.core.windows.net/extendedevents] WITH IDENTITY
=‘SHARED ACCESS SIGNATURE’, secret =
‘sv=2019-12-12&ss=b&srt=sco&sp=rwdlacx&se=2021-12-30T20:03:34Z&st=2021-01-22T12:03:34Z&spr=https&sig=kMj8oq7bKderywanUcYN9vE3ebx0GxOaj3N7NU%2BMdgE%3D’ 

The Identity value is fixed, to identify the kind of key we are using, a SAS key. The name needs to be the URL to the container, but not always, it depends on what feature will be using this credential.

Some more recent features are prepared to use credentials, receiving the name of the credential as a parameter. In these cases, the credential can have whatever name we would like.

However, older features, such as Extended Events, are not prepared to be linked to a credential. This is solved by ensuring the credential name has the same name of the path used by the feature. In this way, SQL Server identifies which credential should be used for that access.

Avoiding Keys

This method ends up spreading SAS keys all around. We can’t really tell this is unsafe, since the credentials are kept encrypted using the SQL Server encryption system, but it would be better if we could make the authentication without directly using a key or password.

That’s what we can achieve using Managed Identities. Each service on Azure can have its own identity registered with Azure Active Directory. Once the identity is stablished, we can use Role Based security (RBAC) to set permissions for the service, avoiding the use of passwords or keys.

Azure SQL Database doesn’t have a control on the UI to set the managed identity, but we can easily do it using PowerShell in the cloud shell on the portal.

Graphical user interface, text, application

Description automatically generated

The statement to set the managed identity is like this:

Setting Identity Permissions

Once we execute this statement, the server gets an identity, and we can use this identity to control the access to the Azure Storage. The next step is to give permission to this identity.

When dealing with RBAC permissions it’s important to mind there are two kinds of permissions: Object permissions, for managing the object, and data permission, to access the data within the object. In this case, we need the data permissions, so SQL Server will be able to write the extended events file to the blob storage. We can set the Managed Identity with the permission Storage Blob Data Contributor, which is different than Storage Blob Contributor.

On the storage account, we access the tab Access Control (IAM) and click the Add button. A new window will open, where we configure the identity and permission. The permission is set on Role dropdown, we just choose it. We type on the Select text box to filter the identities. The Manage Identity will have the same name as the SQL Server we created. Once found, we select it and complete the creation of the role assignment.

Graphical user interface, text, application

Description automatically generated

Next step is creating a credential in the database to use the managed identity. This time we don’t have a secret for the credential, we only define the type of Identity we will use:

CREATE DATABASE scoped credential
[https://dummystorageaccount.blob.core.windows.net/extendedevents] WITH IDENTITY
= ‘Managed Identity’; 

Creating the XE Session

This is only an example of an Extended Events session pointing to the blob storage. It will use the credential to authenticate and, in our example, will be using the SQL Server Managed Identity.

CREATE EVENT SESSION [queries] ON DATABASE
ADD EVENT sqlserver.sql_statement_completed(
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.context_info,sqlserver.database_id,sqlserver.database_name,sqlserver.username)),
ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.username))
ADD TARGET package0.event_file(SET filename=N’https://dummystorageaccount.blob.core.windows.net/extendedevents/queries/’)
WITH (STARTUP_STATE=ON)GO

Conclusion

Managed Identities can make our cloud environment safer, removing keys and passwords from our control.