Service Provider Configuration of Cloud Applications for API-Based Data Protection
For supported software information, click here.
Versa API-based data protection (API-DP) secures SaaS and IaaS applications using APIs provided by cloud services. This article is for cloud service providers and describes how to configure API-DP applications to make them available to their customers, and includes configuration procedures for the following SaaS and IaaS cloud applications:
- Asana
- Box
- Cisco Webex
- Citrix ShareFile
- Confluence
- Dropbox
- Egnyte
- Github
- Gmail
- Google Drive
- Jira
- Microsoft OneDrive
- Microsoft Outlook
- Microsoft SharePoint
- Microsoft Teams
- Microsoft Yammer
- Notion
- Salesforce
- ServiceNow
- Slack
- Trello
- Zendesk
- Zoom
- Amazon Web Services
- Google Cloud Platform
- Microsoft Azure
- Oracle Cloud Infrastructure
Asana for API-DP
- Navigate to the Asana developer console and log in.
- Click Create new app.

- Enter the details as shown in the following image, and then click Create app.

- From the left menu bar, navigate to the OAuth tab, and then click Add redirect URL.

- Add the redirect URL in the format shown below, and then click Add.
Redirect URL: https://<cluster-FQDN>/v1/asana/auth-callback

- In the left menu bar, click Manage distribution. The following screen displays.

- Select Any workspace as the distribution method, and then click Save changes.
- In the left menu bar, click Basic. The following screen displays.

- Store the Client ID and the Client Secret for later use.
Note: For details about configuring and using the saved credentials, refer to the Asana block in the API-DP Helm values.yaml file.
Box API-DP
- Log in to box.com with an admin account.
- Check for the Admin console and Dev Console buttons at the bottom of the left menu bar. If both are not present, as shown below, then the Box account type is not supported for creating applications.

- Click Dev Console.
- Create the OAuth application:
- On the My Platform Apps screen, click Create Platform App.

- In the Create Platform App screen, select Custom App.

- Enter the details in step 1 of the Create a Custom App window, and then click Next.
f
- In step 2, select User Authentication (OAuth 2.0) as the Authentication method, and then click Create App.

The app is created and is ready for use.
- On the My Platform Apps screen, click Create Platform App.
- Click the Configuration tab on the OAuth 2 App screen.
- Copy the Client ID and Client Secret and store them for later use.
- Enter the OAuth 2.0 Redirect URL below:
- Redirect URL—https://<cluster-FQDN>/v1/box/auth-callback

- Redirect URL—https://<cluster-FQDN>/v1/box/auth-callback
- Click Add.
- Add scopes and permissions to the application as shown in the following screenshot, and then click Save Changes at the top right corner of the screen.

OAuth 2.0 is now ready.
- Create the JWT app:
- Click My Platform Apps in the left menu bar.

- Select the Create Platform App option.
- Select Custom App, and then enter the details as shown in step 1 below.

- In step 2, select Server Authentication (with JWT), and then click Create App.

The JWT App is created.
- Click My Platform Apps in the left menu bar.
- Click the Configuration tab on the JWT App screen.

- Copy the client ID and store it for later use.
- Select the scope, and then select the access options as shown in following screenshots.


- To generate a JWT key JSON file, click Generate a Public/Private Keypair button in the Add and Manage Public Keys section. A file is then downloaded. Save this file securely.

Note: For details about configuring and using the saved credentials from steps 6 and 14, refer to the Box block in the API-DP Helm values.yaml file.
- Click the Save changes button in the top right corner.
- Click My Platform Apps in the left menu bar.
- Create the Box Custom Skill app:
- Select the Create Platform App option.
- Select Box Custom Skill.

- Enter the required details, as shown below.

- Click Create App. The Box Skill is created.
- Click the Configuration tab, copy the client ID, and provide the Invocation URL:
- Invocation URL—https://<cluster-FQDN>/v1/box/webhook

- Invocation URL—https://<cluster-FQDN>/v1/box/webhook
- Click the Save Changes button in the top right corner.
- Authorize the OAuth and JWT applications, and set up Skill:
- Navigate to the Admin Console from the left menu bar in your account home screen (see Step 2).
- Click Integrations in the left menu bar.
- Select the Platform Apps Manager tab, click Server Authentication Apps, and then click Add Platform App in the upper right corner.
- Enter the JWT app client ID and the Box custom Skill app client ID, and then authorize.
- Select the User Authentication Apps tab, and then click Add Platform App.
- Enter the OAuth app client ID, and then authorize.

- Navigate from app.box.com/master/platform-apps/userauth to app.box.com/master/skills.
- Click the + Add Skill button.

- Enter the Box Skill client ID. Click Next.
- Select All content in your company, and then click Next.

- Click Enable in the the upper right corner.
Cisco Webex API-DP
- Sign into Webex Developer and navigate to https://developer.webex.com/my-apps/new/integration.

- Fill out Name, Icon, Description, Redirect URL and scopes.
Field Description Integration name Enter the name of the integration as it will appear in Webex. Icon Upload your own icon or select a Webex default icon. Icons must be exactly 512 x 512px in JPEG or PNG format. App Hub Description Enter information about the application, up to 1024 characters. Redirect URI(s) Enter one or more URIs that a user will be redirected to when completing an OAuth grant flow. - Select one or more scopes. You must select at least the following scopes:
- meeting:admin_participants_read
- spark-compliance:events_read
- spark-compliance:messages_read
- spark-compliance:messages_write
- spark-compliance:people_read
- spark-compliance:recordings_read
- spark-compliance:webhooks_read
- spark-compliance:webhooks_write
- spark:all
- spark:webhooks_read
- spark:webhooks_write
- Click Add Integration. The following screen displays.

- Store the client ID and client secret for later use.
Citrix ShareFile for API-DP
To configure Citrix ShareFile for API-DP, the service provider registers one ShareFile OAuth application. Every customer authorizes that same application against their own ShareFile account.
Perform the actions shown in this section before onboarding the first customer.
The process for enabling access involves two hosts:
- Central secure.sharefile.com—The host to which the authorize call is sent.
- Customer's own <subdomain>.<apicp> host—The host to which the token exchange and all subsequent API calls are sent.
ShareFile returns the subdomain and apicp (API Control Plane) as query parameters on the callback, so that the customer never enters their domain. apicp is the domain suffix for the customer's ShareFile data center (for example, sharefile.com). Since ShareFile operates multiple data centers and the value can differ per tenant, the connector stores whatever ShareFile returns rather than hardcoding it. The connector uses that returned lower-case subdomain as the app-tenant id.
The redirect URI must be enter corrected because it is registered with ShareFile and must match what the connector sends.
To configure a new instance for Citrix ShareFile:
- Register the ShareFile OAuth app—Register the application from the provider's Citrix/ShareFile developer account. The connector uses the authorization code flow: it sends response_type=code to secure.sharefile.com/oauth/authorize and exchanges the result with grant_type=authorization_code, then renews with grant_type=refresh_token.
Confirm the current developer-portal URL and application-approval process with Citrix before registering — this doc does not pin them down, and they have changed in the past.
The connector requires the following:- An app name your customers will recognize on the consent screen — they see it when approving access, so use the provider's own product name.

- Set the redirect URI to the connector's auth-callback endpoint: https://<clusterHostname>/v1/citrixfile/auth-callback.
<clusterHostname> is the is global.clusterHostname from the helm/cluster-values/asc-infra/<cluster>.yaml file (for example, cluster.domain.com). The connector builds this URL itself and sends it as redirect_uri on the authorize call. ShareFile rejects the exchange if the registered value differs in any way, by even a trailing slash.
- Store the client id and client secret securely for later use. Both are needed in Step 3 below, and both are sent on every token exchange and refresh.

