-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow authentication using RBAC instead of API Keys #427
Conversation
Do you also need to add RBAC roles for this to work, like https://github.com/Azure-Samples/azure-search-openai-demo/blob/87d15fc021a2a84c4cbcbec56b2fe0560af05d52/infra/main.bicep#L336 ? |
@pamelafox Yes! Looks like I missed that. Some roles are there already but a few are missing. I'll get them added now. |
@pamelafox Those have now been added |
@@ -8,6 +8,7 @@ param sku object = { | |||
|
|||
param authOptions object = {} | |||
param semanticSearch string = 'disabled' | |||
param searchApiKeyEnabled bool = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @jongio who likes to be notified about potential changes to infra/core Bicep files (as we try to reuse the same infra/core across azd templates)
infra/main.bicep
Outdated
@@ -271,6 +273,46 @@ module searchRoleBackend 'core/security/role.bicep' = { | |||
} | |||
} | |||
|
|||
module searchRoleOpenAi 'core/security/role.bicep' = if (!searchApiKeyEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you only did the system roles, what about local server running? For the other repo with these roles, we also have the equivalent for the user. I don't recall if this repo can be run locally or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I tried locally and it didn't require me to add any roles. I think this is because we're still calling OpenAI with API key. I missed this before, so will make the change and push to this branch/PR along with the associated required role.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want rbac to work for the local user as well.
README.md
Outdated
@@ -114,6 +114,17 @@ const getUserInfoList = async () => { | |||
} | |||
``` | |||
|
|||
### Authenticate using Azure RBAC | |||
To authenticate using Azure RBAC instead of the default API Keys follow the steps below: | |||
1. Ensure role assignments listed on [this page](https://learn.microsoft.com/azure/ai-services/openai/concepts/use-your-data?tabs=ai-search#azure-role-based-access-controls-azure-rbac-for-adding-data-sources) have been created |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should mention these should be created by azd provision already
@@ -114,6 +114,17 @@ const getUserInfoList = async () => { | |||
} | |||
``` | |||
|
|||
### Authenticate using Azure RBAC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather the flow of the application take care of all the settings and not require the user to take manual action.
We are experimenting with adding an AZURE_AUTH_TYPE parameter that can get set to rbac or keys and the bicep does the appropriate thing based on that.
It's not finalized, but should be soon.
@@ -41,3 +44,5 @@ output id string = account.id | |||
output name string = account.name | |||
output skuName string = account.sku.name | |||
output key string = account.listKeys().key1 | |||
output identityPrincipalId string = account.identity.principalId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should match the name of the other core files when they provide an id, which is just principalId
@@ -17,8 +18,8 @@ resource search 'Microsoft.Search/searchServices@2021-04-01-preview' = { | |||
type: 'SystemAssigned' | |||
} | |||
properties: { | |||
authOptions: authOptions | |||
disableLocalAuth: false | |||
authOptions: searchApiKeyEnabled ? authOptions : null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Param should be something like 'authType' with allowed values of rbac or keys
@@ -41,3 +42,4 @@ output endpoint string = 'https://${name}.search.windows.net/' | |||
output name string = search.name | |||
output skuName string = sku.name | |||
output adminKey string = search.listAdminKeys().primaryKey | |||
output identityPrincipalId string = search.identity.principalId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about name principalId
infra/main.bicep
Outdated
@@ -26,6 +26,7 @@ param searchContentColumns string = 'content' | |||
param searchFilenameColumn string = 'filepath' | |||
param searchTitleColumn string = 'title' | |||
param searchUrlColumn string = 'url' | |||
param searchApiKeyEnabled bool = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
authType
infra/main.bicep
Outdated
@@ -271,6 +273,46 @@ module searchRoleBackend 'core/security/role.bicep' = { | |||
} | |||
} | |||
|
|||
module searchRoleOpenAi 'core/security/role.bicep' = if (!searchApiKeyEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want rbac to work for the local user as well.
principalType: 'ServicePrincipal' | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In outputs below we shouldn't be outputting keys. You will get a bicep linter warning. Best to ask the user to manually set them with in env vars at this time until we have a secure way to store them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Phew, glad to see the keys are out of this output finally! That's been a TODO (in my head) for a long time.
Another option btw is to provide a script that grabs the keys, which is what I've had to do for another repo which unfortunately requires keys:
https://github.com/Azure-Samples/contoso-chat/pull/33/files#diff-c8719e3915d76118aeee543ed85367b315252d46ef1d793635a82eaef96ce7b4R19
But probably okay not to do that here, since we now have the keyless option.
Heya, thanks for your review comments! I've made some changes. Please note, I've yet to test them out. I'll update on here when I have. |
infra/main.parameters.json
Outdated
@@ -43,6 +43,9 @@ | |||
}, | |||
"authClientSecret": { | |||
"value": "${AUTH_CLIENT_SECRET}" | |||
}, | |||
"authType": { | |||
"value": "${AZURE_AUTH_TYPE}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll want to default this to rbac
"value": "${AZURE_AUTH_TYPE=rbac}"
app.py
Outdated
@@ -40,6 +39,7 @@ def assets(path): | |||
SEARCH_TOP_K = os.environ.get("SEARCH_TOP_K", 5) | |||
SEARCH_STRICTNESS = os.environ.get("SEARCH_STRICTNESS", 3) | |||
SEARCH_ENABLE_IN_DOMAIN = os.environ.get("SEARCH_ENABLE_IN_DOMAIN", "true") | |||
AZURE_AUTH_TYPE = os.environ.get("AZURE_AUTH_TYPE", "apikeys") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we'll use 'keys'
@@ -8,7 +8,7 @@ param sku object = { | |||
|
|||
param authOptions object = {} | |||
param semanticSearch string = 'disabled' | |||
param searchApiKeyEnabled bool = true | |||
param authType string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add rbac default
.env.sample
Outdated
@@ -1,3 +1,4 @@ | |||
AZURE_AUTH_TYPE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all the others have an =
I've now tested this deployed to Azure, as well as running locally. I did not have to create any additional role assignments to get this to work locally. |
Did you test with both rbac and keys in both local and azure? |
Yep, both worked without any additional roles being required. |
app.py
Outdated
default_credential = DefaultAzureCredential() | ||
token = default_credential.get_token("https://cognitiveservices.azure.com/.default") | ||
openai.api_key = token.token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be refactored to remove dupe code above?
Heya, I believe this is ready for re-review. Thanks |
Can we move this to azure-samples github org? Not sure history on why it is in the microsoft org, but most samples go in azure-samples org. https://github.com/azure-samples |
infra/core/host/appservice.bicep
Outdated
@@ -132,6 +132,6 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing | |||
name: applicationInsightsName | |||
} | |||
|
|||
output identityPrincipalId string = managedIdentity ? appService.identity.principalId : '' | |||
output principalId string = managedIdentity ? appService.identity.principalId : '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stand corrected, the official name is identityPrincipalId
Please change it back.
@@ -41,3 +44,5 @@ output id string = account.id | |||
output name string = account.name | |||
output skuName string = account.sku.name | |||
output key string = account.listKeys().key1 | |||
output principalId string = account.identity.principalId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to identityPrincipalId? (Sorry)
@@ -20,6 +20,9 @@ resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = { | |||
publicNetworkAccess: publicNetworkAccess |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do a PR to update this too? https://github.com/Azure/azure-dev/blob/main/templates/common/infra/bicep/core/ai/cognitiveservices.bicep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What updates are required? Do you just mean to pull from main?
@@ -8,6 +8,7 @@ param sku object = { | |||
|
|||
param authOptions object = {} | |||
param semanticSearch string = 'disabled' | |||
param authType string = 'rbac' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do a PR to update this? https://github.com/Azure/azure-dev/blob/main/templates/common/infra/bicep/core/search/search-services.bicep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What updates are required? Do you just mean to pull from main?
} | ||
} | ||
|
||
module searchRoleOpenAi 'core/security/role.bicep' = if (authType == 'rbac') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any new roles you create will also need to be assigned to the user's principalId, see "user roles" above.
Co-authored-by: Pamela Fox <[email protected]>
4f21291
to
314aca8
Compare
Heya @jongio, thanks for the further comments. I have addressed them and rebased from main. Unfortunately, I have no information as to why this is not in the azure samples org. |
We have considered moving this to the azure-samples org but haven't taken the action yet. The repo is used in multiple ways (code-first sample, source code for apps deployed from Azure OpenAI studio, storage place for public-facing utility scripts such as data preparation). For now we're keeping it here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thank you very much for the contribution.
Heya, can this be merged? Thanks |
app.py
Outdated
@@ -41,6 +41,7 @@ def assets(path): | |||
SEARCH_TOP_K = os.environ.get("SEARCH_TOP_K", 5) | |||
SEARCH_STRICTNESS = os.environ.get("SEARCH_STRICTNESS", 3) | |||
SEARCH_ENABLE_IN_DOMAIN = os.environ.get("SEARCH_ENABLE_IN_DOMAIN", "true") | |||
AZURE_AUTH_TYPE = os.environ.get("AZURE_AUTH_TYPE", "rbac") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we actually have this default to "keys" and set it to "rbac" from the bicep deployment? The reason to have it default to keys is that for the case of deployment from the Azure OpenAI Studio chat playground, role assignments are not configured by default between the resources, so keys need to be used by default in that scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Good point! I've just pushed that change.
This is required as the OpenAI Studio does not create roles so this change would break deployments from there.
Heya! Is this ready to be merged now? Thanks |
@sarah-widder Is this still required? It looks like similar changes have been made in #460? |
I guess it's just the infra side of things that's still required? |
Hey @adamdougal yes, #460 should have already addressed using RBAC in the app backend, but the infra changes you were working on to automatically assign the right roles during deployment are still needed. If you want to rebase and just keep the infra changes I will give it another review. Thanks very much for your contribution! |
I'm going to close this. It looks like the openai version bump has brought significant changes so a fresh PR/branch would probably be a better approach. |
Required by #391