Skip to main content

Guide: Fetching Google Groups during authentication

Before You Start

Obtaining the Google Groups a user belongs to is useful in a number of situations. In particular, using Google Groups to make authorization decisions is increasingly common among organizations. Whether you are using Gate to make authorization decisions or adopting a different approach, SlashID allows you to retrieve Google Groups for a given user.

Google doesn't expose an OAuth scope to obtain the user groups as part of the OIDC flow. In order to obtain the groups a user belongs to in Google, you need to enable the Google Admin SDK API and create a service account. This guide will take you through the steps for creating those credentials and enabling Google Groups retrieval with SlashID.

Enabling the Admin SDK API

First, log in to the GCP Console, and select the project you want to use, or create a new project.

Select a project

Next, make sure you have the appropriate administrator permissions and enable the Admin SDK API here.

If you have the right permissions, you should see the following after the SDK has been enabled: Select APIs and Services

Create a service account with Domain-wide delegation

First, head to the IAM & Admin section and select "Create Service Account" in the navigation menu.

Create Service Account

Assign a name of your choice such as "groups-retrieval" to the service account and click "Done".

Service Account

Next you'll be redirected back to the previous page. Select the service account just created and expand the "Advanced Settings" section. Make a note of the Client ID and click on the "View Google Workspace Admin Console".

Service Account Detail

You'll be redirected to admin.google.com. Once you are logged in, select "Security > Access and data control > API Controls" from the navigation menu on the left-hand side and click on "Manage Domain Wide Delegation".

Admin Panel

You can also use this url to get there. Now click "Add New", use the service account Client ID you noted down, and specify "https://www.googleapis.com/auth/admin.directory.group.readonly" as the scope. If everything is set up correctly, you'll see a screen like this:

Domain Wide Delegation

Now head back to the GCP console in the Service Account view and generate a new key pair.

Keypair

The file will be automatically downloaded and it should look like this:

{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "8167c485286f057e06e4a9d17e99ab4913627dbd",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCiaBGNydTgs0WV\numdNqzt5FlqigilYVk4J2oQqimg6Cnf8Q27ChShgDzUfwMbImm65MRFWD8UbiVGs\nZ9Q36bK53HKPgi07sZtdxuuwx2/CZ24l1q1N3Dpv5pfYzm2Z24pJbzWIF1pvDnmp\nZLA0iEXCnvOUIZ2tZ1sYmC7KH1MAbip7LNa6pJ/3fA1dRW7NWvporqFZCaGNsGwM\n0vNtS6dEwayhh8IFh2tCSARXOP62ji3BppTUItqBoh3mqP5L7iTv9iXTKTcTXb9E\nm5U1Espzc//UbElWashstYksTZYa6yrD7p2Zns2T4xRASL7j33dT5uHzIkvfeRdu\nyPj09W9TAgMBAAECggEASBj3IgDl1lL/oza7QYmwv1KjLd2mySaXQlyVq+UB3DJl\njcHJ2+UNRYe6x7vnA4s7eE9GKPSbRlwxu93kImZHB6fL29WoiwWPuZPjcfk3rhAI\noBernBMWhjLSWldZ5KHHxE3wb9geN4svi3m9l7Sfc4TpEWvS+fYWRNbafrRlPpz0\nQoFDSQy9FqxB7tGhs7insl+N16C8eQyjaysQt/xvk7pUQO6tYpVU1RVKIZlzjesU\nvOx2NfZSktILhB4teFYRQbGU0trPDfXOfj/NEQ1TUrL0gARHjYjalyrPgk2DNzXH\nCEx6ImQEKHLiJ9YeOGWvCkMBOb66kstlSwm6PxDf4QKBgQDXbvFKFmco970Yqg79\nuwJkOA29Wtqz+J9RnQd9WGL2wbFk/NCpqDnmbNM7UQm6nS9fhNkNG2BbBbW1gaYG\n+5sQ6X69ctxSVvfBqeFwwSdDqz6VReyGeQO7pNT51Ze4cW7O3BIKEoxicAgrw5uR\nAIUvHKs+UYtipAt0Y/I5GMdbSQKBgQDA/PGsnVdnPHuaPHbdJcDuXXmglOf9Nhj3\nK/eiMOE7UxeHy4vNDQyNPfhtGe7zyWqbshV2Gi2l9gyOfjt+sRDFpTG27i4Cc9Du\nNJ7EBnBIkoyswJOUmdt6YbmuAKEELZGQB9v94hIPzTpa51qbuyjNFQWVDaj2xPC5\nfmWVCW65uwKBgQDCb0ns0Q1oJzgOo6WGERuWchTMesx6tACuuygAVB51kNlXSOnW\nxZMESeHXXkuGlskjz5XKQ5QScrPOTmYXVUxd1i9iMuFwmzdfHcDvcBTM+Sgxt3tC\n3sOkvp7NoZ4ehJo6rtrFJnp3eZ+WSCQGmc6ad6iCRTyk2WPRN0dtitSaqQKBgENi\nTnQqABGw4auJ/yraetH/228BbztPf0oWlQGRtaMEMUwd+zNeogpTIAHgMzn2Ev5I\nIQw6ucOf9ORwGQ/0fVm1g3VPFsuOat4xi1oAsYX1fZ74Is+ZJTRHGREzcQVHb/Lt\ne5fbLtlLnFuPOmjz4ZwyAd/4hA2d2Du8cXWndHzvAoGBAJyuL43KBer234fD9Giu\nw+1/PR26rSO0rdKLihE2zRn4l/Kv+/UTZxGSLqpNZpGYnxJ0hAJ7J6N5yFFWZwBp\nvPB5yHmzkMVEYjWgNPzt4WjR3AroYJVzykNEPjdKcBCAM9GA+46W5KbBXbfWavE+\namtNmCJjuaiHJJjydyrTSUVB\n-----END PRIVATE KEY-----\n",
"client_email": "groups-retrieval-guide@your-project-id.iam.gserviceaccount.com",
"client_id": "104092906165806390865",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/groups-retrieval-guide%40your-project-id.iam.gserviceaccount.com"
}