Nothing about scopes is set here, and none are requested; the connector sends no scope parameter at all. What the application is allowed do is determined by the permissions that you grant the app at registration and by the rights of the customer admin who approves it.
- An app name your customers will recognize on the consent screen — they see it when approving access, so use the provider's own product name.
- Enable the connector—Enable Citrix Files in two charts, neither of which is enabled by default:
- asc-infra—In the helm/cluster-values/asc-infra/<cluster>.yaml file, enter the following under global.services:
global:
services:
citrixfile:
enable: true
The common_app_config.yaml file renders global.services into the configuration that the connector reads at runtime. The OAuth credentials travel via the secret in Step 3.
- apidp—In the helm/cluster-values/apidp/<cluster>.yaml file, enter the following at the top level:
citrixfile:
enable: true
This is the Helm dependency condition. The API-DP chart carries condition: citrixfile.enable. If you leave this setting in the default false state, the subchart never renders at all; no deployment will occur, and no saas-citrixfile-oauth secret for Step 3 will be populated.
Also, confirm that global.clusterHostname in the asc-infra values matches the hostname you registered as the redirect URI in Step 1. It feeds base_url in the common_app_config.yaml file, onto which the connector concatenates the callback path. The same value becomes the webhook URL on which ShareFile calls back.
- asc-infra—In the helm/cluster-values/asc-infra/<cluster>.yaml file, enter the following under global.services:
- Set the API key in the secret—The credentials from Step 1 reach the service as a Kubernetes secret, which is by default saas-citrixfile-oauth in the apidp namespace. The backend reads it at runtime and uses it to authorize every tenant and to refresh the token.
Secret Key Value client-id ShareFile OAuth client ID client-secret ShareFile OAuth client secret - Add the base64-encoded client id and client secret to the citrixfile block in the API-DP Helm chart values in the helm/cluster-values/apidp/<cluster>.yaml file, the same top-level block you enabled in Step 2b:
citrixfile:
enable: true
auth:
secretData:
clientId: "<base64 of the ShareFile client id>"
clientSecret: "<base64 of the ShareFile client secret>"
The values must be base64-encoded — the chart writes them straight into the secret's data: block, which Kubernetes requires to be base64. A raw key fails to deploy. Encode with:
echo -n '<ShareFile client id>' | base64
echo -n '<ShareFile client secret>' | base64
The keys are clientId / clientSecret in values; the chart kebab-cases them (a naming convention that allows a developer to create whitespace between words in code by separating each word with a dash character) to client-id / client-secret in the secret.
The helm/apidp/versa/citrixfile/values.yaml file carries a default key belonging to another account. Do not edit this file. Rather, override the keys in cluster values as shown above, or else the platform authenticates as that other account against your customers' domains.
- To use a different secret name, set citrixfile.auth.secretName (or point citrixfile.auth.existingSecret at a secret you manage yourself). The deployment passes the result to the pod as AUTH_SECRET_NAME and the backend reads that, falling back to saas-<app>-oauth. This is not required for most deployments.
- Rotating the key is an edit to the same values plus a helm upgrade. Existing tenants keep working on their stored access and refresh tokens until the next refresh, which will then fail. You should plan a re-grant for each tenant, or rotate the key during a maintenance window.
- Add the base64-encoded client id and client secret to the citrixfile block in the API-DP Helm chart values in the helm/cluster-values/apidp/<cluster>.yaml file, the same top-level block you enabled in Step 2b:
- Verify
- Confirm the the secret holds the provider's own key and not the shipped default with the following command:
kubectl get secret saas-citrixfile-oauth -n apidp -o jsonpath='{.data.client-id}' | base64 -d
This command should print your ShareFile client ID. If it prints anything else, it means that the chart default is still in place and Step 3 has not taken effect.
- Onboard one internal test tenant and walk the full grant, as follows:
# connector is actually running (Step 2.2)
kubectl get pods -n apidp | grep citrixfile# after clicking Grant Access, the authorize URL should carry YOUR client id,
# the registered redirect URI
kubectl logs -n apidp deploy/saas-citrixfile | grep "Grant access called" -A2# after consent, a successful exchange stores tokens and creates the webhook;
# this must NOT appear
kubectl logs -n apidp deploy/saas-citrixfile | grep "Create New Webhook Failed"
On a successful grant, the connector subscribes to File Upload, Update, and Delete events at https://<subdomain>.<apicp>/sf/v3/WebhookSubscriptions, scoped to the customer's whole Account, and stores the returned subscription ID against the tenant. A grant that completes but logs Create New Webhook Failed leaves a tenant that looks healthy while receiving no change events.
Revoking access does not invalidate the tokens. ShareFile exposes no token-revocation endpoint, so revoke deletes the webhook subscription and the local tenant records only—the issued access and refresh tokens stay valid until they expire on ShareFile's own schedule. If a tenant must be cut off immediately, revoke the application's authorization from the ShareFile side.
- Confirm the the secret holds the provider's own key and not the shipped default with the following command:
Troubleshooting
| Symptom | Likely Cause |
|---|---|
|
ShareFile rejects the request before showing consent |
The redirect URI registered with ShareFile does not match https://<clusterHostname>/v1/citrixfile/auth-callback (Step 1b), or global.clusterHostname was changed after registration. |
|
Token exchange fails right after consent |
Client secret wrong, still the chart default, or a trailing newline picked up when base64-encoding (Step 3). |
|
Grant succeeds, Create New Webhook Failed in the log |
Webhook subscription against the customer's account was rejected. Check the error in the pod log; the account-id lookup runs first and needs the token to be valid. |
|
Tenant authorized, no change events, no webhook error |
Customer's ShareFile account cannot reach the webhook URL. The cluster hostname must be publicly resolvable. |
|
Refresh failures on previously healthy tenants |
Client secret rotated, or the application's authorisation was removed on the ShareFile side; tenants need a re-grant |
|
Connector not running at all |
citrixfile.enable is still false in the apidp cluster values (Step 2b)—the subchart is gated on it. |
Confluence for API-DP
Configure Confluence for Authentication
- Navigate to https://developer.atlassian.com/console/myapps/ and log in.
- In the My Apps screen, click Create > OAuth 2.0 integration.

- In the new window, enter the App name, click the checkbox to agree to the terms, and then click Create.

- In the Developer screen, click Permissions in the left menu bar, then click the Add button to the right of Confluence API.

- Click the Configure action for Confluence API.

- In the new window, click Edit Scopes.

- Assign the following permissions to the application:
- Classic scopes:
- write:confluence-content
- read:confluence-space.summary
- write:confluence-file
- read:confluence-content.all
- read:confluence-content.summary
- search:confluence
- read:confluence-content.permission
- read:confluence-user
- read:confluence-groups
- write:confluence-groups
- readonly:content.attachment:confluence
- Granular scopes:
- read:space:confluence
- read:space-details:confluence
- write:space:confluence
- delete:space:confluence
- read:page:confluence
- write:page:confluence
- delete:page:confluence
- read:blogpost:confluence
- write:blogpost:confluence
- delete:blogpost:confluence
- read:comment:confluence
- write:comment:confluence
- delete:comment:confluence
- read:attachment:confluence
- write:attachment:confluence
- delete:attachment:confluence
- read:content:confluence
- read:content-details:confluence
- write:content:confluence
- delete:content:confluence
- read:content.metadata:confluence
- read:label:confluence
- write:label:confluence
- read:email-address:confluence
- Classic scopes:
- After assigning permissions, navigate to the Authorization tab, and then click the Add action for OAuth 2.0.

- Enter the Callback URL below, and then click Save changes.
- Callback URL—https://<cluster-FQDN>/v1/confluence/auth-callback

- Callback URL—https://<cluster-FQDN>/v1/confluence/auth-callback
- Navigate to Distribution and tab, and then click Edit.

- Select Distribution Status as Sharing, enter all details, and select Yes for the Personal Data Declaration, as shown below, and click Save changes.

- Navigate to the Overview > App information or Settings, copy the Client ID and Client Secret, and store them for later use.

