{"id":3096,"date":"2024-06-24T07:51:08","date_gmt":"2024-06-24T14:51:08","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=3096"},"modified":"2024-07-12T09:29:18","modified_gmt":"2024-07-12T16:29:18","slug":"improve-security-posture-in-azure-service-connections-with-azurepipelinescredential","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/improve-security-posture-in-azure-service-connections-with-azurepipelinescredential\/","title":{"rendered":"Improve security posture in Azure service connections with AzurePipelinesCredential"},"content":{"rendered":"<p>Recently, the Azure Pipelines team introduced the support for <a href=\"https:\/\/devblogs.microsoft.com\/devops\/public-preview-of-workload-identity-federation-for-azure-pipelines\/\">Federated Identity Credentials (FIC) through Service Connections<\/a>. This feature uses an industry-standard technology, Open ID Connect (OIDC), to simplify the authentication between Azure Pipelines and Azure services. Before this new feature, users needed to store and regularly rotate secrets or certificates. With this feature, not only is authenticating to Azure services easier, but it&#8217;s also more secure, as no persistent secret is involved. The tasks running in pipeline jobs can&#8217;t leak or exfiltrate secrets that have access to the production environments.<\/p>\n<p>To support FIC in <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/get-started\/what-is-azure-pipelines?view=azure-devops\">Azure Pipelines<\/a> (part of Azure DevOps), the Azure Identity libraries for .NET, C++, Go, Java, JavaScript, and Python introduced a new credential called <code>AzurePipelinesCredential<\/code>.<\/p>\n<p>Before the existence of this credential, Azure Identity library consumers needed to build their own custom credential to support the <a href=\"https:\/\/learn.microsoft.com\/rest\/api\/azure\/devops\/distributedtask\/oidctoken\/create?view=azure-devops-rest-7.1\">OIDC token request API<\/a> callback for Azure Pipelines using <code>ClientAssertionCredential<\/code>. For example:<\/p>\n<pre><code class=\"language-ts\">function pipelinesServiceConnectionAssertion(\r\n  serviceConnectionId: string\r\n): () =&gt; Promise&lt;string&gt; {\r\n  return async () =&gt; {\r\n    const oidcRequestUrl = `${process.env.SYSTEM_OIDCTOKENURI}?api-version=7.1&amp;serviceConnectionId=${serviceConnectionId}`;\r\n    const systemAccessToken = `${process.env.SYSTEM_ACCESSTOKEN}`;\r\n    const oidcToken = await requestOidcToken(oidcRequestUrl, systemAccessToken);\r\n    return oidcToken;\r\n  };\r\n}\r\n\r\nasync function requestOidcToken(\r\n  oidcRequestUrl: string,\r\n  systemAccessToken: string\r\n): Promise&lt;string&gt; {\r\n  \/\/ code for sending request using this REST API https:\/\/learn.microsoft.com\/rest\/api\/azure\/devops\/distributedtask\/oidctoken\/create?view=azure-devops-rest-7.1\r\n  \/\/ extract and return \"oidcToken\" from the response from above request\r\n}\r\nconst credential = new ClientAssertionCredential(\r\n  \"&lt;tenantId&gt;\",\r\n  \"&lt;clientId&gt;\",\r\n  pipelinesServiceConnectionAssertion(\"&lt;serviceConnectionId&gt;\"),\r\n  options\r\n);<\/code><\/pre>\n<h2>Credential design<\/h2>\n<p>Users can now use the <code>AzurePipelinesCredential<\/code> by setting the following values in its constructor, eliminating the need for a two-step process or a custom callback:<\/p>\n<ul>\n<li><code>clientId<\/code>: Client ID from your user-assigned managed identity OR Application (client) ID from your app registration.<\/li>\n<li><code>tenantId<\/code>: Tenant ID from your user-assigned managed identity OR Directory (tenant) ID from your app registration.<\/li>\n<li><code>serviceConnectionId<\/code>: The service connection ID is the <strong>GUID representing your service connection<\/strong> and can be obtained by looking at the browser&#8217;s address bar when you navigate to a service connection in Azure Pipelines. It&#8217;s the <code>resourceId<\/code>, as found in the URL&#8217;s querystring.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-exampleServiceConnectionUrl.png\" alt=\"resourceId as found in the querystring of the Azure Resource Manager service connection created in Azure Pipelines\" \/><\/li>\n<li><code>systemAccessToken<\/code>: <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/build\/variables?view=azure-devops&amp;tabs=yaml#systemaccesstoken\">See how to configure the predefined system-level variable $System.AccessToken for the Azure Pipelines task<\/a>. Pass this field into the credential&#8217;s constructor.<\/li>\n<\/ul>\n<pre><code class=\"language-ts\">\/**\r\n * Authenticate with Azure Pipelines federated identity.\r\n *\/\r\nfunction withAzurePipelinesCredential() {\r\n  const clientId = \"&lt;YOUR_CLIENT_ID&gt;\";\r\n  const tenantId = \"&lt;YOUR_TENANT_ID&gt;\";\r\n  const serviceConnectionId = \"&lt;YOUR_SERVICE_CONNECTION_ID&gt;\";\r\n  const systemAccessToken = \"&lt;SYSTEM_ACCESSTOKEN&gt;\";\r\n  const credential = new AzurePipelinesCredential(\r\n    tenantId,\r\n    clientId,\r\n    serviceConnectionId,\r\n    systemAccessToken\r\n  );\r\n\r\n  const client = new SecretClient(\r\n    \"https:\/\/key-vault-name.vault.azure.net\",\r\n    credential\r\n  );\r\n}<\/code><\/pre>\n<h2>Package versions<\/h2>\n<p>The following table provides the minimum stable or beta library versions required to use <code>AzurePipelinesCredential<\/code>.<\/p>\n<table>\n<thead>\n<tr>\n<th>Language<\/th>\n<th>Library version<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>.NET<\/td>\n<td><a href=\"https:\/\/www.nuget.org\/packages\/Azure.Identity\/1.12.0\">1.12.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>C++<\/td>\n<td><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-cpp\/tree\/main\/sdk\/identity\/azure-identity\">1.9.0-beta.1<\/a><\/td>\n<\/tr>\n<tr>\n<td>Go<\/td>\n<td><a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity@v1.7.0\">1.7.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>Java<\/td>\n<td><a href=\"https:\/\/mvnrepository.com\/artifact\/com.azure\/azure-identity\/1.13.0\">1.13.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td><a href=\"https:\/\/www.npmjs.com\/package\/@azure\/identity\/v\/4.3.0\">4.3.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td><a href=\"https:\/\/pypi.org\/project\/azure-identity\/1.17.0\/\">1.17.0<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Set up FIC in Azure Pipelines<\/h2>\n<p>To use FIC in Azure Pipelines, configure the Azure Resource Manager service connection in one of two ways:<\/p>\n<ul>\n<li>As an <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/library\/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-service-connection-that-uses-workload-identity-federation\">automatic recommended approach<\/a><\/li>\n<li>Create it manually either using a <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/release\/configure-workload-identity?view=azure-devops#set-a-workload-identity-service-connection-to-use-managed-identity-authentication\">user-assigned managed identity as FIC<\/a> or using an <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/release\/configure-workload-identity?view=azure-devops#set-a-workload-identity-service-connection-to-use-service-principal-authentication\">App Registration as FIC<\/a><\/li>\n<\/ul>\n<h2>Create a service connection or convert an existing one to use FIC<\/h2>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/library\/connect-to-azure?view=azure-devops#convert-an-existing-azure-resource-manager-service-connection-to-use-workload-identity-federation\">Convert your existing Azure service connections<\/a> based on secrets to the new scheme. You can perform this conversion one connection at a time. Best of all, you don&#8217;t have to modify any of the pipelines that use those service connections. They automatically apply the new scheme once you complete the conversion.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-convert-service-connection.png\" alt=\"Convert your existing Azure service connections\" \/><\/li>\n<li>Create a new Azure service connection using federated identity by selecting workload identity federation (automatic) in the Azure service connection creation experience. Follow the steps:<\/li>\n<ol>\n<li>In Azure DevOps, go to <strong>Project Settings<\/strong> and then <strong>Service connections<\/strong>.<\/li>\n<li>Select <strong>New service connection<\/strong>.<\/li>\n<li>Select <strong>Azure Resource Manager<\/strong> and select <strong>Next<\/strong>.<\/li>\n<li>Select <strong>Workload identity federation (automatic)<\/strong> and select <strong>Next<\/strong>.<\/li>\n<li>Enter a unique value for <strong>Service connection name<\/strong> and select <strong>Next<\/strong>.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-create-service-connection.gif\" alt=\"Create a new Azure service connections\" \/><\/p>\n<blockquote><p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>To enable every pipeline in your project to use the service connection, check the Grant access permission to all pipelines box.<\/div><\/p><\/blockquote>\n<p>You can also create the workload identity federation manually in step 3 above by selecting <strong>Workload identity federation (manual)<\/strong> with either a user-assigned managed identity as an FIC or an app registration as an FIC.\n<\/ul>\n<h3>User-assigned managed identity as an FIC<\/h3>\n<ol>\n<li>First, you need a <a href=\"https:\/\/learn.microsoft.com\/entra\/identity\/managed-identities-azure-resources\/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity\">user-assigned managed identity<\/a>.<\/li>\n<li>Copy the <strong>Subscription ID<\/strong> and <strong>Client ID<\/strong> values for your managed identity to use later.<\/li>\n<li>Go to <strong>Settings<\/strong> &gt; <strong>Properties<\/strong>.<\/li>\n<li>Copy the <strong>Tenant Id<\/strong> value to use later.<\/li>\n<li>Go to <strong>Settings<\/strong> &gt; <strong>Federated credentials<\/strong>.<\/li>\n<li>Select <strong>Add credentials<\/strong>.<\/li>\n<li>Select the <strong>Other issuer<\/strong> scenario.<\/li>\n<li>Enter values for <strong>Issuer<\/strong> and <strong>Subject identifier<\/strong>. You&#8217;ll replace these values later.<br>\n<table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Issuer<\/td>\n<td>Enter <code>https:\/\/app.vstoken.visualstudio.com\/&lt;unique-identifier&gt;<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>Subject identifier<\/td>\n<td>Specify <code>sc:\/\/&lt;Azure DevOps organization&gt;\/&lt;project name&gt;\/&lt;service connection name&gt;<\/code>. The service connection doesn&#8217;t need to be already created.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li>Select <strong>Save<\/strong>.<\/li>\n<li>Keep this window open. Later in the process, you return to the window and update your app registration federated credentials.<\/li>\n<li>Grant permissions to managed identity with the Azure portal:\n<ol>\n<li>In the Azure portal, go to the Azure resource that you want to grant permissions for (for example, a resource group).<\/li>\n<li>Select <strong>Access control (IAM)<\/strong>.<\/li>\n<li>Select <strong>Add role assignment<\/strong>. Assign the required role to your managed identity (for example, Contributor).<\/li>\n<li>Select <strong>Review and assign<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>Read the <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/release\/configure-workload-identity?view=azure-devops#set-a-workload-identity-service-connection-to-use-managed-identity-authentication\">detailed instructions<\/a> on setting up a user-assigned managed identity as an FIC service connection.<\/p>\n<h3>App registration as an FIC<\/h3>\n<ol>\n<li>In the Microsoft Entra ID section of the Azure portal, go to <strong>App registrations<\/strong>.<\/li>\n<li>Select <strong>New registration<\/strong>.<\/li>\n<li>In the <strong>Name<\/strong> textbox, enter a name for your app registration. Then select the appropriate radio button in the <strong>Who can use this application or access this API<\/strong> section.<\/li>\n<li>Copy the values for <strong>Application (client) ID<\/strong> and <strong>Directory (tenant) ID<\/strong> from your app registration to use later.<\/li>\n<li>Go to <strong>Manage<\/strong> &gt; <strong>Certificates &amp; secrets<\/strong>.<\/li>\n<li>Select <strong>Federated credentials<\/strong>.<\/li>\n<li>Select <strong>Add credentials<\/strong>.<\/li>\n<li>Select the <strong>Other issuer<\/strong> scenario. Enter values for <strong>Issuer<\/strong> and <strong>Subject identifier<\/strong>. You&#8217;ll replace these values later.<br>\n<table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Issuer<\/td>\n<td>Enter https:\/\/app.vstoken.visualstudio.com\/.<\/td>\n<\/tr>\n<tr>\n<td>Subject identifier<\/td>\n<td>Specify <code>sc:\/\/&lt;Azure DevOps organization&gt;\/&lt;project name&gt;\/&lt;service connection name&gt;<\/code>. The service connection doesn&#8217;t need to be already created.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li>Select <strong>Save<\/strong>.<\/li>\n<li>Keep this window open. Later in the process, you return to the window and update your app registration federated credentials.<\/li>\n<li>Grant permissions to the app registration:\n<ol>\n<li>In the Azure portal, go to the Azure resource that you want to grant permissions for (for example, a resource group).<\/li>\n<li>Select <strong>Access control (IAM)<\/strong>.<\/li>\n<li>Select <strong>Add role assignment<\/strong>. Assign the required role to the app registration (for example, Contributor).<\/li>\n<li>Select <strong>Review and assign<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>Read the <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/release\/configure-workload-identity?view=azure-devops#set-a-workload-identity-service-connection-to-use-service-principal-authentication\">detailed instructions<\/a> on setting up an app registration as an FIC service connection.<\/p>\n<h3>Create service connection for either MI as FIC or app registration as FIC<\/h3>\n<ol>\n<li>In Azure DevOps, open your project and go to &gt; <strong>Pipelines<\/strong> &gt; <strong>Service connections<\/strong>.<\/li>\n<li>Select <strong>New service connection<\/strong>.<\/li>\n<li>Select <strong>Azure Resource Manager<\/strong>, and then select <strong>Next<\/strong>.<\/li>\n<li>Select <strong>Workload Identity federation (manual)<\/strong>, and then select <strong>Next<\/strong>.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-workload-identity-service-connection-manual.png\" alt=\"Select Workload Identity federation (manual)\" \/><\/li>\n<li>For <strong>Service connection name<\/strong>, enter the value that you used for Subject identifier when you created your federated credentials (either MI or App Registration).<\/li>\n<li>For <strong>Subscription Id<\/strong> and <strong>Subscription Name<\/strong>, enter the values for the subscription in your Azure portal account.<br>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-federated-set-subscription.png\" alt=\"Subscription Details\" \/><\/li>\n<li>In the <strong>Authentication<\/strong> section:\n<ol>\n<li>For <strong>Service Principal Id<\/strong>, enter the value of <strong>Client Id<\/strong> from either your managed identity or app registration.<\/li>\n<li>For <strong>Tenant ID<\/strong>, enter the value of <strong>Tenant Id<\/strong> from your managed identity or app registration.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-federated-managed-values.png\" alt=\"managed-identity-example-values\" \/><\/li>\n<\/ol>\n<\/li>\n<li>In Azure DevOps, copy the generated values for <strong>Issuer<\/strong> and <strong>Subject identifier<\/strong>.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-federated-credentials-devops.png\" alt=\"federated-values-devops\" \/><\/li>\n<li>In the Azure portal, return to your managed identity or app registration federated credentials.<\/li>\n<li>Paste the values for <strong>Issuer<\/strong> and <strong>Subject identifier<\/strong> that you copied from your Azure DevOps project into your federated credentials in the Azure portal.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/06\/06-18-copy-federated-credential.png\" alt=\"copy-federated-credential\" \/><\/li>\n<li>In the Azure portal, select <strong>Update<\/strong> to save the updated credentials.<\/li>\n<li>In Azure DevOps, select <strong>Verify and save<\/strong>.<\/li>\n<\/ol>\n<h2>Example of using the Azure Pipelines task<\/h2>\n<p>To use the federated identity through service connections feature in Azure Pipelines, use one of the <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/release\/troubleshoot-workload-identity?view=azure-devops#review-pipeline-tasks\">recommended tasks<\/a>.\nThe following YAML script is an example of running the <code>AzureCLI@2<\/code> task for using service connections federated identity with <code>@azure\/identity<\/code>.<\/p>\n<p>In the Azure Pipelines task, make sure to <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/build\/variables?view=azure-devops&amp;tabs=yaml#systemaccesstoken\">configure the predefined system variable System.AccessToken<\/a>.<\/p>\n<pre><code class=\"language-yml\">trigger:\r\n  - main\r\n\r\npool:\r\n  vmImage: ubuntu-latest\r\n\r\nsteps:\r\n  - script: |\r\n      npm install @azure\/identity\r\n      npm install @azure\/keyvault-secrets\r\n    displayName: \"Install the latest version of Azure Identity\"\r\n\r\n  - task: AzureCLI@2\r\n    displayName: \"Azure CLI Task\"\r\n    env:\r\n      SYSTEM_ACCESSTOKEN: $(System.AccessToken)\r\n    inputs:\r\n      azureSubscription: \"&lt;Name_of_AZURE_SERVICE_CONNECTION&gt;\"\r\n      scriptType: bash\r\n      scriptLocation: \"inlineScript\"\r\n      inlineScript: |\r\n        node &lt;path-to-the-javascript-code&gt;<\/code><\/pre>\n<h2>Troubleshooting<\/h2>\n<p>Select one of the following links to see language-specific troubleshooting guidance for <code>AzurePipelinesCredential<\/code>:<\/p>\n<ul>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/net\/identity\/azurepipelinescredential\/troubleshoot\">.NET<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/cpp\/identity\/azurepipelinescredential\/troubleshoot\">C++<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/go\/identity\/azurepipelinescredential\/troubleshoot\">Go<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/js\/identity\/azurepipelinescredential\/troubleshoot\">JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/java\/identity\/azurepipelinescredential\/troubleshoot\">Java<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/azsdk\/python\/identity\/azurepipelinescredential\/troubleshoot\">Python<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn about the new AzurePipelinesCredential, designed to support federated identity credential authentication through Azure Service Connections in Azure Pipelines.<\/p>\n","protected":false},"author":35190,"featured_media":3085,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[927,870,929,928,158,930],"class_list":["post-3096","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-authentication","tag-azure-devops","tag-azure-pipelines","tag-federated-credentials","tag-identity","tag-service-connections"],"acf":[],"blog_post_summary":"<p>Learn about the new AzurePipelinesCredential, designed to support federated identity credential authentication through Azure Service Connections in Azure Pipelines.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3096","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/35190"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=3096"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3096\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/3085"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=3096"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=3096"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=3096"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}