Stay organized with collections
Save and categorize content based on your preferences.
You can use service accounts in your Community Connectors for centralized
management of resource access. A common use case would be to delegate access to
data that users would not able to access using their own credentials.
You can implement your own access control layer in your connector.
You can delegate access to data or resources that the user's credentials
does not have access to.
Implementation steps
Create a service account for the platform from which you are fetching data.
Provide the necessary permissions to the service account so it can access
required resources.
Store the service account's credentials in your connector's script
properties.
During connector execution, use the stored credentials to fetch required
data.
Optional: Implement access control logic to filter the data.
Example: Accessing BigQuery with Looker Studio Advanced Services and a service account
You are building a solution where your users will build dashboards from a
BigQuery table. If your users use Looker Studio's BigQuery connector, they will
need read access to the BigQuery table. They will also require a billing account
for Google Cloud Platform (GCP). The following steps illustrate how to use a
service account to consolidate billing and delegate access to the BigQuery data.
For your getData function, authenticate the service account and generate
an access token. Set the OAuth2 scope to
https://www.googleapis.com/auth/bigquery.readonly.
Return access token with other configuration items in getData response.
The following is a complete example of the connector code:
main.js
varcc=DataStudioApp.createCommunityConnector();varscriptProperties=PropertiesService.getScriptProperties();functionisAdminUser(){returntrue;}functiongetAuthType(){varAuthTypes=cc.AuthType;returncc.newAuthTypeResponse().setAuthType(AuthTypes.NONE).build();}functiongetConfig(request){varconfig=cc.getConfig();config.newInfo().setId('generalInfo').setText('This is an example connector to showcase row level security.');returnconfig.build();}functiongetFields(){varfields=cc.getFields();vartypes=cc.FieldType;varaggregations=cc.AggregationType;fields.newDimension().setId('region').setName('Region').setType(types.TEXT);fields.newMetric().setId('sales').setName('Sales').setType(types.NUMBER).setAggregation(aggregations.SUM);fields.newDimension().setId('date').setName('Date').setType(types.YEAR_MONTH_DAY);returnfields;}functiongetSchema(request){return{schema:getFields().build()};}varSERVICE_ACCOUNT_CREDS='SERVICE_ACCOUNT_CREDS';varSERVICE_ACCOUNT_KEY='private_key';varSERVICE_ACCOUNT_EMAIL='client_email';varBILLING_PROJECT_ID='project_id';/** * Copy the entire credentials JSON file from creating a service account in GCP. */functiongetServiceAccountCreds(){returnJSON.parse(scriptProperties.getProperty(SERVICE_ACCOUNT_CREDS));}functiongetOauthService(){varserviceAccountCreds=getServiceAccountCreds();varserviceAccountKey=serviceAccountCreds[SERVICE_ACCOUNT_KEY];varserviceAccountEmail=serviceAccountCreds[SERVICE_ACCOUNT_EMAIL];returnOAuth2.createService('RowLevelSecurity').setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth').setTokenUrl('https://accounts.google.com/o/oauth2/token').setPrivateKey(serviceAccountKey).setIssuer(serviceAccountEmail).setPropertyStore(scriptProperties).setCache(CacheService.getScriptCache()).setScope(['https://www.googleapis.com/auth/bigquery.readonly']);}varBASE_SQL='SELECT d.region, d.sales, d.date '+'FROM `datastudio-solutions.row_level_security.data` d '+'INNER JOIN `datastudio-solutions.row_level_security.access` a '+'ON d.region = a.region '+'where a.email=@email';functiongetData(request){varaccessToken=getOauthService().getAccessToken();varserviceAccountCreds=getServiceAccountCreds();varbillingProjectId=serviceAccountCreds[BILLING_PROJECT_ID];varemail=Session.getEffectiveUser().getEmail();varbqTypes=DataStudioApp.createCommunityConnector().BigQueryParameterType;returncc.newBigQueryConfig().setAccessToken(accessToken).setBillingProjectId(billingProjectId).setUseStandardSql(true).setQuery(BASE_SQL).addQueryParameter('email',bqTypes.STRING,email).build();}
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-09-18 UTC."],[[["\u003cp\u003eCommunity Connectors can utilize service accounts for centralized resource access management, enabling data access delegation beyond user credentials.\u003c/p\u003e\n"],["\u003cp\u003eService accounts offer benefits like consolidated billing, custom access control implementation, and access to otherwise restricted data or resources.\u003c/p\u003e\n"],["\u003cp\u003eImplementing service accounts involves creating a dedicated account, granting necessary permissions, securely storing credentials in script properties, and utilizing these during connector execution.\u003c/p\u003e\n"],["\u003cp\u003eFor enhanced security, avoid storing service account credentials directly in code; instead, leverage connector script properties to safeguard sensitive information.\u003c/p\u003e\n"],["\u003cp\u003eThe provided example demonstrates using a service account with Looker Studio Advanced Services for secure and controlled access to BigQuery data, consolidating billing and delegating access efficiently.\u003c/p\u003e\n"]]],[],null,["# Use a service account\n\nYou can use service accounts in your Community Connectors for centralized\nmanagement of resource access. A common use case would be to delegate access to\ndata that users would not able to access using their own credentials.\n\nReview [Understanding service accounts](https://cloud.google.com/iam/docs/understanding-service-accounts) to familiarize yourself with the topic.\n\nBenefits\n--------\n\n- You can consolidate billing for data access.\n- You can implement your own access control layer in your connector.\n- You can delegate access to data or resources that the user's credentials does not have access to.\n\nImplementation steps\n--------------------\n\n1. Create a service account for the platform from which you are fetching data.\n2. Provide the necessary permissions to the service account so it can access required resources.\n3. Store the service account's credentials in your connector's script properties.\n4. During connector execution, use the stored credentials to fetch required data.\n5. *Optional*: Implement access control logic to filter the data.\n\n| **Caution:** Do not store the service account's credentials in your code. Instead use the connector's script properties to ensure that other users with view access to your code (either via Apps Script or via external code repository) cannot see the credentials.\n\nExample: Accessing BigQuery with Looker Studio Advanced Services and a service account\n--------------------------------------------------------------------------------------\n\nYou are building a solution where your users will build dashboards from a\nBigQuery table. If your users use Looker Studio's BigQuery connector, they will\nneed read access to the BigQuery table. They will also require a billing account\nfor Google Cloud Platform (GCP). The following steps illustrate how to use a\nservice account to consolidate billing and delegate access to the BigQuery data.\n\n1. [Create a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating_a_service_account) in your desired GCP project.\n2. Ensure the service account can create BigQuery jobs and view the data for the required table. See [BigQuery Access Control](https://cloud.google.com/bigquery/docs/access-control) for details.\n3. [Create a key for the service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating_service_account_keys) and store the credentials in your connector's [script properties](/apps-script/reference/properties/properties).\n4. Include the [OAuth2 Apps Script](https://github.com/googleworkspace/apps-script-oauth2#setup) library in your Apps Script project.\n5. For your [`getData`](/looker-studio/connector/reference#getdata) function, authenticate the service account and generate an access token. Set the OAuth2 scope to `https://www.googleapis.com/auth/bigquery.readonly`.\n6. Return access token with other configuration items in `getData` response.\n\n#### The following is a complete example of the connector code:\n\nmain.js \n\n```transact-sql\nvar cc = DataStudioApp.createCommunityConnector();\nvar scriptProperties = PropertiesService.getScriptProperties();\n\nfunction isAdminUser() {\n return true;\n}\n\nfunction getAuthType() {\n var AuthTypes = cc.AuthType;\n return cc\n .newAuthTypeResponse()\n .setAuthType(AuthTypes.NONE)\n .build();\n}\n\nfunction getConfig(request) {\n var config = cc.getConfig();\n\n config\n .newInfo()\n .setId('generalInfo')\n .setText('This is an example connector to showcase row level security.');\n\n return config.build();\n}\n\nfunction getFields() {\n var fields = cc.getFields();\n var types = cc.FieldType;\n var aggregations = cc.AggregationType;\n\n fields\n .newDimension()\n .setId('region')\n .setName('Region')\n .setType(types.TEXT);\n\n fields\n .newMetric()\n .setId('sales')\n .setName('Sales')\n .setType(types.NUMBER)\n .setAggregation(aggregations.SUM);\n\n fields\n .newDimension()\n .setId('date')\n .setName('Date')\n .setType(types.YEAR_MONTH_DAY);\n\n return fields;\n}\n\nfunction getSchema(request) {\n return {schema: getFields().build()};\n}\n\nvar SERVICE_ACCOUNT_CREDS = 'SERVICE_ACCOUNT_CREDS';\nvar SERVICE_ACCOUNT_KEY = 'private_key';\nvar SERVICE_ACCOUNT_EMAIL = 'client_email';\nvar BILLING_PROJECT_ID = 'project_id';\n\n/**\n * Copy the entire credentials JSON file from creating a service account in GCP.\n */\nfunction getServiceAccountCreds() {\n return JSON.parse(scriptProperties.getProperty(SERVICE_ACCOUNT_CREDS));\n}\n\nfunction getOauthService() {\n var serviceAccountCreds = getServiceAccountCreds();\n var serviceAccountKey = serviceAccountCreds[SERVICE_ACCOUNT_KEY];\n var serviceAccountEmail = serviceAccountCreds[SERVICE_ACCOUNT_EMAIL];\n\n return OAuth2.createService('RowLevelSecurity')\n .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')\n .setTokenUrl('https://accounts.google.com/o/oauth2/token')\n .setPrivateKey(serviceAccountKey)\n .setIssuer(serviceAccountEmail)\n .setPropertyStore(scriptProperties)\n .setCache(CacheService.getScriptCache())\n .setScope(['https://www.googleapis.com/auth/bigquery.readonly']);\n}\n\nvar BASE_SQL =\n 'SELECT d.region, d.sales, d.date ' +\n 'FROM `datastudio-solutions.row_level_security.data` d ' +\n 'INNER JOIN `datastudio-solutions.row_level_security.access` a ' +\n 'ON d.region = a.region ' +\n 'where a.email=@email';\n\nfunction getData(request) {\n var accessToken = getOauthService().getAccessToken();\n var serviceAccountCreds = getServiceAccountCreds();\n var billingProjectId = serviceAccountCreds[BILLING_PROJECT_ID];\n var email = Session.getEffectiveUser().getEmail();\n\n var bqTypes = DataStudioApp.createCommunityConnector().BigQueryParameterType;\n\n return cc\n .newBigQueryConfig()\n .setAccessToken(accessToken)\n .setBillingProjectId(billingProjectId)\n .setUseStandardSql(true)\n .setQuery(BASE_SQL)\n .addQueryParameter('email', bqTypes.STRING, email)\n .build();\n}\n```"]]