Configure Confluence for Real-Time Event Monitoring
Use the following procedure to create the Atlassian Forge app that captures Confluence events and forwards them to API-DP for event monitoring.
- Install the Forge CLI. Refer to Atlassian's setup guide at https://developer.atlassian.com/platform/forge/getting-started/, which covers installing Node.js 22.x or 24.x (LTS), using nvm, and installing the Forge CLI.
- Log in with your Atlassian developer account:
forge login
Authenticate using your Atlassian developer account email and a Forge CLI-scoped API token generated at https://go.atlassian.com/forge-cli-api-token.
- Create the app:
forge create
When prompted:
- Select a developer space (create one if you do not already have one).
- Provide a name for the app.
- Select Show All for both the platform tool and category prompts, then choose the blank template.
- Go to the app directory and install dependencies:
cd <app_name>
Before making any changes, copy the generated app.id value from manifest.yml file. This is the app's permanent identity and is required in the next step.
- Replace the generated manifest.yml with the following. Before saving, update:
- The app ID—Paste the value copied in Step 4 in place of APP-ID.
- The cluster hostname—Enter your API-DP cluster hostname in place of CLUSTER-HOSTNAME (must match the hostname you set in Step 7 below).
app:
id: ari:cloud:ecosystem::app/APP-ID # Paste the ID copied in Step 4
runtime:
name: nodejs22.x
modules:
trigger:
- key: on-page-created
function: forwardToApiDp
events:
- avi:confluence:created:page
- key: on-page-updated
function: forwardToApiDp
events:
- avi:confluence:updated:page
- key: on-page-archived
function: forwardToApiDp
events:
- avi:confluence:archived:page
- key: on-page-unarchived
function: forwardToApiDp
events:
- avi:confluence:unarchived:page
- key: on-page-trashed
function: forwardToApiDp
events:
- avi:confluence:trashed:page
- key: on-page-restored
function: forwardToApiDp
events:
- avi:confluence:restored:page
- key: on-page-deleted
function: forwardToApiDp
events:
- avi:confluence:deleted:page
- key: on-blog-created
function: forwardToApiDp
events:
- avi:confluence:created:blogpost
- key: on-blog-updated
function: forwardToApiDp
events:
- avi:confluence:updated:blogpost
- key: on-blog-trashed
function: forwardToApiDp
events:
- avi:confluence:trashed:blogpost
- key: on-blog-restored
function: forwardToApiDp
events:
- avi:confluence:restored:blogpost
- key: on-blog-deleted
function: forwardToApiDp
events:
- avi:confluence:deleted:blogpost
- key: on-comment-created
function: forwardToApiDp
events:
- avi:confluence:created:comment
- key: on-comment-updated
function: forwardToApiDp
events:
- avi:confluence:updated:comment
- key: on-comment-deleted
function: forwardToApiDp
events:
- avi:confluence:deleted:comment
- key: on-attachment-created
function: forwardToApiDp
events:
- avi:confluence:created:attachment
- key: on-attachment-updated
function: forwardToApiDp
events:
- avi:confluence:updated:attachment
- key: on-attachment-archived
function: forwardToApiDp
events:
- avi:confluence:archived:attachment
- key: on-attachment-unarchived
function: forwardToApiDp
events:
- avi:confluence:unarchived:attachment
- key: on-attachment-trashed
function: forwardToApiDp
events:
- avi:confluence:trashed:attachment
- key: on-attachment-restored
function: forwardToApiDp
events:
- avi:confluence:restored:attachment
- key: on-attachment-deleted
function: forwardToApiDp
events:
- avi:confluence:deleted:attachment
- key: on-space-created
function: forwardToApiDp
events:
- avi:confluence:created:space:V2
- key: on-space-updated
function: forwardToApiDp
events:
- avi:confluence:updated:space:V2
- key: on-space-deleted
function: forwardToApiDp
events:
- avi:confluence:deleted:space:V2
function:
- key: forwardToApiDp
handler: index.run
permissions:
scopes:
- write:confluence-space
- write:confluence-content
- read:confluence-content.summary
- read:confluence-space.summary
external:
fetch:
backend:
- address: https://CLUSTER-HOSTNAME # Enter your API-DP cluster hostname
- Delete the generated source file(s) and create src/index.js with the following handler:
const WEBHOOK_PATH = '/v1/confluence/webhook';
export async function run(event, context) {
const apiDpHost = process.env.HOST_URL;
if (!apiDpHost) {
console.error('[API-DP] HOST_URL is not set - aborting');
return;
}
const cloudId = (context.installContext ?? '').split('/').pop();
const targetUrl = `${apiDpHost}${WEBHOOK_PATH}`;
const payload = {
event_type: event.eventType,
cloud_id: cloudId,
timestamp: new Date().toISOString(),
data: event,
};
try {
const response = await fetch(targetUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) {
console.error(`[API-DP] Delivery failed -> ${targetUrl} | ${response.status}`);
} else {
console.log(`[API-DP] Delivered ${event.eventType} event successfully -> ${targetUrl} | ${response.status}`);
}
} catch (err) {
console.error(`[API-DP] Error -> ${targetUrl} | ${err.message}`);
}}
- Set your API-DP host as an environment variable for both Forge environments:
forge variables set --environment development \
HOST_URL https://CLUSTER-HOSTNAME
forge variables set --environment production \
HOST_URL https://CLUSTER-HOSTNAME
- Run forge lint to check for errors, then deploy and install to a sandbox site for testing:
forge deploy --environment development forge install --environment development
Select Confluence and enter your sandbox site. Create a test page, blog post, comment, or attachment, and confirm delivery with forge logs (a 200 response indicates success).
- Once testing passes, deploy to production:
forge deploy --environment production
- Distribute the app:
- Go to https://developer.atlassian.com/console/myapps, select the app, and open Manage > Distribution. Under Distribution controls, click Edit, then set Distribution Status to Sharing.
- Provide the app details—Company/Department, customer support contact, privacy policy, and terms of service. -Select Yes for "Does your app store personal data?", and then click Save changes.
- Under Installation link settings, select Confluence as the product to generate the installation URL. Copy it and save it for later use.
- Go to the Settings tab, provide the app name and description, and save the changes.
Note: For details about configuring and using the saved credentials from the Configure Confluence for Authentication section and the installation URL from the Configure Confluence for Real-Time Event Monitoring section, refer to the confluence block in the API-DP Helm values file.
Dropbox API-DP
- Login to https://www.dropbox.com/developers (use the admin account), and then click App Console.


- Click Create app.

- Enter all details, select the scope and other details as shown below, and then click Create app.

- Once the app is created, select the Settings subtab, scroll down to the App key and App secret fields. Copy and store them for later use.
Note: For details about configuring and using the saved credentials, refer to the Dropbox block in the API-DP Helm values.yaml file.
- Enter the URLs for OAuth redirect and Webhook shown below:
- OAuth redirect URL—https://<cluster-FQDN>/v1/dropbox/auth-callback
- Webhook URL—https://<cluster-FQDN>/v1/dropbox/webhook

- Select the Permissions subtab, and then select all Individual Scopes and Team Scopes.
Egnyte for API-DP
To configure Egnyte for API-DP, the service provider registers one Egnyte API key and every customer authorizes that same key against their own Egnyte domain. The token exchange happens against the customer's subdomain, not a central Egnyte endpoint—the customer supplies their domain when granting access. The redirect URI must be entered correctly because it is registered with Egnyte and must match what the connector sends.
The following steps must be completed before onboarding the first customer.
- Register the Egnyte OAuth application.
- From the provider's Egnyte developer account, add the application at https://developers.egnyte.com/my-apps/new-app.

- Enter an application name and description.
- Choose the authorization code flow. See the Egnyte authentication documentation.
- Enter the redirect URI to the connector's auth-callback endpoint: https://<clusterHostname>/v1/egnyte/auth-callback
<clusterHostname> is the global.clusterHostname from the helm/cluster-values/asc-infra/<cluster>.yaml file (for example, cluster.domain.com). The connector builds this URL itself and sends it as redirect_uri on both the authorize and token calls. Egnyte rejects the exchange if the registered value differs in any way, such as by a trailing slash.

- Request approval for both the Prod Collaborate and Prod_SnG APIs, then click Save.

- Store the client id (API key) and client secret securely for later use. Both are needed in Step 3. The secret is also used when revoking access, not just at the time of authorization.

Egnyte issues API keys against a sandbox/trial tier first and requires a separate request to promote a key to production rate limits. Confirm the current process and your key's tier on the developer portal before onboarding real customers. A sandbox key works in testing and then throttles under customer load.
- From the provider's Egnyte developer account, add the application at https://developers.egnyte.com/my-apps/new-app.
- Enable the connector. You must enable Egnyte in two charts, which are disabled by default.
- asc-infra—In the helm/cluster-values/asc-infra/<cluster>.yaml file, under global.services, add the following lines:
global:
services:
egnyte:
enable: true
The common_app_config.yaml file renders global.services into the configuration that the connector reads at runtime. Nothing more needs to be configured—the OAuth credentials travel via the secret in Step 3.
- apidp—In the helm/cluster-values/apidp/<cluster>.yaml file, top level, add the following lines:
egnyte:
enable: true
This entry is the Helm dependency condition. The API-DP chart carries the condition egnyte.enable. If this condition is left unchanged (the default setting is enable: false), the subchart never renders at all. In this case, deployment does not occur and no saas-egnyte-oauth secret for Step 3 to have populated.
Also, you must confirm the global.clusterHostname in the asc-infra values matches the hostname you registered as the redirect URI in Step 1. The hostname feeds base_url in the common_app_config.yaml file, onto which the connector concatenates the callback path.
- asc-infra—In the helm/cluster-values/asc-infra/<cluster>.yaml file, under global.services, add the following lines:
- Set the API key in the secret. The credentials from Step 1 reach the service as a Kubernetes secret, which by default is saas-egnyte-oauth in the apidp namespace. The Kubernetes secret is read at runtime and is used for every tenant's authorization and token refresh.
Secret Key Value client-id Egnyte API key client-secret Egnyte client secret - Add the base64-encoded client id and client secret to the Egnyte block in the API-DP Helm chart values in the helm/cluster-values/apidp/<cluster>.yaml file, the same top-level block you enabled in Step 2b:
egnyte:
enable: true
auth:
secretData:
clientId: "<base64 of the Egnyte API key>"
clientSecret: "<base64 of the Egnyte client secret>"
The values must be base64-encoded — the chart writes them straight into the secret's data: block, which Kubernetes requires to be base64. A raw key fails to deploy. Encode with:
echo -n '<Egnyte API key>' | base64
echo -n '<Egnyte client secret>' | base64
The keys are clientId / clientSecret in values; the chart kebab-cases them (a naming convention that allows a developer to create whitespace between words in code by separating each word with a dash character) to client-id / client-secret in the secret itself.
The helm/apidp/versa/egnyte/values.yaml file carries a default key belonging to another account. Do not edit this file. Rather, override the keys in cluster values as shown above, or else the platform authenticates as that other account against your customers' domains.
- To use a different secret name, set egnyte.auth.secretName (or point egnyte.auth.existingSecret at a secret you manage yourself). The deployment passes the result to the pod as AUTH_SECRET_NAME and the backend reads that, falling back to saas-<app>-oauth. This is not required for most deployments.
- Rotating the key is an edit to the same values plus a helm upgrade. Existing tenants keep working on their stored access and refresh tokens until the next refresh, which will then fail. You should plan a re-grant for each tenant, or rotate the key during a maintenance window.
- Add the base64-encoded client id and client secret to the Egnyte block in the API-DP Helm chart values in the helm/cluster-values/apidp/<cluster>.yaml file, the same top-level block you enabled in Step 2b:
- Verify
- Confirm the the secret holds the provider's own key and not the shipped default with the following command:
kubectl get secret saas-egnyte-oauth -n apidp -o jsonpath='{.data.client-id}' | base64 -d
This command should print your Egnyte client ID. If it prints anything else, it means that the chart default is still in place and Step 3 has not taken effect.
- Onboard one internal test tenant and walk the full grant, as follows:
# connector is actually running (Step 2.2)
kubectl get pods -n apidp | grep egnyte# after clicking Grant Access, the authorize URL should carry YOUR client id, the registered redirect URI, and: # Egnyte.filesystem Egnyte.webhooks Egnyte.permission
# Egnyte.user Egnyte.group Egnyte.link
kubectl logs -n apidp deploy/saas-egnyte | grep "Grant access called" -A2# after consent, a successful exchange stores tokens and creates the webhook;
# these two must NOT appear
kubectl logs -n apidp deploy/saas-egnyte | grep -E "Failure in auth_callback|Webhook Creation Failed"
A grant that completes but logs Webhook Creation Failed leaves a tenant that looks healthy while receiving no change events. The authorization succeeded but the webhook registration against the customer's domain did not—read the Egnyte error in the pod log to see why this happened.
- Confirm the the secret holds the provider's own key and not the shipped default with the following command:
Troubleshooting
| Symptom | Likely Cause |
|---|---|
|
Egnyte consent screen errors before showing consent |
Redirect URI registered with Egnyte does not match https://<clusterHostname>/v1/egnyte/auth-callback (Step 1b), or global.clusterHostname was changed after registration. |
|
Failure in auth_callback right after consent |
Client secret wrong, still the chart default, or a trailing newline picked up when base64-encoding (Step 3). |
|
invalid_client from the token endpoint |
Same as above—the secret is what the exchange authenticates with. |
|
Grant succeeds, Webhook Creation Failed in the log |
Webhook registration against the customer's domain was rejected. Check the Egnyte error in the pod log. |
|
Tenant authorized, no change events, no webhook error |
Customer's Egnyte domain cannot reach https://<clusterHostname>/v1/egnyte/webhook—the cluster hostname must be publicly resolvable |
|
Refresh failures on previously healthy tenants |
API key rotated or revoked on the Egnyte side; tenants need a re-grant. |
|
Connector not running at all |
egnyte.enable still false in apidp cluster values (Step 2b)—the subchart is gated on it |
GitHub for API-DP
- Navigate to https://github.com and log in.
- Click your profile icon in the top-right corner of the GitHub interface.

