I have a Google cloud vm instance that has a directory in a persistent disk that I want to transfer over to a bucket. I'm using the command
gsutil cp -r directoryname gs://my-bucket
but it keeps giving me the error
AccessDeniedException: 403 Insufficient OAuth2 scope to perform this operation.
Acceptable scopes: https://www.googleapis.com/auth/cloud-platform
the vm instance has all Clouod API's enabled.
In order to execute this operation, your instance should be having an access to the cloud storage write operation. You can view service account, access scope and change access scope of the VM instance from which you are trying to execute this command. Alternatively, you can create a new service account, given it appropriate IAM permission and assign to VM instance. Moreover, you can view authorized account for the VM by "gcloud auth list" command and login an account by "gcloud auth login"
Related
I have a web api to access "resources". These are not user specific resources.
There is a "reader" app role.
User1 is added to "reader" role
App1 has been granted permission to the "reader" role
[HttpGet]
[Authorize(Roles = "Reader")]
[RequiredScope("Asset.Read")]
public async Task<IActionResult> GetResource(Guid resourceId)
When user1 accesses the route, (with a token with the scope) it works.
When app1 tries to access the route it gets a 403 forbidden, even though it had ".default" which I thought would give it access to all scopes?
Question 1: Why can't app1 access the route?
Question 2: Why do I even need a scope? It seems like there is a lot of conflicting documentation on why to setup scopes.
Question 1: Why can't app1 access the route?
In addition to what RahulKumarShaw-MT has answered, this likely is because for the OauthV2 Client Credentials flow for AzureAD, the JWT token issued with the /.default scope in the request does not bear an scp parameter for delegated permissions. This is likely what the "Asset.Read" scope is. For your scenario, you'll need to verify the scope parameter exists in the JWT in the case of clients that access data on behalf of the user e.g. Single Page Apps that do not use the Client Credentials flow, but skip the scope verification for Daemon Apps or confidential clients that use the Client Credentials Flow. This question highlights a similar issue to the one you're having.
Question 2: Why do I even need a scope? It seems like there is a lot
of conflicting documentation on why to setup scopes.
You only need the custom-defined scope if your App is performing actions on behalf of the "signed in" user. Such as reading user data. If however, the App is not doing this and is instead a Daemon App or service in a non-public environment that can hold a client secret, then you should be able to assign an App Role and use the client credentials flow without verifying the app scope. App roles assigned to Daemon Apps will require admin consent.
I have a user managed identity, for which I want to generate a token
I tried in user's context
az login
az account get-access-token --resource "<client-id of user managed identity>"
I get the error
Get Token request returned http error: 400 and server response: {"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Microsoft Azure CLI'. Send an interactive authorization request for this user and resource.
Regarding the above error, I have come across threads which suggest to add Azure CLI as preAuthorizedApplication. However I did not find this managed identity in App RegistrationsI did find an entry in `Enterprise Applications, but did not find how to pre-authorize Azure CLI here.
I tried to achieve the same in a non-user context
az login --service-principal -u <capp-id> -p <client-secret> --tenant <tenant-id>
az account get-access-token --resource "<client-id of user managed identity>"
This works.
Why does the command fail in user context? How can I make it work?
Managed Identities do not have app registrations, only a service principal (aka enterprise app).
The way you are trying to use them is not the way they are meant to be used in my opinion.
The second one working is actually just the feature of Azure AD that allows an application using the client credentials flow (client id + secret) to acquire a token for any app in the tenant.
The token won't have any permissions though, so it wouldn't be valid if you are doing authorization correctly.
You usually don't want to use the managed identities as token targets, only for acquiring tokens.
So if you need to protect an API, you'd need an app registration, where you can then allow Az CLI to call it.
You can also define application permissions and allow applications using client credentials flow to access the API with proper authorization.
I'm trying to create a GCP App Engine domain mapping via Terraform with the following configuration:
provider "google" {
version = "3.36.0"
region = var.region
}
resource "google_app_engine_domain_mapping" "domain_mapping" {
project = local.project_id
domain_name = var.domain_name
ssl_settings {
ssl_management_type = "AUTOMATIC"
}
depends_on = [
google_app_engine_application.backend_app
]
}
Terraform is configured to use an organization level service account for the GCP provider with the following IAM permissions (no conditions):
Billing Account User
Project Creator
Service Config Editor (I've added this thinking it would resolve the issue based on this and this doc page.)
The Google account that is the owner of the organization has verified the domain in question, yet I'm getting the following error:
Error: Error creating DomainMapping: googleapi: Error 403: Caller is not authorized to administer the domain 'testing.redacted.com'. If you own 'testing.redacted.com', you can obtain authorization by verifying ownership of the domain, or any of its parent domains, via the Webmaster Central portal: https://www.google.com/webmasters/verification/verification?domain=testing.redacted.com. We recommend verifying ownership of the largest scope you wish to use with subdomains (eg. verify 'example.com' if you wish to map 'subdomain.example.com').
I've also tried adding the service account's email as a user in the Google Search Console to the domain to no avail.
The solution is rather simple but sort of hidden in the docs. You need to add your service account email as owner of the domain.
Go here
Select the property you want
Tap the "Add an owner" button at the bottom of the page and add the email address (e.g. terraform#<PROJECT_ID>.iam.gserviceaccount.com)
I am trying to update a SSL certificate for a Google App Engine project via CLI:
gcloud app ssl-certificates update NNNN --project XXX --configuration XXX --display-name=xxx.co.za --certificate=./fullchain.pem --private-key=./privkey_gae.pem
This command used to work previously but I am now getting the following error:
ERROR: (gcloud.app.ssl-certificates.update) PERMISSION_DENIED: Caller is not authorized to administer this certificate. You must be a verified owner of the certificate's domain(s) [xxx.co.za, *.xxx.co.za] to create, modify, or delete this resource. Your authorized domain(s) are []. If you own the certificate domain(s), you can obtain authorization by verifying ownership via the Webmaster Central portal: https://www.google.com/webmasters/verification/verification.
This error does not make sense as the domains are verified according to the URL (as they are also the custom domain used by the app itself). Also this was working just last month, so it seems that something changed?
I found the issue. Domains are verified by an IAM user, but I use a different IAM/Service-account for the CI/CD server.
It seems that the security around accessing verified domains has changed, in that the Service-account will not automatically have access to the verified domains, even though the App does.
I was able to fix this issue by adding the service-account (jenkins#XXX-ci.iam.gserviceaccount.com) as verified owner here: https://www.google.com/webmasters/verification/verification
I am trying to execute the following API using a bearer token issued to a service principal NOT an AD User. Yes I know this is the AD Graph versus Microsoft Graph endpoint, but I have my reasons :)
https://graph.windows.net/GUID-REDACTED/users/GUID-REDACTED?api-version=1.6
I get a 403 error despite the fact that I have granted all Application Permissions for "Windows Azure Active Directory" (and Microsoft Graph) to that principal. I also applied admin consent (via Grant Permissions) in the portal. Note that a request to read all users (i.e., remove last GUID off URL above) DOES succeed.
The bearer token contains the following seven claims (curiously in AD, EIGHT permissions are granted):
"Device.ReadWrite.All",
"Directory.Read.All",
"Member.Read.Hidden",
"Directory.ReadWrite.All",
"Domain.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"Application.ReadWrite.All"
The token was acquired via:
var context = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");
var m = new HttpRequestMessage()
var accessToken = context.AcquireTokenAsync("https://graph.windows.net", credentials).Result.AccessToken;
m.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
I have tried the analog of this via the Microsoft Graph endpoint, but with the ADAL AuthenticationContext and get the same 403 result. If I use the Microsoft Graph Explorer though, it works. In that case I am logged in as a user though. Upon comparing the scopes in the tokens (scp) there are differences (because the user has certain 'user' scopes), but nothing that immediately looks suspicious.
Directory.AccessAsUser.All is on the user scope but not the application identity scope, but that makes sense to me, unless that scope is (incorrectly?) required for the operation I am trying.
Any ideas what I am missing here? Is there a reference that maps the scopes/roles required to the actual API operations? Does the SP need a directory role, like a user would need?
As #MarcLaFleur said, it's not a good idea to give an application permissions to reset users' password. But if you don't have other choices you can still use client credentials flow to achieve this. But this is not recommeded unless you don't have other choices.
Solution:
You can assign Company Administrators Role to your Service principal. You can refer to this document to do that.
Use AAD Powershell to Connect AAD:
Connect-AzureAD
Get the Role of Company Administrator:
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}
Assign the role to your SP:
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $yoursp.ObjectId