Access denied linking variable group to key vault in VSTS - azure

When I try to link a variable group to key vault in VSTS, every time I select my endpoint, it tells me:
"Specified Azure endpoint needs to have "Get, List" secret management permissions on the selected key vault. Click "Authorize" to enable VSTS to set these permissions or manage secret permissions in Azure portal."
It makes no sense. That specific endpoint has Get and List for secrets, keys, certificates. The endpoint is using the correct Service Principal Client ID- I know because I pulled its corresponding app registration up in Azure by searching with that ID. And the app registration is specifically listed in the key vault's Access policies, with the correct permissions.
Trying to click "Authorize" in VSTS just give me
"Resource not found for the segment 'DirectoryDataService.getServicePrincipalsByAppIds'. For troubleshooting refer to https://go.microsoft.com/fwlink/?linkid=835898"
and the endpoint is broken until I re-verify it.
I'm kind of at my wit's end here- everything is set exactly as https://learn.microsoft.com/en-us/vsts/build-release/concepts/library/variable-groups?view=vsts says it should be.
Edit: Turns out the Azure tried to add the app reg as a person instead of an app when I listed it in the ARM template by object ID (app ID most definitely does not work there). So now I just need to figure out how to add it as an application in the ARM template...
Edit Edit: Soooo... the Object ID the Azure Portal shows for an App Registration? That's not the Object ID the ARM template wants. It wants the... I'm not sure what you'd call it. In Powershell, you use it with -Object ID, but when you list the properties, it's under "Id". Whatever. To get it, you run
Get-AzureRmADServicePrincipal -SearchString "[your-app-reg-name]"
And it shows up under Id. That's what you want to use as an object ID in your ARM template.

According to the error Resource not found for the segment 'DirectoryDataService.getServicePrincipalsByAppIds, the issue seems more related to Azure side.
To access azure-keyvault you need four things :
- clientId = "<client id of your application registed on Azure AD>";
- domain = "<your talnet id>";
- secret = "<client key of your application registed on Azure AD>";
- subscription = "<your subscription id>";
Then these will combine ApplicationTokenCredentials, finally Authorize to KeyVaultClient . Suggest you take a look at this question: Azure keyvault client 1.0.0 initiate client
Besides also double check/confirm the specific endpoint has Get and List for secrets, keys, certificates.

Related

Azure Key Vault: The user, group, or app does not have secrets set permission on key vault

I am creating a script using Azure CLI that will automatically generate an App Registration (service principal), and then use that App Registration to create a secret that will be stored in Azure Key Vault.
However, I am getting the following error:
The user, group or application 'appid=04b07795-8ddb-461a-bbee-02f9e1bf7b46;oid=0ec2b0e8-daeb-46a8-b627-0d4f61f87157;numgroups=134;iss=https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/' does not have secrets set permission on key vault 'asakeyabcfelaqpgsfnxcy;location=eastus'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287
Can anyone provide guidance on what this ID is and how to resolve this error? This is not my App Registration Object ID or App ID.
I think there're 2 points you're now concerning, one is you failed to add secret, another is the app id in the error message is not the one you registered.
I think you've followed the document to execute the cli command, so I just want to explain the second point. Pls allow me show you a code sample for a better explanation.
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
public async Task<IActionResult> PrivacyAsync()
{
var kvUri = "https://your_vault_name.vault.azure.net/";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
_ = await client.SetSecretAsync("test0311", "hello");
return View();
}
When we want to add key vault secret to azure, we need to provide a credential so that our operations are authenticated. This is the DefaultAzureCredential() here, and it has several sources to get the authentication like screenshot below.
That means if someone sets the environment variables for authentication, then it will cover the information you entered when executing cli command, this may usually cause the issue that the app is different from what you set. I think you may follow this document to check all your configurations and try again, or you can directly add environment variables with the app you registered on your computer.
By the way, pls don't forget to add access policy in azure portal for the azure ad app you registered.

How can I identify what the "first party service" is when failing to authenticate to Azure KeyVault?