- Select Settings from the drop-down menu.

- In the left menu, choose Developer Settings.

- Click GitHub Apps on the Developer Settings section, and then click New GitHub App.

- Enter the following application details:
Field Description GitHub App name
Enter a unique name for your GitHub App (for example, Versa Networks).
Homepage URL (Optional)
Add a URL that users can visit for more information (for example, https://versa-networks.com).
Callback URL
Enter https://<cluster-FQDN>/v1/github/auth-callback.
Webhook URL
Enter https://<cluster-FQDN>/v1/github/webhook.
Permissions
Repository permissions:
- Administration—Read and write
- Contents—Read and write
- Webhooks—Read and write
Organization permissions:
- Administration—Read only
- Events—Read only
- Members—Read and write
- Personal access tokens—Read and write
- Webhooks—Read and write
Account permissions:
- Email addresses—Read only
Subscribe to events
Member, Push, and Repository.
Where can this GitHub App be installed?
Enter Any account.
- Retain the default values for the remaining fields.
- Click Create GitHub App to create the app.

- After creating the GitHub App, copy the Client ID and Public link.

- Click the “Generate a new client secret” button.

- Copy the generated client secret.

- Click “Save changes”.
Note: For details about configuring and using the saved credentials and public link from steps 9 and 11, please refer to the GitHub block in the API-DP Helm values.yaml file.
Gmail for API-DP
- Navigate to the Google Cloud Console at https://console.cloud.google.com and log in.
- Locate the project where you want to create the application, and then search for APIs & Services in the search bar and select the project from the results.

- Select Credentials in the left menu.

- Click + CREATE CREDENTIALS in the top menu bar, and then choose OAuth client ID from the drop-down list.

- Click the Application type field, and select Web Application from the drop-down list.

- In the Name field, enter a name to identify the application.
- In the Authorized redirect URIs section, click + ADD URI.

- Enter the URI using the following format, then click Create:
- https://<cluster-FQDN>/v1/gmail/auth-callback

- https://<cluster-FQDN>/v1/gmail/auth-callback
- After the credentials are created, a popup window appears with the Client ID and Client Secret. Store these for later use.

- Click “OK” and navigate to the OAuth consent screen from the left-hand navigation bar.

- Navigate to the Branding section and then enter the required application details.

- Navigate to the Audience section, set the User Type to External, and then publish the app to production.

- Create a service account:
- Repeat Steps 1-3 above to navigate to the Credentials tab, click + CREATE CREDENTIALS in the top menu bar, and then select Service account from the drop-down list.

- Enter the required details, and then click Create and Continue.
- Click the newly created service account (It may take up to a minute to appear), and then navigate to the Keys tab.

- Click Add Key > Create new key.

- Select JSON as the key type, and then click Create. Your credentials are downloaded automatically in a JSON file. Store this file securely.
Note: For details about configuring and using the saved credentials from Steps 9 and Step 13e, refer to the Gmail block in the API-DP Helm values.yaml file.
- Repeat Steps 1-3 above to navigate to the Credentials tab, click + CREATE CREDENTIALS in the top menu bar, and then select Service account from the drop-down list.
Google Drive for API-DP
- Create a Google Cloud project.
- Navigate to the Google Cloud Console: https://console.cloud.google.com/.
- Sign in with your Google Account.
- Click on the project drop-down (top left, next to Google Cloud).
- Click New Project.
- In the Select a resource screen, enter your project details, and then click Create.

- To enable billing:
- Navigate to the Billing Section at https://console.cloud.google.com/billing.
- Select your newly-created project.
- If no billing account exists, click Create Account.
- Attach the Billing Account to your project.
- To enable Google Drive API:
- Navigate to the API Library at https://console.cloud.google.com/apis/library.
- Search for Google Drive API.
- Click on Google Drive API and enable it.

- To create a service account (this allows your application to authenticate without user intervention):
- Navigate to Service Accounts at:
https://console.cloud.google.com/iam-admin/serviceaccounts. - Select your project.
- Click + Create Service Account.
- Enter the details of the account.
- Click Create and Continue.
- Grant roles.
- Click Continue, and then click Done.

- Navigate to Service Accounts at:
- Generate a JSON Key for the service account.
- In the Service Accounts page, click on your newly-created service account.
- Navigate to the Keys tab.
- Click Add Key > Create new key.
- Select JSON as the key type.
- Click Create.

Note: Your credentials are downloaded automatically in a JSON file. Store this file securely. It contains sensitive information.
- Enable domain-wide delegation.
- Navigate to the Service Accounts page at https://console.cloud.google.com/iam...erviceaccounts.
- Select the service account.
- Click Edit.
- Click the checkbox for Create Google Workspace marketplace-compatible oauth client.
- Enter a name for the OAuth consent screen (if prompted).
- Save the changes.
- Copy the Client ID shown on the page and store it for later use.

- Create OAuth Client for Grant Access flow.
- Navigate to Google Cloud Console.
- Select your project or create a new one.
- Navigate to APIs & Services > Credentials.
- Click Create Credentials > OAuth Client ID.
- Set application type. For a web app, select Web application.
- Configure Authorized Redirect URIs, for example, https://<cluster-FQDN>/v1/gdrive/auth-callback.
- Click Create.
- Copy the Client ID and Client Secret and store them for later use.

- API Quotas
- Navigate to IAM & Admin > Quotas & System Limits > Google Drive API.
- The screen displays the default quotas.

- To request more quotas, enter a quota value and click SUBMIT REQUEST.
Pre Grant-Access Steps
- If you are using a Google Workspace domain, grant API scopes in the Google Admin Console (For Workspace Admins).
- Navigate to the Google Admin Console at https://admin.google.com/.
- Go to Security > Access and Data Control > API Controls > Domain-wide Delegation.
- Click Add new.
- Paste the Client ID (from the previous steps).
- Enter the OAuth Scopes required for the Google Drive API (comma-separated):
"openid",
"email",
"profile",
"https://www.googleapis.com/auth/drive"
"https://www.googleapis.com/auth/drive.file"
"https://www.googleapis.com/auth/drive.readonly"
"https://www.googleapis.com/auth/driv...adata.readonly"
"https://www.googleapis.com/auth/drive.appdata"
"https://www.googleapis.com/auth/drive.metadata"
"https://www.googleapis.com/auth/drive.photos.readonly"
"https://www.googleapis.com/auth/admi....user.readonly"
"https://www.googleapis.com/auth/admi...group.readonly"
"https://www.googleapis.com/auth/admi....user.security"
"https://www.googleapis.com/auth/admi...ember.readonly"
"https://www.googleapis.com/auth/admi...omain.readonly"
"https://www.googleapis.com/auth/admi...audit.readonly"
"https://www.googleapis.com/auth/admi...y.group.member"
"https://www.googleapis.com/auth/admin.directory.group"
"https://www.googleapis.com/auth/admin.directory.user"
"https://www.googleapis.com/auth/admin.datatransfer"
"https://www.googleapis.com/auth/admi...ctory.customer"
- Click Authorize.

Jira for API-DP
Configure Jira for Authentication
- Navigate to https://developer.atlassian.com/console/myapps/ and log in.
- Click Create in the My apps section, and then select OAuth 2.0 integration.

- Enter the application name in the new window, select Access type as Account-level, click the checkbox to agree to the terms, and then click Create.

- Navigate to the Permissions tab, and then click the Add action for Jira API.

- Click the Configure action for Jira API.

- In the new window, under Classic scopes, click Edit Scopes.

- Assign the following permissions to the application:
- read:jira-user
- read:jira-work
- write:jira-work
- manage:jira-webhook
- manage:jira-data-provider
- manage:jira-configuration
- manage:jira-project
- After assigning permissions, navigate to the Authorization tab, and then click the Add action for OAuth 2.0.

- Enter the Callback URL below, and then click Save changes.
- Callback URL—https://<cluster-FQDN>/v1/jira/auth-callback

- Callback URL—https://<cluster-FQDN>/v1/jira/auth-callback
- Go to the Distribution tab, and then click Edit.

- Select Distribution Status as Sharing, enter all details, and select Yes for the Personal Data Declaration, as shown below and save changes.

- Navigate to the Overview > App information or Settings, copy the Client ID and Client Secret, and store them for later use.

Configure Jira for Real-Time Event Monitoring
Use the procedure below to create the Atlassian Forge app that captures Jira events and forwards them to API-DP for event monitoring.
- Install the Forge CLI. Refer to Atlassian's setup guide at https://developer.atlassian.com/platform/forge/getting-started/, which covers installing Node.js 22.x or 24.x (LTS), using nvm, and installing the Forge CLI.
- Log in with your Atlassian developer account:
forge login
Authenticate using your Atlassian developer account email and a Forge CLI-scoped API token generated at https://go.atlassian.com/forge-cli-api-token.
- Create the app:
forge create
When prompted:
- Select a developer space (create one if you don't already have one).
- Provide a name for the app.
- Select Show All for both the platform tool and category prompts, then choose the blank template.
- Go to the app directory and install dependencies:
cd <app_name>
Before making any changes, copy the generated app.id value from the manifest.yml. file This is the app's permanent identity and is required in the next step.
- Replace the generated manifest.yml file with the following. Before saving, update:
- The app ID—Paste the value copied in Step 4 in place of APP-ID.
- The cluster hostname—Enter your API-DP cluster hostname in place of CLUSTER-HOSTNAME (must match the hostname you set in Step 7 below).
app:
id: ari:cloud:ecosystem::app/APP-ID # Paste the ID copied in Step 4
runtime:
name: nodejs22.x
modules:
trigger:
- key: on-issue-created
function: forwardToApiDp
events:
- avi:jira:created:issue
- key: on-issue-updated
function: forwardToApiDp
events:
- avi:jira:updated:issue
- key: on-issue-deleted
function: forwardToApiDp
events:
- avi:jira:deleted:issue
- key: on-comment-activity
function: forwardToApiDp
events:
- avi:jira:commented:issue
- key: on-comment-deleted
function: forwardToApiDp
events:
- avi:jira:deleted:comment
- key: on-project-created
function: forwardToApiDp
events:
- avi:jira:created:project
- key: on-project-updated
function: forwardToApiDp
events:
- avi:jira:updated:project
- key: on-project-deleted
function: forwardToApiDp
events:
- avi:jira:deleted:project
- key: on-project-soft-deleted
function: forwardToApiDp
events:
- avi:jira:softdeleted:project
- key: on-project-restored
function: forwardToApiDp
events:
- avi:jira:restored:project
- key: on-project-archived
function: forwardToApiDp
events:
- avi:jira:archived:project
- key: on-project-unarchived
function: forwardToApiDp
events:
- avi:jira:unarchived:project
function:
- key: forwardToApiDp
handler: index.run
permissions:
scopes:
- read:jira-work
external:
fetch:
backend:
- address: https://CLUSTER-HOSTNAME # Enter your API-DP cluster hostname
- Delete the generated source file(s) and create src/index.js with the following handler:
const WEBHOOK_PATH = '/v1/jira/webhook';
export async function run(event, context) {
const apiDpHost = process.env.HOST_URL;
if (!apiDpHost) {
console.error('[API-DP] HOST_URL is not set - aborting');
return;
}
const cloudId = (context.installContext ?? '').split('/').pop();
const targetUrl = `${apiDpHost}${WEBHOOK_PATH}`;
const payload = {
event_type: event.eventType,
cloud_id: cloudId,
timestamp: new Date().toISOString(),
data: event,
};
try {
const response = await fetch(targetUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) {
console.error(`[API-DP] Delivery failed -> ${targetUrl} | ${response.status}`);
} else {
console.log(`[API-DP] Delivered ${event.eventType} event successfully ->
${targetUrl} | ${response.status}`);
}
} catch (err) {
console.error(`[API-DP] Error -> ${targetUrl} | ${err.message}`);
}}
- Set the API-DP host as an environment variable for both Forge environments:
forge variables set --environment development \
HOST_URL https://CLUSTER-HOSTNAME
forge variables set --environment production \
HOST_URL https://CLUSTER-HOSTNAME
- Run the forge lint command to check for errors, then deploy and install to a sandbox site for testing:
forge deploy --environment development forge install --environment development
Select Jira and enter the sandbox site. Create a test issue, comment, or project, and confirm delivery with the forge logs command (a 200 response indicates success).
- Once testing passes, deploy to production:
forge deploy --environment production
- Distribute the app:
- Go to https://developer.atlassian.com/console/myapps, select the app, and open Manage > Distribution. Under Distribution controls, click Edit, then set Distribution Status to Sharing.
- Provide the app details—Company/Department, customer support contact, privacy policy, and terms of service. Select Yes for "Does your app store personal data?", and then click Save changes.
- Under Installation link settings, select Jira as the product to generate the installation URL. Copy it and save it for later use.
- Go to the Settings tab, provide the app name and description, and save the changes.
Note: For details about configuring and using the saved credentials from Configure Jira for Authentication section and the installation URL from the Configure Jira for Real-Time Event Monitoring section, refer to the jira block in the API-DP Helm values file.
Microsoft OneDrive API-DP
- Navigate to https://portal.azure.com.
- Select App Registrations.
- Click New Registration.

- Enter details as shown below:
- Name—Enter a name for the application.
- Supported account types—Select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant).
- Redirect URL—Select Web as the URL type, and enter the URL in the following format:
https://<cluster-FQDN>/v1/msonedrive/auth-callback

- Click Register to complete the registration.
- Record the application (client) ID and store it for later use.

- In the left menu bar, select Certificates & secrets.
- Click + New client secret.

- Enter a description and expiry time, and then click Add at the bottom of the page.
- Copy the Value (not the Secret ID) and store it for later use. Note that this value is not accessible once you leave the page.
Note: For details on configuring and using the saved credentials from Step 5 and Step 9, refer to the msonedrive block in the API-DP Helm values.yaml file.
- Assign API permissions in the created application:
- In the newly created application's left menu bar, click API Permissions, and then select the + Add a permission option.
- Assign all permissions shown in the following table.
Permission
Type
Description
Application.Read.All
Application
Read all applications
Application.ReadWrite.All
Application
Read and write all applications
Directory.Read.All
Application
Read directory data
Directory.ReadWrite.All
Application
Read and write directory data
Domain.ReadWrite.All
Application
Read and write domains
Files.Read.All
Application
Read files in all site collections
Files.ReadWrite.All
Application
Read and write files in all site collections
Mail.ReadWrite
Application
Read and write mail in all mailboxes
MailboxSettings.ReadWrite
Application
Read and write all user mailbox settings
offline_access
Delegated
Maintain access to data you have given it access to
Sites.FullControl.All
Application
Have full control of all site collections
Sites.Manage.All
Application
Create, edit, and delete items and lists in all site collections
Sites.Read.All
Application
Read items in all site collections
Sites.ReadWrite.All
Application
Read and write items in all site collections
User.Read
Delegated
Sign in and read user profile
User.Read.All
Application
Read all users' full profiles
-
After adding permissions, select Grant admin consent for <org_name>.
Microsoft Outlook API-DP
- Navigate to https://portal.azure.com.
- Select App Registrations.
- Click New Registration.

- Enter details as shown below.
- Name—Enter a name for the application.
- Supported account types—Select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant).
- Redirect URL—Select Web as the URL type, and enter the URL in the following format:
- https://<cluster-FQDN>/v1/msoutlook/auth-callback

