Jekyll2023-03-18T21:13:23+00:00/feed.xmlpacodelacruz.ioPaco de la Cruz's blog. Sharing my personal journey with Azure, cloud solution architecture, and software development. Thanks for visiting :) Assessing Azure API Management authorisation approaches2023-03-17T10:00:00+00:002023-03-17T10:00:00+00:00/assessing-azure-api-management-auth-approaches<h2><img src="/assets/img/2023/03/passport-01.jpeg" alt="passport" width="1200" height="600" loading="lazy" style="height: auto; max-width: 100%; width: 1200px;" /></h2>
<h2>Introduction</h2>
<p>As part of our consulting engagements, it is common that our customers ask us to provide guidance on the different authentication and authorisation approaches available on API Management and how they meet their security needs while offering support to existing legacy API clients. While many people now know that <a href="https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/auth-oauth2">OAuth 2.0</a> is the industry protocol for HTTP authorisation, there are cases where some API consumers don’t provide support for it. Thus, organisations need to know when alternative controls can be implemented.</p>
<!--more-->
<p>In this post, I will share our starting position for this type of assessment. It’s worth noting that each organisation has different needs and there is always the need to tailor this assessment accordingly.</p>
<h2>Context</h2>
<p>Before assessing each of the different authorisation approaches available on API Management, it’s important to understand the <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-vs-authorization">difference between authentication and authorisation</a>. We also need to understand who is meant to be calling the API and the type of data being exposed. Let’s explore these topics in more detail.</p>
<h3>API client authentication use cases</h3>
<p>To classify an API consumer, first, we can consider different use cases. Do we need to authorise an application or an end user? Shall we allow an anonymous client to call the API? Three main use cases are described in the table below.</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: 1px solid #99acc2;">
<tbody>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Use case</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Description</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Examples</span></strong></p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Anonymous</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>No authentication is required to call an API. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Any unauthenticated client</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>End-user authentication </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Permissions are granted at user level.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A user accessing their own data via an API</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Application authentication </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>An application needs to authenticate to gain access to an API. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A web application needs to authenticate against a database to get access to data.</p>
<p>A service running in the background needs to authenticate to call an API.</p>
</td>
</tr>
</tbody>
</table>
<h3>API client trust level</h3>
<p>Depending on who owns and manages the API client and where it is deployed, different security controls will need to be in place. We can use the model below to classify API clients based on their trust level.</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: 1px solid #99acc2;">
<tbody>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p><strong><span style="color: black;">Trust level</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p><strong><span style="color: black;">Description</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Examples</span></strong></p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>First-party internal</p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>A trusted application that belongs to the organisation and is deployed within a trusted private network, either on-premises or on the cloud.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A service running in the background and deployed on-premises</p>
<p>A serverless function deployed in the organisation’s cloud private network.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>First-party external </p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>A trusted system that is owned and controlled by the organization but deployed outside the private network. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A cloud-hosted SaaS application owned by the organisation, e.g., a SaaS CRM or ERP.</p>
<p>A corporate mobile app developed internally.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>Third-party </p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>Any system that is not trusted. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A strategic customer’s application</p>
<p>A vendor’s system</p>
<p>An application configured by an end user.</p>
</td>
</tr>
</tbody>
</table>
<h3>API client types</h3>
<p>It is important that we also consider if the API client is a mobile application, a client-side web application, or a server-side application. This is relevant to understand how the API credentials are going to be managed and stored.</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: 1px solid #99acc2;">
<tbody>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p><strong><span style="color: black;">Trust level</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p><strong><span style="color: black;">Description</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Examples</span></strong></p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>Client-side web application </p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>A single-page web application that directly calls the APIs. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A javascript application that runs in the user's browser</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>Native mobile application </p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>A native mobile application that calls the APIs. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>An Android app</p>
<p>An iOS app</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;" width="141">
<p>Server-side application </p>
</td>
<td style="border: solid windowtext 1.0pt;" width="259">
<p>A server application that calls APIs in another system. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>A cloud based serverless application that calls APIs hosted on another service</p>
</td>
</tr>
</tbody>
</table>
<h3>Data confidentiality and integrity</h3>
<p>When protecting an API, it’s crucial to understand the type of information that is being exposed by the API and the type of operations the API consumer can perform against the data.</p>
<p>When implementing authorisation on an API, we are dealing with two key data security pillars.</p>
<ul>
<li><strong>Confidentiality</strong> ensures that only allowed consumers can access the exposed data. We should have a <a href="https://learn.microsoft.com/en-us/compliance/assurance/assurance-data-classification-and-labels#what-is-a-data-classification-framework">data-classification framework</a> in place to understand the level of sensitivity of the information being exposed and an access control model that dictates who has access to what.</li>
<li><strong>Integrity</strong> ensures that the data exposed by the API cannot be altered by clients that are not authorised to do so. We need to understand if different API consumers have different access levels to the information being exposed. For instance, while some users have read-only access, others can modify their own records, and some privileged users are able to perform read and write operations on all records.</li>
</ul>
<p>A secure API must be able to guarantee the confidentiality and integrity of the information it exposes. Understanding the confidentiality level of the data and the data operations being exposed by the API would help us to better define the authorisation approach required for the API.</p>
<p>We have explored the different authentication use cases, client trust levels and types, and discussed the importance of understanding the data classification and the type of operations API clients can perform against the exposed data. Let’s now explore the different authentication and authorisation approaches available on API Management.</p>
<h2>Available Approaches</h2>
<p>Let’s start by describing the authentication and authorisation approaches available on API Management. In the table below I describe different authentication and authorisation approaches and give a summary of how they can be implemented on API Management.</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: 1px solid #99acc2;">
<tbody>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Approach</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Description</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Authentication</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Authorisation</span></strong></p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Anonymous</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Anonymous access allows any user or application to access an API without requiring authentication</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Client IP address</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The API client authenticates against the API using its own IP address</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Source IP address in the IP packets or the <strong>X-Forwarded-For</strong> header for requests going through a proxy.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><a href="https://learn.microsoft.com/en-us/azure/api-management/ip-filter-policy">ip-filter</a> policy for direct calls.</p>
<p>Using the <a href="https://learn.microsoft.com/en-us/azure/api-management/check-header-policy">check-header</a> policy for calls going through a proxy to validate the <strong>X-Forwarded-For</strong> header</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>API key</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The client application authenticates by adding a key to each API request.</p>
<p>API keys can be sent as query parameters or HTTP headers.</p>
<p>API keys are relatively easy for legacy API clients to implement.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>API key in the query parameters or HTTP headers</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Requires a <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-subscriptions">subscription</a> at product or API level and the corresponding subscription <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-subscriptions#scope-of-subscriptions">scope assignment</a>. </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>HTTP basic authentication</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The basic HTTP authentication scheme transmits credentials as user-id/password pairs, encoded in Base64.</p>
<p>The standard is documented in the Internet Engineering Task Force's <a href="https://datatracker.ietf.org/doc/html/rfc7617">RFC7617</a>.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>User-id/password pair encoded in Base64 via the <strong>Authorization</strong> header as described in the <a href="https://datatracker.ietf.org/doc/html/rfc7617#section-2">official documentation</a>. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Using the <a href="https://learn.microsoft.com/en-us/azure/api-management/check-header-policy">check-header</a> policy and checking that the “Authorization” header contains “Basic” + the base64 encoded user-id/password pair.</p>
<p> </p>
<p>When dealing with secrets on API Management, these must be <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-properties?tabs=azure-portal#key-vault-secrets">stored as secret name values in Key Vault</a>.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Client certificate</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Client certificate authentication is an authentication approach, where the client provides its client certificate to the server to prove its identity as a part of the TLS handshake.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The client provides a client certificate message excluding the private key. The client is authenticated by using its private key to sign a hash of all the messages. The recipient verifies the signature using the public key of the signer, thus ensuring it was signed with the client’s private key. Refer to <a href="https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.6">RFC 5246</a> for more details.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Using the <a href="https://learn.microsoft.com/en-us/azure/api-management/validate-client-certificate-policy">validate-client-certificate</a> policy or <a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates-for-clients#certificate-validation-with-context-variables">validating context variables</a>.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>OAuth 2.0 client credentials flow</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow">OAuth 2.0 client credentials grant flow</a> is part of the <a href="https://en.wikipedia.org/wiki/OAuth">open authorisation standard</a> and permits an application to use its own credentials – instead of impersonating a user – to authenticate when calling an API. It is commonly used for server-to-server interactions that must run in the background.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The client application authenticates against an identity provider to get an access token that is passed to the API for authorisation following a standard <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#protocol-diagram">flow</a>. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Using the <a href="https://learn.microsoft.com/en-au/azure/api-management/validate-azure-ad-token-policy">validate-azure-ad-token</a> policy for validating JWTs provided by Azure AD and <a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#ValidateJWT">validate-jwt</a> policy for third-party identity providers.</p>
<p> </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>OAuth 2.0 authorization code flow</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>The OAuth 2.0 authorization code flow is described in <a href="https://tools.ietf.org/html/rfc6749">section 4.1 of the OAuth 2.0 specification</a>. It's used to perform authentication and authorization in the majority of application types, including <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-app-types#single-page-apps-javascript">single-page applications</a>, <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-app-types#web-apps">server-side web applications</a>, <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-app-types#mobile-and-native-apps">native mobile apps</a>, and <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-app-types#daemons-and-server-side-apps">daemons and server-side apps</a>.</p>
<p>The flow enables applications to securely acquire end-user access tokens that can be used to access secured resources.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>An end user authenticates against an identity provider to get a token that is passed to the API for authorisation following a standard <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#protocol-diagram">flow</a>. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Using the <a href="https://learn.microsoft.com/en-au/azure/api-management/validate-azure-ad-token-policy">validate-azure-ad-token</a> policy for validating <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens#claims-in-an-id-token">JWTs or ID tokens</a> provided by Azure AD and <a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#ValidateJWT">validate-jwt</a> policy for third-party identity providers.</p>
<p> </p>
</td>
</tr>
</tbody>
</table>
<h2>Assessment</h2>
<p>Once we understand the different authorisation approaches available on API Management, let’s assess them against different scenarios and define when these approaches are recommended or if not, when they can be leveraged as tolerated approaches under certain circumstances. In the table below, I describe when the scenarios for which these approaches are not applicable, when they are recommended, the conditions under which they can be tolerated and additional considerations for each. As mentioned previously, this assessment should be used just as a starting position but must be tailored to each organisation’s needs.</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: 1px solid #99acc2;">
<tbody>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Approach</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Not applicable scenarios</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Recommended scenarios</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Tolerated scenarios</span></strong></p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><strong><span style="color: black;">Additional notes</span></strong></p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Anonymous</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Not recommended</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For 1st party internal clients and read-only APIs that do not expose sensitive or confidential information.</p>
<p>When required for external clients, for read-only and minimal risk APIs that only expose information classified as public.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When exposing anonymous APIs, additional security controls must be in place, such as a firewall for thread detection & protection, DDoS protection, a web application firewall, rate-limiting policies, etc.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Client IP address</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>End-user authentication</p>
<p>Client-side web application</p>
<p>Native mobile applications</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Not recommended</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>1st party internal clients using a private IP address when recommended authorisation approaches are not available to the API consumer.</p>
<p>As an additional security control on top of endorsed authorisation approaches or security measures.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p><a href="https://en.wikipedia.org/wiki/IP_address_spoofing">IP spoofing</a> can be easily leveraged to overcome security controls.</p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>API key</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For client-side web applications or native mobile apps, as API keys can be easily leaked. </p>
<p>While end users can get API keys, keys are typically used for application authentication scenarios.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Not recommended</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For APIs that do not expose sensitive or confidential information and a recommended authorisation method is not supported by the clients.</p>
<p>Not as an authorisation approach, but for rate limiting or usage statistics.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When used for authentication purposes, always use HTTP headers to pass an API key. Secrets must never be passed in URL query strings as there are <a href="https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url">many risk factors</a>.</p>
<p> </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>HTTP basic authentication</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For client-side web applications or native mobile apps, as secrets can be easily leaked. </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Not recommended</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For APIs that do not expose sensitive or confidential information and a recommended authorisation method is not supported by API clients.</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When using this approach, avoid storing plain text credentials in an API Management policy. Instead, use <a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-properties?tabs=azure-portal#key-vault-secrets">secret named values stored on Key Vault</a>. </p>
<p> </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>Client certificate</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>End-user authentication</p>
<p>Client-side web application</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>For application authentication scenarios, where certificates are preferred over client ids and client secrets.</p>
<p> </p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When client certificates are preferred over client secrets, consider leveraging the <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate">OAuth 2.0 client credentials flow with certificate-based request</a>.</p>
<p>While certificate authentication can be used for end-users, it is not recommended as authentication policies on API Management expect to authorise a single certificate. The same restriction applies to client-side web applications.</p>
<p>Consider the operational overhead of managing client certificates. </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>OAuth 2.0 client credentials flow</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>End-user authentication</p>
<p>Client-side web application</p>
<p>Native mobile application</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Recommended for server-side application authorisation</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When validating JWTs, it is important to validate not only the audience but role claims as well to ensure the application has the right level of access as documented <a href="/oauth2-client-credentials-flow-on-azure-api-management">here</a>. </p>
</td>
</tr>
<tr>
<td style="border: solid windowtext 1.0pt;">
<p>OAuth 2.0 authorization code flow</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Application authentication</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>Recommended for end-user authorisation</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>N/A</p>
</td>
<td style="border: solid windowtext 1.0pt;">
<p>When validating JWTs, it is important to validate not only the audience but role claims as well to ensure the end user has the right level of access.</p>
</td>
</tr>
</tbody>
</table>
<h2>An additional note on OAuth 2.0 client credentials.</h2>
<p>When discussing the different authorisation approaches with customers, a couple of times I’ve faced some skepticism about the OAuth 2.0 client credentials flow. Their main arguments have typically been:</p>
<ul>
<li>MFA cannot be enabled for applications. Once the client ID and client secret are leaked, then it’s practically the same level of security as basic authentication.</li>
<li>TLS protects the basic authentication credentials on every request.</li>
<li>JWT access tokens cannot be revoked on Azure AD.</li>
<li>Service principals in the Azure Active Directory tenant can be over-permissioned</li>
</ul>
<p>So, what are really the benefits of the OAuth 2.0 client credentials flow over basic authentication? Below are the arguments I present.</p>
<ul>
<li>Even though TLS is protecting every single request, it’s always better to ensure that credentials do not travel very frequently. The less frequently secrets travel over the wire, the lower the chances of getting them compromised by a man-in-the-middle (MITM) attack.</li>
<li>If an access token gets compromised, the access token will expire. On the contrary, when credentials get compromised by a MITM attack, they could be unnoticedly used for a longer period.</li>
<li>Delegating the authentication to a trusted and robust identity provider brings many benefits.
<ul>
<li>Centralised and built-in sign-in audit logs and threat detection and protection features.</li>
<li>Centralised secret strength and expiry policies.</li>
<li>Secret rotation policies and capabilities.</li>
<li>Secrets don’t have to be managed and asserted on the API layer.</li>
<li>Besides validating the token’s audience and the role claims (authorisation), the API is fully abstracted from the authentication process.</li>
</ul>
</li>
<li>Azure AD and other identity providers support not only a shared secret but also <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token">certificates and federated credentials</a> for the client credentials flow.</li>
<li>Azure AD <a href="https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#overview">supports managed identities</a> for the OAuth 2.0 client credentials flow. When the API consumers are an Azure resource within the same tenant, <a href="https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview#managed-identity-types">managed identities</a> remove the need to manage secrets.</li>
<li>The scoping features of the JWTs. Having well-defined audience and roles claims, allows for fine-grained privilege bracketing. When authorising an API client, we can validate not only the target audience in the JWT, but the roles the client has against to on the API, e.g., read, write, etc.</li>
<li>It’s also worth recognising that currently on Azure AD, JWT access tokens <a href="https://learn.microsoft.com/en-us/answers/questions/672062/how-to-revoke-token">cannot be revoked</a>. And while <a href="https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/users-revoke-access#azure-active-directory-environment">refresh tokens (long-lived) can be revoked</a>, the OAuth 2.0 client credentials flow <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow">only relies on access tokens</a>. Thus, considering that we can’t revoke access tokens, we must <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens#access-token-lifetime">configure the access token lifetime</a> according to the organisation’s needs. Furthermore, if an access token gets compromised by a MITM attack, it’s highly likely that it will go unnoticed or if we become aware of it, by the time we can action a revocation procedure, the access token is most likely expired.</li>
<li>To avoid over-permissioned service principals, we need to follow the least privilege principle and apply the right audience and role claims when granting access to the service principal.</li>
</ul>
<h2>Conclusions</h2>
<p>In this post, I discussed and assessed the different authentication and authorisation approaches available in API Management based on general principles. If you’re planning to endorse authorisation approaches for your own project or organisation, please consider this as a baseline. Always make your own assessment based on the organisation’s unique situation and needs.</p>
<p>Furthermore, API authorisation is just one of the many security controls you must consider when protecting your APIs on API Management. I’d recommend you to be familiar with the <a href="https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/api-management-security-baseline#logging-and-threat-detection">API Management security baseline</a> and make sure you have the right security controls in place. Other key security controls to consider are:</p>
<ul>
<li>Implement <strong>network protection:</strong>
<ul>
<li>Segregate <a href="https://learn.microsoft.com/en-us/azure/architecture/example-scenario/apps/publish-internal-apis-externally">public-facing and internal-facing APIs</a>.</li>
<li>Protect against common web exploits and vulnerabilities by deploying a <a href="https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview">Web Application Firewall</a> (WAF) <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-integrate-internal-vnet-appgateway">in front of API Management</a><span>.</span></li>
<li>Implement <a href="https://learn.microsoft.com/en-us/azure/api-management/protect-with-ddos-protection">DDoS protection</a><span>.</span></li>
<li>For higher security, consider <a href="https://learn.microsoft.com/en-us/azure/firewall/threat-intel">thread detection and protection</a> via a firewall.</li>
</ul>
</li>
<li>Always ensure data encryption in transit.</li>
<li>Implement rate-limiting or <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-sample-flexible-throttling">throttling</a></li>
<li>Define and implement <a href="https://learn.microsoft.com/en-us/azure/api-management/api-management-role-based-access-control">role-based access control (RBAC)</a> that includes privilege access management.</li>
<li>Ensure <a href="https://learn.microsoft.com/en-us/azure/architecture/example-scenario/security/apps-zero-trust-identity">zero trust end-to-end protection</a> for APIs and backend services.</li>
</ul>
<p>I hope you’ve found this post useful and that it has provided some guidance to make your APIs more secure.</p>
<p>Happy clouding!</p>
<p>
<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>
</p>Paco de la CruzIntroduction As part of our consulting engagements, it is common that our customers ask us to provide guidance on the different authentication and authorisation approaches available on API Management and how they meet their security needs while offering support to existing legacy API clients. While many people now know that OAuth 2.0 is the industry protocol for HTTP authorisation, there are cases where some API consumers don’t provide support for it. Thus, organisations need to know when alternative controls can be implemented. In this post, I will share our starting position for this type of assessment. It’s worth noting that each organisation has different needs and there is always the need to tailor this assessment accordingly. Context Before assessing each of the different authorisation approaches available on API Management, it’s important to understand the difference between authentication and authorisation. We also need to understand who is meant to be calling the API and the type of data being exposed. Let’s explore these topics in more detail. API client authentication use cases To classify an API consumer, first, we can consider different use cases. Do we need to authorise an application or an end user? Shall we allow an anonymous client to call the API? Three main use cases are described in the table below. Use case Description Examples Anonymous No authentication is required to call an API. Any unauthenticated client End-user authentication Permissions are granted at user level. A user accessing their own data via an API Application authentication An application needs to authenticate to gain access to an API. A web application needs to authenticate against a database to get access to data. A service running in the background needs to authenticate to call an API. API client trust level Depending on who owns and manages the API client and where it is deployed, different security controls will need to be in place. We can use the model below to classify API clients based on their trust level. Trust level Description Examples First-party internal A trusted application that belongs to the organisation and is deployed within a trusted private network, either on-premises or on the cloud. A service running in the background and deployed on-premises A serverless function deployed in the organisation’s cloud private network. First-party external A trusted system that is owned and controlled by the organization but deployed outside the private network. A cloud-hosted SaaS application owned by the organisation, e.g., a SaaS CRM or ERP. A corporate mobile app developed internally. Third-party Any system that is not trusted. A strategic customer’s application A vendor’s system An application configured by an end user. API client types It is important that we also consider if the API client is a mobile application, a client-side web application, or a server-side application. This is relevant to understand how the API credentials are going to be managed and stored. Trust level Description Examples Client-side web application A single-page web application that directly calls the APIs. A javascript application that runs in the user's browser Native mobile application A native mobile application that calls the APIs. An Android app An iOS app Server-side application A server application that calls APIs in another system. A cloud based serverless application that calls APIs hosted on another service Data confidentiality and integrity When protecting an API, it’s crucial to understand the type of information that is being exposed by the API and the type of operations the API consumer can perform against the data. When implementing authorisation on an API, we are dealing with two key data security pillars. Confidentiality ensures that only allowed consumers can access the exposed data. We should have a data-classification framework in place to understand the level of sensitivity of the information being exposed and an access control model that dictates who has access to what. Integrity ensures that the data exposed by the API cannot be altered by clients that are not authorised to do so. We need to understand if different API consumers have different access levels to the information being exposed. For instance, while some users have read-only access, others can modify their own records, and some privileged users are able to perform read and write operations on all records. A secure API must be able to guarantee the confidentiality and integrity of the information it exposes. Understanding the confidentiality level of the data and the data operations being exposed by the API would help us to better define the authorisation approach required for the API. We have explored the different authentication use cases, client trust levels and types, and discussed the importance of understanding the data classification and the type of operations API clients can perform against the exposed data. Let’s now explore the different authentication and authorisation approaches available on API Management. Available Approaches Let’s start by describing the authentication and authorisation approaches available on API Management. In the table below I describe different authentication and authorisation approaches and give a summary of how they can be implemented on API Management. Approach Description Authentication Authorisation Anonymous Anonymous access allows any user or application to access an API without requiring authentication N/A N/A Client IP address The API client authenticates against the API using its own IP address Source IP address in the IP packets or the X-Forwarded-For header for requests going through a proxy. ip-filter policy for direct calls. Using the check-header policy for calls going through a proxy to validate the X-Forwarded-For header API key The client application authenticates by adding a key to each API request. API keys can be sent as query parameters or HTTP headers. API keys are relatively easy for legacy API clients to implement. API key in the query parameters or HTTP headers Requires a subscription at product or API level and the corresponding subscription scope assignment. HTTP basic authentication The basic HTTP authentication scheme transmits credentials as user-id/password pairs, encoded in Base64. The standard is documented in the Internet Engineering Task Force's RFC7617. User-id/password pair encoded in Base64 via the Authorization header as described in the official documentation. Using the check-header policy and checking that the “Authorization” header contains “Basic” + the base64 encoded user-id/password pair. When dealing with secrets on API Management, these must be stored as secret name values in Key Vault. Client certificate Client certificate authentication is an authentication approach, where the client provides its client certificate to the server to prove its identity as a part of the TLS handshake. The client provides a client certificate message excluding the private key. The client is authenticated by using its private key to sign a hash of all the messages. The recipient verifies the signature using the public key of the signer, thus ensuring it was signed with the client’s private key. Refer to RFC 5246 for more details. Using the validate-client-certificate policy or validating context variables. OAuth 2.0 client credentials flow The OAuth 2.0 client credentials grant flow is part of the open authorisation standard and permits an application to use its own credentials – instead of impersonating a user – to authenticate when calling an API. It is commonly used for server-to-server interactions that must run in the background. The client application authenticates against an identity provider to get an access token that is passed to the API for authorisation following a standard flow. Using the validate-azure-ad-token policy for validating JWTs provided by Azure AD and validate-jwt policy for third-party identity providers. OAuth 2.0 authorization code flow The OAuth 2.0 authorization code flow is described in section 4.1 of the OAuth 2.0 specification. It's used to perform authentication and authorization in the majority of application types, including single-page applications, server-side web applications, native mobile apps, and daemons and server-side apps. The flow enables applications to securely acquire end-user access tokens that can be used to access secured resources. An end user authenticates against an identity provider to get a token that is passed to the API for authorisation following a standard flow. Using the validate-azure-ad-token policy for validating JWTs or ID tokens provided by Azure AD and validate-jwt policy for third-party identity providers. Assessment Once we understand the different authorisation approaches available on API Management, let’s assess them against different scenarios and define when these approaches are recommended or if not, when they can be leveraged as tolerated approaches under certain circumstances. In the table below, I describe when the scenarios for which these approaches are not applicable, when they are recommended, the conditions under which they can be tolerated and additional considerations for each. As mentioned previously, this assessment should be used just as a starting position but must be tailored to each organisation’s needs. Approach Not applicable scenarios Recommended scenarios Tolerated scenarios Additional notes Anonymous N/A Not recommended For 1st party internal clients and read-only APIs that do not expose sensitive or confidential information. When required for external clients, for read-only and minimal risk APIs that only expose information classified as public. When exposing anonymous APIs, additional security controls must be in place, such as a firewall for thread detection & protection, DDoS protection, a web application firewall, rate-limiting policies, etc. Client IP address End-user authentication Client-side web application Native mobile applications Not recommended 1st party internal clients using a private IP address when recommended authorisation approaches are not available to the API consumer. As an additional security control on top of endorsed authorisation approaches or security measures. IP spoofing can be easily leveraged to overcome security controls. API key For client-side web applications or native mobile apps, as API keys can be easily leaked. While end users can get API keys, keys are typically used for application authentication scenarios. Not recommended For APIs that do not expose sensitive or confidential information and a recommended authorisation method is not supported by the clients. Not as an authorisation approach, but for rate limiting or usage statistics. When used for authentication purposes, always use HTTP headers to pass an API key. Secrets must never be passed in URL query strings as there are many risk factors. HTTP basic authentication For client-side web applications or native mobile apps, as secrets can be easily leaked. Not recommended For APIs that do not expose sensitive or confidential information and a recommended authorisation method is not supported by API clients. When using this approach, avoid storing plain text credentials in an API Management policy. Instead, use secret named values stored on Key Vault. Client certificate End-user authentication Client-side web application For application authentication scenarios, where certificates are preferred over client ids and client secrets. N/A When client certificates are preferred over client secrets, consider leveraging the OAuth 2.0 client credentials flow with certificate-based request. While certificate authentication can be used for end-users, it is not recommended as authentication policies on API Management expect to authorise a single certificate. The same restriction applies to client-side web applications. Consider the operational overhead of managing client certificates. OAuth 2.0 client credentials flow End-user authentication Client-side web application Native mobile application Recommended for server-side application authorisation N/A When validating JWTs, it is important to validate not only the audience but role claims as well to ensure the application has the right level of access as documented here. OAuth 2.0 authorization code flow Application authentication Recommended for end-user authorisation N/A When validating JWTs, it is important to validate not only the audience but role claims as well to ensure the end user has the right level of access. An additional note on OAuth 2.0 client credentials. When discussing the different authorisation approaches with customers, a couple of times I’ve faced some skepticism about the OAuth 2.0 client credentials flow. Their main arguments have typically been: MFA cannot be enabled for applications. Once the client ID and client secret are leaked, then it’s practically the same level of security as basic authentication. TLS protects the basic authentication credentials on every request. JWT access tokens cannot be revoked on Azure AD. Service principals in the Azure Active Directory tenant can be over-permissioned So, what are really the benefits of the OAuth 2.0 client credentials flow over basic authentication? Below are the arguments I present. Even though TLS is protecting every single request, it’s always better to ensure that credentials do not travel very frequently. The less frequently secrets travel over the wire, the lower the chances of getting them compromised by a man-in-the-middle (MITM) attack. If an access token gets compromised, the access token will expire. On the contrary, when credentials get compromised by a MITM attack, they could be unnoticedly used for a longer period. Delegating the authentication to a trusted and robust identity provider brings many benefits. Centralised and built-in sign-in audit logs and threat detection and protection features. Centralised secret strength and expiry policies. Secret rotation policies and capabilities. Secrets don’t have to be managed and asserted on the API layer. Besides validating the token’s audience and the role claims (authorisation), the API is fully abstracted from the authentication process. Azure AD and other identity providers support not only a shared secret but also certificates and federated credentials for the client credentials flow. Azure AD supports managed identities for the OAuth 2.0 client credentials flow. When the API consumers are an Azure resource within the same tenant, managed identities remove the need to manage secrets. The scoping features of the JWTs. Having well-defined audience and roles claims, allows for fine-grained privilege bracketing. When authorising an API client, we can validate not only the target audience in the JWT, but the roles the client has against to on the API, e.g., read, write, etc. It’s also worth recognising that currently on Azure AD, JWT access tokens cannot be revoked. And while refresh tokens (long-lived) can be revoked, the OAuth 2.0 client credentials flow only relies on access tokens. Thus, considering that we can’t revoke access tokens, we must configure the access token lifetime according to the organisation’s needs. Furthermore, if an access token gets compromised by a MITM attack, it’s highly likely that it will go unnoticed or if we become aware of it, by the time we can action a revocation procedure, the access token is most likely expired. To avoid over-permissioned service principals, we need to follow the least privilege principle and apply the right audience and role claims when granting access to the service principal. Conclusions In this post, I discussed and assessed the different authentication and authorisation approaches available in API Management based on general principles. If you’re planning to endorse authorisation approaches for your own project or organisation, please consider this as a baseline. Always make your own assessment based on the organisation’s unique situation and needs. Furthermore, API authorisation is just one of the many security controls you must consider when protecting your APIs on API Management. I’d recommend you to be familiar with the API Management security baseline and make sure you have the right security controls in place. Other key security controls to consider are: Implement network protection: Segregate public-facing and internal-facing APIs. Protect against common web exploits and vulnerabilities by deploying a Web Application Firewall (WAF) in front of API Management. Implement DDoS protection. For higher security, consider thread detection and protection via a firewall. Always ensure data encryption in transit. Implement rate-limiting or throttling Define and implement role-based access control (RBAC) that includes privilege access management. Ensure zero trust end-to-end protection for APIs and backend services. I hope you’ve found this post useful and that it has provided some guidance to make your APIs more secure. Happy clouding! Cross-posted on Deloitte Engineering Follow me on @pacodelacruzPresentation (Spanish) - Mi experiencia como profesional de TI migrante en Australia2022-10-15T10:00:00+00:002022-10-15T10:00:00+00:00/speaking-feria-internacional-udem-australia<p>This presentation is in Spanish. I participated in “Feria Interacional UDEM 2023”, an event dedicated to migration to Australia. In my session, I shared my personal experience as a migrant and IT & cloud professional in Australia.</p>
<h2 id="slides">Slides</h2>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/Id78dv5i9Ireep" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/pacodelac/mi-experiencia-en-au-itpdf" title="Mi experiencia en AU IT.pdf" target="_blank">Mi experiencia en AU IT.pdf</a> </strong> from <strong><a href="//www.slideshare.net/pacodelac" target="_blank">Paco de la Cruz</a></strong> </div>
<h2 id="recording">Recording</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/95SJyT5TWHs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>Paco de la CruzThis presentation is in Spanish. I participated in “Feria Interacional UDEM 2023”, an event dedicated to migration to Australia. In my session, I shared my personal experience as a migrant and IT & cloud professional in Australia.Interview - Humans of Cloud by my Employer2022-08-09T10:00:00+00:002022-08-09T10:00:00+00:00/interview-humans-of-cloud<p>My current employer ran a campaign to interview practitioners so that readers can know a bit more of what cloud professional do, not only at work but outside work. I shared some insights into my day, how I spend my time, and how I believe Cloud is impacting the world we live in.</p>
<p>This is an extract of the <a href="https://www2.deloitte.com/au/en/blog/consulting-blog/2022/meet-paco-de-la-cruz.html">original post</a>.</p>
<p><i>Meet Paco de la Cruz, a Melbourne-based Principal in the Cloud & Engineering team. He is passionate about solving business challenges and delivering business value through cloud technologies and has been recognised as a Microsoft Azure MVP for 5 years. </i></p>
<p> </p>
<p><img src="/assets/img/2022/08/au-cloud-paco-3.jpg/au-cloud-paco-3.jpg" alt="" /></p>
<p> </p>
<p><b>So, tell us about a day in the life … </b></p>
<p> </p>
<p>I like to start my days doing basic body weights or callisthenics exercises. Then I prepare a nutritious breakfast for my family.</p>
<p> </p>
<p>At work, I’m usually involved in the delivery of a several projects as a cloud solution architect. At the same time, I typically work with our customers to define how modern technologies and the cloud can help them to deliver the business impact and outcomes they aspire. Another key focus area for me is the development of internal assets and accelerators so we can deliver value to our customers with accelerated speed to market and very high standards. </p>
<p> </p>
<p>After work, I like spending time with my family and letting my inner child out, playing with my 3-year-old daughter.</p>
<p> </p>
<p><img src="/assets/img/2022/08/au-cloud-paco-1.jpg" alt="" /></p>
<p> </p>
<p><b>From your perspective, how does Cloud help organisations to unlock business benefits?</b></p>
<p> </p>
<p>I’m old enough to have experienced (but still remember) how IT was done before the cloud was a thing! I love comparing how infrastructure and distributed applications were implemented then and now. </p>
<p> </p>
<p>While cloud services are very broad and include Infrastructure-as-a-Service (IaaS), Platform-as-a-Service (PaaS), and Software-as-a-Service (SaaS), my focus on cloud has been mainly leveraging PaaS so I’ll answer this question from this perspective.</p>
<p> </p>
<p>I see cloud as a key business enabler. When organisations leverage cloud, they get the following benefits: </p>
<ul>
<li>Business agility and accelerated speed to market by leveraging many specialised services and focusing on delivering business value instead of building infrastructure or a platform. </li>
<li>Simplified operations by making use of fully managed services with high levels of abstraction, availability SLAs, repeatable infrastructure and automation capabilities. </li>
<li>Resource optimisation thanks to the elasticity and scaling capabilities provided by the cloud.</li>
<li>Less capital expense by using pay-as-you-go pricing models. </li>
</ul>
<p> </p>
<p>For instance, I was recently part of a global delivery team that was working with a global customer in the mining industry. Our customer embarked on an enterprise-wide digital transformation and application modernisation program that demanded a consistent and modern approach to enterprise application integration. </p>
<p> </p>
<p>Our customer wanted to save valuable time by putting the project in motion, without the need for initial experimentation or proofs of concept. That made it especially important to choose an implementation partner with the experience and tools to begin right away to make rapid progress. </p>
<p> </p>
<p>Our team has a successful history with similar cloud implementations based on a defined set of accelerators and automation pipelines, as well as leading practices from the firm’s breadth of experience following the Microsoft Cloud Adoption Framework for Azure, all of which made it possible to meet a high standard in a short time.</p>
<p> </p>
<p>To provide the flexibility the program needed, we implemented a Center for Enablement and structured the application delivery so different teams could lead development in their own areas, united by governance, reference implementations, common processes, frameworks, standards, and quality controls.</p>
<p> </p>
<p>Some of the key wins of this project were:</p>
<ul>
<li>Ahead-of-schedule delivery of a global Azure enterprise integration platform</li>
<li>Repeatable infrastructure and automated release pipelines</li>
<li>Extra time to develop interfaces, saving time and money</li>
<li>Guaranteed business continuity and resilience </li>
<li>Governance and observability built in via dashboards, policies, budgets, alerts, and a logging framework</li>
<li>A new Center for Enablement to speed integration delivery </li>
<li>Robust documentation and hands-on training to address future delivery and operational needs. </li>
</ul>
<p> </p>
<p><b>Why do you love your job?</b></p>
<p> </p>
<p>I love helping customers in diverse industries with my creativity and what I've learnt through the years to use cloud technologies and bringing business value or solving complex real-world problems that really matter. To me, it is truly fulfilling when our customers are highly satisfied by the value we bring and how we deliver our projects. </p>
<p> </p>
<p>Also, I have to admit that I’m a bit geek and get super excited when I try or work with new services or features on Azure - that’s why I also love to share some of my knowledge by blogging or public speaking about the latest technologies I’m using or learning about. </p>
<p> </p>
<p><b>Let us know more about yourself</b></p>
<ul>
<li>Favourite physical activity? - Callisthenics, body weight exercises and nature walking.</li>
<li>Favourite special meal? - Ribeye steak</li>
<li>Besides tech, what other topics do you like to learn about? - Holistic/systemic health, parenting, leadership</li>
<li>Book recommendations? - Most of my recent books are about parenting :-) but besides those, I’d recommend, “Start with Why” by Simon Sinek, “The Psychology of Money” by Morgan Housel, “Quite” by Susan Cain, “Creative Confidence” by Tom Kelly & David Kelley, “The Unicorn Project” by Gene Kim, “The Carnivore Code” by Paul Saladino, “Permanent Record” by Edward Snowden, and “Sapiens” by Yuval Noah Harari. And about parenting, I’d say: “The Conscious Parent” by Shefali Tsabary and “The Whole-Brain Child” by Daniel J. Siegel and Tina Payne Bryson!</li>
</ul>
<p> </p>
<p><img src="/assets/img/2022/08/au-cloud-paco-2.jpg" alt="" /></p>
<p> </p>Paco de la CruzMy current employer ran a campaign to interview practitioners so that readers can know a bit more of what cloud professional do, not only at work but outside work. I shared some insights into my day, how I spend my time, and how I believe Cloud is impacting the world we live in.Monitoring Logic Apps Standard with Application Insights – Querying & Analysing Traces2021-12-16T10:00:00+00:002021-12-16T10:00:00+00:00/monitoring-logic-apps-standard-with-app-insights-querying<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>Paco de la CruzCross-posted on Deloitte Engineering Follow me on @pacodelacruzMonitoring Logic Apps Standard with Application Insights – Implementation2021-12-10T10:00:00+00:002021-12-10T10:00:00+00:00/monitoring-logic-apps-standard-with-app-insights-implementation<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>Paco de la CruzCross-posted on Deloitte Engineering Follow me on @pacodelacruzMonitoring Logic Apps Standard with Application Insights – Introduction2021-12-07T10:00:00+00:002021-12-07T10:00:00+00:00/monitoring-logic-apps-standard-with-app-insights-intro<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>Paco de la CruzCross-posted on Deloitte Engineering Follow me on @pacodelacruzLogic Apps Standard vs Durable Functions - How to Choose? (2021 Update)2021-11-09T10:00:00+00:002021-11-09T10:00:00+00:00/logic-apps-standard-vs-durable-functions-2021-update<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>Paco de la CruzCross-posted on Deloitte Engineering Follow me on @pacodelacruzPresentation - Custom Distributed Tracing in Azure Functions with Application Insights at Global Azure2021-04-17T10:00:00+00:002021-04-17T10:00:00+00:00/speaking-global-azure-custom-distributed-tracing-azure-functions<h2 id="slides">Slides</h2>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/kBmFeNSGnBONar" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/pacodelac/custom-distributed-tracing-in-azure-functions-20210227" title="Custom Distributed Tracing in Azure Functions (2021-02-27)" target="_blank">Custom Distributed Tracing in Azure Functions (2021-02-27)</a> </strong> from <strong><a href="https://www.slideshare.net/pacodelac" target="_blank">Paco de la Cruz</a></strong> </div>
<h2 id="recording">Recording</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/43LD7G_t33s?start=42" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<h2 id="demo-source-code">Demo source code</h2>
<p><a href="https://github.com/pacodelacruz/observability-pubsub-functions">https://github.com/pacodelacruz/observability-pubsub-functions</a></p>
<h2 id="related-blog-posts">Related blog posts</h2>
<ul>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-1-intro" rel="noopener" target="_blank">Introduction</a> – describes the scenario and why we might need custom distributed tracing in our solution.</li>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-2-design" rel="noopener" target="_blank">Solution design</a> – outlines the detailed design of the suggested solution.</li>
<li><span><a href="/distributed-tracing-and-observability-with-azure-functions-3-implementation" rel="noopener" target="_blank"> Implementation</a> – covers how this is implemented using Azure Functions and Application Insights.</span></li>
</ul>Paco de la CruzSlidesCustom Distributed Tracing and Observability Practices in Azure Functions – Part 3 - Implementation2021-03-10T10:00:00+00:002021-03-10T10:00:00+00:00/distributed-tracing-and-observability-with-azure-functions-3-implementation<p><img src="/assets/img/2021/02/build-featured.png" alt="Build Featured" width="800" loading="lazy" style="width: 800px;" /></p>
<h2>Introduction</h2>
<p>In the previous post of the series, we described the design of an approach to meet common observability requirements of distributed services using Azure Functions. Now, in this post, we are going to cover how this can be implemented and how we can query and analyse the produced tracing logs.</p>
<!--more-->
<p>This post is part of a series outlined below:</p>
<ul>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-1-intro" rel="noopener" target="_blank">Introduction</a> – describes the scenario and why we might need custom distributed tracing in our solution.</li>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-2-design" rel="noopener" target="_blank">Solution design</a> – outlines the detailed design of the suggested solution.</li>
<li>Implementation (this) – covers how this is implemented using Azure Functions and Application Insights.</li>
</ul>
<p>I strongly suggest that you read these posts in sequence, so you understand what the solution presented here is trying to achieve.</p>
<h2>Solution Components</h2>
<p>The proposed solution is based on the Azure services described below:</p>
<table style="border-collapse: collapse; table-layout: fixed; margin-left: auto; margin-right: auto; border: none; width: 634px;" cellpadding="4" border="1">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; width: 162px;">
<p><strong>Component</strong></p>
</td>
<td style="border: 1pt solid windowtext; width: 472px;">
<p><strong>Description</strong></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid windowtext; width: 162px; text-align: center;">
<p><img src="/assets/img/2021/02/Azure%20Functions.png" alt="Azure Functions" width="81" loading="lazy" style="width: 81px;" /></p>
<p>Azure Functions</p>
</td>
<td style="border: 1pt solid windowtext; width: 472px;">
<p>It contains the publisher and subscriber interfaces with a custom distributed tracing implementation.</p>
</td>
</tr>
<tr>
<td style="border: 1pt solid windowtext; width: 162px; text-align: center;">
<p><img src="/assets/img/2021/02/App%20Insights.png" alt="App Insights" width="80" loading="lazy" style="width: 80px;" /></p>
<p>Application Insights</p>
</td>
<td style="border: 1pt solid windowtext; width: 472px;">
<p>Receives and keeps all distributed tracing logs from the Azure Function.</p>
</td>
</tr>
<tr>
<td style="border: 1pt solid windowtext; width: 162px; text-align: center;">
<p><img src="/assets/img/2021/02/Storage.png" alt="Storage" width="80" loading="lazy" style="width: 80px;" /></p>
<p>Storage Account</p>
</td>
<td style="border: 1pt solid windowtext; width: 472px;">
<p>Used for request payload archiving. Leveraging the <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-lifecycle-management-concepts?tabs=azure-portal&WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">lifecycle management</a> capabilities of Azure Blob Storage to transition or delete archive blobs will allow you to optimise costs or achieve privacy compliance.</p>
</td>
</tr>
<tr>
<td style="border: 1pt solid windowtext; width: 162px; text-align: center;">
<p><img src="/assets/img/2021/02/Azure%20Service%20Bus.png" alt="Azure Service Bus" width="81" loading="lazy" style="width: 81px;" /></p>
<p>Service Bus</p>
</td>
<td style="border: 1pt solid windowtext; width: 472px;">
<p>Used to implement temporal decoupling between the publisher and the subscriber interfaces.</p>
</td>
</tr>
</tbody>
</table>
<h2>Show me the Code</h2>
<p>Now, let’s get deeper into the solution code. The full solution can be found in <a href="https://github.com/pacodelacruz/observability-pubsub-functions" rel="noopener" target="_blank">this GitHub repo</a>, however I will go through some of the key components of the solution in this post. I’ve also added comments to my code, ensuring it’s easy to follow.</p>
<h3>Logging Constants</h3>
<p>I suggest using constants and enumerations in the tracing implementation to have consistent values across all the components that use them. In this class, I’ve defined all of them.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/f126342891c33b19b9f4c2c430b01532.js"></script>
</p>
<h3>LoggerExtensions</h3>
<p>To ease structured logging using the default <code>ILogger</code> provider in Azure Functions, I’ve created extension methods that provide typed signatures. The different key-value pairs defined in the previous post are being used in these methods.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/53baa5617216c43e192709c254dc3144.js"></script>
</p>
<h3>LoggerHelper</h3>
<p>To map tracing event status to the standard <code>ILogger.LogLevel</code>, I’ve created this helper with a method that returns the corresponding <code>LogLevel</code> based on the process status.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/cc2af1b15bdd894d3c4418e5831eaf99.js"></script>
</p>
<h3>Publisher Function (UserUpdatedPublisher)</h3>
<p>This is the implementation of the publisher component designed and described in the previous post as an Azure Function. This function receives a HTTP request with user events in the Cloud Events format, splits it into individual events, and sends them to a Service Bus queue.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/c0013c11d9be22c35219e572b5985729.js"></script>
</p>
<h3>Subscriber Function (UserUpdatedSubscriber)</h3>
<p>This class implements the subscriber component designed and described in the previous post as an Azure Function. This function receives a Service Bus message and simulates the delivery to a target system.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/bfdf00bd946664d0026f6a2bd0e58298.js"></script>
</p>
<p>As mentioned above, the full solution can be found in <a href="https://github.com/pacodelacruz/observability-pubsub-functions" rel="noopener" target="_blank">this GitHub repo</a>.</p>
<h2>Deploying the Solution</h2>
<p>In the <a href="https://github.com/pacodelacruz/observability-pubsub-functions/tree/main/infra" rel="noopener" target="_blank">GitHub repo</a>, I’ve included the ARM templates, which create all the infrastructure needed to have this up and running. You will also need to build the demo Azure Function solution and deploy it to your Azure Function App. Bear in mind that there might be some costs associated with these resources.</p>
<h2>Generating Traffic</h2>
<p>You can simulate the webhook calls by using the VS Code <a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client" rel="noopener" target="_blank">REST Client extension</a> and posting HTTP requests. A sample request is as follows.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/71521a2ad380adecd3d2feb5f8bb3392.js"></script>
</p>
<h2>Querying the Distributed Traces</h2>
<p>In the <span>,</span> we listed some of the common requirements that an operations team has when supporting distributed backend services. After a comprehensive design of the tracing approach and its implementation, now we can finally see the benefits in action. We are now able to query our distributed traces in a meaningful way.</p>
<p>Once the Azure Function is running and has logged tracing events, logs in Application Insights can be queried using the <a href="https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">Kusto query language</a>. Let’s go through some of the queries I’ve prepared to meet the observability requirements described previously. All of these queries are available in the <a href="https://github.com/pacodelacruz/observability-pubsub-functions/tree/main/src/Integration.Observability.PubSub.FnApp/AppInsightsOperationsQueries" rel="noopener" target="_blank">GitHub repo</a>.</p>
<h3>Batch Publisher Span Traces</h3>
<p>This query provides the details of all Batch Publisher spans. It correlates the <code>Start</code> and <code>Finish</code> checkpoints and returns the relevant key-value pairs. Traces can be filtered by uncommenting the filters at the bottom of the query and adding the corresponding filter values. For instance, you could filter tracing records related to a particular <code>EntityType</code> and <code>EntityId</code>, <code>InterfaceId</code>, <code>BatchId</code>, etc.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/8fdc65a6aefe37b50ca2fd2c5bd2bc62.js"></script>
</p>
<p>A sample response is as follows:</p>
<p><img src="/assets/img/2021/02/BatchPublisherResults.png" alt="Batch Publisher Results" width="1166" loading="lazy" style="width: 1166px;" /></p>
<h2>Correlated Publisher and Subscriber Span Traces</h2>
<p>This query returns the correlated traces in the lifespan of an individual message. It correlates the <code>Start</code> and <code>Finish</code> checkpoints of both the <code>Publisher</code> and <code>Subscriber</code> spans and returns the relevant key-value pairs. Traces can be filtered by uncommenting the filters at the bottom of the query and adding the corresponding filter values, as discussed above.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/36274b15f79ca167962003435e914784.js"></script>
</p>
<p>The figures below depict a sample response.</p>
<p><img src="/assets/img/2021/02/CorrelatedTracesResults01.png" alt="CorrelatedTracesResults01" width="1183" loading="lazy" style="width: 1183px;" /></p>
<p><img src="/assets/img/2021/02/CorrelatedTracesResults02.png" alt="Correlated Traces Results 02" width="1554" loading="lazy" style="width: 1554px;" /></p>
<h2>Failed Traces</h2>
<p>This query returns traces with a <code>failed</code> status. As in the previous ones, traces can be filtered by uncommenting the filters at the bottom and adding the corresponding filter values.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/1fa1c640769dd3fa3c5a1098a7590660.js"></script>
</p>
<p>A sample response is depicted in the figure below.</p>
<p><img src="/assets/img/2021/02/FailedTracesResults.png" alt="Failed Traces Results" width="1601" loading="lazy" style="width: 1601px;" /></p>
<h2>Message Count per Entity Type over Time</h2>
<p>This query returns the message count per <code>EntityType</code> over time which can be rendered into a chart as shown below.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/2e569a23ddd0e80b6a3c8ecf1531c807.js"></script>
</p>
<p><img src="/assets/img/2021/02/MessageCountOverTime.png" alt="Message Count Over Time" width="541" loading="lazy" style="width: 541px;" /></p>
<h2>Error Count by InterfaceId and TraceEventId</h2>
<p>This query returns the error count grouped by <code>InterfaceId</code> and <code>TraceEventId</code> (<code>EventName</code>). This can be rendered into a pie or doughnut chart.</p>
<p>
<script src="https://gist.github.com/pacodelacruz/3fddcdc66a28c2a8b5717f74df8c5771.js"></script>
</p>
<p><img src="/assets/img/2021/02/ErrorCountByInterfaceAndEventType.png" alt="Error Count By Interface And Event Type" width="405" loading="lazy" style="width: 405px;" /></p>
<p><img src="/assets/img/2021/02/ErrorCountByInterfaceAndEventTypeChart.gif" alt="Error Count By Interface And Event Type Chart" width="531" loading="lazy" style="width: 531px;" /></p>
<h2>Considerations</h2>
<p>If you are planning to implement this approach in your solution, you need to configure the corresponding <a href="https://docs.microsoft.com/en-us/azure/azure-functions/configure-monitoring?tabs=v2#configure-sampling&WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">logging sampling</a> and <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json#logging?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">log level</a> on your Azure Function according to your needs.</p>
<p>Furthermore, before using this approach, bear in mind the points below:</p>
<ul>
<li>There are <a href="https://azure.microsoft.com/en-us/pricing/details/monitor/?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">costs associated</a> with Application Insights for data ingestion and data retention. Depending on the volume of tracing events, this could influence the overall running costs of your solution.</li>
<li>Tracing data can be lost or sampled. Thus, this tracing strategy must not be utilised for auditing purposes.
<ul>
<li>Due to its asynchronous nature, Application Insights <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/telemetry-channels#does-the-application-insights-channel-guarantee-telemetry-delivery-if-not-what-are-the-scenarios-in-which-telemetry-can-be-lost?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">cannot guarantee telemetry delivery</a>.</li>
<li>Application Insights has a <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/pricing#limits-summary?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">daily data cap and throttles the number of requests per second</a>.</li>
<li>Application Insights also has a <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/sampling?WT.mc_id=AZ-MVP-5003116" rel="noopener" target="_blank">sampling configuration</a> on the backend.</li>
</ul>
</li>
<li><a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/data-retention-privacy#how-long-is-the-data-kept?WT.mc_id=AZ-MVP-5003116" rel="noopener">Data retention on Application Insights</a> must be configured based on the requirements. </li>
</ul>
<h2>Wrapping Up</h2>
<p>In this post, we’ve covered how we can implement a comprehensive tracing approach in Azure Functions, adding business-related metadata and leveraging their structured logging capabilities. We aimed to meet some of the common observability requirements that operations teams have when supporting distributed backend services.</p>
<p>We used an approach tailored for integration solutions with Azure Functions which follow the <a href="/enterprise-integration-patterns-on-azure-messaging-channels#publish-subscribe-channel" rel="noopener" target="_blank">publish-subscribe integration pattern</a> and the <a href="/enterprise-integration-patterns-on-azure-routing#splitter" rel="noopener" target="_blank">splitter integration pattern</a>. However, you can leverage similar principles in your own solution.</p>
<p>I hope you’ve found the series useful, and happy monitoring!</p>
<p style="text-align:center;"><span style="font-style:italic;">Cross-posted on </span><a href="https://engineering.deloitte.com.au/articles/author/paco-de-la-cruz"><span style="font-style:italic;">Deloitte Engineering</span></a><br />
<span style="font-style:italic;">Follow me on </span><a href="https://twitter.com/pacodelacruz"><span style="font-style:italic;">@pacodelacruz</span></a></p>Paco de la CruzIntroduction In the previous post of the series, we described the design of an approach to meet common observability requirements of distributed services using Azure Functions. Now, in this post, we are going to cover how this can be implemented and how we can query and analyse the produced tracing logs. This post is part of a series outlined below: Introduction – describes the scenario and why we might need custom distributed tracing in our solution. Solution design – outlines the detailed design of the suggested solution. Implementation (this) – covers how this is implemented using Azure Functions and Application Insights. I strongly suggest that you read these posts in sequence, so you understand what the solution presented here is trying to achieve. Solution Components The proposed solution is based on the Azure services described below: Component Description Azure Functions It contains the publisher and subscriber interfaces with a custom distributed tracing implementation. Application Insights Receives and keeps all distributed tracing logs from the Azure Function. Storage Account Used for request payload archiving. Leveraging the lifecycle management capabilities of Azure Blob Storage to transition or delete archive blobs will allow you to optimise costs or achieve privacy compliance. Service Bus Used to implement temporal decoupling between the publisher and the subscriber interfaces. Show me the Code Now, let’s get deeper into the solution code. The full solution can be found in this GitHub repo, however I will go through some of the key components of the solution in this post. I’ve also added comments to my code, ensuring it’s easy to follow. Logging Constants I suggest using constants and enumerations in the tracing implementation to have consistent values across all the components that use them. In this class, I’ve defined all of them. LoggerExtensions To ease structured logging using the default ILogger provider in Azure Functions, I’ve created extension methods that provide typed signatures. The different key-value pairs defined in the previous post are being used in these methods. LoggerHelper To map tracing event status to the standard ILogger.LogLevel, I’ve created this helper with a method that returns the corresponding LogLevel based on the process status. Publisher Function (UserUpdatedPublisher) This is the implementation of the publisher component designed and described in the previous post as an Azure Function. This function receives a HTTP request with user events in the Cloud Events format, splits it into individual events, and sends them to a Service Bus queue. Subscriber Function (UserUpdatedSubscriber) This class implements the subscriber component designed and described in the previous post as an Azure Function. This function receives a Service Bus message and simulates the delivery to a target system. As mentioned above, the full solution can be found in this GitHub repo. Deploying the Solution In the GitHub repo, I’ve included the ARM templates, which create all the infrastructure needed to have this up and running. You will also need to build the demo Azure Function solution and deploy it to your Azure Function App. Bear in mind that there might be some costs associated with these resources. Generating Traffic You can simulate the webhook calls by using the VS Code REST Client extension and posting HTTP requests. A sample request is as follows. Querying the Distributed Traces In the , we listed some of the common requirements that an operations team has when supporting distributed backend services. After a comprehensive design of the tracing approach and its implementation, now we can finally see the benefits in action. We are now able to query our distributed traces in a meaningful way. Once the Azure Function is running and has logged tracing events, logs in Application Insights can be queried using the Kusto query language. Let’s go through some of the queries I’ve prepared to meet the observability requirements described previously. All of these queries are available in the GitHub repo. Batch Publisher Span Traces This query provides the details of all Batch Publisher spans. It correlates the Start and Finish checkpoints and returns the relevant key-value pairs. Traces can be filtered by uncommenting the filters at the bottom of the query and adding the corresponding filter values. For instance, you could filter tracing records related to a particular EntityType and EntityId, InterfaceId, BatchId, etc. A sample response is as follows: Correlated Publisher and Subscriber Span Traces This query returns the correlated traces in the lifespan of an individual message. It correlates the Start and Finish checkpoints of both the Publisher and Subscriber spans and returns the relevant key-value pairs. Traces can be filtered by uncommenting the filters at the bottom of the query and adding the corresponding filter values, as discussed above. The figures below depict a sample response. Failed Traces This query returns traces with a failed status. As in the previous ones, traces can be filtered by uncommenting the filters at the bottom and adding the corresponding filter values. A sample response is depicted in the figure below. Message Count per Entity Type over Time This query returns the message count per EntityType over time which can be rendered into a chart as shown below. Error Count by InterfaceId and TraceEventId This query returns the error count grouped by InterfaceId and TraceEventId (EventName). This can be rendered into a pie or doughnut chart. Considerations If you are planning to implement this approach in your solution, you need to configure the corresponding logging sampling and log level on your Azure Function according to your needs. Furthermore, before using this approach, bear in mind the points below: There are costs associated with Application Insights for data ingestion and data retention. Depending on the volume of tracing events, this could influence the overall running costs of your solution. Tracing data can be lost or sampled. Thus, this tracing strategy must not be utilised for auditing purposes. Due to its asynchronous nature, Application Insights cannot guarantee telemetry delivery. Application Insights has a daily data cap and throttles the number of requests per second. Application Insights also has a sampling configuration on the backend. Data retention on Application Insights must be configured based on the requirements. Wrapping Up In this post, we’ve covered how we can implement a comprehensive tracing approach in Azure Functions, adding business-related metadata and leveraging their structured logging capabilities. We aimed to meet some of the common observability requirements that operations teams have when supporting distributed backend services. We used an approach tailored for integration solutions with Azure Functions which follow the publish-subscribe integration pattern and the splitter integration pattern. However, you can leverage similar principles in your own solution. I hope you’ve found the series useful, and happy monitoring!Presentation - Custom Distributed Tracing in Azure Functions with Application Insights at Global Integration Bootcamp2021-02-27T10:00:00+00:002021-02-27T10:00:00+00:00/speaking-gib-custom-distributed-tracing-azure-functions<h2 id="slides">Slides</h2>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/kBmFeNSGnBONar" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/pacodelac/custom-distributed-tracing-in-azure-functions-20210227" title="Custom Distributed Tracing in Azure Functions (2021-02-27)" target="_blank">Custom Distributed Tracing in Azure Functions (2021-02-27)</a> </strong> from <strong><a href="https://www.slideshare.net/pacodelac" target="_blank">Paco de la Cruz</a></strong> </div>
<h2 id="recording">Recording</h2>
<p><a href="https://www.youtube.com/watch?v=zfuaPEK-wBk&t=8893s">Watch it on YouTube</a></p>
<h2 id="demo-source-code">Demo source code</h2>
<p><a href="https://github.com/pacodelacruz/observability-pubsub-functions">https://github.com/pacodelacruz/observability-pubsub-functions</a></p>
<h2 id="related-blog-posts">Related blog posts</h2>
<ul>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-1-intro" rel="noopener" target="_blank">Introduction</a> – describes the scenario and why we might need custom distributed tracing in our solution.</li>
<li><a href="/distributed-tracing-and-observability-with-azure-functions-2-design" rel="noopener" target="_blank">Solution design</a> – outlines the detailed design of the suggested solution.</li>
<li><span><a href="/distributed-tracing-and-observability-with-azure-functions-3-implementation" rel="noopener" target="_blank"> Implementation</a> – covers how this is implemented using Azure Functions and Application Insights.</span></li>
</ul>Paco de la CruzSlides