403: Permission iam.serviceAccounts.create is required to perform this operation on project projects/xyz

Viewed 12699

I am trying to create a ServiceAccount using Google cloud api. I am an Oauth client to authenticate on behalf of an user. I am using the correct scope. I am still getting the error 403: Permission iam.serviceAccounts.create is required to perform this operation on project projects/xyz.

This code used to work before. I saw that the new docs also mention this; https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/create

My question is what am I doing wrong. How do I fix this issue?

5 Answers

To allow a user to manage Service Accounts, grant one of the following roles:

  • Service Account User (roles/iam.serviceAccountUser): Grants permissions to get, list, or impersonate a service account.
  • Service Account Admin (roles/iam.serviceAccountAdmin): Includes Service Account User permissions and also grants permissions to create, update, delete, and set or get the Cloud IAM policy on a service account.

According to the question, to create a service account, at minimum the user must be granted the Service Account Admin role (roles/iam.serviceAccountAdmin) or the Editor primitive role (roles/editor).

Since you have not provided the code, please do the following.

  1. Check whether your service account has the above role. If not, please add them
  2. Check whether you have provided the GOOGLE_APPLICATION_CREDENTIALS correctly.
  3. Based on your programming language, try the example code given here.

This is really old but for others, this is likely caused by previous failed attempts. This bug STILL exists, even a year later, in which previous failed attempts seem to propagate this error. If you change the name of the service account it generally works.

In my case, the issue was that I was using the project number instead of the project ID. Oddly enough, I was able to create many resources (VMs, DNS, network,...); and this became an issue only when creating service accounts.

Like you said, the same code worked earlier. That means someone revoked some role/permission from that user being used to create a new service account.

You can look at all the roles assigned to your user. You can add the appropriate role which has iam.serviceAccounts.create permission or you can also create a custom role manually adding this permission to it and then assigning it to the user.

1.Install GoogleCloud SDK for windows 2.After successfully providing the credentials, you can check in at the location C:\Users"yourusername"\AppData\Roaming\gcloud\legacy_credentials"youremail"\adc.json . You can find the credentials stored in the JSON format there 3.Create project GoogleCloud 2.Create ServiceAccount

 using System;
using System.Threading.Tasks;

using Google.Apis.Auth.OAuth2;
using Google.Apis.CloudResourceManager.v1;
using Google.Apis.Services;

using Data = Google.Apis.CloudResourceManager.v1.Data;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;
 using System.Threading;

  namespace CloudResourceManager
 {
   public class Program
  {
    private const string projectId = "notificatgfions-sample";
    private const string applicationName = "tespopety-gamannnjeta";
    private static IamService _service;

    public static void Main(string[] args)
    {
        CreateProject();
        CreateServiceAccount(projectId, applicationName, 
 "Testytytoppwner");
    }

    public static void CreateServiceAccount(string projectId,
    string name, string displayName)
    {
        CancellationToken canTok = new CancellationToken();
        var credential = Task.Run(async
            () => await GoogleCredential.FromFileAsync("adc.json", 
canTok)
        ).Result;
        if (credential.IsCreateScopedRequired)
        {
            credential = 
   credential.CreateScoped(IamService.Scope.CloudPlatform); ;
        }
        _service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });
        var pol = _service.IamPolicies;
        var request = new CreateServiceAccountRequest
        {

            AccountId = name,
            ServiceAccount = new ServiceAccount
            {
                DisplayName = displayName
            }
        };
        var serviceAccount = _service.Projects.ServiceAccounts.Create(
            request, "projects/" + projectId).Execute();
        Console.WriteLine("Created service account: " + serviceAccount.Email);
        EnableServiceAccount(serviceAccount.Email);


    }
    public static void DeleteServiceAccount(string email)
    {
        var credential = GoogleCredential.FromFile("adc.json")
            .CreateScoped(IamService.Scope.CloudPlatform);
        _service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        string resource = "projects/-/serviceAccounts/" + email;
        _service.Projects.ServiceAccounts.Delete(resource).Execute();
        Console.WriteLine("Deleted service account: " + email);
    }
    public static void EnableServiceAccount(string email)
    {
        //var credential = GoogleCredential.FromFile("adc.json")
        //    .CreateScoped(IamService.Scope.CloudPlatform);
        //_service = new IamService(new IamService.Initializer
        //{
        //    HttpClientInitializer = credential
        //});

        var request = new EnableServiceAccountRequest();

        string resource = "projects/-/serviceAccounts/" + email;
        _service.Projects.ServiceAccounts.Enable(request, resource).Execute();
        Console.WriteLine("Enabled service account: " + email);
    }

    private static void CreateProject()
    {
        //Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", @"C:\apikey.json");
        //string Pathsave = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
        var scopes = new string[] {
            CloudResourceManagerService.Scope.CloudPlatform
        };
        GoogleCredential credential = Task.Run(
            () => GoogleCredential.FromFile("adc.json")
        ).Result;

        if (credential.IsCreateScopedRequired)
        {
            credential = credential.CreateScoped(scopes);
        }
        CloudResourceManagerService service = new CloudResourceManagerService(
            new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = applicationName
            }
        );

        Console.WriteLine("1. Create Project");
        Data.Operation operation1 = service.Projects.Create(
            new Data.Project()
            {
                ProjectId = projectId,
            }
        ).Execute();
        Console.Write("2. Awaiting Operation Completion");
        Data.Operation operation2;
        do
        {
            operation2 = service.Operations.Get(operation1.Name).Execute();
            Console.WriteLine(operation2.Done.ToString());
            System.Threading.Thread.Sleep(1000);
        } while (operation2.Done != true);

        Console.WriteLine();
        Console.WriteLine("Enter to continue");
        Console.ReadLine();

        Console.WriteLine("3. Deleting Project");
        var operation3 = service.Projects.Delete(projectId).Execute();
    }
}

}

Related