- https://<cluster-FQDN>/v1/msoutlook/auth-callback
- Click Register to complete the registration.
- Record the application (client) ID and store it for later use.

- In the left menu, select Certificates & secrets.
- Click + New client secret.

- Enter a description and expiry time, and then click on Add at the bottom of the page.
- Record the Value (not the Secret ID) and store it for later use. Note that this value is not accessible once you leave the page.
Note: For details on configuring and using the saved credentials from Step 6 and Step 10, refer to the msoutlook block in the API-DP Helm values.yaml file.
- Assign API permissions in the created application:
- In the newly created application's left menu bar, click API Permissions, then select the + Add a permission option.
- Assign all required Microsoft Graph permissions by selecting each permission type individually.
Permission
Type
Description
AuditLog.Read.All
Application
Application Read all audit log data
Directory.Read.All
Delegated
Read directory data
Directory.Read.All
Application
Read directory data
Domain.Read.All
Application
Application Read domains
Mail.ReadWrite
Application
Application Read and write mail in all mailboxes
MailboxSettings.Read
Application
Application Read all user mailbox settings
offline access
Delegated
Maintain access to data you have given it access to
Organization.Read.All
Application
Application Read organization information
User.Read.All
Application
Application Read all users' full profiles
-
After adding permissions, select Grant admin consent for <org_name>.
Microsoft SharePoint API-DP
- Navigate to https://portal.azure.com.
- Select App Registrations.
- Click New Registration.

