pythongoogle-cloud-platform

How do I add share drive access to a google service account


All the documentation and google's support chat bot doesn't seem to be able to answer this simple question. How do I add share drive access to a service account? I am able to authenticate using python but I get this error when trying to create a folder. I've tried impersonating a user who has access, I also enabled domain-wide delegation in the workspace, adding the email from the service account to a group that has access to the shared drive and I have had no luck. Different pages point to adding roles in the IAM menu but nothing related to Google Drive appears in permissions that can be added.

Authentication code:

def authenticate_google_drive():
    creds = Credentials.from_service_account_file(
        "config/service-credentials.json", scopes=["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/drive.file"]
    )

    service = build("drive", "v3", credentials=creds)
    return service

Create folder code:

def create_folder(service, folder_name, parent_folder_id=None):

    file_metadata = {
        "name": folder_name,
        "mimeType": "application/vnd.google-apps.folder",
    }

    if parent_folder_id:
         file_metadata["parents"] = [parent_folder_id]

    folder = (
        service.files()
        .create(body=file_metadata, supportsAllDrives=True, fields="id")
        .execute()
    )

    return folder.get("id")

Error:

googleapiclient.errors.HttpError: <HttpError 404 when requesting https://www.googleapis.com/drive/v3/files?supportsAllDrives=true&fields=id&alt=json returned "File not found: <FOLDER_ID>.". Details: "[{'message': 'File not found: <FOLDER_ID>.', 'domain': 'global', 'reason': 'notFound', 'location': 'fileId', 'locationType': 'parameter'}]">

Solution

  • To solve the issue I was having I needed to use a delegated account. I couldn't add the service account email directly due to workspace limitations but it was able to act under an email in the workspace

        credentials = service_account.Credentials.from_service_account_file(
            path.join(path.dirname(__file__), "config", "credentials.json"),
            scopes=scopes,
        )
    
        delegated_creds = credentials.with_subject("email@domain.com")
        self.service = build("drive", "v3", credentials=delegated_creds)