Azure-sdk-for-js: [AppConfiguration] 403 when using DefaultAzureCredential or VisualStudioCodeCredential with App Configuration

Created on 6 Nov 2020  ยท  10Comments  ยท  Source: Azure/azure-sdk-for-js

  • Package Name: app-configuration
  • Package Version: 1.1.0
  • Operating system: Windows 10
  • [x] nodejs

    • version: 12.16.0

  • [X] typescript

    • version: 4.0.5

Describe the bug
With VSCode with the Azure Account extension described here I'm trying to access App Configuration, but I'm getting a 403 error when attempting to read a configuration key.

RestError:  
 {
  "name": "RestError",
  "statusCode": 403,
  "request": {
    "streamResponseBody": false,
    "url": "https://[app-config-name].azconfig.io/kv/inf%2FcdnUrl?api-version=1.0",
    "method": "GET",
    "headers": {
      "_headersMap": {
        "content-type": "application/json; charset=utf-8",
        "user-agent": "azsdk-js-app-configuration/1.1.0 core-http/1.2.0 Node/v12.16.0 OS/(x64-Windows_NT-10.0.18362)",
        "x-ms-client-request-id": "[clientid]",
        "authorization": "REDACTED",
        "cookie": "REDACTED"
      }
    },
    "withCredentials": false,
    "timeout": 0,
    "requestId": "b3acfdcf-748b-4ca1-a926-278359bbd592"
  },
  "details": {},
  "message": ""
}

To Reproduce
Steps to reproduce the behavior:

  1. With the following dependencies:
    "@azure/app-configuration": "^1.1.0",
    "@azure/identity": "^1.1.0",
    "@azure/keyvault-secrets": "^4.1.0",
    "dotenv": "^8.2.0"
  1. When I run this code:
import { VisualStudioCodeCredential, DefaultAzureCredential } from "@azure/identity"
import { AppConfigurationClient } from "@azure/app-configuration"
import { SecretClient } from "@azure/keyvault-secrets"

const credentials = new DefaultAzureCredential()

const client = new SecretClient(process.env.KV_ENDPOINT!, credentials)
console.log(await client.getSecret("test-secret")) // Works

const appConfigClientSecret = new AppConfigurationClient(process.env.CONNECTION_STRING!)
console.log(await appConfigClientSecret.getConfigurationSetting({ key: "inf/cdnUrl" })) // Works

const appConfigClient = new AppConfigurationClient(process.env.APPCONFIG_ENDPOINT!, credentials)
console.log(await appConfigClient.getConfigurationSetting({ key: "inf/cdnUrl" })) // Fails with 403:

The first two calls (Key Vault and App Configuration with connection string) works.

Expected behavior
The call to:

appConfigClient.getConfigurationSetting({ key: "inf/cdnUrl" })

should work with DefaultAzureCredential like the Key Vault call does.

Additional context
Originally there was a problem with the Azure Account extension. It was addressed here: https://github.com/microsoft/vscode-azure-account/issues/234

App Configuration Client customer-reported needs-team-attention question

Most helpful comment

I did a retest and here are the results. This time I waited for at least 10 minutes in an attempt to ensure the role assignments were updated.

Role|Access config via API|Access config via portal|Access to resource via portal
-|-|-|-
Owner|โŒ|โœ”|โœ”
Reader|โŒ|โŒ|โœ”
App Configuration Data Reader|โœ”|โŒ|โŒ
App Configuration Data Owner|โœ”|โŒ|โŒ

Based on this it seems that the Owner role is not sufficient to read data via the API, but it is enough to read through the portal which I find strange. Shouldn't the roles grant the same access regardless of the method used for access?

In any case since this now seems to work for App Configuration roles I'll set up our assignments to reflect this so that developers can work with it.

Since I'm not sure if this is a bug or not I'm fine with closing this issue. But maybe some clarity on the Owner and Reader roles could be added to the documentation?

All 10 comments

Just wanted to add that I've tested with the latest dev version of the package "@azure/app-configuration": "^1.1.1-alpha.20201030.1" and the problem persists.

Any news on this one? We are super-keen to start using DefaultAzureCrendetial in all our code, but until this works I'm reluctant to roll it out to all our developers.

facing the same issue.

@rudfoss and @pkvpraveen

I was able to run the following sample successfully from within my vscode terminal:

import { AppConfigurationClient } from "@azure/app-configuration";
import { DefaultAzureCredential } from "@azure/identity"

async function run() {
  const credentials = new DefaultAzureCredential();

  const client = new AppConfigurationClient(process.env.ENDPOINT, credentials);
  const result = await client.getConfigurationSetting({ key: 'my-super-neat-config' });
  console.log(result);
}

run();

Since you're getting a 403 which indicates your user isn't authorized, can you confirm you've given your user role-based access to the App Configuration resource?

If you haven't, you can do this through the portal doing the following:

  1. Open you app configuration resource.
  2. Click the Access control (IAM) blade on the left side bar.
  3. Click +Add -> Role Assignment
  4. When selecting a role select either App Configuration Data Reader (readonly) or App Configuration Data Owner (read/write).
  5. Select your developer account as the user and save.