- Enter the details shown below:
- Name—Enter a name for the application.
- Supported account types—Select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant).
- Redirect URL—Select URL type as Web and enter the URL in the following format:
- https://<cluster-FQDN>/v1/mssharepoint/auth-callback

- https://<cluster-FQDN>/v1/mssharepoint/auth-callback
- Click Register to complete the registration.
- Record the application (client) ID and store it for later use.

- In the left menu, select Certificates & secrets.
- Click + New client secret.

- Enter a description and expiry time, and then click on Add at the bottom of the page.
- Record the Value (not the Secret ID) and store it for later use. Note that this value is not accessible once you leave the page.
Note: For details on configuring and using the saved credentials from step 6 and 10, refer to the mssharepoint block in the API-DP Helm values.yaml file.
- Assign API permissions in the created application:
- In the newly created application's left menu bar, click API Permissions, then select the + Add a permission option.
- Assign all required Microsoft Graph permissions by selecting each permission type individually.
Permission
Type
Description
Application.Read.All
Application
Read all applications
Application.ReadWrite.All
Application
Read and write all applications
Directory.Read.All
Application
Read directory data
Directory.ReadWrite.All
Application
Read and write directory data
Domain.ReadWrite.All
Application
Read and write domains
Files.Read.All
Application
Read files in all site collections
Files.ReadWrite.All
Application
Read and write files in all site collections
Mail.ReadWrite
Application
Read and write mail in all mailboxes
MailboxSettings.ReadWrite
Application
Read and write all user mailbox settings
offline_access
Delegated
Maintain access to data you have given it access to
Sites.FullControl.All
Application
Have full control of all site collections
Sites.Manage.All
Application
Create, edit, and delete items and lists in all site collections
Sites.Read.All
Application
Read items in all site collections
Sites.ReadWrite.All
Application
Read and write items in all site collections
User.Read
Delegated
Sign in and read user profile
User.Read.All
Application
Read all users' full profiles
Microsoft Teams API-DP
- Navigate to https://portal.azure.com.
- Select App Registrations.
- Click New Registration.

- Enter the following details:
- Name—Enter a name for the application.
- Supported account types—Select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant).
- Redirect URL—Select Web as the URL type, and then enter the URL in the following format:
- https://<cluster-FQDN>/v1/msteams/auth-callback

- https://<cluster-FQDN>/v1/msteams/auth-callback
- Click Register to complete the registration.
- Record the application (client) ID and store it for later use.

- In the left menu, select Certificates & secrets.
- Click + New client secret.

- Enter a description and expiry time, and then click Add at the bottom of the page.
- Record the Value (not the Secret ID) and store it for later use. Note that this value is not accessible once you leave the page.
Note: For details on configuring and using the saved credentials from step 6 and 10, refer to the msteams block in the API-DP Helm values.yaml file.
- Assign API permissions in the created application:
- In the newly created application's left menu bar, click API Permissions, and then select the + Add a permission option.
- Assign all required Microsoft Graph permissions by selecting each permission type individually.
Permission
Permission Type
Description
offline_access
Delegated Permission
Maintain access to data you have given it access to
ChatMessage.Send
Delegated Permission
Send user chat messages
Directory.Read.All
Delegated Permission
Read directory data
ChannelMessage.Send
Delegated Permission
Send channel messages
Channel.ReadBasic.All
Application Permission
Read the names and descriptions of all channels
ChannelMessage.Read.All
Application Permission
Read all channel messages
ChannelMessage.UpdatePolicy
Application Permission
Flag channel messages for violating policy
Chat.Read.All|
Application Permission
Read all chat messages
Chat.ReadWrite.All
Application Permission
Read and write all chat messages
Chat.UpdatePolicyViolation
Application Permission
Flag chat messages for violating policy
ChatMessage.Read.All
Application Permission
Read all chat messages
Directory.Read.All
Application Permission
Read directory data
Organization.Read.All
Application Permission
Read organization information
Team.ReadBasic.Alll
Application Permission
Get a list of all teams
TeamMember.ReadWrite.All
Application Permission
Add and remove members from all teams
User.Read.All
Application Permission
Read all users' full profiles
- After adding permissions, select Grant admin consent for <org_name>.
Microsoft Yammer API-DP
- Navigate to https://portal.azure.com.
- Select App Registrations.
- Click New Registration.

- Enter the following details, then click Register.
- Name: Enter a name for the application.
- Supported account types: Select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant).
- Redirect URL: Select URL type as Web and enter the URL in the following format:
- https://<cluster-FQDN>/v1/msyammer/auth-callback

The application is registered.
- https://<cluster-FQDN>/v1/msyammer/auth-callback
- Record the application (client) ID.

- In the left menu bar, select Certificates & secrets.
- Click + New client secret.

- Enter a description and expiry time, and then click on Add at the bottom of the page.
- Immediately copy the Value (not the Secret ID) to somewhere safe. Note that this value will no longer be accessible after you leave the page.
Note: For details on configuring and using the saved credentials from step 5 and 9, refer to the msyammer block in the API-DP Helm values.yaml file.
- Assign API permissions in the created application:
- In the newly created application's left menu bar, click API Permissions, then select the + Add a permission option.
- Select following permissions one by one and click Add Permission.
- Under Microsoft graph > Delegated permission >. User.Read.
- Under Yammer > Delegated permission > access_as_user.

Notion for API-DP
To create a new API-DP integration in Notion:
- Click the three dots in the upper right corner of the screen, and then select Add connections > Manage connections.

- Select My connections > Develop or manage integrations.

- In the Integrations screen, click + New Integration.

- In the APIDP-Notion screen, enter a name in the Company name field.

- Set the integration to public.
- Connect to one workspace and fill out the required information.
- Under OAuth Domain & URIs, enter the Redirect URI using the following format and then click Save:
https://<cluster-FQDN>/v1/notion/auth-callback

- The OAuth Client-ID and OAuth Client Secret are displayed under Secrets. Record and store them for later use.

Salesforce for API-DP
- Login to https://login.salesforce.com/ and navigate to Setup.
- In the left menu, click Platform Tools > Apps > External Client Apps > Settings.

- Turn on Allow creation of connected apps, if available, and click New Connected App.

- Enter the required information for the app, including the name, API name, contact email, and description.

- In the API (Enable OAuth Settings) section, click the checkbox for Enable OAuth Settings.

- Enter the Callback URL for the app in the format shown below, and then select the full and refresh_token scopes, as shown below:
- Callback URL: https://<cluster-FQDN>/v1/salesforce/auth-callback

- Callback URL: https://<cluster-FQDN>/v1/salesforce/auth-callback
- Retain the default settings for the remaining fields, and save the changes.
- Click Manage Consumer Details, which displays a Consumer Key and Consumer Secret, and save these credentials for later use.

- Run the script provided by Versa Networks and follow the onscreen instructions to obtain the app ID and save it for later use.
Note: For details on configuring and using the saved credentials from Step 8 and app ID from Step 9, refer to the Salesforce block in the API-DP Helm values.yaml file.
ServiceNow for API-DP
No configuration is required for ServiceNow.
Slack for API-DP
- Navigate to https://api.slack.com/apps and log in.
- Click Create New App. and then select From an app manifest.

- Select the workspace to develop the app, and then click Next.

- Choose either YAML or JSON, erase the default content, and paste the app manifest provided below in Slack for Application Manifests (by replacing the placeholders for the app name, auth callback, and webhook URLs), then proceed to the next step.

- Confirm the details, and then click Create.

- Under Settings, select Manage Distribution.

- Click to expand the Remove Hard Coded Information section, and then click the checkbox to continue.

- Click on Activate Public Distribution at the bottom of the page.

- Under the Event Subscriptions tab, make sure you do not see "Your URL didn't respond". If you do see this message, as shown below, click Retry.

