--recurse ERROR: Insufficient Permission: Request had insufficient authentication scopes - terminal

I'm trying to copy a directory from my vm to my local machine's Desktop with the following command:
gcloud compute scp --recurse instance-1:~/directory ~/Desktop/
I tried reauthenticating with "gcloud auth login" however it still says
ERROR: (gcloud.compute.scp) Could not fetch resource:
- Insufficient Permission: Request had insufficient authentication scopes.

Try to run a "gcloud auth login" from the machine that you are trying to run the gcloud command.
For more information have a look at this old post, they are reporting the same issue.

You will need roles/compute.instanceAdmin.v1 to use SSH or SCP to an instance for the credentials that you are using. The simplest method is to add Compute Instance Admin to your credentials.
To see what credentials you are using execute gcloud auth list. The account will have an asterisk in the left column.
To figure out what permissions you have execute gcloud projects get-iam-policy PROJECT_ID

Providing entire code for better understanding
private static void upload() throws GeneralSecurityException, IOException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive driveService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
File fileMetadata = new File();
fileMetadata.setName("My Report");
fileMetadata.setMimeType("application/vnd.google-apps.spreadsheet");
java.io.File filePath = new java.io.File("/exportData.csv");
FileContent mediaContent = new FileContent("text/csv", filePath);
File file = driveService.files().create(fileMetadata, mediaContent)
.setFields("id")
.execute();
System.out.println("File ID: " + file.getId());
}

Related

Access denied when using OAuth client credentials flow to create shared mailbox

Short version:
How to correctly set up application permissions and/or role assignments and/or something else that I'm missing, so that application id/secret (OAuth client credentials) can be used to create shared mailboxes?
So far I've tried couple combinations of permissions/roles, e.g. Exchange.ManageAsApp with User Administrator (fe930be7-5e62-47db-91af-98c3a49a38b1), Exchange administrator (29232cdf-9323-42fd-ade2-1d097af3e4de) and bunch of other.
Details:
I have a bunch of powershell scripts used to automate various tasks on Exchange Online. So far I've been using basic auth, which I was able to successfully convert into OAuth password flow.
But to get rid of dependency on service account completely, I'd prefer to use credentials flow. In background I'm trying to do something like this:
var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{TenantId}", false, _tokenCache);
var clientCredential = new ClientCredential(ClientId, ClientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync(Resource, clientCredential);
var username = "OAuthUser#" + TenantId;
var password = authenticationResult.CreateAuthorizationHeader();
var executor = new ExolExecutor(username, password);
await executor.Execute(Script, cancellationToken);
where executor does the regular thing:
Create PSSession to https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true
Executes powershell script using
using PowerShell powershell = PowerShell.Create();
powershell.Runspace = runspace;
powershell.AddScript(script);
...
await Task.Factory.FromAsync(powershell.BeginInvoke(input, output), powershell.EndInvoke);
Remove PSSession
So far so good. Works perfectly fine with Get-Mailbox -ResultSize 1.
But when trying to create new shared mailbox New-Mailbox -Name "pko222" -DisplayName "pko222" -Alias "pko222" -Shared, I'm getting
CategoryInfo.Activity: New-Mailbox
CategoryInfo.Category: 1001
CategoryInfo.Reason: ADOperationException
CategoryInfo.TargetName:
CategoryInfo.TargetType:
ErrorDetails.Message:
ErrorDetails.RecommendedAction:
Exception.Message: Active Directory operation failed on DB7PR01A03DC005.EURPR01A003.prod.outlook.com. This error is not retriable. Additional information: Access is denied.
Active directory response: 00000005: SecErr: DSID-03152612, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
FullyQualifiedErrorId: [Server=BEXP281MB0087,RequestId=88419a8e-78a4-4967-9bca-71d40feb5150,TimeStamp=10/6/2020 11:57:38 AM] [FailureCategory=Cmdlet-ADOperationException] 2C0312E5,Microsoft.Exchange.Management.RecipientTasks.NewMailbox
JWT token looks something like this:
{
"aud": "https://outlook.office365.com",
"iss": "https://sts.windows.net/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/",
"iat": 1601985127,
"nbf": 1601985127,
"exp": 1601989027,
"aio": "E2RgYFCOsw1iZj34elV49CH5zyd5AQ==",
"app_displayname": "XXXXXXXXXXX",
"appid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"appidacr": "1",
"idp": "https://sts.windows.net/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/",
"oid": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"rh": "0.AAAAv9y4fwZQ_0G6_d1kLKJ_sarAXb_REQFHhc2EM1FNn9tIAAA.",
"roles": ["User.Read.All", "full_access_as_app", "Mail.ReadWrite", "MailboxSettings.ReadWrite", "User.ReadBasic.All", "Mailbox.Migration", "Mail.Read", "Mail.Send", "MailboxSettings.Read", "Exchange.ManageAsApp"],
"sid": "qqqqqqqq-qqqq-qqqq-qqqq-qqqqqqqqqqqq",
"sub": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"tid": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
"uti": "CRytfXbD80y3ATmQvd-VAQ",
"ver": "1.0",
"wids": ["29232cdf-9323-42fd-ade2-1d097af3e4de", "88d8e3e3-8f55-4a1e-953a-9b9898b8876b", "fe930be7-5e62-47db-91af-98c3a49a38b1", "9360feb5-f418-4baa-8175-e2a00bac4301", "62e90394-69f5-4237-9190-012177145e10", "0997a1d0-0d1d-4acb-b408-d5ca73121e90"]
}
Fyi i managed to make it work on my side.
you just need to add the following param in the connection uri
&email=SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}#yourtenantname.onmicrosoft.com
so the connection uri looks like :
https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true&email=SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}#yourtenantname.onmicrosoft.com
just change the suffix from 'yourtenantname' with ... your tenant name! dont put the tenant guid !
https://learn.microsoft.com/en-us/answers/questions/451006/pssession-and-modern-auth.html

