Eric G
Eric G

Reputation: 1292

Google Task Queue auth from service account vs installed app credentials

Summary: Using installed (native) application credentials, I am able to authorize and use a pull task queue -- using OAuth2 and the REST API v1beta2. This is OK, but I would prefer to authorize and use the task queue under a service account, since using installed app credentials requires me to use my own email address in the task queue ACLs (see below). However, when I authorize using a service account (2-legged Oauth2), after adding the service account email address to the queue ACL, I am getting permissions errors using the queue. Is there a way to use a task queue under a service account, from a native client application?

Details: I was a bit confused about the task queue ACL, which specifies permissions using an email address -- and installed app credentials don't seem to have an associated email address. But basically it uses whatever google account you are logged into in the browser when you first authorize via 3-legged OAuth. So when I include my own email address under the queue ACL, it works fine:

queue:
- name: my-queue
  mode: pull
  acl:
  - user_email: [email protected]
  - writer_email: [email protected]

But if I add my service account email address the same way, and authorize using the service account, I get an error 403: you are not allowed to make this api call.

queue:
- name: my-queue
  mode: pull
  acl:
  - user_email: [email protected]
  - writer_email: [email protected]

I have double-checked the service email address is correct, and tried quoting it in the queue.yaml file, get the same error.

This indicates to me that the task queue doesn't associate my authorization with the service account email address for some reason. Either it doesn't like 2-legged OAuth, or something else?

Note that the service-account authorization itself does work (ruby code below), it's the subsequent API call that doesn't, and clearly the ACL permissions is the immediate cause of the error.

# issuer == service account email address

def service_auth!(issuer, p12_file)
  key = Google::APIClient::KeyUtils.load_from_pkcs12(p12_file, 'notasecret')
  client.authorization = Signet::OAuth2::Client.new(
    :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
    :audience => 'https://accounts.google.com/o/oauth2/token',
    :scope => 'https://www.googleapis.com/auth/prediction',
    :issuer => issuer,
    :signing_key => key)
  client.authorization.fetch_access_token!

  api = client.discovered_api(TASKQUEUE_API, TASKQUEUE_API_VERSION)

  return client, api
end

Upvotes: 0

Views: 289

Answers (1)

Adam
Adam

Reputation: 6015

I think the issue may just be your scope ('https://www.googleapis.com/auth/prediction').

I'm able to authorize and make calls to the TaskQueue API using a service account without any issues. My example is in Python however (sorry I am not a Rubyist):

queue.yaml:

queue:
- name: pull
  mode: pull
  retry_parameters:
    task_retry_limit: 5
  acl:
  - user_email: [email protected]
  - writer_email: [email protected]

source:

client_email = '[email protected]'

with open('service_account.p12', 'rb') as f:
  private_key = f.read()

credentials = SignedJwtAssertionCredentials(client_email, private_key,
    ['https://www.googleapis.com/auth/taskqueue',
     'https://www.googleapis.com/auth/taskqueue.consumer'])

http = httplib2.Http()
http = credentials.authorize(http)

api = build('taskqueue', 'v1beta2', http=http)   

# Do stuff with api ...

Upvotes: 1

Related Questions