Secure APIM and Azure OpenAI with managed identity
<set-header name=”Authorization” exists-action=”override”>
<value>@(“Bearer ” + (string)context.Variables[“managed-id-access-token”])</value>
</set-header>
name: name
location: location
tags: union(tags, { ‘azd-service-name’: name })
sku: {
name: sku
capacity: (sku == ‘Consumption’) ? 0 : ((sku == ‘Developer’) ? 1 : skuCount)
}
properties: {
publisherEmail: publisherEmail
publisherName: publisherName
// Custom properties are not supported for Consumption SKU
customProperties: sku == ‘Consumption’ ? {} : {
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_GCM_SHA256’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_256_CBC_SHA256’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_CBC_SHA256’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_256_CBC_SHA’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_CBC_SHA’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11’: ‘false’
‘Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Ssl30’: ‘false’
}
}
identity: {
type: ‘SystemAssigned’
}
}
name: ‘your-openai-resource-name’
location: ‘your-location’
sku: {
name: ‘S0’
}
kind: ‘OpenAI’
properties: {
// Add other necessary properties here
}
identity: {
type: ‘SystemAssigned’
}
properties: {
publicNetworkAccess: ‘Disabled’
networkAcls: {
defaultAction: ‘Deny’
}
disableLocalAuth: true
}
}
name: guid(openAI.id, ‘cognitive-services-openai-user-role’)
properties: {
roleDefinitionId: subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, ‘c1c469a3-0a2d-4bba-b0e1-0eaf1d3d728b’) // Role ID for Cognitive Services OpenAI User
principalId: openAI.identity.principalId
principalType: ‘ServicePrincipal’
scope: openAI.id
}
}
name: guid(apimIdentity.id, resourceGroup().id, ‘cognitive-services-openai-user-role’)
properties: {
roleDefinitionId: subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, ‘c1c469a3-0a2d-4bba-b0e1-0eaf1d3d728b’) // Role ID for Cognitive Services OpenAI User
principalId: apimIdentity.properties.principalId
principalType: ‘ServicePrincipal’
scope: resourceGroup().id
}
}
Subscriptions in Azure API Management are a way to control access to APIs. When you publish APIs through APIM, you can secure them using subscription keys. Here’s a quick overview:
Subscriptions: These are containers for a pair of subscription keys (primary and secondary). Developers need a valid subscription key to call the APIs.
Subscription IDs: Each subscription has a unique identifier called a Subscription ID.
How does Subscription relate to the APIM resource though?
Scope of Subscriptions: Subscriptions can be associated with different scopes within an APIM instance:
Product Scope: Subscriptions can be linked to a specific product, which is a collection of one or more APIs. Developers subscribe to the product to access all APIs within it.
API Scope: Subscriptions can also be associated with individual APIs, allowing more granular control over access.
parent: apimService
name: apiName
properties: {
displayName: apiName
apiType: ‘http’
path: apiSuffix
format: ‘openapi+json-link’
value: ‘https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2024-03-01-preview/inference.json’
subscriptionKeyParameterNames: {
header: ‘api-key’
}
}
resource apimDiagnostics ‘diagnostics@2023-05-01-preview’ = {
name: ‘applicationinsights’ // Use a supported diagnostic identifier
properties: {
loggerId: ‘/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.ApiManagement/service/${apimService.name}/loggers/${apimLogger.name}’
metrics: true
}
}
}
// Creating a product for the API. Products are used to group APIs and apply policies to them
resource product ‘Microsoft.ApiManagement/service/products@2020-06-01-preview’ = {
parent: apimService
name: productName
properties: {
displayName: productName
description: productDescription
state: ‘published’
subscriptionRequired: true
}
}
// Create PRODUCT-API association the API with the product
resource productApi1 ‘Microsoft.ApiManagement/service/products/apis@2020-06-01-preview’ = {
parent: product
name: api1.name
}
// Creating a user for the API Management service
resource user ‘Microsoft.ApiManagement/service/users@2020-06-01-preview’ = {
parent: apimService
name: ‘userName’
properties: {
firstName: ‘User’
lastName: ‘Name’
email: ‘user@example.com’
state: ‘active’
}
}
// Creating a subscription for the API Management service
// NOTE: the subscription is associated with the user and the product, AND the subscription ID is what will be used in the request to authenticate the calling client
resource subscription ‘Microsoft.ApiManagement/service/subscriptions@2020-06-01-preview’ = {
parent: apimService
name: ‘subscriptionAIProduct’
properties: {
displayName: ‘Subscribing to AI services’
state: ‘active’
ownerId: user.id
scope: product.id
}
}
“model”:”gpt-35-turbo”,”messages”:[
{
“role”:”system”,”content”:”You’re a helpful assistant”
},
{
“role”:”user”,”content”:prompt
}
]};
return fetch(URL_CHAT, {
method: “POST”,
headers: {
“api-key”: process.env.SUBSCRIPTION_KEY,
“Content-Type”: “application/json”
},
body: JSON.stringify(body)
})
Microsoft Tech Community – Latest Blogs –Read More