- Navigate to the Basic Information tab.
- Copy the Client ID, Client Secret, and Signing Secret, and store them for later use.
Note: For details on configuring and using the saved credentials, refer to the Slack block in the API-DP Helm values.yaml file.
Slack for Application Manifests
Copy and paste the following application manifests for JSON and YAML as described in Step 4 above.
|
JSON |
|
{ "display_information": { "name": <APP NAME> }, "features": { "app_home": { "home_tab_enabled": false, "messages_tab_enabled": true, "messages_tab_read_only_enabled": true }, "bot_user": { "display_name": <APP NAME>, "always_online": true } }, "oauth_config": { "redirect_urls": [ https://<cluster-FQDN>/v1/slack/auth-callback ], "scopes": { "user": [ "channels:history", "channels:read", "groups:history", "groups:read", "im:history", "im:read", "mpim:history", "mpim:read" ], "bot": [ "channels:history", "channels:read", "groups:history", "groups:read", "im:history", "im:read", "mpim:history", "mpim:read" ] } }, "settings": { "event_subscriptions": { "request_url": https://<cluster-FQDN>/v1/slack/webhook, "user_events": [ "channel_archive", "channel_created", "channel_deleted", "channel_id_changed", "channel_rename", "channel_shared", "channel_unarchive", "channel_unshared", "group_archive", "group_deleted", "group_open", "group_rename", "group_unarchive", "im_created", "member_joined_channel", "member_left_channel", "message.channels", "message.groups", "message.im", "message.mpim" ] }, "org_deploy_enabled": false, "socket_mode_enabled": false, "token_rotation_enabled": true } } |
|
YAML |
|
display_information: name: <APP NAME> features: app_home: home_tab_enabled: false messages_tab_enabled: true messages_tab_read_only_enabled: true bot_user: display_name: <APP NAME> always_online: true oauth_config: redirect_urls: - https://<cluster-FQDN>/v1/slack/auth-callback scopes: user: - channels:history - channels:read - groups:history - groups:read - im:history - im:read - mpim:history - mpim:read bot: - channels:history - channels:read - groups:history - groups:read - im:history - im:read - mpim:history - mpim:read settings: event_subscriptions: request_url: https://<cluster-FQDN>/v1/slack/webhook user_events: - channel_archive - channel_created - channel_deleted - channel_id_changed - channel_rename - channel_shared - channel_unarchive - channel_unshared - group_archive - group_deleted - group_open - group_rename - group_unarchive - im_created - member_joined_channel - member_left_channel - message.channels - message.groups - message.im - message.mpim org_deploy_enabled: false socket_mode_enabled: false token_rotation_enabled: true |
Trello for API-DP
- Navigate to https://trello.com/power-ups/admin and log in.
- Click the Get Started button or navigate to the Apps section.
- Click the New button to start the application creation process.

- Fill in the required details for your application, including the name, Workspace, and any relevant URLs, then click Create.

- Navigate to API key tab, and then click Generate a new API key.

- In the Allowed origins field, enter the Callback URL in the format shown below, and then click Add:
- Callback URL: https://<cluster-FQDN>/v1/trello/auth-callback

- Callback URL: https://<cluster-FQDN>/v1/trello/auth-callback
- Copy the API key and Secret and store them for later use.
Note: For details on configuring and using the saved credentials, refer to the Trello block in the API-DP Helm values.yaml file.
Zendesk for API-DP
- Click the Settings icon in the left menu, and then click Go to Admin Center.

- Add the OAuth client by navigating to Admin Center > Apps and Integrations > APIs > Zendesk API > OAuth Client > Add OAuth Client.

- Set the Unique identifier and Type to be confidential, enter the Redirect URL in the format shown below, and then generate the secret:
- Redirect URL: https://<cluster-FQDN>/v1/zendesk/auth-callback

- Redirect URL: https://<cluster-FQDN>/v1/zendesk/auth-callback
- Click Save.
- Store the secret for later use. The unique identifier and secret is the client-id and client-secret used to grant access.
- To create the webhook, go to Apps and integrations > Webhooks > Create Webhook.

- In the Create webhook screen, select Trigger or automation.

- Enter the endpoint URL in the format shown below, the request method (POST), and the format (JSON):
- Endpoint URL: https://<cluster-FQDN>/v1/zendesk/webhook

- Endpoint URL: https://<cluster-FQDN>/v1/zendesk/webhook
- To create a Trigger, go to Objects and rules > Triggers > Add Trigger.

- Add conditions when an event happens (in this case, when comment is created or updated).

- For Actions, choose the webhook created.

- Customize the JSON body:
{ "user": { "id": "{{current_user.id}}", "name": "{{current_user.name}}", "email": "{{ticket.requester.email}}" }, "obj_owner":{ "name": "{{ticket.requester.name}}", "email": "{{ticket.requester.email}}" }, "tenant": { "id" : "{{current_user.organization.id}}", "name" : "{{ticket.brand.name}}" }, "created_at": "{{ticket.updated_at_with_timestamp}}", "ticket_id" : "{{ticket.id}}", "obj_id": "{{ticket.latest_comment.id}}", "subject": "{{ticket.title}}", "content": "{{ticket.latest_comment.value}}", "attachments": [ {% for attachment in ticket.latest_comment.attachments %} { "name": "{{attachment.filename}}", "url": "{{attachment.url}}" }{% unless forloop.last %},{% endunless %} {% endfor %} ] }
Zoom for API-DP
Note: All steps should be performed from the Admin Account.
- Navigate to Account Settings.

- Navigate to Admin -> App Marketplace.
- In the App Marketplace, select Build App from the drop-down list in the top right corner.

- Click General App, and then click Create.

- Copy the Client ID and Secret and store them for later use.

- Add the OAuth Redirect URL in the format shown below, and then click Continue:
Redirect URL: https://<cluster-FQDN>/v1/zoom/auth-callback

- Get the token for event subscription.

- Enable and configure event subscription.
- Set Webhook for file-send/message-send and Webhook Event notification endpoint URL in the following format:
Event notification endpoint URL: https://<cluster-FQDN>/v1/zoom/webhook

- Team Chat DM Message Posted
- Team Chat DM Message Updated
- Team Chat DM Message Deleted
- Team Chat Channel Message Posted
- Team Chat Channel Message Updated
- Team Chat Channel Message Deleted
- Team chat file uploaded
- Team chat file changed
- Team chat file deleted
- Set Webhook for meeting-join/channel-join and Webhook Event notification endpoint URL.


- Meeting
- Participant/Host joined meeting
- Chat Channel
- Chat Channel Created
- Chat Channel Updated
- Chat Channel Deleted
- Member Invited
- Member Removed
- Member Joined
- Meeting
- Set Webhook for file-send/message-send and Webhook Event notification endpoint URL in the following format:
- Click Save and continue.
- Click Continue for Surface configuration.

- Click Continue for Embed configuration.

- On the next screen “Add Scopes”, search and add scopes as shown in the below screens.




Account- account:read:account_setting:master — View an account's settings
- account:read:settings:master — View an account's settings
- account:read:account_setting:admin — View an account's settings
- account:read:settings:admin — View an account's settings
- account:read:lock_settings:admin — View an account's lock settings
- account:read:managed_domains:admin — View an account's managed domains
- account:read:registration_settings:admin — View an account's registration settings
- account:read:vanity_url:admin — View an account's vanity URL
- account:read:entitlement:admin — View an account's entitlement
- account:read:trusted_domains:admin — View an account's trusted domains
- Meeting
- meeting:read:participant:admin — View a meeting's participant
- meeting:read:participant:master — View a meeting's participant
- Recording
- cloud_recording:read:list_user_recordings:admin — Lists all cloud recordings for a user
- Team Chat
- app:channel_content:write:admin — Enable Chatbot within Zoom Team Chat Channel
- imchat:bot — Enable Chatbot within Zoom Team Chat Client
- team_chat:update:chat_control:admin — Update a chat control
- team_chat:write:legal_hold_matter:admin — Add legal hold matter
- team_chat:delete:legal_hold_matter:admin — Delete legal hold matter
- team_chat:update:legal_hold_matter:admin — Update legal hold matter
- team_chat:delete:file:admin — Delete a chat file
- team_chat:write:migrate_dm_conversation_or_channel_operations:admin — Migrate DM conversation and channel operation
- team_chat:write:migrate_chat_messages:admin — Migrate chat messages
- team_chat:write:migrate_channel_members:admin — Migrate channel members
- team_chat:write:migrate_a_chat_channel:admin — Migrate a chat channel
- team_chat:write:migrate_chat_message_reactions:admin — Migrate chat message reactions
- team_chat:write:contact_information:admin — Send contact invitation
- team_chat:read:list_user_channels:admin — View a user's chat channels
- team_chat:read:list_channels:admin — View chat channels
- team_chat:read:channel:admin — View a chat channel
- team_chat:read:user_channel:admin — View a user's chat channel
- team_chat:read:list_members:admin — View a chat channel's members
- team_chat:read:list_invitations:admin — List a user's pending invitations
- team_chat:read:list_administrators:admin — View a chat channel's admins
- team_chat:read:mention_group:admin — List all the mention groups in a channel
- team_chat:read:list_channel_activity_logs:admin — Channel activity logs for specific channel
- team_chat:read:list_user_sessions:admin — View a user's chat sessions
- team_chat:read:list_user_messages:admin — View a user's chat messages
- team_chat:read:user_message:admin — View a user's chat message
- team_chat:read:thread_message:admin — Retrieve messages under a thread
- team_chat:read:list_bookmarks:admin — List user's bookmarks
- team_chat:delete:member:admin — Remove a chat channel's member
- team_chat:delete:user_channel:admin — Delete a user's chat channel
- team_chat:update:mention_group:admin — Update the mention group's information
- team_chat:delete:channels:admin — Delete channels
- team_chat:write:mention_group:admin — Create a mention group
- team_chat:update:retention:admin — Update retention policy of a channel
- team_chat:write:groups:admin — Add groups to a chat channel
- team_chat:read:retention:admin — Get retention policy of a channel
- team_chat:write:administrator:admin — Add administrators to a chat channel
- team_chat:write:user_channel:admin — Create a chat channel for a user
- team_chat:delete:channel:admin — Delete a chat channel
- team_chat:write:members:admin — Add members to a chat channel
- team_chat:delete:group:admin — Remove a chat channel's member group
- team_chat:write:search_channels:admin — Search account's channels
- team_chat:update:channel:admin — Update a chat channel
- team_chat:delete:mention_group:admin — Delete a mention group
- team_chat:update:user_channel:admin — Update a user's chat channel
- team_chat:update:archive_channels:admin — Archive or unarchive channels
- team_chat:read:list_groups:admin — View a chat channel's member groups
- team_chat:delete:batch_members:admin — Remove a chat channel's members
- team_chat:delete:batch_administrators:admin — Remove a chat channel's admins
- team_chat:delete:user_message:admin — Delete a user's chat message
- team_chat:write:user_message:admin — Create a chat message for a user
- team_chat:write:message_files:admin — Add files to chat messages
- team_chat:write:files:admin — Add files to chat
- team_chat:update:user_message:admin — Update a user's chat message
- team_chat:update:message_emoji:admin — Update a user's chat message emoji reaction
- team_chat:update:message_status:admin — Update a user's chat message read status
- team_chat:read:file:admin — Get chat file information
- team_chat:read:migrated_channels:admin — Get migrated chat channels
- team_chat:read:migrated_users:admin — Users can view migrated chat users
- User
- user:read:token:admin — View a user's token
- user:read:list_assistants:admin — View a user's assistants
- Users
- user:read:list_users:admin — View users
- user:read:user:admin — View a user
- user:read:user:master — View a user
- After selecting the scopes, click Continue. The app is configured.
Amazon Web Services for API-DP
The information in this section applies to service providers who operate the API-DP platform and provide the API-DP services to their customers, and covers the one-time provider-side setup that should be completed before onboarding the first customer. The provider's customers own the AWS accounts that are being protected. For information about the per-customer steps, such as granting access, downloading the aws_cft.zip file, and deploying the CloudFormation templates, see Configure Cloud Applications to Use with API-Based Data Protection.
Amazon Web Services (AWS) is an IaaS connector, so the provider does not need to register an OAuth application. Access works as follows:
- The provider holds one long-lived identity and access manager (IAM) user.
- Each customer creates a cross-account role that trusts it.
The provider never holds customer credentials. It holds only its own IAM user, whose sole permission is to assume <Provider>_Role in customer accounts. The provider name is a prefix that is included in every resource created by the customer's stack, so the resource must be created before any customer is onboarded.
The provider performs the following steps before onboarding a customer.
Create the Provider IAM User
In the provider's AWS account:
- Login to the Amazon Web Services (AWS) console and navigate to IAM > Users > Create user.
- In the Specify User Details screen, enter a user name and click Next.

- In the Set Permissions screen, you do not need to set any permissions. The policy will be attached in a later step.
- Click Next to go to the Review and Create screen.
- In the lower-right corner, click Create user.

- In the IAM > IAM Users > <user_name> screen (in this example the user is abc), click the new user's Security credentials tab.

- In the Access keys screen, click Create access key.

- The Access key best practices & alternative screen displays. For this example, select Application running outside AWS so that the connector runs on your Kubernetes cluster, not on the AWS compute node.

- Optionally, set a description tag, or click Create access key.

- In the Retrieve access keys screen, click Download the .csv file and store it securely—the secret access key cannot be retrieved again later.

- In the following window, enter the name for the access key file and select the folder in which to save the file, then click Save.

- Attach the following inline permission policy to the user, replacing <Provider_name> with the actual provider's name.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/<Provider_name>_Role"
}
]
}
- In the Permissions policies screen, click Create inline policy.

