Skip to content

Commit b4e328f

Browse files
committed
Add built-in auth files
1 parent 2114a43 commit b4e328f

File tree

6 files changed

+199
-9
lines changed

6 files changed

+199
-9
lines changed

infra/aca.bicep

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module app 'core/host/container-app-upsert.bicep' = {
5050
}
5151
}
5252

53-
output SERVICE_ACA_IDENTITY_PRINCIPAL_ID string = acaIdentity.properties.principalId
54-
output SERVICE_ACA_NAME string = app.outputs.name
55-
output SERVICE_ACA_URI string = app.outputs.uri
56-
output SERVICE_ACA_IMAGE_NAME string = app.outputs.imageName
53+
output identityPrincipalId string = acaIdentity.properties.principalId
54+
output name string = app.outputs.name
55+
output uri string = app.outputs.uri
56+
output imageName string = app.outputs.imageName

infra/appregistration.bicep

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
extension microsoftGraphV1
2+
3+
@description('Specifies the name of cloud environment to run this deployment in.')
4+
param cloudEnvironment string = environment().name
5+
6+
// NOTE: Microsoft Graph Bicep file deployment is only supported in Public Cloud
7+
@description('Audience uris for public and national clouds')
8+
param audiences object = {
9+
AzureCloud: {
10+
uri: 'api://AzureADTokenExchange'
11+
}
12+
AzureUSGovernment: {
13+
uri: 'api://AzureADTokenExchangeUSGov'
14+
}
15+
USNat: {
16+
uri: 'api://AzureADTokenExchangeUSNat'
17+
}
18+
USSec: {
19+
uri: 'api://AzureADTokenExchangeUSSec'
20+
}
21+
AzureChinaCloud: {
22+
uri: 'api://AzureADTokenExchangeChina'
23+
}
24+
}
25+
26+
@description('Specifies the ID of the user-assigned managed identity.')
27+
param webAppIdentityId string
28+
29+
@description('Specifies the unique name for the client application.')
30+
param clientAppName string
31+
32+
@description('Specifies the display name for the client application')
33+
param clientAppDisplayName string
34+
35+
@description('Specifies the scopes that the client application requires.')
36+
param clientAppScopes array = ['User.Read', 'offline_access', 'openid', 'profile']
37+
38+
param serviceManagementReference string = ''
39+
40+
param issuer string
41+
42+
param webAppEndpoint string
43+
44+
// Get the MS Graph Service Principal based on its application ID:
45+
// https://learn.microsoft.com/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in
46+
var msGraphAppId = '00000003-0000-0000-c000-000000000000'
47+
resource msGraphSP 'Microsoft.Graph/[email protected]' existing = {
48+
appId: msGraphAppId
49+
}
50+
51+
var graphScopes = msGraphSP.oauth2PermissionScopes
52+
resource clientApp 'Microsoft.Graph/[email protected]' = {
53+
uniqueName: clientAppName
54+
displayName: clientAppDisplayName
55+
signInAudience: 'AzureADMyOrg'
56+
serviceManagementReference: empty(serviceManagementReference) ? null : serviceManagementReference
57+
web: {
58+
redirectUris: [
59+
'http://localhost:50505/.auth/login/aad/callback'
60+
'${webAppEndpoint}/.auth/login/aad/callback'
61+
]
62+
implicitGrantSettings: { enableIdTokenIssuance: true }
63+
}
64+
requiredResourceAccess: [
65+
{
66+
resourceAppId: msGraphAppId
67+
resourceAccess: [
68+
for (scope, i) in clientAppScopes: {
69+
id: filter(graphScopes, graphScopes => graphScopes.value == scope)[0].id
70+
type: 'Scope'
71+
}
72+
]
73+
}
74+
]
75+
76+
resource clientAppFic '[email protected]' = {
77+
name: '${clientApp.uniqueName}/miAsFic'
78+
audiences: [
79+
audiences[cloudEnvironment].uri
80+
]
81+
issuer: issuer
82+
subject: webAppIdentityId
83+
}
84+
}
85+
86+
resource clientSp 'Microsoft.Graph/[email protected]' = {
87+
appId: clientApp.appId
88+
}
89+
90+
output clientAppId string = clientApp.appId
91+
output clientSpId string = clientSp.id

