Azure Functions that ship with Static Web Apps cannot be configured to access Key Vault
- Dominant language
- No language data
- Stars
- 346
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
Opening for visibility as #1091 was closed without explanation and the feature is still not available.
Having failed to use Key Vault references with the Azure Function that ships with Azure Static Web Apps, I tried to access the Key Vault directly and could not.
See #1090
**To Reproduce**
Use the same config as described in #1090, but this time pass through what's necessary to access a Key Vault; ClientId / TenantId / Client Secret:
```bicep
module staticWebApp 'static-sites.bicep' = {
name: '${deploymentPrefix}-how-you-doin-${branchHash}'
params: {
appSettings: {
// THESE WILL WORK FINE
AAD_CLIENT_ID: aadClientIdRef
AAD_CLIENT_SECRET: aadClientSecretRef
}
functionAppAppSettings: {
APPINSIGHTS_INSTRUMENTATIONKEY: appInsights.properties.InstrumentationKey
APPLICATIONINSIGHTS_CONNECTION_STRING: appInsights.properties.ConnectionString
// These are the settings that are used to access the key vault
AZURE_TENANT_ID: aadTenantId
AZURE_CLIENT_ID: aadClientId
AZURE_CLIENT_SECRET: aadClientSecret
keyVaultName: keyVaultName
}
location: location
repositoryBranch: repositoryBranch
repositoryUrl: repositoryUrl
staticSiteName: staticSiteName
tags: tagsWithHiddenLinks
customDomainName: (repositoryBranch == 'main') ? customDomainName : ''
}
}
```
Create an Azure Function which does something like this:
```ts
export async function getFromKeyVault(
secretNames: string[],
log: Logger
): Promise> {
const credential = new DefaultAzureCredential();
const secrets = new Map();
const url = `https://${getConfig().keyVaultName}.vault.azure.net`;
const client = new SecretClient(url, credential);
for (const secretName of secretNames) {
// Read the secret we created
const secret = await client.getSecret(secretName);
log("secret: ", secret);
secrets.set(secretName, secret.value);
}
return secrets;
}
const httpTrigger: AzureFunction = async function (
context: Context,
req: HttpRequest
): Promise {
try {
const secrets = await getFromKeyVault(
["telemetryDbKey"],
context.log
);
context.log("secrets", secrets);
} catch (error) {
context.log("unexpected error", error, req);
context.res = {
status: 500,
body: "There was an error",
};
}
};
```
It will error out like this at runtime:
```
problem reading from keyvault RestError: Caller is not authorized to perform action on resource.
If role assignments, deny assignments or role definitions were changed recently, please observe propagation time.
Caller: appid=586bc697-2c6b-40f3-b91d-2ee65e5d4c7a;oid=92521cf5-b763-4b0e-ac50-1060dca0095d;iss=https://sts.windows.net/6d6a11bc-469a-48df-a548-d3f353ac1be8/
Action: 'Microsoft.KeyVault/vaults/secrets/getSecret/action'
Resource: '/subscriptions/5b380244-4d89-4218-a9ad-e6295602f103/resourcegroups/rg-azure-engineering-metrics-dev-001/providers/microsoft.keyvault/vaults/kv-kv-2mb9k5bwz8-dev/secrets/telemetrydbkey'
Assignment: (not found)
Vault: kv-kv-2mb9k5bwz8-dev;location=westeurope
```
There appears to be no way to provide this RBAC access to the built in function. The same RBAC access has been supplied to the SWA:
```bicep
// Allow the static web app to read from the Key Vault
// Allow the service connection and admin group to create secrets
module keyVaultRoles 'br:icebox.azurecr.io/bicep/ice/composites/key-vault/role-assignments:v1.0' = {
name: '${deploymentPrefix}-roles-${branchHash}'
params: {
keyVaultName: keyVault.outputs.keyVaultName
roleAssignments: [
{
roleDefinitionId: keyVaultSecretsOfficerRole
principalId: serviceConnectionPrincipalId
principalType: 'ServicePrincipal'
}
{
roleDefinitionId: keyVaultSecretsUserRole
principalId: staticWebApp.outputs.staticWebAppSystemAssignedIdentityId // ACCESS PROVIDED HERE
principalType: 'ServicePrincipal'
}
]
}
}
```
**Expected behavior**
The values are returned from the vault.
**Screenshots**

**Device info (if applicable):**
N/A
**Additional context**
Happy to demo this issue to you.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.