- In the Specify permissions screen, add the inline policy shown in Step 12, above.

- In the Review and create screen, enter a policy name, and then click Create policy in the lower-right corner.

This is the complete permission set. It is used for one API call (sts:AssumeRole). Everything that is run after this API call runs on the temporary credentials that the API call returns, inside the customer's account.
The wildcard account in the resource ARN covers every customer account, present and future, with no per-customer edit. It does not grant access to arbitrary accounts. The customer's role must also name this user in its trust policy and match the per-tenant external ID.
Record the account number and IAM user name. Both are needed below in the Configure the Deployment section, below.
Configure the Deployment
- Provider Name—Set the provider name in the helm/cluster-values/asc-infra/<cluster>.yaml, as follows:
global:
providerName: "abc"
The helm/cluster-values/apidp/<cluster>.yaml file also carries a global.providerName; the names should be the same. This name becomes the prefix on the IAM roles and policies created in each customer's account — providerName: "abc" gives the Abc_Role, and so on. It must match the <Provider_name>_Role used in Create the Provider IAM User, above.
Choose the provider name before onboarding the first customer. If you attempt to change the provider name later, the configuration will fail. To recover, you will need to redeploy the stacks in every affected customer account.
- Enable AWS and Set the Trusted Identity—In helm/cluster-values/asc-infra/<cluster>.yaml, under global.services, enter:
global:
services:
aws:
enable: true
iam_user: "<iam user name from Step 1>"
account_number: "<provider account number from Step 1>"
This block specifically—common_app_config.yaml—renders global.services into the configuration the connector reads at runtime. The aws.iam_user / aws.account_number fields in helm/cluster-values/apidp/values-template.yaml are vestigial; nothing reads them. These fields are substituted into the trust policy of the role template the customer downloads, so their <Provider>_Role trusts the provider's IAM user.
aws.enable defaults to false—the connector will not deploy until it is set.
If iam_user or account_number is left empty, the substitution is skipped silently and the customer's role is generated trusting the default account shipped in the template. The customer's stack still deploys cleanly. The failure only appears later as AccessDenied on every assume-role. Set both together.
Set the Access Keys
The access keys from the Create the Provider IAM User section are read at runtime and are used to assume each customer's role.
Despite the OAuth name (which is inherited from the SaaS connectors that do use OAuth), these are IAM access keys, not OAuth credentials:
| Secret Key | Value |
|---|---|
| client-id | AWS access key ID (AKIA...) |
| client-secret | AWS secret access key |
Set them in helm/cluster-values/apidp/<cluster>.yaml. Note that these are the API-DP cluster values, not the asc-infra file used in Step 2 in the Configure the Deployment section, and the aws block here is top-level rather than nested under global.services:
aws:
enable: true
auth:
secretData:
clientId: "<base64 of the AWS access key ID>"
clientSecret: "<base64 of the AWS secret access key>"
The values must be base64-encoded—the chart writes them straight into the secret's data: block, which Kubernetes requires to be base64. A raw access key here fails to deploy. Encode with:
printf '%s' '<AWS access key ID>' | base64
printf '%s' '<AWS secret access key>' | base64
Note: Use printf rather than echo. A trailing newline becomes part of the credential and produces a confusing SignatureDoesNotMatch at runtime.
The keys are clientId / clientSecret in values; the chart kebab-cases them to client-id / client-secret in the secret itself.
helm/apidp/versa/aws/values.yaml carries a default set of keys belonging to another account. Do not edit that file. Rather, override the keys in cluster values as shown above, or the platform authenticates as that other account and cannot assume any role your own customers created.
To use a different secret name, set aws.auth.secretName; the deployment passes it to the pod as AUTH_SECRET_NAME and the backend reads that, falling back to saas-<app>-oauth. Most deployments can leave it alone.
The keys are rotated with no customer-side impact.
Verify
- Onboard one internal test tenant, download aws_cft.zip, unzip it, and check the generated bundle before letting a customer use it:
# 1. your provider prefix applied throughout (expect several matches each)
grep -c "Abc_" aws-instance-role-master.yaml aws-instance-setup-master.yaml
# 1b. and none of the shipped default prefix left behind (expect 0 each)
grep -c "Versa" aws-instance-role-master.yaml aws-instance-setup-master.yaml
# 2. trust policy points at the PROVIDER's account and IAM user
grep "arn:aws:iam::.*:user/" aws-instance-role-master.yaml
# 3. webhook endpoint is the provider's own cluster
grep "Endpoint:" aws-instance-setup-master.yaml
All are provider configurations; if any one is wrong, fix it and regenerate rather than onboarding customers. The bundle is cached per tenant, so after a configuration change, clear the tenant's directory on the saas-aws pod or the same stale zip is served again.
- Confirm the secret is in place and holds the provider's own key:
kubectl get secret saas-aws-oauth -n apidp -o jsonpath='{.data.client-id}' | base64 -d
Troubleshooting
| Symptom | Likely Cause |
|---|---|
| AccessDenied assuming the customer role | iam_user / account_number unset or wrong (Step 2b), or saas-aws-oauth still holds the default keys (Step 3). |
|
InvalidClientTokenId / SignatureDoesNotMatch |
Access keys wrong or deactivated, or a trailing newline picked up when base64-encoding them (Step 3). |
|
Customer re-granted access but the bundle is unchanged |
Cached zip—clear the tenant directory on the saas-aws pod. |
| Connector not running at all | aws.enable is still false (Step 2b). |
Google Cloud Platform for API-DP
No configuration is required for Google Cloud Platform.
Microsoft Azure for API-DP
No configuration is required for Microsoft Azure.
Oracle Cloud Infrastructure for API-DP
No configuration is required for Oracle Cloud Infrastructure.
Supported Software Information
Release 12.2.2 and later support all content described in this article.
