turbot / steampipe-plugin-googledirectory

Use SQL to instantly query users, groups, domains and more from Google Directory. Open source CLI. No DB required.
https://hub.steampipe.io/plugins/turbot/googledirectory
Apache License 2.0
11 stars 1 forks source link

Connection config: support ADC & service account impersonation #30

Closed chr-b closed 2 years ago

chr-b commented 2 years ago

Is your feature request related to a problem? Please describe. I am running Steampipe with googledirectory from within a GCP environment, so there is no need for exporting the service account key as JSON file for connection establishment. Also, the service account I am using to run Steampipe has to impersonate another service account so it can access Google Directory APIs.

Describe the solution you'd like 1) The credential_file connection parameter should be optional. If it is not provided, the Application Default Credential (ADC) should be used. 2) Provide an additional, optional impersonate_service_account parameter for the connection config. If specified, the plugin will make API calls using service account impersonation.

Describe alternatives you've considered Generating and exporting service account keys as JSON should be avoided, for security reasons (key files have the risk of being leaked).

Additional context The Steampipe GCP plugin supports both ADC and service account impersonation: see connection_config.go and utils.go.

The Steampipe Google Workspace plugin also supports ADC. See connection_config.go and service.go.

rajlearner17 commented 2 years ago

@chr-b Appreciate trying out Steampipe!!

Thanks for the valuable suggestions. We are checking this out, the update will be provided by respective team members. CC @cbruno10 @LalitTurbot

cbruno10 commented 2 years ago

Hey @chr-b , we added support for ADC + user impersonation creds in https://github.com/turbot/steampipe-plugin-googledirectory/commit/dc01edbe806d505a0a17979bd9d451e71eeb50e1. We're planning on releasing this next week, but if you have a chance to try it out and have any feedback, please let us know!

I'll close this issue now, but please re-open if you run into any issues or have questions.

chr-b commented 2 years ago

Sorry for the late response. Is this in the v0.2.0 release? If yes, I will test it soon.

cbruno10 commented 2 years ago

@chr-b Yes, it's available in v0.2.0. Please let us know how you go!

chr-b commented 2 years ago

Application Default Credentials work!

Unfortunately, service account impersonation does not. I don't see any relevant changes in dc01edbe806d505a0a17979bd9d451e71eeb50e1 either.

Result: googleapi: Error 403: Not Authorized to access this resource/api, forbidden (SQLATETE HV000)

The other service account does have sufficient permissions. And no, putting the service account email into the impersonated_user_email config option will not help.

Subhajit97 commented 2 years ago

Hey @chr-b, thanks for verifying the changes. Great to hear that ADC is working for you! sorry you're running into issues! just to confirm few things,

chr-b commented 2 years ago

Hi @Subhajit97 ,

  1. No, there is no domain-wide delegation enabled. Because a custom read-only role has been directly assigned to the service account. See https://support.google.com/a/answer/2406043
  2. Assigned scope: https://www.googleapis.com/auth/admin.directory.user.readonly
  3. Query: select full_name, id, primary_email from googledirectory_user where primary_email = 'user@my-domain.com';
  4. This whole setup is working when directly calling the Google API using a Python script and the Google SDKs. IIRC the HTTP endpoint is https://admin.googleapis.com/admin/directory/v1/users
Subhajit97 commented 2 years ago

hi @chr-b, sorry currently our plugin supports authentication using Domain-Wide Delegation, where user impersonation is required. We have tried to reproduce your scenario, but got a different error. Below is steps I followed in the process:

On running below query in steampipe I am getting error:

Error: Get "https://admin.googleapis.com/admin/directory/v1/users?alt=json&customer=my_customer&maxResults=500&prettyPrint=false&query=": impersonate: status code 403: {
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED"
  }
}

Can you please share some info about your setup, so that we can reproduce the same. Also if you can share some code snippet from your python script will be helpful, thanks.

chr-b commented 2 years ago

Hi, The basic setup is identical to mine: GCP service account with assigned custom role that grants the Admin API privilege Users - Read.

The Python code is:

from google.auth import default as default_cred
from google.auth import impersonated_credentials
from googleapiclient.discovery import build
from urllib.error import HTTPError
import json

# Credential setup
SCOPES = [ 'https://www.googleapis.com/auth/admin.directory.user.readonly' ]
credentials, project_id = default_cred(scopes=SCOPES)
target_credentials = credentials

# query Google Directory API
service = build('admin', 'directory_v1', credentials=target_credentials)
users = service.users()
request = users.list(domain='{{inputs.parameters.domain}}')
try:
  response = request.execute()
except HTTPError as e:
  print('Error response status code : {0}, reason : {1}'.format(e.status_code, e.error_details))
  exit(1)

print(json.dumps(response))
service.close()
Subhajit97 commented 2 years ago

hi @chr-b, sorry for the super late response. Did you find any workaround on this, or is it still a blocker for you?

Just wanted to confirm when you say, I am running Steampipe with googledirectory from within a GCP environment, does this mean you are running Steampipe locally with GCP credentials, or are you trying to run it within a GCP instance (or somewhere else in GCP)?

Also, can you please share your ~/.steampipe/config/googledirectory.spc file that you are using (with any sensitive information removed)?

Thanks!

chr-b commented 2 years ago

Hi @Subhajit97 ,

My workaround is to use the Python SDK to fetch this data, instead of using Steampipe.

The execution environment is a container inside GCP GKE, with a GCP service account assigned to it. I am afraid I don't have the .spc flie availble any more.

cbruno10 commented 2 years ago

@chr-b We're closing this issue as you mentioned you're using the Python SDK for now. If you see any other issues though, feel free to re-open this one or create a new issue, thanks!