Please let me know if this helps.

Hi @chradek, thanks for the reply.

My account is a subscription admin and listed as an Owner in the Access Control page:
image

I'm also able to modify all configurations through the portal.

But for completeness I added the role specifically:
image

Signed out and back in and retried with this code with and without the VisualStudioCodeCredential explicitly:

import dotenv from "dotenv"
dotenv.config()

import { VisualStudioCodeCredential, DefaultAzureCredential } from "@azure/identity"
import { AppConfigurationClient } from "@azure/app-configuration"

const start = async () => {
    const credentials = new DefaultAzureCredential()
    console.log("Instance", process.env.APP_CONFIG_ENDPOINT)
    const appConfigClient = new AppConfigurationClient(process.env.APP_CONFIG_ENDPOINT!, credentials)
    console.log(await appConfigClient.getConfigurationSetting({ key: "inf/cdnUrl" })) // Fails with 403:
}

start().catch((error) => {
    console.error(error)
    console.error(error.stack)
    process.exit(1)
})

The error is the same:

RestError:  
 {
  "name": "RestError",
  "statusCode": 403,
  "request": {
    "streamResponseBody": false,
    "url": "https://[instance].azconfig.io/kv/inf%2FcdnUrl?api-version=1.0",
    "method": "GET",
    "headers": {
      "_headersMap": {
        "content-type": "application/json; charset=utf-8",
        "user-agent": "azsdk-js-app-configuration/1.1.1 core-http/1.2.0 Node/v12.16.0 OS/(x64-Windows_NT-10.0.18363)",
        "x-ms-client-request-id": "3d6409d6-c9a2-4de6-920e-244c5a299956",
        "authorization": "REDACTED",
        "cookie": "REDACTED"
      }
    },
    "withCredentials": false,
    "timeout": 0,
    "requestId": "3d6409d6-c9a2-4de6-920e-244c5a299956"
  },
  "details": {},
  "message": ""
}

@rudfoss
I was able to reproduce the 403 error if I removed user's App Configuration Data Owner role assignment, and if I changed the role assignment to App Configuration Data Reader.

Can you try setting your role assignment to App Configuration Data Owner and see if that at least gets you past the 403 error?

In either case, I'd have expected the App Configuration Data Reader to work with the getConfigurationSetting operation based on the roles documented here. We'll need to follow up with the service team to determine what's going on with that scenario.

Edit: It appears App Configuration Data Reader is working for listing and retrieving settings now that I've waited ~10 minutes and signed out/back in, so I may have just needed to clear my cache/wait for permissions to propagate in this case.

EDIT: Disregard this test. I did not wait for the role membership cache to time out.

Hi @chradek

I tried again this morning and for some reason I'm able to read config with just the Owner role now. Has there been some update to the service? I've tested with several role assignments and logging out and back in between each test:

  • Owner: โœ”
  • App Configuration Data Owner: โœ”
  • App Configuration Data Reader: โœ”

I've even tried assigning the App Configuration Data Reader role, verifying it works and removing the user again. It still works even after signing out and back in so I guess there is some caching of roles going on here. Unsure how I can properly vet this.

I did a retest and here are the results. This time I waited for at least 10 minutes in an attempt to ensure the role assignments were updated.

Role|Access config via API|Access config via portal|Access to resource via portal
-|-|-|-
Owner|โŒ|โœ”|โœ”
Reader|โŒ|โŒ|โœ”
App Configuration Data Reader|โœ”|โŒ|โŒ
App Configuration Data Owner|โœ”|โŒ|โŒ

Based on this it seems that the Owner role is not sufficient to read data via the API, but it is enough to read through the portal which I find strange. Shouldn't the roles grant the same access regardless of the method used for access?

In any case since this now seems to work for App Configuration roles I'll set up our assignments to reflect this so that developers can work with it.

Since I'm not sure if this is a bug or not I'm fine with closing this issue. But maybe some clarity on the Owner and Reader roles could be added to the documentation?

I did a retest and here are the results. This time I waited for at least 10 minutes in an attempt to ensure the role assignments were updated.
Role Access config via API Access config via portal Access to resource via portal
Owner โŒ โœ” โœ”
Reader โŒ โŒ โœ”
App Configuration Data Reader โœ” โŒ โŒ
App Configuration Data Owner โœ” โŒ โŒ

Based on this it seems that the Owner role is not sufficient to read data via the API, but it is enough to read through the portal which I find strange. Shouldn't the roles grant the same access regardless of the method used for access?

In any case since this now seems to work for App Configuration roles I'll set up our assignments to reflect this so that developers can work with it.

Since I'm not sure if this is a bug or not I'm fine with closing this issue. But maybe some clarity on the Owner and Reader roles could be added to the documentation?

I was trying to access config from an app service. with App Configuration Data Reader app service is able to access the config. Thank you @rudfoss

Apologies for the delayed response here. I reached out to the service team to let them know the page on roles could use some clarification so am closing the issue here on our side.

This comment summarizes the access behavior working in the portal vs the API very well.

Was this page helpful?
0 / 5 - 0 ratings