Despite multiple hours of troubleshooting, I cannot get Visual Studio to authenticate to an Azure KeyVault. No matter what I try, I get the following unhelpful error:
Service request failed.
Status: 403 (Forbidden)
Content:
{"error":{"code":"Forbidden","message":"Access denied to first party service.\r\nCaller: name=from-infra;tid=GUID_REDACTED;appid=GUID_REDACTED;iss=https://sts.windows.net/GUID_REDACTED/\r\nVault: VAULT_NAME;location=westus","innererror":{"code":"AccessDenied"}}}
Is there anything in here (maybe one of the redacted GUID values) I can use to determine what the "First Party Service" it is having a problem with is?
I am signed in with my MSDN account in the "Azure Service Authentication" section. The KeyVault exists in that MSDN account. There are also Access policies in that KeyVault for both my MSDN account and the principal ID of my App Service. These appear to be completely ignored when trying to authenticate.
Here is the basic code I have been trying to use.
var credential = new VisualStudioCredential(new VisualStudioCredentialOptions { TenantId = "GUID from tid in above error" });
// Create a secret client using the DefaultAzureCredential
var client = new SecretClient(new Uri("https://MY_VAULT.vault.azure.net/"), new DefaultAzureCredential());
var secret = client.GetSecret("MySecretId");
I have tried multiple versions of the VisualStudioCredential and DefaultAzureCredential. No matter what I do, I cannot get away from this "Access denied to first party service" error, so I think the next step is to find out what the "first party service" is, because it does not seem to be my MSDN account nor my App Service.
Tenant f8cdef31-a31e-4b4a-93e4-5f571e91255a is a special tenant where Microsoft first party applications are defined. Certain ARM and Compute scenarios access Key Vault using tokens from this tenant, but in general Key Vault rejects tokens from this tenant and it is not available for use by customers.
The tenant you should use is the one that shows up under "Tenant ID" when you look at the "Azure Active Directory" section in the Azure Portal. Personal accounts, such as outlook.com accounts, can get tokens issued by the first party tenant if they do not specify their own tenant ID. Organization accounts get tokens from their home tenant based on the verified domains associated with the tenant, so they generally do not need to specify a tenant ID explicitly.

Unable to get access token. 'AADSTS500011: The resource principal named 'xxx' was not found in the tenant -tenantid