Add an attribute called super_user to the end of the JSON object with the email address of a super-admin for the Google account. For example:

{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "8167c485286f057e06e4a9d17e99ab4913627dbd",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCiaBGNydTgs0WV\numdNqzt5FlqigilYVk4J2oQqimg6Cnf8Q27ChShgDzUfwMbImm65MRFWD8UbiVGs\nZ9Q36bK53HKPgi07sZtdxuuwx2/CZ24l1q1N3Dpv5pfYzm2Z24pJbzWIF1pvDnmp\nZLA0iEXCnvOUIZ2tZ1sYmC7KH1MAbip7LNa6pJ/3fA1dRW7NWvporqFZCaGNsGwM\n0vNtS6dEwayhh8IFh2tCSARXOP62ji3BppTUItqBoh3mqP5L7iTv9iXTKTcTXb9E\nm5U1Espzc//UbElWashstYksTZYa6yrD7p2Zns2T4xRASL7j33dT5uHzIkvfeRdu\nyPj09W9TAgMBAAECggEASBj3IgDl1lL/oza7QYmwv1KjLd2mySaXQlyVq+UB3DJl\njcHJ2+UNRYe6x7vnA4s7eE9GKPSbRlwxu93kImZHB6fL29WoiwWPuZPjcfk3rhAI\noBernBMWhjLSWldZ5KHHxE3wb9geN4svi3m9l7Sfc4TpEWvS+fYWRNbafrRlPpz0\nQoFDSQy9FqxB7tGhs7insl+N16C8eQyjaysQt/xvk7pUQO6tYpVU1RVKIZlzjesU\nvOx2NfZSktILhB4teFYRQbGU0trPDfXOfj/NEQ1TUrL0gARHjYjalyrPgk2DNzXH\nCEx6ImQEKHLiJ9YeOGWvCkMBOb66kstlSwm6PxDf4QKBgQDXbvFKFmco970Yqg79\nuwJkOA29Wtqz+J9RnQd9WGL2wbFk/NCpqDnmbNM7UQm6nS9fhNkNG2BbBbW1gaYG\n+5sQ6X69ctxSVvfBqeFwwSdDqz6VReyGeQO7pNT51Ze4cW7O3BIKEoxicAgrw5uR\nAIUvHKs+UYtipAt0Y/I5GMdbSQKBgQDA/PGsnVdnPHuaPHbdJcDuXXmglOf9Nhj3\nK/eiMOE7UxeHy4vNDQyNPfhtGe7zyWqbshV2Gi2l9gyOfjt+sRDFpTG27i4Cc9Du\nNJ7EBnBIkoyswJOUmdt6YbmuAKEELZGQB9v94hIPzTpa51qbuyjNFQWVDaj2xPC5\nfmWVCW65uwKBgQDCb0ns0Q1oJzgOo6WGERuWchTMesx6tACuuygAVB51kNlXSOnW\nxZMESeHXXkuGlskjz5XKQ5QScrPOTmYXVUxd1i9iMuFwmzdfHcDvcBTM+Sgxt3tC\n3sOkvp7NoZ4ehJo6rtrFJnp3eZ+WSCQGmc6ad6iCRTyk2WPRN0dtitSaqQKBgENi\nTnQqABGw4auJ/yraetH/228BbztPf0oWlQGRtaMEMUwd+zNeogpTIAHgMzn2Ev5I\nIQw6ucOf9ORwGQ/0fVm1g3VPFsuOat4xi1oAsYX1fZ74Is+ZJTRHGREzcQVHb/Lt\ne5fbLtlLnFuPOmjz4ZwyAd/4hA2d2Du8cXWndHzvAoGBAJyuL43KBer234fD9Giu\nw+1/PR26rSO0rdKLihE2zRn4l/Kv+/UTZxGSLqpNZpGYnxJ0hAJ7J6N5yFFWZwBp\nvPB5yHmzkMVEYjWgNPzt4WjR3AroYJVzykNEPjdKcBCAM9GA+46W5KbBXbfWavE+\namtNmCJjuaiHJJjydyrTSUVB\n-----END PRIVATE KEY-----\n",
"client_email": "groups-retrieval-guide@your-project-id.iam.gserviceaccount.com",
"client_id": "104092906165806390865",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/groups-retrieval-guide%40your-project-id.iam.gserviceaccount.com",
"super_user": "yoda@slashid.dev"
}