infra/appupdate.bicep

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
metadata description = 'Creates an Azure Container Apps Auth Config using Microsoft Entra as Identity Provider.'
2+
3+
@description('The name of the container apps resource within the current resource group scope')
4+
param containerAppName string
5+
6+
@description('The client ID of the Microsoft Entra application.')
7+
param clientId string
8+
9+
param openIdIssuer string
10+
11+
@description('Enable token store for the Container App.')
12+
param includeTokenStore bool = false
13+
14+
@description('The URI of the Azure Blob Storage container to be used for token storage.')
15+
param blobContainerUri string = ''
16+
@description('The resource ID of the managed identity to be used for accessing the Azure Blob Storage.')
17+
param appIdentityResourceId string = ''
18+
19+
resource app 'Microsoft.App/containerApps@2023-05-01' existing = {
20+
name: containerAppName
21+
}
22+
23+
resource auth 'Microsoft.App/containerApps/authConfigs@2024-10-02-preview' = {
24+
parent: app
25+
name: 'current'
26+
properties: {
27+
platform: {
28+
enabled: true
29+
}
30+
globalValidation: {
31+
redirectToProvider: 'azureactivedirectory'
32+
unauthenticatedClientAction: 'RedirectToLoginPage'
33+
}
34+
identityProviders: {
35+
azureActiveDirectory: {
36+
enabled: true
37+
registration: {
38+
clientId: clientId
39+
clientSecretSettingName: 'override-use-mi-fic-assertion-client-id'
40+
openIdIssuer: openIdIssuer
41+
}
42+
validation: {
43+
defaultAuthorizationPolicy: {
44+
allowedApplications: []
45+
}
46+
}
47+
}
48+
}
49+
login: {
50+
// https://learn.microsoft.com/azure/container-apps/token-store
51+
tokenStore: {
52+
enabled: includeTokenStore
53+
azureBlobStorage: includeTokenStore ? {
54+
blobContainerUri: blobContainerUri
55+
managedIdentityResourceId: appIdentityResourceId
56+
} : {}
57+
}
58+
}
59+
}
60+
}

infra/bicepconfig.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"experimentalFeaturesEnabled": {
3+
"extensibility": true
4+
},
5+
// specify an alias for the version of the v1.0 dynamic types package you want to use
6+
"extensions": {
7+
"microsoftGraphV1": "br:mcr.microsoft.com/bicep/extensions/microsoftgraph/v1.0:0.1.8-preview"
8+
}
9+
}

infra/main.bicep

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ param disableKeyBasedAuth bool = true
3838
// Parameters for the specific Azure AI deployment:
3939
param aiServicesDeploymentName string = 'DeepSeek-R1'
4040

41+
@description('Service Management Reference for the Entra app registration')
42+
param serviceManagementReference string = ''
4143

4244
var resourceToken = toLower(uniqueString(subscription().id, name, location))
4345
var tags = { 'azd-env-name': name }
@@ -131,12 +133,37 @@ module aca 'aca.bicep' = {
131133
}
132134
}
133135

136+
/*var issuer = '${environment().authentication.loginEndpoint}${tenant().tenantId}/v2.0'
137+
module registration 'appregistration.bicep' = {
138+
name: 'reg'
139+
scope: resourceGroup
140+
params: {
141+
clientAppName: '${prefix}-entra-client-app'
142+
clientAppDisplayName: 'DeepSeek Entra Client App'
143+
webAppEndpoint: aca.outputs.uri
144+
webAppIdentityId: aca.outputs.identityPrincipalId
145+
issuer: issuer
146+
serviceManagementReference: serviceManagementReference
147+
}
148+
}*/
149+
150+
/*module appupdate 'appupdate.bicep' = {
151+
name: 'appupdate'
152+
scope: resourceGroup
153+
params: {
154+
containerAppName: aca.outputs.name
155+
clientId: registration.outputs.clientAppId
156+
openIdIssuer: issuer
157+
includeTokenStore: false
158+
}
159+
}*/
160+
134161

135162
module aiServicesRoleBackend 'core/security/role.bicep' = {
136163
scope: aiServicesResourceGroup
137164
name: 'aiservices-role-backend'
138165
params: {
139-
principalId: aca.outputs.SERVICE_ACA_IDENTITY_PRINCIPAL_ID
166+
principalId: aca.outputs.identityPrincipalId
140167
roleDefinitionId: 'a97b65f3-24c7-4388-baec-2e87135dc908'
141168
principalType: 'ServicePrincipal'
142169
}
@@ -148,10 +175,10 @@ output AZURE_TENANT_ID string = tenant().tenantId
148175
output AZURE_DEEPSEEK_DEPLOYMENT string = aiServicesDeploymentName
149176
output AZURE_INFERENCE_ENDPOINT string = 'https://${aiServices.outputs.name}.services.ai.azure.com/models'
150177

151-
output SERVICE_ACA_IDENTITY_PRINCIPAL_ID string = aca.outputs.SERVICE_ACA_IDENTITY_PRINCIPAL_ID
152-
output SERVICE_ACA_NAME string = aca.outputs.SERVICE_ACA_NAME
153-
output SERVICE_ACA_URI string = aca.outputs.SERVICE_ACA_URI
154-
output SERVICE_ACA_IMAGE_NAME string = aca.outputs.SERVICE_ACA_IMAGE_NAME
178+
output SERVICE_ACA_IDENTITY_PRINCIPAL_ID string = aca.outputs.identityPrincipalId
179+
output SERVICE_ACA_NAME string = aca.outputs.name
180+
output SERVICE_ACA_URI string = aca.outputs.uri
181+
output SERVICE_ACA_IMAGE_NAME string = aca.outputs.imageName
155182

156183
output AZURE_CONTAINER_ENVIRONMENT_NAME string = containerApps.outputs.environmentName
157184
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerApps.outputs.registryLoginServer

infra/main.parameters.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
},
2020
"disableKeyBasedAuth": {
2121
"value": "${DISABLE_KEY_BASED_AUTH=true}"
22+
},
23+
"serviceManagementReference": {
24+
"value": "${AZURE_SERVICE_MANAGEMENT_REFERENCE}"
2225
}
2326
}
2427
}

0 commit comments

Comments
 (0)