{"id":62352,"date":"2021-09-17T08:00:45","date_gmt":"2021-09-17T16:00:45","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/devops\/?p=62352"},"modified":"2021-09-14T11:27:46","modified_gmt":"2021-09-14T19:27:46","slug":"introducing-azure-devops-audit-stream","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/introducing-azure-devops-audit-stream\/","title":{"rendered":"Introducing Azure DevOps Audit Stream"},"content":{"rendered":"<p>Auditing is important in any environment and solution, to get a view on who is doing what, typically from a compliance or governance perspective. In most scenarios, the solution allows you to store auditing to a logfile. The downside is that nobody is really watching over the logs, until something goes wrong.<\/p>\n<p>Auditing is enabled by default for all Azure DevOps organizations, and cannot be turned off. This guarantees that you never miss an actionable event. Events get stored for 90 days after which they will get deleted automatically. One possibility though is, you can back up audit events to an external location to keep the data for longer than the 90-day period.<\/p>\n<p>The scenario I talk about in this article, is optimizing Audit Logging within Azure DevOps, by enabling the new, currently in public preview, <strong>ADO Audit Stream<\/strong>.<\/p>\n<h2>What\/Why ADO Audit Stream<\/h2>\n<p>Instead of using the built-in Audit Logging, which allows DevOps Project Admins to retrieve Audit logging on screen, validate the activities happening in the Azure DevOps organization and optionally exporting to a JSON- or CSV-file type logfile, ADO Audit Stream allows for more <strong>transactional<\/strong> streaming of auditing information.<\/p>\n<p>By deploying an audit stream, auditing data can get sent to other services or solutions outside of Azure DevOps for further processing or inspection. Sending auditing data to other Security Incident and Event Management (SIEM) tools opens possibilities, such as alerting on specific auditing events, creating views on auditing data, and performing anomaly detection. It also allows you to store more than the default (and fixed) 90-days retention of auditing data.<\/p>\n<p>Audit streams represent a continuous stream of auditing logging events from your Azure DevOps organization to a stream target. Every half hour or less, new audit events are bundled and streamed to your targets. Remember that Audit Stream is an <strong>Organization<\/strong> setting, capturing all audit events from all projects within Azure DevOps.<\/p>\n<p>For now &#8211; remember it is in <strong>Public Preview<\/strong> <em>so features might still change<\/em> &#8211; Audit Stream supports 3 different scenarios as Stream Targets:<\/p>\n<p>a) <a href=\"https:\/\/azure.microsoft.com\/services\/event-grid\/?WT.mc_id=devops-38440-petender\">Azure Event Grid<\/a> b) <a href=\"https:\/\/docs.microsoft.com\/azure\/azure-monitor\/logs\/data-platform-logs\/?WT.mc_id=devops-38440-petender\">Azure Monitor Logs<\/a> c) <a href=\"https:\/\/www.splunk.com\/?WT.mc_id=devops-38440-petender\">Splunk<\/a><\/p>\n<h2>Scenario<\/h2>\n<p>In this article, I focus on <strong>Azure Event Grid<\/strong> integration only, to give you some idea about the concept of Auditing Stream<\/p>\n<p>The flow is the following:<\/p>\n<ol>\n<li>An Auditing event is generated in Azure DevOps<\/li>\n<li>Auditing Event Stream is configured for Event Grid<\/li>\n<li>Event Grid transferts the message to an Azure Storage Account Queue (Event Grid can do a lot more though&#8230; like triggering Functions, WebHooks)<\/li>\n<li>From Azure Storage Account Queue, the message could be send along to &#8220;any 3rd party monitoring tool&#8221;<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_01.png\" alt=\"Auditing_Flow_EventGrid\" \/><\/p>\n<h2>Walkthrough Setup<\/h2>\n<p>Now you do have an idea what Auditing Stream is about, let me guide you through the main steps to see it in action.<\/p>\n<h2>Enable Streams<\/h2>\n<ol>\n<li>To enable Streams, open the <strong>Organization Settings<\/strong> and navigate to the <strong>Auditing<\/strong> menu option. Besides Logs, you should also see <strong>Streams<\/strong><\/li>\n<\/ol>\n<p>(If you don&#8217;t see Streams, make sure you have Azure DevOps Preview Features enabled, which can be validated as follows: From the Azure DevOps Portal, navigate to <strong>User Settings<\/strong> (upper right corner next to your user account bubble) and select <strong>Preview Features<\/strong>)<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_02.png\" alt=\"PreviewFeatures\" \/><\/p>\n<ol>\n<li>From the Streams window, click the <strong>New Stream<\/strong> button, and notice the 3 different options of streaming integration available for now<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_03.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>\n<p>Select <strong>Azure Event Grid<\/strong><\/p>\n<\/li>\n<li>\n<p>You are asked for the Azure Event Grid Topic URL and Access Key.<\/p>\n<\/li>\n<\/ol>\n<h2>Deploy Azure Event Grid Topic<\/h2>\n<p>Assuming you don&#8217;t have an Azure Event Grid Topic yet, use the following steps to create this resource:<\/p>\n<ol>\n<li>From the Azure Portal (https:\/\/portal.azure.com), search for <strong>Event Grid Topic<\/strong> in the <em>&#8220;Search Resources, services and docs&#8221;<\/em> field and click the <strong>+ Create<\/strong> button to deploy a new Event Grid Topic. <\/li>\n<\/ol>\n<ul>\n<li>provide the necessary details around Subscription, Resource Group, unique Resource Name and Region for this resource to get created. <\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_04.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>Wait for the resource to get deployed successfully, and open it in the Azure Portal. Notice the <strong>Topic EndPoint<\/strong> under the Overview Blade of Event Grid Topic. This is the URL you need to provide in the Azure DevOps Stream settings for the Event Grid Topic. <\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_05.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>Navigate to the <strong>Access Keys<\/strong> option and copy the <strong>Key 1<\/strong> content to the corresponding field in the Azure DevOps Stream settings for Event Grid Topic.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_06.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>The Event Grid settings for Azure DevOps Stream look similar to my sample setup:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_07.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>Save the settings, which creates the Stream integration.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_08.png\" alt=\"StreamOptions\" \/><\/p>\n<p>If you would now trigger an Azure DevOps Event, it will get streamed to Azure Event Grid. However, Event Grid has no subscriptions yet, so it has no idea what to do with this receiving information.<\/p>\n<p>Event Grid supports different <strong>EndPoints<\/strong> such as Azure Functions, WebHooks, Service Bus, Storage Queue as targets.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_09.png\" alt=\"StreamOptions\" \/><\/p>\n<h2>Create Storage Account Queue with Managed Identity<\/h2>\n<p>In this example, I will use a Storage Account Queue, but if you have experience with any of the other options, feel free to give that a try.<\/p>\n<p>In order to define this as an EndPoint, let&#8217;s create the Storage Account Queue.<\/p>\n<ol>\n<li>\n<p>Create a new Azure Storage Account v2, in the same Location and Resource Group as where the Event Grid Resource got created earlier.<\/p>\n<\/li>\n<li>\n<p>Once the Storage Account is created, navigate to <strong>Data Storage \/ Queue<\/strong> in the Storage Account blade, and create a new Queue. I called mine <strong>devopsmessages<\/strong> but it can have any name you want.<\/p>\n<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_10.png\" alt=\"StreamOptions\" \/><\/p>\n<p>To allow the Event Grid Resource to communicate with the Azure Storage Account Queue, I&#8217;m using <strong>Azure Managed Identity<\/strong>. This relies on the Azure Identity Service Principal concept to authorize both services to communicate with each other.<\/p>\n<ol>\n<li>Navigate back to the Event Grid Topic created earlier, and select <strong>Identity<\/strong> under the settings. Next, select <strong>System Assigned<\/strong>, which creates a 1-to-1 mapping between the Event Grid Resource and its Azure Identity Service Principal object. <strong>Save<\/strong> the changes.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_11.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>Navigate back to the Azure Storage Account you created earlier, and select <strong>Access COntrol (IAM)<\/strong> from the settings. Specify the following Role Permissions:<\/li>\n<\/ol>\n<ul>\n<li><strong>Role<\/strong>: Storage Queue Data Contributor<\/li>\n<li><strong>Assign access to<\/strong>: User, Group, Service Principal<\/li>\n<li><strong>Select<\/strong>: <the name of the Event Grid Resource><\/the><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_12.png\" alt=\"StreamOptions\" \/><\/p>\n<p>This provides the necessary Role Based Access Control, to allow Event Grid to communicate with the Storage Account Queue, and creating messages in the queue itself.<\/p>\n<h2>Configure Event Grid Subscription<\/h2>\n<p>In this last step, let&#8217;s configure an Event Grid Subscription, which will &#8220;listen&#8221; for events on the Azure Audit side.<\/p>\n<ol>\n<li>Open your Event Grid Topic blade, select <strong>Overview<\/strong> and click <strong>+ Event Subscription<\/strong>. Complete the necessary fields with the correct parameters:<\/li>\n<\/ol>\n<ul>\n<li><strong>Name<\/strong>: a unique name for the Event Grid Subscription <\/li>\n<li><strong>Event Schema<\/strong>: Event Grid Schema<\/li>\n<li><strong>EndPoint Type<\/strong>: Storage Queues<\/li>\n<li><strong>EndPoint<\/strong>: The Storage Account Queue object<\/li>\n<li><strong>Managed Identity Type<\/strong>: System Assigned <\/li>\n<\/ul>\n<p>Here is a screenshot of the settings I used for this article setup:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_13.png\" alt=\"StreamOptions\" \/><\/p>\n<h2>Monitoring Audit Stream info coming in<\/h2>\n<p>Event Grid and its subcomponent Event Grid Subscription, provide detailed metrics information directly from within the Resource Blade.<\/p>\n<ol>\n<li>\n<p><strong>Generate<\/strong> a few Events on the Azure DevOps side, by for example checking the Audit Log, Trigger a Pipeline run or change Permissions on a Project.<\/p>\n<\/li>\n<li>\n<p>After only a few minutes, you should see the events showing up in the <strong>Event Grid Topic<\/strong> Overview section:<\/p>\n<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_14.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>At the bottom of the chart, select the <strong>Storage Queue Subscription<\/strong> object, which redirects you to a more granular dashboard view for the subscription object.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_15.png\" alt=\"StreamOptions\" \/><\/p>\n<ol>\n<li>Last, select the <strong>Storage Queues EndPoint<\/strong> underneath the chart, which opens the Storage Account Queue, where you can see the actual DevOps Audit information in a queue message. <\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/09\/ADOAuditStream_2021-09-08_16.png\" alt=\"StreamOptions\" \/><\/p>\n<p>This confirms the setup is complete and Azure DevOps Audit Stream to Event Grid and Storage Queue EndPoint is working as expected.<\/p>\n<h2>Summary<\/h2>\n<p>In this article, I wanted to introduce you to a new <strong>Public Preview<\/strong> feature available in Azure DevOps, namely <strong>Audit Stream<\/strong>. This feature allows an organization to stream Auditing information out of Azure DevOps Logs to another solution, for example Azure Event Grid, Azure Monitor Logs or Splunk.<\/p>\n<p>This article covered Event Grid with Storage Account Queue as an example scenario to get you started and get an understanding of the core capabilities. Since Auditing is a crucial component of a healthy platform, I would recommend you to keep your eyes out for any updates on this preview feature, to see it moving to General Availability. If you should have any questions in meantime, do not hesitate to reach out [petender] @ [microsoft.com] or [pdtit] on Twitter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Auditing is important in any environment and solution, to get a view on who is doing what, typically from a compliance or governance perspective. In most scenarios, the solution allows you to store auditing to a logfile. The downside is that nobody is really watching over the logs, until something goes wrong. Auditing is enabled [&hellip;]<\/p>\n","protected":false},"author":45107,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[224],"tags":[],"class_list":["post-62352","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure"],"acf":[],"blog_post_summary":"<p>Auditing is important in any environment and solution, to get a view on who is doing what, typically from a compliance or governance perspective. In most scenarios, the solution allows you to store auditing to a logfile. The downside is that nobody is really watching over the logs, until something goes wrong. Auditing is enabled [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/62352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/45107"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=62352"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/62352\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=62352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=62352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=62352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}