Adding your credentials to SlashID

SlashID exposes a simple REST API to keep secrets and external credentials. The credentials are encrypted using envelope encryption backed by an HSM.

We are going to use the API to create the credential and retrieve it:

curl -L -X POST 'https://api.slashid.com/organizations/config/external-credentials' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <YOUR ORG ID>' \
-H 'SlashID-API-Key: <YOUR API KEY>' \
--data-raw '{
"extcred_provider": "google",
"extcred_type": "json_credentials",
"extcred_label": "group retrieval credential"
"json_blob": {
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "8167c485286f057e06e4a9d17e99ab4913627dbd",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCiaBGNydTgs0WV\numdNqzt5FlqigilYVk4J2oQqimg6Cnf8Q27ChShgDzUfwMbImm65MRFWD8UbiVGs\nZ9Q36bK53HKPgi07sZtdxuuwx2/CZ24l1q1N3Dpv5pfYzm2Z24pJbzWIF1pvDnmp\nZLA0iEXCnvOUIZ2tZ1sYmC7KH1MAbip7LNa6pJ/3fA1dRW7NWvporqFZCaGNsGwM\n0vNtS6dEwayhh8IFh2tCSARXOP62ji3BppTUItqBoh3mqP5L7iTv9iXTKTcTXb9E\nm5U1Espzc//UbElWashstYksTZYa6yrD7p2Zns2T4xRASL7j33dT5uHzIkvfeRdu\nyPj09W9TAgMBAAECggEASBj3IgDl1lL/oza7QYmwv1KjLd2mySaXQlyVq+UB3DJl\njcHJ2+UNRYe6x7vnA4s7eE9GKPSbRlwxu93kImZHB6fL29WoiwWPuZPjcfk3rhAI\noBernBMWhjLSWldZ5KHHxE3wb9geN4svi3m9l7Sfc4TpEWvS+fYWRNbafrRlPpz0\nQoFDSQy9FqxB7tGhs7insl+N16C8eQyjaysQt/xvk7pUQO6tYpVU1RVKIZlzjesU\nvOx2NfZSktILhB4teFYRQbGU0trPDfXOfj/NEQ1TUrL0gARHjYjalyrPgk2DNzXH\nCEx6ImQEKHLiJ9YeOGWvCkMBOb66kstlSwm6PxDf4QKBgQDXbvFKFmco970Yqg79\nuwJkOA29Wtqz+J9RnQd9WGL2wbFk/NCpqDnmbNM7UQm6nS9fhNkNG2BbBbW1gaYG\n+5sQ6X69ctxSVvfBqeFwwSdDqz6VReyGeQO7pNT51Ze4cW7O3BIKEoxicAgrw5uR\nAIUvHKs+UYtipAt0Y/I5GMdbSQKBgQDA/PGsnVdnPHuaPHbdJcDuXXmglOf9Nhj3\nK/eiMOE7UxeHy4vNDQyNPfhtGe7zyWqbshV2Gi2l9gyOfjt+sRDFpTG27i4Cc9Du\nNJ7EBnBIkoyswJOUmdt6YbmuAKEELZGQB9v94hIPzTpa51qbuyjNFQWVDaj2xPC5\nfmWVCW65uwKBgQDCb0ns0Q1oJzgOo6WGERuWchTMesx6tACuuygAVB51kNlXSOnW\nxZMESeHXXkuGlskjz5XKQ5QScrPOTmYXVUxd1i9iMuFwmzdfHcDvcBTM+Sgxt3tC\n3sOkvp7NoZ4ehJo6rtrFJnp3eZ+WSCQGmc6ad6iCRTyk2WPRN0dtitSaqQKBgENi\nTnQqABGw4auJ/yraetH/228BbztPf0oWlQGRtaMEMUwd+zNeogpTIAHgMzn2Ev5I\nIQw6ucOf9ORwGQ/0fVm1g3VPFsuOat4xi1oAsYX1fZ74Is+ZJTRHGREzcQVHb/Lt\ne5fbLtlLnFuPOmjz4ZwyAd/4hA2d2Du8cXWndHzvAoGBAJyuL43KBer234fD9Giu\nw+1/PR26rSO0rdKLihE2zRn4l/Kv+/UTZxGSLqpNZpGYnxJ0hAJ7J6N5yFFWZwBp\nvPB5yHmzkMVEYjWgNPzt4WjR3AroYJVzykNEPjdKcBCAM9GA+46W5KbBXbfWavE+\namtNmCJjuaiHJJjydyrTSUVB\n-----END PRIVATE KEY-----\n",
"client_email": "groups-retrieval-guide@your-project-id.iam.gserviceaccount.com",
"client_id": "104092906165806390865",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/groups-retrieval-guide%40your-project-id.iam.gserviceaccount.com",
"super_user": "yoda@slashid.dev"
}
}'

