title: Google API Node.js Library - Grant Role to service account at project level
body: <h1>Goal</h1>
  <p>Assign a role <code>dialogflow.admin</code> to a service account I created for a project using the Node.js Client library for Google APIs.</p>
  <h1>Issue</h1>
  <p>When I try to update my service accounts IAM Policy and add a role to the service account. I get an error that the role is not supported for this resource type.</p>
  <p>I am trying to give my service account the <strong>Dialogflow API Admin Role</strong> <code>roles/dialogflow.admin</code></p>
  <p>The method in the Node.js client library I am using is <code>iam.projects.serviceAccounts.setIamPolicy</code>.</p>
  <p>I have already managed to create the service account with this Node.js client library with a function shown here.</p>
  <pre><code>async function createServiceAccount(projectID, serviceAccountID){
      const authClient = await auth.getClient();
      var request = {
          name: &quot;projects/&quot;+projectID,
          resource: {
          &quot;accountId&quot;: serviceAccountID,
          &quot;serviceAccount&quot;: {
              &quot;description&quot; : &quot;Service Account for project: &quot;+projectID+&quot; for DialogFlow authentication with VA&quot;,
              &quot;displayName&quot;: &quot;VA Dialogflow Service Account &quot;+projectID
          }
        },
        
        auth: authClient,
      };
    
      await iam.projects.serviceAccounts.create(request, function(err, response) {
        if (err) {
          console.error(err);
          return;
        }
         console.log(JSON.stringify(response, null, 2));
      });
  }
  </code></pre>
  <p>after this function runs, and I am sure the service account is created, I run my <strong>function that is meant to set the roles of this service account.</strong></p>
  <pre><code>async function setServiceAccountRoles(projectID, serviceAccountID){
      const authClient = await auth.getClient();
      var request = {
          resource_: &quot;projects/&quot;+projectID+&quot;/serviceAccounts/&quot;+serviceAccountID,
          resource: {
              policy: {
                  bindings: [
                      {
                          // role: &quot;projects/&quot;+projectID+&quot;roles/dialogflow.admin&quot;,
                          role: &quot;roles/dialogflow.admin&quot;,
                          &quot;members&quot;: [
                              &quot;serviceAccount:&quot;+serviceAccountID
                          ]
                      }
                      ],
                      version: 1
              }
          },
        
        auth: authClient,
      };
    
      await iam.projects.serviceAccounts.setIamPolicy(request, function(err, response) {
        if (err) {
          console.error(err);
          return;
        }
         console.log(JSON.stringify(response, null, 2));
      });
  }
  </code></pre>
  <h2>Error</h2>
  <p>When I run this function I am give this error:</p>
  <pre><code>  code: 400,
    errors: [
      {
        message: 'Role roles/dialogflow.admin is not supported for this resource.',
        domain: 'global',
        reason: 'badRequest'
      }
    ]
  </code></pre>
  <p>I have used these following resources to get this far:
  <a href="https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts/setIamPolicy" rel="nofollow noreferrer">https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts/setIamPolicy</a></p>
  <p><a href="https://cloud.google.com/iam/docs/reference/rest/v1/Policy" rel="nofollow noreferrer">https://cloud.google.com/iam/docs/reference/rest/v1/Policy</a></p>
  <p><a href="https://cloud.google.com/iam/docs/granting-changing-revoking-access#granting_access_to_a_service_account_for_a_resource" rel="nofollow noreferrer">https://cloud.google.com/iam/docs/granting-changing-revoking-access#granting_access_to_a_service_account_for_a_resource</a></p>
  <h2>Alternative methods.</h2>
  <p>I have tried changing the role to a project specific path like this:</p>
  <pre><code>async function setServiceAccountRoles(projectID, serviceAccountID){
      const authClient = await auth.getClient();
      var request = {
          resource_: &quot;projects/&quot;+projectID+&quot;/serviceAccounts/&quot;+serviceAccountID,
          resource: {
              policy: {
                  bindings: [
                      {
                          role: &quot;projects/&quot;+projectID+&quot;roles/dialogflow.admin&quot;,
                          &quot;members&quot;: [
                              &quot;serviceAccount:&quot;+serviceAccountID
                          ]
                      }
                      ],
                      version: 1
              }
          },
        
        auth: authClient,
      };
    
      await iam.projects.serviceAccounts.setIamPolicy(request, function(err, response) {
        if (err) {
          console.error(err);
          return;
        }
         console.log(JSON.stringify(response, null, 2));
      });
  }
  </code></pre>
  <p>however, with this I get the error : <code>message: &quot;Role (projects/va-9986d601/roles/dialogflow.admin) does not exist in the resource's hierarchy.&quot;,</code></p>
  <p>Is it possible that the only way to update my service account's roles and permission is through the console or gcloud commands? If so, is there any recommended ways of running said gcloud commands through the node.js client library or from a node application itself?</p>