Prevent KeyVault from updating secrets using Terraform

I'm building a terraform template to create Azure resources including Keyvault Secrets. The customer Subscription policy doesn't allow anyone to update/delete/view keyvault secrets.
If I run terraform apply for the first time, it will work perfectly. However, running the same template again will give you the following error: Error:
Error updating Key Vault "####" (Resource Group "####"): keyvault.VaultsClient#Update: Failure responding to request: StatusCode=403 --
Original Error: autorest/azure: Service returned an error. Status=403 Code="RequestDisallowedByPolicy" Message="Resource '###' was disallowed by policy. Policy identifiers: '[{\"policyAssignment\":{\"name\":\"###nis-deny-keyvault-acl\", ...
on ..\..\modules\azure\keyvault\main.tf line 15, in resource "azurerm_key_vault" "keyvault":
15: resource "azurerm_key_vault" "keyvault" {
How can I get my CI/CD working while that means terraform apply will be continuously running?
Is there a way to pass this policy in terraform?
Is there a way to prevent terraform from updating KV once it created (other than locking the resource)?
Here is the Keyvault module:
variable "keyvault_id" {
type = string
}
variable "secrets" {
type = map(string)
}
locals {
secret_names = keys(var.secrets)
}
resource "azurerm_key_vault_secret" "secret" {
count = length(var.secrets)
name = local.secret_names[count.index]
value = var.secrets[local.secret_names[count.index]]
key_vault_id = var.keyvault_id
}
data "azurerm_key_vault_secret" "secrets" {
count = length(var.secrets)
depends_on = [azurerm_key_vault_secret.secret]
name = local.secret_names[count.index]
key_vault_id = var.keyvault_id
}
output "keyvault_secret_attributes" {
value = [for i in range(length(azurerm_key_vault_secret.secret.*.id)) : data.azurerm_key_vault_secret.secrets[i]]
}
And here is the module from my template:
locals {
secrets_map = {
appinsights-key = module.app_insights.app_insights_instrumentation_key
storage-account-key = module.storage_account.primary_access_key
}
output_secret_map = {
for secret in module.keyvault_secrets.keyvault_secret_attributes :
secret.name => secret.id
}
}
module "keyvault" {
source = "../../modules/azure/keyvault"
keyvault_name = local.kv_name
resource_group_name = azurerm_resource_group.app_rg.name
}
module "keyvault_secrets" {
source = "../../modules/azure/keyvault-secret"
keyvault_id = module.keyvault.keyvault_id
secrets = local.secrets_map
}
module "app_service_keyvault_access_policy" {
source = "../../modules/azure/keyvault-policy"
vault_id = module.keyvault.keyvault_id
tenant_id = module.app_service.app_service_identity_tenant_id
object_ids = module.app_service.app_service_identity_object_ids
key_permissions = ["get", "list"]
secret_permissions = ["get", "list"]
certificate_permissions = ["get", "list"]
}
Using Terraform for provisioning and managing a keyvault with that kind of limitations sounds like a bad idea. Terraforms main idea is to monitor the state of your resources - if it is not allowed to read the resource it becomes pretty useless. Your problem is not even that Terraform is trying to update something, it fails because it wants to check the current state of your resource and fails.
If your goal is just to create secrets in a keyvault, I would just us the az keyvault commands like this:
az login
az keyvault secret set --name mySecret --vault-name myKeyvault --value mySecretValue
An optimal solution would of course be that your service principal that you use for executing Terrafom commands has the sufficient rights to perform the actions it was created for.
I know this is a late answer, but for future visitors:
The pipeline running the Terraform Plan and Apply will need to have proper access to the key vault.
So, if you are running your CI/CD from Azure Pipelines, you would typically have a service connection that your pipeline uses for authentication.
The service connection you use for Terraform is most likely based on a service principal that has contributor rights (at least at resource group level) for it to provisioning anything at all.
If that is the case, then you must add a policy giving that same service principal (Use the Service Principals Enterprise Object Id) to have at least list, get and set permissions for secrets.

Unable to get folder by id when using Boxr JWT get_user_token- Box API

I'm unable to a folder by providing an id to that folder using Boxr gem. Previously I didn't has the enterprise settings as shown in this post which I have now fixed. I'm creating a token using JWT authentication get_user_token method the following way.
token = Boxr::get_user_token("38521XXXX", private_key: ENV.fetch('JWT_PRIVATE_KEY'), private_key_password: ENV.fetch('JWT_PRIVATE_KEY_PASSWORD'), public_key_id: ENV.fetch('JWT_PUBLIC_KEY_ID'), client_id: ENV.fetch('BOX_CLIENT_ID'), client_secret: ENV.fetch('BOX_CLIENT_SECRET'))
I then pass this this token when creating a client.
client = Boxr::Client.new(token)
when I check the current user on client this is what I get:
client.current_user
=> {"type"=>"user",
"id"=>"60853XXXX",
"name"=>"OnlineAppsPoC",
"login"=>"AutomationUser_629741_06JgxiPtPj#boxdevedition.com",
"created_at"=>"2018-10-04T08:41:32-07:00",
"modified_at"=>"2018-10-04T08:41:50-07:00",
"language"=>"en",
"timezone"=>"America/Los_Angeles",
"space_amount"=>10737418240,
"space_used"=>0,
"max_upload_size"=>2147483648,
"status"=>"active",
"job_title"=>"",
"phone"=>"",
"address"=>"",
"avatar_url"=>"https://app.box.com/api/avatar/large/6085300897"}
When I run client.methods I see there is folder_from_id however when I call that method I get the following error:
pry(#<FormsController>)> client.folder_from_id("123456", fields: [])
Boxr::BoxrError: 404: Not Found
from /usr/local/bundle/gems/boxr-1.4.0/lib/boxr/client.rb:239:in `check_response_status'
I have the following settings:
I also authorize the application. Not sure what else to do.
token = Boxr::get_user_token(user_id,
private_key: ENV.fetch('JWT_PRIVATE_KEY'),
private_key_password: ENV.fetch('JWT_PRIVATE_KEY_PASSWORD'),
public_key_id: ENV.fetch('JWT_PUBLIC_KEY_ID'),
client_id: ENV.fetch('BOX_CLIENT_ID'),
client_secret: ENV.fetch('BOX_CLIENT_SECRET'))
client = Boxr::Client.new(token.access_token)
folder = client.folder_from_id(folder_id)
client.upload_file(file_path, folder)
For anybody using C# and BOXJWT.
You just need to have a boxManager set up and will get you with anything you need, say BoxFile, Folder etc.
If you have the folderID, well & good, but if you need to retrieve, this can be done as shown below:
string inputFolderId = _boxManager.GetFolder(RootFolderID).Folders.Where(i => i.Name == boxFolder).FirstOrDefault().Id; //Retrieves FolderId
Folder inputFolder = _boxManager.GetFolder(inputFolderId);

How can I open a facebook.session with access token and permissions in android?

How can I open a session with the specified permission?
I open a com.facebook.Session with API Session#openActiveSessionWithAccessToken() in an android.app.Service.
And then the opened session is used to get me/friendrequests by sending a request.
It results in an error as below:
{HttpStatus: 403, errorCode: 289, errorType: OAuthException, errorMessage: (#289) Requires extended permission: read_requests} ;
The permissions retrieved by using mSession.getPermissions() before creating the requests are as follows:
[read_requests, read_mailbox, manage_notifications]
Could you tell me what's wrong with my code?
Or could you tell me what should I do?
Code:
private static final List<String> PERMISSIONS = Arrays.asList("read_requests", "read_mailbox", "manage_notifications");
....
AccessToken token =
AccessToken.createFromExistingAccessToken(mAccount.getAccessToken(), new Date(mAccount.getExpireTime()), null,
AccessTokenSource.CLIENT_TOKEN, PERMISSIONS);
mSession = Session.openActiveSessionWithAccessToken(mContext, token, new StatusCallback(){
#Override
public void call(Session aSession, SessionState aState, Exception aException) {
if (aException != null) {
Log.i(Log.Tag.OTHER, TAG + "#createSession#call " + aException.getMessage());
}
//getNewInfos();
}
});
I have solved this problem.

How to validate credentials in EWS Java API

I am using EWSJavaAPI 1.1.5. I am trying to login with invalid credentials, but I don't get any exceptions.
Please advise how to detect and handle invalid login.
Here is my code:
String host = "myhost";
ExchangeService service = null;
try {
service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials("wrongemail",
"wrongpass");
service.setCredentials(credentials);
service.setUrl(new java.net.URI("https://" + host
+ "/EWS/Exchange.asmx"));
} catch (Exception e) {
e.printStackTrace();
}
Found it, i had to bind the service to a folder:
Folder.bind(service, WellKnownFolderName.Inbox);
and if the credentials are wrong, HttpErrorException is thrown.

Resources