{"id":92797,"date":"2021-11-22T17:00:34","date_gmt":"2021-11-22T17:00:34","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=92797"},"modified":"2021-11-15T18:10:40","modified_gmt":"2021-11-15T18:10:40","slug":"dynamic-data-mask-is-now-useful-and-no-one-noticed-it","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/dynamic-data-mask-is-now-useful-and-no-one-noticed-it\/","title":{"rendered":"Dynamic Data Mask is now useful and no one noticed it"},"content":{"rendered":"<p>Dynamic data mask is a very interesting security feature allowing us to mask critical fields such as e-mail, phone number, credit card and so on. We can decide what users will be able to see the value of these features or not.<\/p>\n<p>This feature faced many flaws when it was released, but I believe it&#8217;s stable now, although It&#8217;s not the main security feature you should care about, it can still be very useful.<\/p>\n<p>However, until very recently, this feature was not very useful. If you mask many fields in many different tables, the fields may require different permission levels in order to be unmasked.<\/p>\n<p>The only permission control provided for Mask and Unmask fields where this: See everything masked or everything unmasked. In this way, the feature was not useful, because there is not doubt that phone number and credit card should have different permission levels.<\/p>\n<p>Finally, the granular permission control for Data Mask is available in Azure SQL Databases. The feature became way more useful and with so many news around these weeks, not many people noticed.<\/p>\n<h2>Test Environment<\/h2>\n<p>Let&#8217;s test this feature using the <strong>AdventureWorksLT<\/strong>. We can provision this database in <strong>Azure SQL<\/strong> by choosing to provision a sample database.<\/p>\n<h2>\nApplying the Data Mask<\/h2>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: blue\">table<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: blue\">column<\/span>\u00a0<span style=\"color: maroon\">EmailAddress<\/span>\u00a0<span style=\"color: black\"><i>nvarchar<\/i><\/span><span style=\"color: maroon\">(<\/span><span style=\"color: black\">50<\/span><span style=\"color: maroon\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon\">masked<\/span>\u00a0<span style=\"color: blue\">with<\/span>\u00a0<span style=\"color: maroon\">(<\/span><span style=\"color: blue\">function<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8217;email()&#8217;<\/span><span style=\"color: maroon\">)<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: blue\">table<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: blue\">column<\/span>\u00a0<span style=\"color: maroon\">Phone<\/span>\u00a0<span style=\"color: black\"><i>nvarchar<\/i><\/span><span style=\"color: maroon\">(<\/span><span style=\"color: black\">25<\/span><span style=\"color: maroon\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon\">masked<\/span>\u00a0<span style=\"color: blue\">with<\/span><span style=\"color: maroon\">(<\/span><span style=\"color: blue\">function<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8216;partial(3,&#8221;XXXXXXXXX&#8221;,0)&#8217;<\/span><span style=\"color: maroon\">)<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span> <\/span><\/div>\n<h3>\nCreate Roles to control Mask Permissions<\/h3>\n<p>\nControl permissions in a field level is something complex. A good practice to do this is using database roles. Let&#8217;s create database roles for this and set the permission of these roles as data reader to make the example easier.<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Create<\/span>\u00a0<span style=\"color: maroon\">Role<\/span>\u00a0<span style=\"color: maroon\">EmailView<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">Create<\/span>\u00a0<span style=\"color: maroon\">Role<\/span>\u00a0<span style=\"color: maroon\">PhoneView<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">Alter<\/span>\u00a0<span style=\"color: maroon\">Role<\/span>\u00a0<span style=\"color: maroon\">db_datareader<\/span>\u00a0<span style=\"color: blue\">add<\/span>\u00a0<span style=\"color: maroon\">member<\/span>\u00a0<span style=\"color: maroon\">EmailView<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">Alter<\/span>\u00a0<span style=\"color: maroon\">Role<\/span>\u00a0<span style=\"color: maroon\">db_datareader<\/span>\u00a0<span style=\"color: blue\">add<\/span>\u00a0<span style=\"color: maroon\">member<\/span>\u00a0<span style=\"color: maroon\">PhoneView<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span> <\/span><\/div>\n<h3>\nGrant the unmask peremission<\/h3>\n<p>On our example, we will grant the unmask permission over each field for the different database roles. The statements will be like this:<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Grant<\/span>\u00a0<span style=\"color: maroon\">UnMask<\/span>\u00a0<span style=\"color: blue\">on<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span><span style=\"color: maroon\">(<\/span><span style=\"color: maroon\">Phone<\/span><span style=\"color: maroon\">)<\/span>\u00a0<span style=\"color: blue\">to<\/span>\u00a0<span style=\"color: maroon\">PhoneView<\/span> <br \/>\n<span style=\"color: blue\">go<\/span> <br \/>\n<span style=\"color: blue\">Grant<\/span>\u00a0<span style=\"color: maroon\">UnMask<\/span>\u00a0<span style=\"color: blue\">on<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span><span style=\"color: maroon\">(<\/span><span style=\"color: maroon\">EmailAddress<\/span><span style=\"color: maroon\">)<\/span>\u00a0<span style=\"color: blue\">to<\/span>\u00a0<span style=\"color: maroon\">Emailview<\/span> <br \/>\n<span style=\"color: blue\">go<\/span> <\/span><\/div>\n<p>\nThe granular unmask permission also would allow to grant permission schema level:<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Grant<\/span>\u00a0<span style=\"color: maroon\">UnMask<\/span>\u00a0<span style=\"color: blue\">on<\/span>\u00a0<span style=\"color: blue\">Schema<\/span><span style=\"color: silver\">::<\/span><span style=\"color: maroon\">SalesLT<\/span>\u00a0<span style=\"color: blue\">to<\/span>\u00a0<span style=\"color: maroon\">CustomRole<\/span> <\/span><\/div>\n<p>Or also on table level:<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Grant<\/span>\u00a0<span style=\"color: maroon\">UnMask<\/span>\u00a0<span style=\"color: blue\">on<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span>\u00a0<span style=\"color: blue\">to<\/span>\u00a0<span style=\"color: maroon\">CustomRole<\/span> <\/span><\/div>\n<p>\nAnyway, now making the data mask feature really useful.<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Create<\/span>\u00a0<span style=\"color: blue\">user<\/span>\u00a0<span style=\"color: maroon\">CanReadEmail<\/span>\u00a0<span style=\"color: blue\">with<\/span>\u00a0<span style=\"color: maroon\">password<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8216;9646xpahmW&#8217;<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">Create<\/span>\u00a0<span style=\"color: blue\">user<\/span>\u00a0<span style=\"color: maroon\">CanReadPhone<\/span>\u00a0<span style=\"color: blue\">with<\/span>\u00a0<span style=\"color: maroon\">password<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8216;9646xpahmW&#8217;<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: maroon\">role<\/span>\u00a0<span style=\"color: maroon\">EmailView<\/span>\u00a0<span style=\"color: blue\">add<\/span>\u00a0<span style=\"color: maroon\">member<\/span>\u00a0<span style=\"color: maroon\">CanReadEmail<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">alter<\/span>\u00a0<span style=\"color: maroon\">role<\/span>\u00a0<span style=\"color: maroon\">PhoneView<\/span>\u00a0<span style=\"color: blue\">add<\/span>\u00a0<span style=\"color: maroon\">member<\/span>\u00a0<span style=\"color: maroon\">CanReadPhone<\/span><\/span><\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: maroon\">go<\/span> <\/span><\/div>\n<div>\u00a0<\/div>\n<h3>Test the users and UnMask Feature<\/h3>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Execute<\/span>\u00a0<span style=\"color: blue\">as<\/span>\u00a0<span style=\"color: blue\">user<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8216;CanReadEmail&#8217;<\/span><\/span><\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">select<\/span>\u00a0<span style=\"color: silver\">*<\/span>\u00a0<span style=\"color: blue\">from<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span><\/span><\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">revert<\/span> <\/span><\/div>\n<p>This first user can read the phone, but not the e-mail:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92799\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/PhoneMasked.png\" alt=\"\" width=\"377\" height=\"315\" \/><\/p>\n<p>&nbsp;<\/p>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"> <span style=\"color: blue\">Execute<\/span>\u00a0<span style=\"color: blue\">as<\/span>\u00a0<span style=\"color: blue\">user<\/span><span style=\"color: silver\">=<\/span><span style=\"color: red\">&#8216;CanReadPhone&#8217;<\/span><\/span><\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">select<\/span>\u00a0<span style=\"color: silver\">*<\/span>\u00a0<span style=\"color: blue\">from<\/span>\u00a0<span style=\"color: maroon\">SalesLT<\/span><span style=\"color: silver\">.<\/span><span style=\"color: maroon\">Customer<\/span><\/span><\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-family: Courier New;font-size: 10pt\"><span style=\"color: blue\">revert<\/span> <\/span><\/div>\n<p>This 2nd user can read the e-mail but not the phone:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92798\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/EmailMasked.png\" alt=\"\" width=\"245\" height=\"290\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Conclusion<\/h2>\n<p>We have a new powerful security feature on our hands to work with and I hope this feature to be in SQL Server 2022 as well<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dynamic data mask is a very interesting security feature allowing us to mask critical fields such as e-mail, phone number, credit card and so on. We can decide what users will be able to see the value of these features or not. This feature faced many flaws when it was released, but I believe it&#8217;s&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,1],"tags":[5364,136322,145492,4619],"coauthors":[6810],"class_list":["post-92797","post","type-post","status-publish","format-standard","hentry","category-blogs","category-uncategorized","tag-azure","tag-azure-sql","tag-data-mask","tag-security"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92797","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=92797"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92797\/revisions"}],"predecessor-version":[{"id":92800,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92797\/revisions\/92800"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=92797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=92797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=92797"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=92797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}