4

I'm trying to retrieve some secrets from Azure's keyvault but I cannot seem to authenticate using @azure/identity module.

Versions:

"@azure/identity": "^1.0.0-preview.6",
"@azure/keyvault-secrets": "^4.0.0-preview.9",

I have an azure functions app and I have configured the app both in production and locally using the local.settings.json having filled in the proper values for:

{
    "IsEncrypted": false,
    "Values": {
        "AZURE_CLIENT_ID": "REDACTED",
        "AZURE_CLIENT_SECRET": "REDACTED",
        "AZIRE_TENANT_ID": "REDACTED"
    },
    "ConnectionStrings": {}
}

  • App Registered via Azure Active Directory => App Registrations.
  • Disabled login
  • Created App Secret

Then, I have added the app to the keyvault with the role 'reader' giving it the ability to 'get' secrets but nothing else, not even list:

Role Assignment screenshot

Now when I try to retreive the secrets:

import { KeyVaultSecret, SecretClient } from '@azure/keyvault-secrets';
import { EnvironmentCredential } from '@azure/identity';

export const GetSecret = async (key: string): Promise<string> => {
    try {
        const credential: EnvironmentCredential = new EnvironmentCredential();

        console.log('CREDENTIAL: ', credential);
        console.log('CLIENT SECRET', process.env.AZURE_CLIENT_SECRET);
        console.log('CLIENT ID', process.env.AZURE_CLIENT_ID);

        const url = 'https://tlabs-vault.vault.azure.net';
        const client = new SecretClient(url, credential);
        let secret: KeyVaultSecret = await client.getSecret(key);
        return secret.value;
    } catch (err) {
        console.error('Error getting secret from Azure Vault', err);
    }
};

But this is not working, on the console I see the result of credentials as:

EnvironmentCredential { _credential: undefined }

And the full request that throws the error:

request:
[10/28/2019 1:14:16 PM]    WebResource {
[10/28/2019 1:14:16 PM]      streamResponseBody: false,
[10/28/2019 1:14:16 PM]      url:
[10/28/2019 1:14:16 PM]       'https://REDACTED_VAULT_NAME.vault.azure.net/secrets/REDACTED_SECRET_NAME/?api-version=7.0',
[10/28/2019 1:14:16 PM]      method: 'GET',
[10/28/2019 1:14:16 PM]      headers: HttpHeaders { _headersMap: [Object] },
[10/28/2019 1:14:16 PM]      body: undefined,
[10/28/2019 1:14:16 PM]      query: undefined,
[10/28/2019 1:14:16 PM]      formData: undefined,
[10/28/2019 1:14:16 PM]      withCredentials: false,
[10/28/2019 1:14:16 PM]      abortSignal: undefined,
[10/28/2019 1:14:16 PM]      timeout: 0,
[10/28/2019 1:14:16 PM]      onUploadProgress: undefined,
[10/28/2019 1:14:16 PM]      onDownloadProgress: undefined,
[10/28/2019 1:14:16 PM]      proxySettings: undefined,
[10/28/2019 1:14:16 PM]      keepAlive: true,
[10/28/2019 1:14:16 PM]      operationSpec:
[10/28/2019 1:14:16 PM]       { httpMethod: 'GET',
[10/28/2019 1:14:16 PM]         path: 'secrets/{secret-name}/{secret-version}',
[10/28/2019 1:14:16 PM]         urlParameters: [Array],
[10/28/2019 1:14:16 PM]         queryParameters: [Array],
[10/28/2019 1:14:16 PM]         responses: [Object],
[10/28/2019 1:14:16 PM]         serializer: [Serializer] } },
[10/28/2019 1:14:16 PM]   response:
[10/28/2019 1:14:16 PM]    { body:
[10/28/2019 1:14:16 PM]       '{"error":{"code":"Unauthorized","message":"Request is missing a Bearer or PoP token."}}',
[10/28/2019 1:14:16 PM]      headers: HttpHeaders { _headersMap: [Object] },
[10/28/2019 1:14:16 PM]      status: 401,
[10/28/2019 1:14:16 PM]      parsedBody: { error: [Object] } },
[10/28/2019 1:14:16 PM]   details:
[10/28/2019 1:14:16 PM]    { error:
[10/28/2019 1:14:16 PM]       { code: 'Unauthorized',
[10/28/2019 1:14:16 PM]         message: 'Request is missing a Bearer or PoP token.' } } }
SteveC
  • 15,808
  • 23
  • 102
  • 173
SebastianG
  • 8,563
  • 8
  • 47
  • 111
  • Any update on this issue, could you use key vault now? – George Chen Nov 01 '19 at 08:20
  • @GeorgeChen Hi George, I've made a github thread about this issue where I've linked to the two threads I made on this issue. The issue has been that the tenant ID property was missing (misspelled) and it didn't provide a meaningful error message only when I used the 'ClientSecretCredential' method. I did indeed have to add an access policy on top of RBAC after that but it provided a meaningful error message after that so it was easy to identify. – SebastianG Nov 01 '19 at 09:28

1 Answers1

2

Please follow this blog about how to Integrate Key Vault Secrets With Azure Functions.

The main steps are Enable system-asigned managed identity for the Function App and Add Key Vault access policy for the Function App.

enter image description here

After these don't forget to add Key Vault secrets reference in the Function App configuration with @Microsoft.KeyVault(SecretUri={copied identifier for the username secret}). If you set it correctly, after configuration it will display the below pic.

enter image description here

And below is my test result, I use os.environ[name] to get the secret.

enter image description here

George Chen
  • 13,703
  • 2
  • 11
  • 26