Finally, we can create a set of OAuth credentials for Google and associate the external credential just created:

curl --location --request POST 'https://api.slashid.com/organizations/sso/oidc/provider-credentials' \
--header 'SlashID-OrgID: <YOUR ORG ID>' \
--header 'SlashID-API-Key: <YOUR API KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"client_id": "<CLIENT ID>",
"client_secret": "<CLIENT SECRET>",
"provider": "google",
"label": "A label for this set of credentials"
"external_cred": <EXTERNAL_CRED_ID>
}
'

Retrieving Groups when the user authenticates

Now that we have the necessary pieces in place, you can use the requires_groups parameter in your authentication requests. For example:

let user = await sid.id(oid, null, {
method: "oidc",
options: {
client_id: clientId,
provider: provider,
ux_mode: uxMode,
requires_groups: "true",
},
})

The call above will retrieve the Google groups for the user logging in and return them as part of the OIDC token in user.decodedTokenContainer.oidc_tokens:

google: {
"access_token": "xIh3qoOXAFTaiOma2ZS6eCgP7rJF6iNDzleux+t69h8XktpsbHDKpiuwH2SwDO5/pSfwwn1+GeYZjxYxGbcJHAfiTztUfz3XqiejND4NasfuCGs550d0YSruxuC5yeKN9GUBbap1t/El7db23GlzjdJodp85ZFJsYsF9NTvP7ws4LkaX64s4VvlVWVT4fxOctFjO3oE1iR/oOBD1QCawvPdrLomQYFcXzN0R1UY9mIlDtUvsXh9cT+gAT9vXdjZ+Q9hR/b2QVR/l241AzmZ4VeIbVPQ=",
"client_id": "32189023109-4332109.apps.googleusercontent.com",
"expires_at": 1673092551,
"id_token": "lVddu2HJAGO/VEnyh30vEeYTH169x2r+/X2/kImNUNeyt6lpDJaJMF7TwSDwmTdAf4Sxs6Ul5eTCrIfHk73F8Ec7WUa/bjekZoj7Ee/xPYNmZpjGuTNpcQCwl+MfEbdd
zXPPFoCdZF+CcZxldSOwzLUDYcLgXZ8fpBMg2erIMtqaH5e682GwY7iJD4ySUeTj3JftxQYBYizUUPfueNkbgsh+bC1bUtzMHDjVU53kZFvygjYydThtw8gl7Kw5G3NW
6f9Ch/D/9WnFbyb/Q3eibJeIKnMNrow003l70DefZzRLM2/6mkEd/VEMuGo9ejW2An2zf/vVQSKyxXP6ySNSkU/nrTtkGFS0s/ENsCB6taj12i57JOtzgDiigJayXB8N
KKgWtJmT/ESgLxsH54Mg3AYK91wo53jmfo9ZLPn88muczG96GfAzUMAOM5Drl/MKyPP+WZ+zwJ1gnoRqnxIUrv+WDwkwbbvA2vjkW8Op+gXVkactQCQVQ26GBGDPh7MtbTUSsW6LKb8/3oEMBuSIZQ==",
"oidc_groups": [
"test-group@slashid.dev",
"sso-guide@slashid.dev",
],
"provider": "google",
"refresh_token": ""
}

You are now ready to start using SlashID to retrieve Google Groups as part of the SSO sign-in flow.