I am trying to get the access token for the Azure function app. I have enabled managed identity for the function app(system assigned). but while fetching the token using the nuget Azure.Identity.
var tokenCredential = new DefaultAzureCredential();
var accessToken = await tokenCredential.GetTokenAsync(
new TokenRequestContext(scopes: new string[] { "https://xxx.azure-api.net/" + "/.default" }) { }
);
I am getting the error.
The resource principal named 'xxx.azure-api.net' was not found in
the tenant 123
but when run az cli to check the subscription details, the subscription indeed part of the tenant 123 only.
Here is what I have finally done.
I have registered an App in AD. and Exposed the API of that App.
I have assigned System Assigned Managed Identity to the Function.
In the local I am not able to request token because Azure CLI is not given consent.
After deploying the application in Function my Function app can request a token using its identity.
You need to register the application in azure ad and enable the access token. Once that is done the you need to provide RBAC access to your xxx.azurewebsites.net
Follow this article for the step by step documentation Microsoft Document Reference
Unfortunately, the error message is not really helpful. But adding a scope to the app registration solved the problem for me:
In Azure Portal navigate to App Registrations
Find your app, in the left side menu select Manage => Expose an API
Add a scope. I named mine api_access as this was where this error occurred.
In my case I then got an API URI (like api://client-id/scope_name) which I used in my Angular app. Error message was gone.
Also, make sure that in the Enterprise Application you have created, under Manage => Properties, "Assignment required" and "Visible to users" is turned on.

Azure Keyvault - "The operation "List" is not enabled in this key vault's access policy." while creating keyvault programmatically

I am creating azure keyvault using .net core 2.1 with OpenIdConnect with following AccessPolicies
AccessPolicies = new List<AccessPolicyEntry>()
{
new AccessPolicyEntry
{
TenantId = Guid.Parse(tenantId),
ObjectId = objectId,
Permissions = new Permissions
{
Secrets = new List<string> { "all" },
Keys = new string[] { "all" },
Certificates = new string[]{"all" }
}
}
}
using that, now, I can create keyvault but while go to newly created keyvault(in Azure portal) settings blade {Key,Secrete,Certificate} it shows warning
"The operation "List" is not enabled in this key vault's access policy."
Note :- As shown in above code "All permission are given".I can see it in azure portal.
What I have tried :-
I have tried to refer following stack-overflow already question-answer
Azure Keyvault - "Operation "list" is not allowed by vault policy" but all permissions are checked
How do I fix an "Operation 'set' not allowed" error when creating an Azure KeyVault secret programmatically?
according to above stackoverflow answer(s) "need to pass the object ID of the service principal of the Azure AD application instead of object ID of your Azure AD application".
I have tried to find out object ID of the service principal of the azure AD application using following powershell script
Get-AzADServicePrincipal -ServicePrincipalName "<app client ID>"
it gives following result
I have tried to use "Id"(in above screenshot) in objectId of AccessPolicyEntry but it not solved problem.
Question :-
Is any other permission need to set in AccessPolicyEntry?
What should be the objectID in AccessPolicyEntry(currently, I am giving obectId of Azure AD application)?
If needed objectId of service princpal. how can get it programmatically?
Well, I can reproduce your issue on my side.
First, the operation pass the object ID of the service principal instead of object ID of your Azure AD application is completely correct. After giving all the permissions to the service principal in the Access policies, the service principal will have the permissions.
But when you check the keyvault in the portal, you are using your user account which login the azure portal instead of the service principal, it caused the warning.
So if you want to fix the warning, just add your user account in the Access policies via + Add Access Policy button in the portal, or you can specify the object id of your user account in your code with the permissions when creating the keyvault.
Then about your questions:
Is any other permission need to set in AccessPolicyEntry?
No, the permissions are enough.
What should be the objectID in AccessPolicyEntry(currently, I am giving obectId of Azure AD application)?
You should not use the object id of the AD App, your option is to use the object id of the service principal/security group/user account, it depends on your requirement, details here.
If needed objectId of service principal. how can get it programmatically?
You can use the powershell command as you used, or the Azure CLI az ad sp show via the service principal name.
Or if you could use Microsoft Graph SDK for C# along with the filter, something like:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var serviceprincipals = await graphClient.Serviceprincipals
.Request().
.Filter("some condition").
.GetAsync();

How can I set up my Azure account in order to make ARM deployments via the REST API?

I have an Azure accounts and I want to make deployment of ARM templates using the ASP.NET libraries. I've noticed that in the Azure Portal generated Deployment class (in the DeploymentHelper.cs file that I've downloaded from the Portal) I have the following fields that I need to provide my own data:
string subscriptionId = "your-subscription-id";
string clientId = "your-service-principal-clientId";
string clientSecret = "your-service-principal-client-secret";
string resourceGroupName = "resource-group-name";
string deploymentName = "deployment-name";
string resourceGroupLocation = "resource-group-location";
string pathToTemplateFile = "path-to-template.json-on-disk";
string pathToParameterFile = "path-to-parameters.json-on-disk";
string tenantId = "tenant-id";
I'm having a hard time with these:
string clientId = "your-service-principal-clientId";
string clientSecret = "your-service-principal-client-secret";
I know that the subscriptionId I can get in the Subscriptions blade. I also know that the tenantId I can get in the Azure Active Directory > Properties blade under the Directory ID field.
I have followed this documentation page in order to try and set up an App Registration on Azure Active Directory, which I've read is what I need to obtain the cliendId and clientSecret values. I think it's worth mentioning I have no experience whatsoever with Active Directory or Azure Active Directory.
When following the docs my first issue is with this blade:
I don't know what I should put in the "Sign-on URL" field. I've tried filling it with my personal website just because it's required (probably my first mistake). Then with the Registered App I go in "Application ID" and use the value as clientId within my code.
I then generate the key in the "Settings" blade and use it as the clientSecret within my code.
However when I run my code I get the following error:
Exception thrown: 'Microsoft.Rest.Azure.CloudException' in System.Private.CoreLib.dll
An exception of type
'Microsoft.Rest.Azure.CloudException' occurred in System.Private.CoreLib.dll but was not handled in user code
Operation returned an invalid status code 'Forbidden'
I wouldn't want to do any fancy Azure AD set up in order to make deployments via Azure. I'm trying this on my personal account, so it's not like a have an AD environment set up.
I don't know what I should put in the "Sign-on URL" field. I've tried filling it with my personal website just because it's required (probably my first mistake).
If you develop a WebApplication, you could Webapplication address it as sign-on url. In your case your could add a vaild url address. And you could add your personal website.
Operation returned an invalid status code 'Forbidden'
It means that you have no access to deploy the resource to the subscription.
You need to assgin role to the WebApplication. For more information, refer to how to registry an Azure AD application and assigin role.

Resources