Skip to content

Commit

Permalink
Docs: Google directory sync (#283)
Browse files Browse the repository at this point in the history
* Docs: Google Workspace directory

* add NPM library option

* add steps

* add observability

* configure OAuth app

* add sync

* Fix formatting in env variables.

* Update env description

* Fix the URL

* Fix the URL

* Update dsync environment variable
names

* Update directory sync API endpoint

---------

Co-authored-by: Deepak Prabhakara <[email protected]>
  • Loading branch information
Kiran K and deepakprabhakara authored Nov 27, 2023
1 parent 61df1bf commit e310d75
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 35 deletions.
189 changes: 165 additions & 24 deletions docs/directory-sync/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ The following guides provide information about the APIs and SDKs that are availa

### Directory

Below are the properties of a directory connection.

#### Properties

- `name`: The name of the directory
- `tenant`: The tenant ID of the tenant you want to create the directory for.
- `product`: The product ID of the product you want to create the directory for.
- `type`: The directory provider type. See the [Directory Providers](./providers) for more information.
- `webhook_url`: The webhook URL to which the directory connection will POST the events.
- `webhook_secret`: The webhook secret used to sign the webhook payload.
- `webhook.endpoint`: The webhook URL to which the directory connection will POST the events.
- `webhook.secret`: The webhook secret used to sign the webhook payload.
- `log_webhook_events`: Indicate if the webhook events should be logged.
- `deactivated`: Indicate if the directory connection is deactivated.

:::info
The `tenant` and `product` should not contain the `:` character since we use it as a delimiter internally.
Expand Down Expand Up @@ -89,7 +93,7 @@ curl --request POST \

#### Response

```javascript
```json
{
"data": {
"id": "58b5cd9dfaa39d47eb8f5f88631f9a629a232016",
Expand Down Expand Up @@ -149,7 +153,7 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": [
{
Expand Down Expand Up @@ -208,7 +212,7 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": {
"id": "58b5cd9dfaa39d47eb8f5f88631f9a629a232016",
Expand Down Expand Up @@ -266,7 +270,7 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": [
{
Expand All @@ -276,9 +280,7 @@ curl --request GET \
"email": "[email protected]",
"active": true,
"raw": {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Aswin",
Expand Down Expand Up @@ -313,9 +315,7 @@ curl --request GET \
"email": "[email protected]",
"active": true,
"raw": {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Kiran",
Expand Down Expand Up @@ -383,7 +383,7 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": {
"id": "ebc31d6e-7d62-4f81-b9e5-eb5f1a04ee92",
Expand All @@ -392,9 +392,7 @@ curl --request GET \
"email": "[email protected]",
"active": true,
"raw": {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Kiran",
Expand Down Expand Up @@ -460,16 +458,14 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": [
{
"id": "44d08c0e-d185-4a5e-80a6-b47a717ffaa5",
"name": "Developers",
"raw": {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Developers",
"members": [
{
Expand Down Expand Up @@ -525,15 +521,13 @@ curl --request GET \

#### Response

```javascript
```json
{
"data": {
"id": "44d08c0e-d185-4a5e-80a6-b47a717ffaa5",
"name": "Developers",
"raw": {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Developers",
"members": [
{
Expand Down Expand Up @@ -564,6 +558,153 @@ curl --request GET \

---

### Google Directory Sync

Google Directory Sync specific properties:

- `google_domain`: The Google Workspace domain name.
- `google_access_token`: The Google Admin access token.
- `google_refresh_token`: The Google Admin refresh token.

Jackson requires following API scopes:

- `https://www.googleapis.com/auth/admin.directory.group.member.readonly`
- `https://www.googleapis.com/auth/admin.directory.group.readonly`

#### 1. Get Authentication URL

Get the URL to authenticate with admin credentials. Google will prompt the user to authenticate with the admin credentials and authorize the application to access the Google Workspace directories.

#### Request

<Tabs>
<TabItem value="01" label="Node.js" default>

```javascript showLineNumbers
await directorySyncController.google.generateAuthorizationUrl({
directoryId: '58b5cd9dfaa39d47eb8f5f88631f9a629a232016',
});
```

</TabItem>
</Tabs>

#### Response

```json
{
"data": {
"authorizationUrl": "https://accounts.google.com/..."
},
"error": null
}
```

#### 2. Get Access Token

Get the access token from the authorization code.

#### Request

<Tabs>
<TabItem value="01" label="Node.js" default>

```javascript showLineNumbers
await directorySyncController.google.getAccessToken({
directoryId: '58b5cd9dfaa39d47eb8f5f88631f9a629a232016',
code: 'authorization-code',
});
```

</TabItem>
</Tabs>

#### Response

```json
{
"data": {
"access_token": "ya29.a0AWY7CknlXtELCHzdKuS...",
"refresh_token": "1//03MJpa-zseicbCgYIARAAGAMSNwF-...",
"scope": "https://www.googleapis.com/auth/admin.directory.group.member.readonly https://www.googleapis.com/auth/admin.directory.group.readonly",
"token_type": "Bearer",
"expiry_date": 1684343934305
},
"error": null
}
```

#### 3. Set Access Token to Directory

Set the access token and refresh token to the directory. We'll use the access token to make requests to the Google Directory API.

#### Request

<Tabs>
<TabItem value="01" label="Node.js" default>

```javascript showLineNumbers
await directorySyncController.google.setToken({
directoryId: '58b5cd9dfaa39d47eb8f5f88631f9a629a232016',
accessToken: 'ya29.a0AWY7CknlXtELCHzdKuS...',
refreshToken: '1//03MJpa-zseicbCgYIARAAGAMSNwF-...',
});
```

</TabItem>
</Tabs>

#### Response

```json
{
"data": {
"id": "58b5cd9dfaa39d47eb8f5f88631f9a629a232016",
"name": "App",
"tenant": "boxyhq",
"product": "jackson",
"type": "google",
"google_domain": "boxyhq.com",
"google_access_token": "ya29.a0AWY7CknlXtELCHzdKuS...",
"google_refresh_token": "1//03MJpa-zseicbCgYIARAAGAMSNwF-..."
},
"error": null
}
```

#### 4. Sync Directory

Jackson can be configured to sync your Google Workspace directory.

<Tabs>
<TabItem value="01" label="Node.js" default>

```javascript showLineNumbers
const callback = (event: DirectorySyncEvent) => {
console.log(event);
};

await directorySyncController.sync(callback);
```

</TabItem>
<TabItem value="02" label="Shell">

```bash
curl -X POST \
-H "Authorization: Api-Key YOUR_API_KEY" \
http://localhost:5225/api/v1/dsync/cron/sync-google
```

</TabItem>
</Tabs>

You'll ideally want to run the sync on a schedule (e.g. every 2 hours). You can use a cron job to invoke this URL on a schedule.

See more information about the [Directory Sync Event](#handle-the-requests-from-identity-providers) below.

---

### Handle the Requests from Identity Providers

Make sure your application can handle the requests from Identity Providers.
Expand Down
13 changes: 13 additions & 0 deletions docs/directory-sync/observability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Observability

Jackson provides first-class observability on the back of OpenTelemetry. Currently we support the following metrics. Traces and logs are coming soon.

Please check the [Environment Variables](../jackson/deploy/env-variables#opentelemetry-configuration) to configure to enable this feature.

## Metrics

| Name | Description | Type |
| --------------------------------- | --------------------------------------------------- | ----- |
| `jackson.dsync.connection.create` | Number of directory sync connection create requests | Count |
| `jackson.dsync.connection.get` | Number of directory sync connection get requests | Count |
| `jackson.dsync.connection.delete` | Number of directory sync connection delete requests | Count |
58 changes: 58 additions & 0 deletions docs/directory-sync/providers/google.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: Google Workspace Directory
sidebar_label: Google Workspace
---

# Google Workspace

The following guide will walk you through the process of configuring SAML Jackson to use Google Workspace as a directory sync provider.

---

Jackson requires a Google OAuth App to be configured to access the Google Workspace API. You can use your existing OAuth App or create a new one.

### Create OAuth App

Navigate to the [Google Cloud Console](https://console.cloud.google.com/) and select your project from the list.

![img alt](/img/dsync/providers/google/oauth/1.png)

Select **APIs & Services** from the left menu and then select **Credentials**.

Select **OAuth client ID** from the **CREATE CREDENTIALS** dropdown.

![img alt](/img/dsync/providers/google/oauth/2.png)

Give your credentials a name and select **Web application** as the **Application type**.

Add the following **Authorised redirect URIs** and then click **Create**.

`https://<your-domain>/api/scim/oauth/callback`

![img alt](/img/dsync/providers/google/oauth/3.png)

:::info
Note that the above callback URL works if you're using Jackson as a service.

If using Jackson as an NPM package, the Authorised redirect URIs will be a URL on your application that you'll need to configure. See [Google Directory Sync API](/docs/directory-sync/api-reference#google-directory-sync) for more information.
:::

Copy the **Client ID** and **Client secret** and save them for later.

![img alt](/img/dsync/providers/google/oauth/4.png)

See the [Environment Variables](/docs/directory-sync/api-reference#google-directory-sync) section to learn how to configure Jackson with these values.

Once configuring Jackson, you can authenticate the tenants with Google OAuth and sync their Workspace directory.

### Schedule Sync

Jackson can be configured to sync your Google Workspace directory on a schedule (e.g. every 2 hours).

Jackson service exposes the below API URL that can be called to trigger a sync. You can use a cron job to invoke this URL on a schedule.

Depending on the number of Google directories you have, the sync can take a few minutes to complete.

`https://<your-domain>/api/scim/cron/sync-google`

Learn more about [Google Directory Sync API](/docs/directory-sync/api-reference#4-sync-directory).
1 change: 1 addition & 0 deletions docs/directory-sync/providers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ SAML Jackson supports the following directory providers:
- [OneLogin SCIM v2.0](./onelogin)
- [Okta SCIM v2.0](./okta)
- [JumpCloud SCIM v2.0](./jumpcloud)
- [Google Workspace](./google)
20 changes: 20 additions & 0 deletions docs/jackson/deploy/env-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,26 @@ Set one of these to `1` or `true` to turn off our anonymous analytics. We only t

The following env vars are used to configure the directory sync feature.

`DSYNC_GOOGLE_` env vars are only applicable if you are using Google Workspace as a directory sync provider.

### **DSYNC_WEBHOOK_BATCH_SIZE**

Enable batch processing of directory sync events. The value represents the number of events to batch together instead of sending each event individually. This requires you to configure a cron job to [process the queued events](/docs/directory-sync/api-reference#batch-processing-events)

### **DSYNC_GOOGLE_CLIENT_ID**

The Google authentication client ID.

NPM library option: `dsync.providers.google.clientId`

### **DSYNC_GOOGLE_CLIENT_SECRET**

The Google authentication client secret.

NPM library option: `dsync.providers.google.clientSecret`

### **DSYNC_GOOGLE_REDIRECT_URI**

The URI to redirect to after completing the authentication request.

NPM library option: `dsync.providers.google.callbackUrl`
Loading

0 comments on commit e310d75

Please sign in to comment.