From 6bd2147076a64143250e39e0d0d165abfb9d2a5d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 10:44:32 -0400 Subject: [PATCH 1/4] feat: add soc 2 type 1 badge CS-240 New Framework - Type 1 & badge updates --- .../frameworks/components/FrameworksTable.tsx | 1 + .../components/FrameworksOverview.tsx | 3 + .../components/TrustPortalSwitch.tsx | 91 +- .../portal-settings/components/logos.tsx | 866 ++++++++++++------ 4 files changed, 658 insertions(+), 303 deletions(-) diff --git a/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksTable.tsx b/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksTable.tsx index 8034a3b047..b35763256a 100644 --- a/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksTable.tsx +++ b/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksTable.tsx @@ -47,6 +47,7 @@ const FRAMEWORK_BADGES: Record = { 'PCI DSS Level 1': '/badges/pci-dss.svg', 'NEN 7510': '/badges/nen7510.svg', 'ISO 9001': '/badges/iso9001.svg', + 'SOC 2 Type 1': '/badges/soc2.svg', }; function getFrameworkBadge(name: string): string | null { diff --git a/apps/app/src/app/(app)/[orgId]/overview/components/FrameworksOverview.tsx b/apps/app/src/app/(app)/[orgId]/overview/components/FrameworksOverview.tsx index f11b6c7a54..ea6e1436eb 100644 --- a/apps/app/src/app/(app)/[orgId]/overview/components/FrameworksOverview.tsx +++ b/apps/app/src/app/(app)/[orgId]/overview/components/FrameworksOverview.tsx @@ -62,6 +62,9 @@ export function mapFrameworkToBadge(framework: FrameworkInstanceWithControls) { if (frameworkName === 'ISO 9001') { return '/badges/iso9001.svg'; } + if (frameworkName === 'SOC 2 Type 1') { + return '/badges/soc2.svg'; + } return null; } diff --git a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx index 57340223bf..3448218e14 100644 --- a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx +++ b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx @@ -16,7 +16,6 @@ import { SelectContent, SelectItem, SelectTrigger, - SelectValue, Switch, Tabs, TabsContent, @@ -41,17 +40,25 @@ import { TrustPortalOverview } from './TrustPortalOverview'; import { TrustPortalVendors } from './TrustPortalVendors'; import { UpdateTrustFavicon } from './UpdateTrustFavicon'; import { BrandSettings } from './BrandSettings'; -import type { FaqItem } from '../types/faq'; import { GDPR, + GDPRInProgress, HIPAA, + HIPAAInProgress, ISO27001, + ISO27001InProgress, ISO42001, + ISO42001InProgress, ISO9001, + ISO9001InProgress, NEN7510, + NEN7510InProgress, PCIDSS, + PCIDSSInProgress, SOC2Type1, + SOC2Type1InProgress, SOC2Type2, + SOC2Type2InProgress, } from './logos'; // Client-side form schema (includes all fields for form state) @@ -888,6 +895,43 @@ export function TrustPortalSwitch({ ); } +function ComplianceFrameworkLogo({ title, status, enabled }: { title: string; status: string; enabled: boolean }) { + const isInProgress = status === 'in_progress'; + let LogoComponent: React.ElementType | null = null; + + if (title === 'ISO 27001') { + LogoComponent = enabled && isInProgress ? ISO27001InProgress : ISO27001; + } else if (title === 'ISO 42001') { + LogoComponent = enabled && isInProgress ? ISO42001InProgress : ISO42001; + } else if (title === 'GDPR') { + LogoComponent = enabled && isInProgress ? GDPRInProgress : GDPR; + } else if (title === 'HIPAA') { + LogoComponent = enabled && isInProgress ? HIPAAInProgress : HIPAA; + } else if (title === 'SOC 2 Type 1') { + LogoComponent = enabled && isInProgress ? SOC2Type1InProgress : SOC2Type1; + } else if (title === 'SOC 2 Type 2') { + LogoComponent = enabled && isInProgress ? SOC2Type2InProgress : SOC2Type2; + } else if (title === 'PCI DSS') { + LogoComponent = enabled && isInProgress ? PCIDSSInProgress : PCIDSS; + } else if (title === 'NEN 7510') { + LogoComponent = enabled && isInProgress ? NEN7510InProgress : NEN7510; + } else if (title === 'ISO 9001') { + LogoComponent = enabled && isInProgress ? ISO9001InProgress : ISO9001; + } else { + LogoComponent = null; + } + + if (LogoComponent) { + return ( +
+ +
+ ); + } + + return null; +} + // Extracted component for compliance frameworks to reduce repetition and improve readability function ComplianceFramework({ title, @@ -988,51 +1032,14 @@ function ComplianceFramework({ } }; - const logo = - title === 'ISO 27001' ? ( -
- -
- ) : title === 'ISO 42001' ? ( -
- -
- ) : title === 'GDPR' ? ( -
- -
- ) : title === 'HIPAA' ? ( -
- -
- ) : title === 'SOC 2 Type 1' ? ( -
- -
- ) : title === 'SOC 2 Type 2' ? ( -
- -
- ) : title === 'PCI DSS' ? ( -
- -
- ) : title === 'NEN 7510' ? ( -
- -
- ) : title === 'ISO 9001' ? ( -
- -
- ) : null; - return ( <>
-
{logo}
+
+ +
{title}
diff --git a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx index a140a10a8f..aa0bfffe3a 100644 --- a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx +++ b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx @@ -1,297 +1,483 @@ import * as React from 'react'; export const ISO27001 = (props: React.SVGProps) => ( - + + + + + + + + + +); + +export const ISO27001InProgress = (props: React.SVGProps) => ( + + + + + + + + +); + +export const GDPR = (props: React.SVGProps) => ( + + + + + + + + + ); -export const GDPR = (props: React.SVGProps) => ( - +export const GDPRInProgress = (props: React.SVGProps) => ( + + + + + + + + +); + +export const HIPAA = (props: React.SVGProps) => ( + + + + + + + + +); + +export const HIPAAInProgress = (props: React.SVGProps) => ( + + + + + + + ); -export const HIPAA = (props: React.SVGProps) => ( - +export const SOC2Type1 = (props: React.SVGProps) => ( + + + + + + + + +); + +export const SOC2Type1InProgress = (props: React.SVGProps) => ( + - + + + + + + ); -export const SOC2Type1 = (props: React.SVGProps) => ( - - - - - - - - - - - - - - +export const SOC2Type2 = (props: React.SVGProps) => ( + + + + + + + - - - + + + + ); -export const SOC2Type2 = (props: React.SVGProps) => ( - - - - - - - - - - - - - - +export const SOC2Type2InProgress = (props: React.SVGProps) => ( + + + + + + + - - - + + + + ); @@ -330,178 +516,336 @@ export const PCIDSS = (props: React.SVGProps) => ( strokeWidth="2.5" /> - + ); -export const ISO42001 = (props: React.SVGProps) => ( - + +export const PCIDSSInProgress = (props: React.SVGProps) => ( + - + + + + + + + + +); + +export const ISO42001 = (props: React.SVGProps) => ( + + + + + + + ); -export const NEN7510 = (props: React.SVGProps) => ( - +export const ISO42001InProgress = (props: React.SVGProps) => ( + + + + + + + + + +); + +export const NEN7510 = (props: React.SVGProps) => ( + - - - - - + - - - - + + + + ); -export const ISO9001 = (props: React.SVGProps) => ( +export const NEN7510InProgress = (props: React.SVGProps) => ( + + + + + + + + + +); + +export const ISO9001 = (props: React.SVGProps) => ( + + + + + + + + +); + +export const ISO9001InProgress = (props: React.SVGProps) => ( + + + + + + + ); From 166ae4b2662ee938e31480cc6eeffd3bf0aed27d Mon Sep 17 00:00:00 2001 From: Tofik Hasanov Date: Fri, 1 May 2026 12:01:37 -0400 Subject: [PATCH 2/4] chore(integrations-catalog): refresh 2026-04-29 round 3 10 added, 152 updated. Total: 569 integrations / 9 categories. Added: braintree, carta, culture-amp, gainsight, mailgun, metabase, n8n, pinecone, plaid, squarespace Co-Authored-By: Claude Opus 4.7 (1M context) --- integrations-catalog/README.md | 120 ++++----- integrations-catalog/index.json | 230 ++++++++++++------ .../integrations/1password.json | 4 +- .../integrations/360learning.json | 4 +- .../integrations/absolute.json | 10 +- .../integrations/absorb-lms.json | 1 + .../acronis-cyber-protect-cloud.json | 1 + .../integrations/activtrak.json | 2 +- integrations-catalog/integrations/addigy.json | 18 +- integrations-catalog/integrations/atera.json | 1 + integrations-catalog/integrations/auth0.json | 8 +- integrations-catalog/integrations/auvik.json | 5 +- .../integrations/axonius.json | 2 +- .../barracuda-email-gateway-defense.json | 4 +- .../integrations/beehiiv.json | 4 +- .../integrations/bonusly.json | 2 +- .../integrations/braintree.json | 70 ++++++ integrations-catalog/integrations/brex.json | 2 +- integrations-catalog/integrations/buddy.json | 12 +- integrations-catalog/integrations/canva.json | 13 +- .../integrations/carbon-black.json | 26 +- integrations-catalog/integrations/carta.json | 43 ++++ .../integrations/cato-networks.json | 22 +- .../integrations/chartmogul.json | 6 +- .../integrations/checkly.json | 20 +- integrations-catalog/integrations/checkr.json | 14 +- .../integrations/cisco-meraki.json | 12 +- .../integrations/cisco-secure-endpoint.json | 1 + integrations-catalog/integrations/clerk.json | 4 +- .../integrations/clickhouse.json | 8 +- .../integrations/clockify.json | 4 +- integrations-catalog/integrations/close.json | 14 +- integrations-catalog/integrations/cobalt.json | 4 +- .../integrations/code42-incydr.json | 1 + .../integrations/codefresh.json | 4 +- integrations-catalog/integrations/cohere.json | 4 +- .../integrations/commvault.json | 3 +- .../integrations/confluent-cloud.json | 20 +- .../integrations/connectwise-manage.json | 38 ++- .../integrations/contentstack.json | 8 +- .../integrations/coolify.json | 20 +- .../integrations/coralogix.json | 4 +- .../integrations/coursera-business.json | 2 +- .../integrations/cronitor.json | 15 +- .../integrations/crowdstrike.json | 8 +- .../integrations/culture-amp.json | 52 ++++ .../integrations/cyberark.json | 5 +- integrations-catalog/integrations/datto.json | 8 +- integrations-catalog/integrations/domo.json | 2 +- integrations-catalog/integrations/druva.json | 3 +- integrations-catalog/integrations/egnyte.json | 2 +- .../integrations/employment-hero.json | 1 + .../integrations/endor-labs.json | 10 +- integrations-catalog/integrations/env0.json | 10 +- .../integrations/factorial.json | 12 +- .../integrations/fireworks-ai.json | 4 +- .../integrations/fivetran.json | 16 +- .../integrations/fleetdm.json | 22 +- .../integrations/fortinet-fortigate.json | 15 +- .../integrations/freshbooks.json | 17 +- .../integrations/freshdesk.json | 12 +- .../integrations/fullstory.json | 6 +- .../integrations/gainsight.json | 52 ++++ integrations-catalog/integrations/go1.json | 4 +- integrations-catalog/integrations/grain.json | 2 +- .../integrations/greenhouse.json | 8 +- integrations-catalog/integrations/groq.json | 4 +- .../integrations/hashicorp-vault.json | 4 +- .../integrations/hellosign.json | 8 +- .../integrations/helpscout.json | 14 +- .../integrations/huntress.json | 4 +- .../integrations/hyperproof.json | 23 +- .../integrations/incident-io.json | 4 +- .../integrations/infisical.json | 4 +- .../integrations/inngest.json | 4 +- .../integrations/instatus.json | 4 +- .../integrations/it-glue.json | 18 +- integrations-catalog/integrations/juro.json | 2 +- integrations-catalog/integrations/kenjo.json | 14 +- integrations-catalog/integrations/keycdn.json | 4 +- integrations-catalog/integrations/kolide.json | 2 +- integrations-catalog/integrations/kombo.json | 10 +- integrations-catalog/integrations/koyeb.json | 12 +- .../integrations/kustomer.json | 2 +- .../integrations/lacework.json | 18 +- .../integrations/lambdatest.json | 14 +- integrations-catalog/integrations/logdna.json | 14 +- integrations-catalog/integrations/logzio.json | 12 +- integrations-catalog/integrations/lucid.json | 14 +- .../integrations/lucidchart.json | 2 +- integrations-catalog/integrations/mabl.json | 18 +- .../integrations/mailchimp.json | 14 +- .../integrations/mailgun.json | 58 +++++ .../integrations/malwarebytes.json | 23 +- .../integrations/metabase.json | 57 +++++ .../integrations/metronome.json | 4 +- .../integrations/mintlify.json | 10 +- .../integrations/miradore.json | 1 + integrations-catalog/integrations/miro.json | 4 +- integrations-catalog/integrations/mosyle.json | 34 ++- .../integrations/n-able-n-sight.json | 7 +- integrations-catalog/integrations/n8n.json | 58 +++++ .../integrations/netskope.json | 6 +- integrations-catalog/integrations/ngrok.json | 4 +- .../integrations/northflank.json | 12 +- .../integrations/openphone.json | 4 +- .../integrations/opsgenie.json | 4 +- .../integrations/orca-security.json | 18 +- .../integrations/outreach.json | 17 +- .../integrations/pagerduty.json | 2 +- .../integrations/palo-alto.json | 30 ++- .../integrations/paychex.json | 14 +- .../integrations/persona.json | 4 +- .../integrations/personio.json | 20 +- .../integrations/pinecone.json | 44 ++++ .../integrations/pipedream.json | 4 +- integrations-catalog/integrations/plaid.json | 64 +++++ .../integrations/port-io.json | 30 ++- .../integrations/postman.json | 14 +- .../integrations/probely.json | 12 +- .../integrations/proofpoint.json | 14 +- .../integrations/pulumi-cloud.json | 12 +- integrations-catalog/integrations/pulumi.json | 12 +- integrations-catalog/integrations/qase.json | 12 +- integrations-catalog/integrations/qovery.json | 14 +- integrations-catalog/integrations/qualys.json | 5 +- .../integrations/quave-cloud.json | 1 + integrations-catalog/integrations/ramp.json | 1 + integrations-catalog/integrations/rapid7.json | 4 +- integrations-catalog/integrations/readme.json | 13 +- integrations-catalog/integrations/remote.json | 4 +- .../integrations/roboflow.json | 4 +- .../integrations/rollbar.json | 4 +- integrations-catalog/integrations/rubrik.json | 1 + .../integrations/rudderstack.json | 4 +- .../integrations/scalefusion.json | 4 +- .../integrations/secureframe.json | 4 +- .../integrations/servicenow.json | 18 +- .../integrations/sigma-computing.json | 14 +- .../integrations/squarespace.json | 45 ++++ .../integrations/strongdm.json | 18 +- .../integrations/sumo-logic.json | 24 +- .../integrations/sumologic.json | 18 +- integrations-catalog/integrations/tanium.json | 8 +- .../integrations/teamwork.json | 22 +- integrations-catalog/integrations/telnyx.json | 4 +- .../integrations/tenable-cloud.json | 2 +- .../integrations/threatdown.json | 2 +- .../integrations/together-ai.json | 6 +- .../integrations/transcend.json | 4 +- .../integrations/trigger-dev.json | 6 +- .../integrations/twingate.json | 1 + integrations-catalog/integrations/veeam.json | 3 +- .../integrations/veracode.json | 24 +- integrations-catalog/integrations/vultr.json | 4 +- integrations-catalog/integrations/wandb.json | 4 +- .../integrations/watchguard.json | 1 + integrations-catalog/integrations/webex.json | 4 +- .../integrations/webflow.json | 4 +- .../integrations/workato.json | 12 +- integrations-catalog/integrations/xero.json | 1 + integrations-catalog/integrations/zapier.json | 4 +- .../integrations/zscaler-zpa.json | 38 ++- integrations-catalog/integrations/zuora.json | 18 +- 164 files changed, 1816 insertions(+), 489 deletions(-) create mode 100644 integrations-catalog/integrations/braintree.json create mode 100644 integrations-catalog/integrations/carta.json create mode 100644 integrations-catalog/integrations/culture-amp.json create mode 100644 integrations-catalog/integrations/gainsight.json create mode 100644 integrations-catalog/integrations/mailgun.json create mode 100644 integrations-catalog/integrations/metabase.json create mode 100644 integrations-catalog/integrations/n8n.json create mode 100644 integrations-catalog/integrations/pinecone.json create mode 100644 integrations-catalog/integrations/plaid.json create mode 100644 integrations-catalog/integrations/squarespace.json diff --git a/integrations-catalog/README.md b/integrations-catalog/README.md index b64c12d771..dd39bc71ae 100644 --- a/integrations-catalog/README.md +++ b/integrations-catalog/README.md @@ -2,9 +2,9 @@ Public catalog of all compliance integrations available in the [CompAI](https://trycomp.ai) platform. -**559 integrations** across 9 categories. +**569 integrations** across 9 categories. -> Last updated: 2026-04-29 +> Last updated: 2026-05-01 ## What's in this catalog @@ -34,18 +34,18 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ ## Summary by category - **Security** — 129 integrations -- **Productivity** — 115 integrations -- **HR & People** — 61 integrations -- **Monitoring** — 53 integrations -- **Cloud** — 52 integrations +- **Productivity** — 119 integrations +- **HR & People** — 63 integrations +- **Monitoring** — 54 integrations +- **Cloud** — 54 integrations - **Development** — 52 integrations -- **Communication** — 46 integrations +- **Communication** — 47 integrations - **Infrastructure** — 31 integrations - **Identity & Access** — 20 integrations ## Full catalog -### Cloud (52) +### Cloud (54) | Integration | Slug | Auth | Checks | Sync | |-------------|------|------|--------|------| @@ -53,9 +53,10 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Aiven](integrations/aiven.json) | `aiven` | api_key | 2 | | | [Anthropic](integrations/anthropic.json) | `anthropic` | custom | 2 | | | [Box](integrations/box.json) | `box` | oauth2 | 2 | | +| [Braintree](integrations/braintree.json) | `braintree` | custom | 3 | | | [Brex](integrations/brex.json) | `brex` | api_key | 1 | | | [Civo](integrations/civo.json) | `civo` | api_key | 2 | | -| [ClickHouse Cloud](integrations/clickhouse.json) | `clickhouse` | api_key | 2 | | +| [ClickHouse Cloud](integrations/clickhouse.json) | `clickhouse` | basic | 2 | | | [Cloudinary](integrations/cloudinary.json) | `cloudinary` | custom | 2 | | | [CockroachDB](integrations/cockroachdb.json) | `cockroachdb` | api_key | 2 | | | [Cohere](integrations/cohere.json) | `cohere` | api_key | 2 | | @@ -70,7 +71,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Elastic Cloud](integrations/elastic-cloud.json) | `elastic-cloud` | custom | 2 | | | [Firebase](integrations/firebase.json) | `firebase` | oauth2 | 2 | | | [Fireworks AI](integrations/fireworks-ai.json) | `fireworks-ai` | api_key | 2 | | -| [Fivetran](integrations/fivetran.json) | `fivetran` | custom | 2 | | +| [Fivetran](integrations/fivetran.json) | `fivetran` | basic | 2 | | | [Fly.io](integrations/fly.json) | `fly` | api_key | 2 | | | [Groq](integrations/groq.json) | `groq` | api_key | 2 | | | [Heroku](integrations/heroku.json) | `heroku` | custom | 2 | | @@ -84,6 +85,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Neon](integrations/neon.json) | `neon` | api_key | 2 | | | [Netlify](integrations/netlify.json) | `netlify` | api_key | 2 | | | [Oracle Cloud Infrastructure](integrations/oracle-cloud.json) | `oracle-cloud` | custom | 3 | | +| [Pinecone](integrations/pinecone.json) | `pinecone` | api_key | 3 | | | [Quave Cloud](integrations/quave-cloud.json) | `quave-cloud` | custom | 4 | | | [Redis Cloud](integrations/redis-cloud.json) | `redis-cloud` | custom | 2 | | | [Render](integrations/render.json) | `render` | api_key | 2 | | @@ -102,13 +104,12 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Weights & Biases](integrations/wandb.json) | `wandb` | api_key | 2 | | | [Xata](integrations/xata.json) | `xata` | api_key | 2 | | -### Communication (46) +### Communication (47) | Integration | Slug | Auth | Checks | Sync | |-------------|------|------|--------|------| | [ActiveCampaign](integrations/activecampaign.json) | `activecampaign` | custom | 2 | | | [Aircall](integrations/aircall.json) | `aircall` | basic | 3 | ✓ | -| [Barracuda Email Gateway Defense](integrations/barracuda-email-gateway-defense.json) | `barracuda-email-gateway-defense` | oauth2 | 3 | | | [beehiiv](integrations/beehiiv.json) | `beehiiv` | api_key | 2 | | | [Bird](integrations/bird.json) | `bird` | custom | 2 | | | [Braze](integrations/braze.json) | `braze` | custom | 2 | | @@ -123,7 +124,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Drip](integrations/drip.json) | `drip` | custom | 2 | | | [Front](integrations/front.json) | `front` | api_key | 2 | | | [Gorgias](integrations/gorgias.json) | `gorgias` | custom | 2 | | -| [Help Scout](integrations/helpscout.json) | `helpscout` | api_key | 2 | | +| [Help Scout](integrations/helpscout.json) | `helpscout` | custom | 2 | | | [Hunter](integrations/hunter.json) | `hunter` | custom | 2 | | | [Intercom](integrations/intercom.json) | `intercom` | custom | 2 | | | [Iterable](integrations/iterable.json) | `iterable` | custom | 2 | | @@ -131,6 +132,8 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Knock](integrations/knock.json) | `knock` | api_key | 2 | | | [Kustomer](integrations/kustomer.json) | `kustomer` | custom | 1 | | | [Loops](integrations/loops.json) | `loops` | api_key | 2 | | +| [Mailchimp](integrations/mailchimp.json) | `mailchimp` | custom | 2 | | +| [Mailgun](integrations/mailgun.json) | `mailgun` | custom | 3 | | | [Mattermost](integrations/mattermost.json) | `mattermost` | api_key | 2 | | | [MessageBird](integrations/messagebird.json) | `messagebird` | custom | 2 | | | [Microsoft Teams](integrations/microsoft-teams.json) | `microsoft-teams` | custom | 2 | | @@ -162,7 +165,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Baseten](integrations/baseten.json) | `baseten` | custom | 2 | | | [Bitbucket](integrations/bitbucket.json) | `bitbucket` | custom | 2 | | | [BrowserStack](integrations/browserstack.json) | `browserstack` | basic | 2 | | -| [Buddy](integrations/buddy.json) | `buddy` | api_key | 2 | | +| [Buddy](integrations/buddy.json) | `buddy` | custom | 2 | | | [Buildkite](integrations/buildkite.json) | `buildkite` | api_key | 2 | | | [Census](integrations/census.json) | `census` | api_key | 2 | | | [CircleCI](integrations/circleci.json) | `circleci` | custom | 2 | | @@ -182,20 +185,20 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Jenkins](integrations/jenkins.json) | `jenkins` | basic | 2 | | | [JFrog Artifactory](integrations/jfrog.json) | `jfrog` | custom | 2 | | | [Jira](integrations/jira.json) | `jira` | custom | 2 | | -| [LambdaTest](integrations/lambdatest.json) | `lambdatest` | custom | 2 | | +| [LambdaTest](integrations/lambdatest.json) | `lambdatest` | basic | 2 | | | [LaunchDarkly](integrations/launchdarkly.json) | `launchdarkly` | api_key | 2 | | | [Linear](integrations/linear.json) | `linear` | custom | 2 | | | [Liveblocks](integrations/liveblocks.json) | `liveblocks` | api_key | 2 | | -| [Mabl](integrations/mabl.json) | `mabl` | custom | 2 | | +| [Mabl](integrations/mabl.json) | `mabl` | basic | 2 | | | [Mintlify](integrations/mintlify.json) | `mintlify` | custom | 2 | | | [OpenAI](integrations/openai.json) | `openai` | custom | 2 | | | [Optimizely](integrations/optimizely.json) | `optimizely` | api_key | 2 | | | [Pipedream](integrations/pipedream.json) | `pipedream` | api_key | 2 | | -| [Port](integrations/port-io.json) | `port-io` | api_key | 2 | | +| [Port](integrations/port-io.json) | `port-io` | custom | 2 | | | [Postman](integrations/postman.json) | `postman` | api_key | 2 | | | [Prefect](integrations/prefect.json) | `prefect` | api_key | 2 | | | [Qase](integrations/qase.json) | `qase` | api_key | 2 | | -| [ReadMe](integrations/readme.json) | `readme` | custom | 2 | | +| [ReadMe](integrations/readme.json) | `readme` | basic | 2 | | | [Replicate](integrations/replicate.json) | `replicate` | custom | 2 | | | [Shortcut](integrations/shortcut.json) | `shortcut` | api_key | 2 | | | [SonarCloud](integrations/sonarqube-cloud.json) | `sonarqube-cloud` | api_key | 2 | | @@ -210,7 +213,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Travis CI](integrations/travis-ci.json) | `travis-ci` | custom | 2 | | | [Trigger.dev](integrations/trigger-dev.json) | `trigger-dev` | custom | 2 | | -### HR & People (61) +### HR & People (63) | Integration | Slug | Auth | Checks | Sync | |-------------|------|------|--------|------| @@ -221,16 +224,18 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [BambooHR](integrations/bamboohr.json) | `bamboohr` | custom | 2 | | | [Bonusly](integrations/bonusly.json) | `bonusly` | custom | 1 | | | [Breathe HR](integrations/breathe-hr.json) | `breathe-hr` | custom | 2 | ✓ | +| [Carta](integrations/carta.json) | `carta` | oauth2 | 2 | | | [Ceridian Dayforce](integrations/ceridian-dayforce.json) | `ceridian-dayforce` | custom | 2 | ✓ | | [ChartHop](integrations/charthop.json) | `charthop` | custom | 3 | ✓ | -| [Checkr](integrations/checkr.json) | `checkr` | api_key | 2 | | +| [Checkr](integrations/checkr.json) | `checkr` | custom | 2 | | +| [Culture Amp](integrations/culture-amp.json) | `culture-amp` | custom | 2 | ✓ | | [Darwinbox](integrations/darwinbox.json) | `darwinbox` | custom | 3 | ✓ | | [Deel](integrations/deel.json) | `deel` | api_key | 2 | | | [Deputy](integrations/deputy.json) | `deputy` | custom | 2 | ✓ | | [Employment Hero](integrations/employment-hero.json) | `employment-hero` | custom | 3 | ✓ | -| [Factorial](integrations/factorial.json) | `factorial` | custom | 2 | | +| [Factorial](integrations/factorial.json) | `factorial` | api_key | 2 | | | [Freshteam](integrations/freshteam.json) | `freshteam` | custom | 3 | ✓ | -| [Greenhouse](integrations/greenhouse.json) | `greenhouse` | api_key | 2 | | +| [Greenhouse](integrations/greenhouse.json) | `greenhouse` | basic | 2 | | | [Gusto](integrations/gusto.json) | `gusto` | oauth2 | 2 | | | [HiBob](integrations/bob.json) | `bob` | basic | 2 | ✓ | | [HiBob](integrations/hibob.json) | `hibob` | custom | 2 | | @@ -238,7 +243,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Humaans](integrations/humaans.json) | `humaans` | custom | 1 | | | [Justworks](integrations/justworks.json) | `justworks` | oauth2 | 2 | ✓ | | [Keka](integrations/keka.json) | `keka` | custom | 4 | ✓ | -| [Kenjo](integrations/kenjo.json) | `kenjo` | api_key | 2 | ✓ | +| [Kenjo](integrations/kenjo.json) | `kenjo` | custom | 2 | ✓ | | [Kombo](integrations/kombo.json) | `kombo` | custom | 2 | | | [Lattice](integrations/lattice.json) | `lattice` | api_key | 2 | | | [Lever](integrations/lever.json) | `lever` | custom | 1 | | @@ -254,7 +259,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [PayFit](integrations/payfit.json) | `payfit` | custom | 1 | | | [Payhawk](integrations/payhawk.json) | `payhawk` | custom | 1 | | | [Paylocity](integrations/paylocity.json) | `paylocity` | custom | 2 | ✓ | -| [Personio](integrations/personio.json) | `personio` | api_key | 2 | | +| [Personio](integrations/personio.json) | `personio` | custom | 2 | | | [Pingboard](integrations/pingboard.json) | `pingboard` | custom | 1 | | | [Qonto](integrations/qonto.json) | `qonto` | custom | 1 | | | [Qualtrics](integrations/qualtrics.json) | `qualtrics` | custom | 1 | | @@ -309,13 +314,13 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Akamai](integrations/akamai.json) | `akamai` | custom | 3 | | | [Backblaze B2](integrations/backblaze.json) | `backblaze` | custom | 2 | | | [Bunny.net](integrations/bunny-net.json) | `bunny-net` | custom | 2 | | -| [Cisco Meraki](integrations/cisco-meraki.json) | `cisco-meraki` | custom | 2 | | +| [Cisco Meraki](integrations/cisco-meraki.json) | `cisco-meraki` | api_key | 2 | | | [Cloudflare](integrations/cloudflare.json) | `cloudflare` | custom | 4 | | -| [Confluent Cloud](integrations/confluent-cloud.json) | `confluent-cloud` | basic | 4 | | -| [Coolify](integrations/coolify.json) | `coolify` | api_key | 2 | | -| [Datto](integrations/datto.json) | `datto` | api_key | 2 | | +| [Confluent Cloud](integrations/confluent-cloud.json) | `confluent-cloud` | custom | 4 | | +| [Coolify](integrations/coolify.json) | `coolify` | custom | 2 | | +| [Datto](integrations/datto.json) | `datto` | basic | 2 | | | [Druva](integrations/druva.json) | `druva` | custom | 5 | | -| [env0](integrations/env0.json) | `env0` | api_key | 2 | | +| [env0](integrations/env0.json) | `env0` | basic | 2 | | | [Fastly](integrations/fastly.json) | `fastly` | api_key | 2 | | | [KeyCDN](integrations/keycdn.json) | `keycdn` | custom | 2 | | | [Kong Konnect](integrations/kong.json) | `kong` | api_key | 2 | | @@ -327,7 +332,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [PlanetScale](integrations/planetscale.json) | `planetscale` | custom | 3 | | | [Pulumi](integrations/pulumi.json) | `pulumi` | api_key | 2 | | | [Pulumi Cloud](integrations/pulumi-cloud.json) | `pulumi-cloud` | api_key | 2 | | -| [Qovery](integrations/qovery.json) | `qovery` | api_key | 2 | | +| [Qovery](integrations/qovery.json) | `qovery` | custom | 2 | | | [Railway](integrations/railway.json) | `railway` | custom | 2 | | | [Snipe-IT](integrations/snipeit.json) | `snipeit` | custom | 3 | | | [Tailscale](integrations/tailscale.json) | `tailscale` | api_key | 2 | | @@ -337,20 +342,20 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Veeam Backup & Replication](integrations/veeam.json) | `veeam` | custom | 3 | | | [ZeroTier](integrations/zerotier.json) | `zerotier` | custom | 2 | | -### Monitoring (53) +### Monitoring (54) | Integration | Slug | Auth | Checks | Sync | |-------------|------|------|--------|------| | [ActivTrak](integrations/activtrak.json) | `activtrak` | custom | 3 | | | [Amplitude](integrations/amplitude.json) | `amplitude` | api_key | 2 | | | [Anodot](integrations/anodot.json) | `anodot` | custom | 2 | | -| [Auvik](integrations/auvik.json) | `auvik` | basic | 2 | | +| [Auvik](integrations/auvik.json) | `auvik` | custom | 2 | | | [Axiom](integrations/axiom.json) | `axiom` | custom | 2 | | | [Better Stack](integrations/better-stack.json) | `better-stack` | custom | 3 | | | [Bugsnag](integrations/bugsnag.json) | `bugsnag` | api_key | 2 | | -| [Checkly](integrations/checkly.json) | `checkly` | api_key | 2 | | +| [Checkly](integrations/checkly.json) | `checkly` | custom | 2 | | | [Coralogix](integrations/coralogix.json) | `coralogix` | custom | 2 | | -| [Cronitor](integrations/cronitor.json) | `cronitor` | api_key | 2 | | +| [Cronitor](integrations/cronitor.json) | `cronitor` | basic | 2 | | | [CrowdStrike LogScale](integrations/logscale.json) | `logscale` | custom | 2 | | | [Dynatrace](integrations/dynatrace.json) | `dynatrace` | api_key | 2 | | | [Elastic Cloud](integrations/elastic.json) | `elastic` | custom | 2 | | @@ -366,15 +371,16 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Instatus](integrations/instatus.json) | `instatus` | custom | 2 | | | [LogicMonitor](integrations/logicmonitor.json) | `logicmonitor` | custom | 5 | | | [LogRocket](integrations/logrocket.json) | `logrocket` | api_key | 2 | | -| [Logz.io](integrations/logzio.json) | `logzio` | api_key | 2 | | +| [Logz.io](integrations/logzio.json) | `logzio` | custom | 2 | | | [Lumigo](integrations/lumigo.json) | `lumigo` | custom | 1 | | | [Mezmo](integrations/mezmo.json) | `mezmo` | custom | 2 | | -| [Mezmo (LogDNA)](integrations/logdna.json) | `logdna` | api_key | 2 | | +| [Mezmo (LogDNA)](integrations/logdna.json) | `logdna` | custom | 2 | | | [Microsoft Sentinel](integrations/microsoft-sentinel.json) | `microsoft-sentinel` | oauth2 | 3 | | | [Mixpanel](integrations/mixpanel.json) | `mixpanel` | custom | 2 | | | [Monte Carlo](integrations/monte-carlo.json) | `monte-carlo` | custom | 2 | | | [New Relic](integrations/new-relic.json) | `new-relic` | custom | 3 | | | [Opsgenie](integrations/opsgenie.json) | `opsgenie` | api_key | 2 | | +| [PagerDuty](integrations/pagerduty.json) | `pagerduty` | custom | 2 | | | [Papertrail](integrations/papertrail.json) | `papertrail` | custom | 2 | | | [Pendo](integrations/pendo.json) | `pendo` | api_key | 2 | | | [Plausible Analytics](integrations/plausible.json) | `plausible` | api_key | 2 | | @@ -390,12 +396,12 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Statsig](integrations/statsig.json) | `statsig` | custom | 2 | | | [StatusCake](integrations/statuscake.json) | `statuscake` | custom | 4 | | | [Statuspage](integrations/statuspage.json) | `statuspage` | api_key | 2 | | -| [Sumo Logic](integrations/sumo-logic.json) | `sumo-logic` | basic | 2 | | | [Sumo Logic](integrations/sumologic.json) | `sumologic` | custom | 2 | | +| [Sumo Logic](integrations/sumo-logic.json) | `sumo-logic` | custom | 2 | | | [Updown.io](integrations/updown.json) | `updown` | custom | 2 | | | [Uptime Robot](integrations/uptime-robot.json) | `uptime-robot` | api_key | 2 | | -### Productivity (115) +### Productivity (119) | Integration | Slug | Auth | Checks | Sync | |-------------|------|------|--------|------| @@ -413,14 +419,14 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Cal.com](integrations/cal-com.json) | `cal-com` | api_key | 2 | | | [Calendly](integrations/calendly.json) | `calendly` | api_key | 2 | | | [Canny](integrations/canny.json) | `canny` | custom | 2 | | -| [Canva](integrations/canva.json) | `canva` | api_key | 2 | | +| [Canva](integrations/canva.json) | `canva` | oauth2 | 2 | | | [Chameleon](integrations/chameleon.json) | `chameleon` | custom | 2 | | | [Chargebee](integrations/chargebee.json) | `chargebee` | custom | 2 | | -| [ChartMogul](integrations/chartmogul.json) | `chartmogul` | api_key | 2 | | +| [ChartMogul](integrations/chartmogul.json) | `chartmogul` | custom | 2 | | | [Clearbit](integrations/clearbit.json) | `clearbit` | api_key | 2 | | | [ClickUp](integrations/clickup.json) | `clickup` | api_key | 2 | | | [Clockify](integrations/clockify.json) | `clockify` | api_key | 2 | | -| [Close](integrations/close.json) | `close` | api_key | 2 | | +| [Close](integrations/close.json) | `close` | custom | 2 | | | [Close CRM](integrations/close-crm.json) | `close-crm` | custom | 2 | | | [Coda](integrations/coda.json) | `coda` | api_key | 2 | | | [Confluence](integrations/confluence.json) | `confluence` | custom | 2 | | @@ -430,11 +436,12 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Copper CRM](integrations/copper.json) | `copper` | custom | 2 | | | [Cornerstone OnDemand](integrations/cornerstone.json) | `cornerstone` | custom | 2 | ✓ | | [Coupa](integrations/coupa.json) | `coupa` | custom | 2 | ✓ | +| [Coursera for Business](integrations/coursera-business.json) | `coursera-business` | custom | 2 | ✓ | | [Docebo](integrations/docebo.json) | `docebo` | custom | 2 | ✓ | | [DocuSign](integrations/docusign.json) | `docusign` | oauth2 | 2 | | | [Domo](integrations/domo.json) | `domo` | custom | 2 | | | [Dropbox Business](integrations/dropbox-business.json) | `dropbox-business` | oauth2 | 3 | ✓ | -| [Dropbox Sign](integrations/hellosign.json) | `hellosign` | api_key | 2 | | +| [Dropbox Sign](integrations/hellosign.json) | `hellosign` | basic | 2 | | | [Dropbox Sign](integrations/dropbox-sign.json) | `dropbox-sign` | custom | 1 | | | [Dub.co](integrations/dub.json) | `dub` | api_key | 2 | | | [Dynamics 365](integrations/dynamics-365.json) | `dynamics-365` | custom | 3 | | @@ -442,10 +449,11 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Fibery](integrations/fibery.json) | `fibery` | custom | 2 | | | [Figma](integrations/figma.json) | `figma` | api_key | 2 | | | [Frame.io](integrations/frame-io.json) | `frame-io` | custom | 1 | | -| [FreshBooks](integrations/freshbooks.json) | `freshbooks` | api_key | 2 | | +| [FreshBooks](integrations/freshbooks.json) | `freshbooks` | oauth2 | 2 | | | [Freshdesk](integrations/freshdesk.json) | `freshdesk` | custom | 2 | | | [Freshsales](integrations/freshsales.json) | `freshsales` | custom | 2 | ✓ | | [Freshservice](integrations/freshservice.json) | `freshservice` | custom | 2 | | +| [Gainsight](integrations/gainsight.json) | `gainsight` | custom | 2 | ✓ | | [Google Workspace](integrations/google-workspace-admin.json) | `google-workspace-admin` | oauth2 | 2 | | | [Grain](integrations/grain.json) | `grain` | custom | 3 | | | [Guru](integrations/guru.json) | `guru` | custom | 1 | | @@ -461,20 +469,21 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Litmos](integrations/litmos.json) | `litmos` | custom | 2 | ✓ | | [Lob](integrations/lob.json) | `lob` | custom | 2 | | | [Looker](integrations/looker.json) | `looker` | custom | 2 | | -| [Lucid](integrations/lucid.json) | `lucid` | api_key | 2 | | +| [Lucid](integrations/lucid.json) | `lucid` | custom | 2 | | | [Lucidchart](integrations/lucidchart.json) | `lucidchart` | custom | 2 | | -| [Mailchimp](integrations/mailchimp.json) | `mailchimp` | custom | 2 | | | [Make](integrations/make.json) | `make` | custom | 2 | | | [Mercury](integrations/mercury.json) | `mercury` | api_key | 1 | | +| [Metabase](integrations/metabase.json) | `metabase` | custom | 2 | | | [Metronome](integrations/metronome.json) | `metronome` | api_key | 2 | | | [Microsoft 365](integrations/microsoft-365.json) | `microsoft-365` | oauth2 | 3 | | | [Microsoft Power BI](integrations/power-bi.json) | `power-bi` | custom | 2 | | | [Miro](integrations/miro.json) | `miro` | api_key | 2 | | | [Monday.com](integrations/monday.json) | `monday` | custom | 2 | | | [MURAL](integrations/mural.json) | `mural` | custom | 2 | | +| [n8n](integrations/n8n.json) | `n8n` | custom | 3 | | | [NetSuite](integrations/netsuite.json) | `netsuite` | custom | 2 | ✓ | | [Notion](integrations/notion.json) | `notion` | api_key | 3 | | -| [Outreach](integrations/outreach.json) | `outreach` | api_key | 2 | | +| [Outreach](integrations/outreach.json) | `outreach` | oauth2 | 2 | | | [Paddle](integrations/paddle.json) | `paddle` | api_key | 2 | | | [PandaDoc](integrations/pandadoc.json) | `pandadoc` | custom | 2 | | | [Pipedrive](integrations/pipedrive.json) | `pipedrive` | api_key | 2 | | @@ -492,15 +501,16 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [SAP Concur](integrations/sap-concur.json) | `sap-concur` | custom | 1 | ✓ | | [ServiceNow](integrations/servicenow.json) | `servicenow` | custom | 2 | | | [Shopify](integrations/shopify.json) | `shopify` | custom | 2 | | -| [Sigma Computing](integrations/sigma-computing.json) | `sigma-computing` | api_key | 2 | | +| [Sigma Computing](integrations/sigma-computing.json) | `sigma-computing` | custom | 2 | | | [SignNow](integrations/signnow.json) | `signnow` | custom | 1 | | | [Smartsheet](integrations/smartsheet.json) | `smartsheet` | api_key | 2 | | | [Sprig](integrations/sprig.json) | `sprig` | custom | 2 | | | [Square](integrations/square.json) | `square` | api_key | 2 | | +| [Squarespace](integrations/squarespace.json) | `squarespace` | custom | 2 | | | [Storyblok](integrations/storyblok.json) | `storyblok` | custom | 2 | | | [Stripe](integrations/stripe.json) | `stripe` | custom | 1 | | | [Tableau](integrations/tableau.json) | `tableau` | custom | 2 | | -| [Teamwork](integrations/teamwork.json) | `teamwork` | api_key | 2 | | +| [Teamwork](integrations/teamwork.json) | `teamwork` | custom | 2 | | | [Toggl Track](integrations/toggl.json) | `toggl` | basic | 2 | | | [Totango](integrations/totango.json) | `totango` | custom | 2 | | | [Trello](integrations/trello.json) | `trello` | custom | 2 | | @@ -533,13 +543,14 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Atera](integrations/atera.json) | `atera` | custom | 3 | | | [Automox](integrations/automox.json) | `automox` | api_key | 2 | | | [Axonius](integrations/axonius.json) | `axonius` | custom | 5 | ✓ | +| [Barracuda Email Gateway Defense](integrations/barracuda-email-gateway-defense.json) | `barracuda-email-gateway-defense` | oauth2 | 3 | | | [BeyondTrust](integrations/beyond-trust.json) | `beyond-trust` | custom | 3 | | | [BigID](integrations/bigid.json) | `bigid` | custom | 3 | | | [Bitdefender GravityZone](integrations/bitdefender-gravityzone.json) | `bitdefender-gravityzone` | custom | 5 | | | [Bitsight](integrations/bitsight.json) | `bitsight` | custom | 5 | | | [Bitwarden](integrations/bitwarden.json) | `bitwarden` | custom | 3 | | | [Bugcrowd](integrations/bugcrowd.json) | `bugcrowd` | custom | 3 | | -| [Carbon Black](integrations/carbon-black.json) | `carbon-black` | api_key | 2 | | +| [Carbon Black](integrations/carbon-black.json) | `carbon-black` | custom | 2 | | | [Cato Networks](integrations/cato-networks.json) | `cato-networks` | custom | 2 | | | [Certn](integrations/certn.json) | `certn` | custom | 2 | | | [Chainguard](integrations/chainguard.json) | `chainguard` | custom | 2 | | @@ -553,7 +564,6 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Commvault](integrations/commvault.json) | `commvault` | custom | 3 | | | [Contrast Security](integrations/contrast-security.json) | `contrast-security` | custom | 2 | | | [Cortex XDR](integrations/cortex-xdr.json) | `cortex-xdr` | custom | 3 | | -| [Coursera for Business](integrations/coursera-business.json) | `coursera-business` | custom | 2 | ✓ | | [CrowdStrike Falcon](integrations/crowdstrike.json) | `crowdstrike` | custom | 5 | | | [CyberArk Identity](integrations/cyberark-identity.json) | `cyberark-identity` | custom | 3 | ✓ | | [Cybereason](integrations/cybereason.json) | `cybereason` | custom | 4 | | @@ -578,7 +588,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [Hexnode](integrations/hexnode.json) | `hexnode` | custom | 5 | ✓ | | [Hoxhunt](integrations/hoxhunt.json) | `hoxhunt` | custom | 4 | | | [Huntress](integrations/huntress.json) | `huntress` | basic | 3 | | -| [Hyperproof](integrations/hyperproof.json) | `hyperproof` | api_key | 2 | | +| [Hyperproof](integrations/hyperproof.json) | `hyperproof` | custom | 2 | | | [Illumio](integrations/illumio.json) | `illumio` | custom | 7 | | | [Infisical](integrations/infisical.json) | `infisical` | api_key | 2 | | | [Invicti](integrations/invicti.json) | `invicti` | custom | 6 | | @@ -606,11 +616,11 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [NordPass](integrations/nordpass.json) | `nordpass` | custom | 3 | | | [OneTrust](integrations/onetrust.json) | `onetrust` | custom | 3 | | | [Orca Security](integrations/orca-security.json) | `orca-security` | custom | 2 | | -| [PagerDuty](integrations/pagerduty.json) | `pagerduty` | custom | 2 | | -| [Palo Alto Networks SASE](integrations/palo-alto.json) | `palo-alto` | api_key | 2 | | +| [Palo Alto Networks SASE](integrations/palo-alto.json) | `palo-alto` | custom | 2 | | +| [Plaid](integrations/plaid.json) | `plaid` | custom | 3 | | | [Prisma Cloud](integrations/prisma-cloud.json) | `prisma-cloud` | custom | 2 | | | [Probely](integrations/probely.json) | `probely` | api_key | 2 | | -| [Proofpoint](integrations/proofpoint.json) | `proofpoint` | custom | 2 | | +| [Proofpoint](integrations/proofpoint.json) | `proofpoint` | basic | 2 | | | [Proofpoint TAP](integrations/proofpoint-tap.json) | `proofpoint-tap` | basic | 3 | | | [Qualys VMDR](integrations/qualys.json) | `qualys` | custom | 4 | | | [Rapid7](integrations/rapid7.json) | `rapid7` | custom | 2 | | @@ -647,7 +657,7 @@ curl https://raw.githubusercontent.com/trycompai/comp/main/integrations-catalog/ | [WatchGuard](integrations/watchguard.json) | `watchguard` | custom | 3 | | | [Wiz](integrations/wiz.json) | `wiz` | custom | 2 | | | [Zscaler Internet Access](integrations/zscaler-zia.json) | `zscaler-zia` | custom | 4 | | -| [Zscaler Private Access](integrations/zscaler-zpa.json) | `zscaler-zpa` | api_key | 2 | | +| [Zscaler Private Access](integrations/zscaler-zpa.json) | `zscaler-zpa` | custom | 2 | | ## How this is maintained diff --git a/integrations-catalog/index.json b/integrations-catalog/index.json index b94cb1ec46..88c081c3a0 100644 --- a/integrations-catalog/index.json +++ b/integrations-catalog/index.json @@ -1,16 +1,16 @@ { - "generatedAt": "2026-04-29T16:30:41.116Z", - "total": 559, - "sourceCount": 559, - "uniqueSlugs": 559, + "generatedAt": "2026-05-01T16:01:14.900Z", + "total": 569, + "sourceCount": 569, + "uniqueSlugs": 569, "byCategory": { - "HR & People": 61, + "HR & People": 63, "Security": 129, - "Productivity": 115, + "Productivity": 119, "Infrastructure": 31, - "Communication": 46, - "Monitoring": 53, - "Cloud": 52, + "Communication": 47, + "Monitoring": 54, + "Cloud": 54, "Development": 52, "Identity & Access": 20 }, @@ -352,7 +352,7 @@ "slug": "auvik", "name": "Auvik", "category": "Monitoring", - "authType": "basic", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/auvik.json" @@ -414,7 +414,7 @@ { "slug": "barracuda-email-gateway-defense", "name": "Barracuda Email Gateway Defense", - "category": "Communication", + "category": "Security", "authType": "oauth2", "checkCount": 3, "syncSupported": false, @@ -546,6 +546,15 @@ "syncSupported": false, "file": "integrations/box.json" }, + { + "slug": "braintree", + "name": "Braintree", + "category": "Cloud", + "authType": "custom", + "checkCount": 3, + "syncSupported": false, + "file": "integrations/braintree.json" + }, { "slug": "braze", "name": "Braze", @@ -595,7 +604,7 @@ "slug": "buddy", "name": "Buddy", "category": "Development", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/buddy.json" @@ -667,7 +676,7 @@ "slug": "canva", "name": "Canva", "category": "Productivity", - "authType": "api_key", + "authType": "oauth2", "checkCount": 2, "syncSupported": false, "file": "integrations/canva.json" @@ -676,11 +685,20 @@ "slug": "carbon-black", "name": "Carbon Black", "category": "Security", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/carbon-black.json" }, + { + "slug": "carta", + "name": "Carta", + "category": "HR & People", + "authType": "oauth2", + "checkCount": 2, + "syncSupported": false, + "file": "integrations/carta.json" + }, { "slug": "cato-networks", "name": "Cato Networks", @@ -757,7 +775,7 @@ "slug": "chartmogul", "name": "ChartMogul", "category": "Productivity", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/chartmogul.json" @@ -775,7 +793,7 @@ "slug": "checkly", "name": "Checkly", "category": "Monitoring", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/checkly.json" @@ -793,7 +811,7 @@ "slug": "checkr", "name": "Checkr", "category": "HR & People", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/checkr.json" @@ -811,7 +829,7 @@ "slug": "cisco-meraki", "name": "Cisco Meraki", "category": "Infrastructure", - "authType": "custom", + "authType": "api_key", "checkCount": 2, "syncSupported": false, "file": "integrations/cisco-meraki.json" @@ -865,7 +883,7 @@ "slug": "clickhouse", "name": "ClickHouse Cloud", "category": "Cloud", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/clickhouse.json" @@ -892,7 +910,7 @@ "slug": "close", "name": "Close", "category": "Productivity", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/close.json" @@ -1045,7 +1063,7 @@ "slug": "confluent-cloud", "name": "Confluent Cloud", "category": "Infrastructure", - "authType": "basic", + "authType": "custom", "checkCount": 4, "syncSupported": false, "file": "integrations/confluent-cloud.json" @@ -1099,7 +1117,7 @@ "slug": "coolify", "name": "Coolify", "category": "Infrastructure", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/coolify.json" @@ -1161,7 +1179,7 @@ { "slug": "coursera-business", "name": "Coursera for Business", - "category": "Security", + "category": "Productivity", "authType": "custom", "checkCount": 2, "syncSupported": true, @@ -1171,7 +1189,7 @@ "slug": "cronitor", "name": "Cronitor", "category": "Monitoring", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/cronitor.json" @@ -1194,6 +1212,15 @@ "syncSupported": false, "file": "integrations/logscale.json" }, + { + "slug": "culture-amp", + "name": "Culture Amp", + "category": "HR & People", + "authType": "custom", + "checkCount": 2, + "syncSupported": true, + "file": "integrations/culture-amp.json" + }, { "slug": "customer-io", "name": "Customer.io", @@ -1288,7 +1315,7 @@ "slug": "datto", "name": "Datto", "category": "Infrastructure", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/datto.json" @@ -1477,7 +1504,7 @@ "slug": "hellosign", "name": "Dropbox Sign", "category": "Productivity", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/hellosign.json" @@ -1555,22 +1582,22 @@ "file": "integrations/egnyte.json" }, { - "slug": "elastic", + "slug": "elastic-cloud", "name": "Elastic Cloud", - "category": "Monitoring", + "category": "Cloud", "authType": "custom", "checkCount": 2, "syncSupported": false, - "file": "integrations/elastic.json" + "file": "integrations/elastic-cloud.json" }, { - "slug": "elastic-cloud", + "slug": "elastic", "name": "Elastic Cloud", - "category": "Cloud", + "category": "Monitoring", "authType": "custom", "checkCount": 2, "syncSupported": false, - "file": "integrations/elastic-cloud.json" + "file": "integrations/elastic.json" }, { "slug": "employment-hero", @@ -1594,7 +1621,7 @@ "slug": "env0", "name": "env0", "category": "Infrastructure", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/env0.json" @@ -1639,7 +1666,7 @@ "slug": "factorial", "name": "Factorial", "category": "HR & People", - "authType": "custom", + "authType": "api_key", "checkCount": 2, "syncSupported": false, "file": "integrations/factorial.json" @@ -1702,7 +1729,7 @@ "slug": "fivetran", "name": "Fivetran", "category": "Cloud", - "authType": "custom", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/fivetran.json" @@ -1765,7 +1792,7 @@ "slug": "freshbooks", "name": "FreshBooks", "category": "Productivity", - "authType": "api_key", + "authType": "oauth2", "checkCount": 2, "syncSupported": false, "file": "integrations/freshbooks.json" @@ -1842,6 +1869,15 @@ "syncSupported": true, "file": "integrations/fusionauth.json" }, + { + "slug": "gainsight", + "name": "Gainsight", + "category": "Productivity", + "authType": "custom", + "checkCount": 2, + "syncSupported": true, + "file": "integrations/gainsight.json" + }, { "slug": "gitbook", "name": "GitBook", @@ -1954,7 +1990,7 @@ "slug": "greenhouse", "name": "Greenhouse", "category": "HR & People", - "authType": "api_key", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/greenhouse.json" @@ -2035,7 +2071,7 @@ "slug": "helpscout", "name": "Help Scout", "category": "Communication", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/helpscout.json" @@ -2206,7 +2242,7 @@ "slug": "hyperproof", "name": "Hyperproof", "category": "Security", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/hyperproof.json" @@ -2431,7 +2467,7 @@ "slug": "kenjo", "name": "Kenjo", "category": "HR & People", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": true, "file": "integrations/kenjo.json" @@ -2548,7 +2584,7 @@ "slug": "lambdatest", "name": "LambdaTest", "category": "Development", - "authType": "custom", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/lambdatest.json" @@ -2656,7 +2692,7 @@ "slug": "logzio", "name": "Logz.io", "category": "Monitoring", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/logzio.json" @@ -2683,7 +2719,7 @@ "slug": "lucid", "name": "Lucid", "category": "Productivity", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/lucid.json" @@ -2710,7 +2746,7 @@ "slug": "mabl", "name": "Mabl", "category": "Development", - "authType": "custom", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/mabl.json" @@ -2718,12 +2754,21 @@ { "slug": "mailchimp", "name": "Mailchimp", - "category": "Productivity", + "category": "Communication", "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/mailchimp.json" }, + { + "slug": "mailgun", + "name": "Mailgun", + "category": "Communication", + "authType": "custom", + "checkCount": 3, + "syncSupported": false, + "file": "integrations/mailgun.json" + }, { "slug": "make", "name": "Make", @@ -2805,6 +2850,15 @@ "syncSupported": false, "file": "integrations/messagebird.json" }, + { + "slug": "metabase", + "name": "Metabase", + "category": "Productivity", + "authType": "custom", + "checkCount": 2, + "syncSupported": false, + "file": "integrations/metabase.json" + }, { "slug": "metronome", "name": "Metronome", @@ -2827,7 +2881,7 @@ "slug": "logdna", "name": "Mezmo (LogDNA)", "category": "Monitoring", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/logdna.json" @@ -3012,6 +3066,15 @@ "syncSupported": false, "file": "integrations/n-able-n-sight.json" }, + { + "slug": "n8n", + "name": "n8n", + "category": "Productivity", + "authType": "custom", + "checkCount": 3, + "syncSupported": false, + "file": "integrations/n8n.json" + }, { "slug": "namely", "name": "Namely", @@ -3259,7 +3322,7 @@ "slug": "outreach", "name": "Outreach", "category": "Productivity", - "authType": "api_key", + "authType": "oauth2", "checkCount": 2, "syncSupported": false, "file": "integrations/outreach.json" @@ -3285,7 +3348,7 @@ { "slug": "pagerduty", "name": "PagerDuty", - "category": "Security", + "category": "Monitoring", "authType": "custom", "checkCount": 2, "syncSupported": false, @@ -3295,7 +3358,7 @@ "slug": "palo-alto", "name": "Palo Alto Networks SASE", "category": "Security", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/palo-alto.json" @@ -3412,11 +3475,20 @@ "slug": "personio", "name": "Personio", "category": "HR & People", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/personio.json" }, + { + "slug": "pinecone", + "name": "Pinecone", + "category": "Cloud", + "authType": "api_key", + "checkCount": 3, + "syncSupported": false, + "file": "integrations/pinecone.json" + }, { "slug": "ping-identity", "name": "Ping Identity", @@ -3453,6 +3525,15 @@ "syncSupported": false, "file": "integrations/pipedrive.json" }, + { + "slug": "plaid", + "name": "Plaid", + "category": "Security", + "authType": "custom", + "checkCount": 3, + "syncSupported": false, + "file": "integrations/plaid.json" + }, { "slug": "plain", "name": "Plain", @@ -3502,7 +3583,7 @@ "slug": "port-io", "name": "Port", "category": "Development", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/port-io.json" @@ -3574,7 +3655,7 @@ "slug": "proofpoint", "name": "Proofpoint", "category": "Security", - "authType": "custom", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/proofpoint.json" @@ -3637,7 +3718,7 @@ "slug": "qovery", "name": "Qovery", "category": "Infrastructure", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/qovery.json" @@ -3709,7 +3790,7 @@ "slug": "readme", "name": "ReadMe", "category": "Development", - "authType": "custom", + "authType": "basic", "checkCount": 2, "syncSupported": false, "file": "integrations/readme.json" @@ -4033,7 +4114,7 @@ "slug": "sigma-computing", "name": "Sigma Computing", "category": "Productivity", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/sigma-computing.json" @@ -4129,22 +4210,22 @@ "file": "integrations/socket.json" }, { - "slug": "sonarcloud", + "slug": "sonarqube-cloud", "name": "SonarCloud", - "category": "Security", - "authType": "custom", + "category": "Development", + "authType": "api_key", "checkCount": 2, "syncSupported": false, - "file": "integrations/sonarcloud.json" + "file": "integrations/sonarqube-cloud.json" }, { - "slug": "sonarqube-cloud", + "slug": "sonarcloud", "name": "SonarCloud", - "category": "Development", - "authType": "api_key", + "category": "Security", + "authType": "custom", "checkCount": 2, "syncSupported": false, - "file": "integrations/sonarqube-cloud.json" + "file": "integrations/sonarcloud.json" }, { "slug": "sonarqube-server", @@ -4236,6 +4317,15 @@ "syncSupported": false, "file": "integrations/square.json" }, + { + "slug": "squarespace", + "name": "Squarespace", + "category": "Productivity", + "authType": "custom", + "checkCount": 2, + "syncSupported": false, + "file": "integrations/squarespace.json" + }, { "slug": "stackhawk", "name": "StackHawk", @@ -4336,22 +4426,22 @@ "file": "integrations/stytch.json" }, { - "slug": "sumo-logic", + "slug": "sumologic", "name": "Sumo Logic", "category": "Monitoring", - "authType": "basic", + "authType": "custom", "checkCount": 2, "syncSupported": false, - "file": "integrations/sumo-logic.json" + "file": "integrations/sumologic.json" }, { - "slug": "sumologic", + "slug": "sumo-logic", "name": "Sumo Logic", "category": "Monitoring", "authType": "custom", "checkCount": 2, "syncSupported": false, - "file": "integrations/sumologic.json" + "file": "integrations/sumo-logic.json" }, { "slug": "supabase", @@ -4447,7 +4537,7 @@ "slug": "teamwork", "name": "Teamwork", "category": "Productivity", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/teamwork.json" @@ -5032,7 +5122,7 @@ "slug": "zscaler-zpa", "name": "Zscaler Private Access", "category": "Security", - "authType": "api_key", + "authType": "custom", "checkCount": 2, "syncSupported": false, "file": "integrations/zscaler-zpa.json" diff --git a/integrations-catalog/integrations/1password.json b/integrations-catalog/integrations/1password.json index dcfdc8f318..9b4dbb31ba 100644 --- a/integrations-catalog/integrations/1password.json +++ b/integrations-catalog/integrations/1password.json @@ -8,13 +8,13 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "Requires: 1Password Business plan (not available on Teams or Teams Starter Pack).\n\n1. Sign in to 1Password.com as an owner or admin\n2. Go to Integrations → Events Reporting\n3. Click New Integration → select Other\n4. Enable scopes: Sign-in attempts, Item usages, Audit events\n5. Copy the generated token\n6. Enter your region: com (US), eu (Europe), or ca (Canada)\n7. Paste the token below\n\nNote: Do NOT use a Service Account token — Events Reporting tokens are required.", + "setupInstructions": "Requires: 1Password Business plan (not available on Teams or Teams Starter Pack).\n\n1. Sign in to 1Password.com as an owner or admin\n2. Go to Integrations > Events Reporting\n3. Click New Integration > select Other\n4. Enable scopes: Sign-in attempts, Item usages, Audit events\n5. Copy the generated token\n6. Enter your region: com (US), eu (Europe), or ca (Canada)\n7. Paste the token below\n\nNote: Do NOT use a Service Account token — Events Reporting tokens are required.", "credentialFields": [ { "label": "Events API Token", "type": "password", "required": true, - "helpText": "Create an Events Reporting integration at 1Password.com → Integrations → Events Reporting. Enable scopes: Sign-in attempts, Item usages, Audit events." + "helpText": "Create an Events Reporting integration at 1Password.com > Integrations > Events Reporting. Enable scopes: Sign-in attempts, Item usages, Audit events." }, { "label": "Region", diff --git a/integrations-catalog/integrations/360learning.json b/integrations-catalog/integrations/360learning.json index ef796562ff..c93392c595 100644 --- a/integrations-catalog/integrations/360learning.json +++ b/integrations-catalog/integrations/360learning.json @@ -3,8 +3,8 @@ "name": "360Learning", "description": "Monitor 360Learning LMS for compliance training completion and user management.", "category": "Security", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://360learning.readme.io/reference", + "baseUrl": "https://app.360learning.com", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/absolute.json b/integrations-catalog/integrations/absolute.json index 93c3a02c19..f83774170e 100644 --- a/integrations-catalog/integrations/absolute.json +++ b/integrations-catalog/integrations/absolute.json @@ -8,21 +8,25 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to the Absolute console\n2. Go to Settings > API Token Management\n3. Create a new API token\n4. Copy the Token ID and Secret Key (secret is shown only once)\n5. Determine your API Base URL based on your region:\n - US Commercial: https://api.absolute.com\n - US Federal: https://api.us.absolute.com\n - EU: https://api.eu.absolute.com\n6. Enter all values below", "credentialFields": [ { "label": "Token ID", "type": "text", - "required": true + "required": true, + "helpText": "API Token ID from the Absolute Console. Go to Settings > API Token Management to create one." }, { "label": "Secret Key", "type": "password", - "required": true + "required": true, + "helpText": "The Secret Key paired with your Token ID. Shown only once at creation." }, { "label": "API Base URL", "type": "text", - "required": true + "required": true, + "helpText": "Your Absolute API base URL. US: https://api.absolute.com, US Federal: https://api.us.absolute.com, EU: https://api.eu.absolute.com" } ] } diff --git a/integrations-catalog/integrations/absorb-lms.json b/integrations-catalog/integrations/absorb-lms.json index 27d311c917..927b0d2e56 100644 --- a/integrations-catalog/integrations/absorb-lms.json +++ b/integrations-catalog/integrations/absorb-lms.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your Absorb LMS portal as an administrator\n2. Note your portal URL (e.g., yourcompany.myabsorb.com)\n3. Contact Absorb Support or your System Admin to obtain your API Private Key (GUID)\n4. Use your admin account username and password\n5. Enter all values below\n\nNote: The API Private Key is a unique GUID assigned to your portal. It is NOT the same as your password.", "credentialFields": [ { "label": "Portal URL", diff --git a/integrations-catalog/integrations/acronis-cyber-protect-cloud.json b/integrations-catalog/integrations/acronis-cyber-protect-cloud.json index 294fabc5e2..b12db05c02 100644 --- a/integrations-catalog/integrations/acronis-cyber-protect-cloud.json +++ b/integrations-catalog/integrations/acronis-cyber-protect-cloud.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to the Acronis Management Portal as an administrator\n2. Navigate to Settings > API Clients\n3. Create a new API client with the required scopes\n4. Copy the Client ID and Client Secret\n5. Note your Datacenter URL (e.g., https://us-cloud.acronis.com or https://eu-cloud.acronis.com)\n6. Find your Tenant ID in the portal under Company > Overview\n7. Enter all values below", "credentialFields": [ { "label": "Datacenter URL", diff --git a/integrations-catalog/integrations/activtrak.json b/integrations-catalog/integrations/activtrak.json index 70c0286558..1b9c7d7ee4 100644 --- a/integrations-catalog/integrations/activtrak.json +++ b/integrations-catalog/integrations/activtrak.json @@ -4,7 +4,7 @@ "description": "Monitor ActivTrak workforce analytics platform for user activity monitoring, alerting, and agent deployment compliance", "category": "Monitoring", "docsUrl": "https://developers.activtrak.com/introduction", - "baseUrl": "https://{{credentials.region}}/", + "baseUrl": "https://api.activtrak.com", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/addigy.json b/integrations-catalog/integrations/addigy.json index 928bdfd6bf..1e9164d844 100644 --- a/integrations-catalog/integrations/addigy.json +++ b/integrations-catalog/integrations/addigy.json @@ -7,7 +7,23 @@ "baseUrl": null, "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Log in to Addigy at https://app.addigy.com\n2. Go to Account > Integrations > API v2\n3. Generate or copy your API Token\n4. Find your Parent Organization ID in Account > Organization\n5. Enter both values below", + "credentialFields": [ + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Your Addigy API v2 token from Account > Integrations > API v2" + }, + { + "label": "Organization ID", + "type": "text", + "required": true, + "helpText": "Your Addigy Parent Organization ID" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/atera.json b/integrations-catalog/integrations/atera.json index 694733bc94..1a1bea64a7 100644 --- a/integrations-catalog/integrations/atera.json +++ b/integrations-catalog/integrations/atera.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Atera at https://app.atera.com\n2. Go to Admin > API Management\n3. Generate a new API key or copy an existing one\n4. Paste the API key below", "credentialFields": [ { "label": "API Key", diff --git a/integrations-catalog/integrations/auth0.json b/integrations-catalog/integrations/auth0.json index 1d95d8edc7..0737a70d3a 100644 --- a/integrations-catalog/integrations/auth0.json +++ b/integrations-catalog/integrations/auth0.json @@ -8,8 +8,14 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Go to Auth0 Dashboard > Applications > Create Application\n2. Select Machine to Machine\n3. Authorize the Auth0 Management API with read:users, read:logs, read:guardian_factors permissions\n4. Deploy and copy the access token\n5. Paste it below", + "setupInstructions": "1. Go to Auth0 Dashboard > Applications > Create Application\n2. Select Machine to Machine\n3. Authorize the Auth0 Management API with read:users, read:logs, read:guardian_factors permissions\n4. Deploy and copy the access token\n5. Enter your Auth0 domain (e.g., myapp.auth0.com) and the access token below", "credentialFields": [ + { + "label": "Auth0 Domain", + "type": "text", + "required": true, + "helpText": "Your Auth0 tenant domain, e.g. myapp.auth0.com" + }, { "label": "Management API Token", "type": "password", diff --git a/integrations-catalog/integrations/auvik.json b/integrations-catalog/integrations/auvik.json index 6901d9eced..7f910720ed 100644 --- a/integrations-catalog/integrations/auvik.json +++ b/integrations-catalog/integrations/auvik.json @@ -4,10 +4,11 @@ "description": "Monitor Auvik network infrastructure for device inventory, alerts, and network management compliance", "category": "Monitoring", "docsUrl": "https://support.auvik.com/hc/en-us/articles/360031007111-Auvik-API-Integration-Guide", - "baseUrl": "https://auvikapi.{{credentials.region}}.my.auvik.com", + "baseUrl": "https://auvikapi.us1.my.auvik.com", "authConfig": { - "type": "basic", + "type": "custom", "config": { + "setupInstructions": "1. Log in to Auvik at https://my.auvik.com\n2. Go to Admin > Integrations > API\n3. Generate an API key if you have not already\n4. Copy the API username and API key\n5. Select your Auvik data region\n6. Enter the values below", "credentialFields": [ { "label": "API Username", diff --git a/integrations-catalog/integrations/axonius.json b/integrations-catalog/integrations/axonius.json index ac7f3e3b26..ac0ec7c9e9 100644 --- a/integrations-catalog/integrations/axonius.json +++ b/integrations-catalog/integrations/axonius.json @@ -4,7 +4,7 @@ "description": "Axonius cybersecurity asset management platform integration for asset discovery, device compliance, and user visibility", "category": "Security", "docsUrl": "https://docs.axonius.com/docs/axonius-rest-api", - "baseUrl": null, + "baseUrl": "https://placeholder.axonius.com", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/barracuda-email-gateway-defense.json b/integrations-catalog/integrations/barracuda-email-gateway-defense.json index 3b3acf68b5..a986e67592 100644 --- a/integrations-catalog/integrations/barracuda-email-gateway-defense.json +++ b/integrations-catalog/integrations/barracuda-email-gateway-defense.json @@ -2,7 +2,7 @@ "slug": "barracuda-email-gateway-defense", "name": "Barracuda Email Gateway Defense", "description": "Monitor Barracuda Email Gateway Defense cloud email security platform for domain configuration, account access, and security compliance", - "category": "Communication", + "category": "Security", "docsUrl": "https://documentation.campus.barracuda.com/wiki/spaces/EGD/pages/2851437/Getting+Started+with+the+API", "baseUrl": "https://api.barracudanetworks.com/", "authConfig": { @@ -12,7 +12,7 @@ "ess:account:read" ], "clientAuthMethod": "body", - "supportsRefreshToken": false + "supportsRefreshToken": true } }, "capabilities": [ diff --git a/integrations-catalog/integrations/beehiiv.json b/integrations-catalog/integrations/beehiiv.json index 42240478ee..c93307d4fd 100644 --- a/integrations-catalog/integrations/beehiiv.json +++ b/integrations-catalog/integrations/beehiiv.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.beehiiv.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to beehiiv at https://app.beehiiv.com\n2. Go to Settings > Integrations > API Keys\n3. Create a new API key with read permissions\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/bonusly.json b/integrations-catalog/integrations/bonusly.json index ec74633d9c..093771a70a 100644 --- a/integrations-catalog/integrations/bonusly.json +++ b/integrations-catalog/integrations/bonusly.json @@ -3,7 +3,7 @@ "name": "Bonusly", "description": "Bonusly employee recognition and rewards platform", "category": "HR & People", - "docsUrl": "https://bonusly.docs.apiary.io/", + "docsUrl": "https://docs.bonus.ly/reference/authentication", "baseUrl": "https://bonus.ly/api/v1", "authConfig": { "type": "custom", diff --git a/integrations-catalog/integrations/braintree.json b/integrations-catalog/integrations/braintree.json new file mode 100644 index 0000000000..60ad6588c1 --- /dev/null +++ b/integrations-catalog/integrations/braintree.json @@ -0,0 +1,70 @@ +{ + "slug": "braintree", + "name": "Braintree", + "description": "PayPal's payment processing platform. Monitor merchant account status, API access, and subscription configuration.", + "category": "Cloud", + "docsUrl": "https://developer.paypal.com/braintree/docs/reference/overview", + "baseUrl": "https://api.braintreegateway.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to the Braintree Control Panel at https://www.braintreegateway.com/login (production) or https://sandbox.braintreegateway.com/login (sandbox)\n2. Navigate to Settings > API Keys\n3. Copy your Merchant ID, Public Key, and Private Key\n4. Set the Environment to 'sandbox' or 'production' based on your account type\n5. Enter the credentials below", + "credentialFields": [ + { + "label": "Merchant ID", + "type": "text", + "required": true, + "helpText": "Your Braintree Merchant ID, found in Settings > API Keys in the Braintree Control Panel" + }, + { + "label": "Public Key", + "type": "text", + "required": true, + "helpText": "Your Braintree API public key, found in Settings > API Keys in the Braintree Control Panel" + }, + { + "label": "Private Key", + "type": "password", + "required": true, + "helpText": "Your Braintree API private key, found in Settings > API Keys in the Braintree Control Panel" + }, + { + "label": "Environment", + "type": "text", + "required": true, + "helpText": "Enter 'sandbox' for testing or 'production' for live accounts" + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "braintree_app_availability", + "name": "App Availability", + "description": "Verifies the Braintree gateway is accessible by generating a client token.", + "defaultSeverity": "high", + "enabled": true + }, + { + "slug": "braintree_merchant_account_status", + "name": "Merchant Account Status", + "description": "Checks that merchant accounts are active and properly configured.", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "braintree_subscription_plans", + "name": "Subscription Plans Configuration", + "description": "Monitors subscription plans to verify billing configuration is present and accessible.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 3, + "isActive": true +} diff --git a/integrations-catalog/integrations/brex.json b/integrations-catalog/integrations/brex.json index 8859c8061e..0380e16b41 100644 --- a/integrations-catalog/integrations/brex.json +++ b/integrations-catalog/integrations/brex.json @@ -4,7 +4,7 @@ "description": "Monitor Brex corporate card users and accounts for financial compliance", "category": "Cloud", "docsUrl": "https://developer.brex.com/docs/authentication/", - "baseUrl": "https://platform.brexapis.com/", + "baseUrl": "https://api.brex.com/", "authConfig": { "type": "api_key", "config": {} diff --git a/integrations-catalog/integrations/buddy.json b/integrations-catalog/integrations/buddy.json index b5c3a1383c..ea4f8136eb 100644 --- a/integrations-catalog/integrations/buddy.json +++ b/integrations-catalog/integrations/buddy.json @@ -6,15 +6,21 @@ "docsUrl": "https://buddy.works/docs/api/getting-started/overview", "baseUrl": "https://api.buddy.works/", "authConfig": { - "type": "api_key", + "type": "custom", "config": { - "setupInstructions": "1. Log in to Buddy at https://app.buddy.works\n2. Go to Profile → Personal Access Tokens\n3. Generate a new token with workspace and pipeline scopes\n4. Enter it below", + "setupInstructions": "1. Log in to Buddy at https://app.buddy.works (US) or https://eu.buddy.works (EU)\n2. Go to Profile > Personal Access Tokens\n3. Generate a new token with workspace and pipeline scopes\n4. Set the API Endpoint URL based on your region:\n - US accounts: https://api.buddy.works\n - EU accounts: https://api.eu.buddy.works\n - Self-hosted: https://YOUR-IP/api\n5. Enter both values below", "credentialFields": [ { "label": "Personal Access Token", "type": "password", "required": true, - "helpText": "Found in Buddy Profile → Personal Access Tokens" + "helpText": "Found in Buddy Profile > Personal Access Tokens. Generate a token with workspace and pipeline scopes." + }, + { + "label": "API Endpoint URL", + "type": "text", + "required": true, + "helpText": "Your Buddy API endpoint. US accounts: https://api.buddy.works, EU accounts: https://api.eu.buddy.works, Self-hosted: https://YOUR-IP/api" } ] } diff --git a/integrations-catalog/integrations/canva.json b/integrations-catalog/integrations/canva.json index d1b219d756..567b202b01 100644 --- a/integrations-catalog/integrations/canva.json +++ b/integrations-catalog/integrations/canva.json @@ -6,8 +6,17 @@ "docsUrl": "https://www.canva.dev/docs/connect/", "baseUrl": "https://api.canva.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "oauth2", + "config": { + "setupInstructions": "1. Go to the Canva Developer Portal at https://www.canva.com/developers/integrations/\n2. Create a new integration\n3. Generate a client secret\n4. Select required scopes (design:content:read, design:meta:read, profile:read)\n5. Add the CompAI callback URL as a redirect URI\n6. Copy your Client ID and Client Secret into CompAI\n7. Click Connect to authorize", + "scopes": [ + "design:content:read", + "design:meta:read", + "profile:read" + ], + "clientAuthMethod": "header", + "supportsRefreshToken": true + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/carbon-black.json b/integrations-catalog/integrations/carbon-black.json index 6cb3a8a220..2da3dca3fa 100644 --- a/integrations-catalog/integrations/carbon-black.json +++ b/integrations-catalog/integrations/carbon-black.json @@ -6,8 +6,30 @@ "docsUrl": "https://developer.carbonblack.com/reference/carbon-black-cloud/", "baseUrl": "https://defense.conferdeploy.net/", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Carbon Black Cloud console\n2. Go to Settings > API Access\n3. Create a Custom Access Level with Device read permissions\n4. Create an API Key with that access level\n5. Copy the API Secret Key and API ID (format: SECRET/ID)\n6. Copy your Org Key from the same page\n7. Enter your API URL, Org Key, and API Token below", + "credentialFields": [ + { + "label": "API URL", + "type": "text", + "required": true, + "helpText": "Your Carbon Black Cloud API URL (e.g. https://defense.conferdeploy.net). Found in Settings > API Access." + }, + { + "label": "Org Key", + "type": "text", + "required": true, + "helpText": "Your Carbon Black Cloud org key (found in Settings > API Access > API Keys)" + }, + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Your API Secret Key / API ID combined (format: SECRET_KEY/API_ID)" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/carta.json b/integrations-catalog/integrations/carta.json new file mode 100644 index 0000000000..1885e334fd --- /dev/null +++ b/integrations-catalog/integrations/carta.json @@ -0,0 +1,43 @@ +{ + "slug": "carta", + "name": "Carta", + "description": "Carta is an equity management and cap table platform used by VC-backed startups for managing equity, valuations, and stakeholder records.", + "category": "HR & People", + "docsUrl": "https://docs.carta.com/api-platform/docs/introduction", + "baseUrl": "https://api.carta.com", + "authConfig": { + "type": "oauth2", + "config": { + "setupInstructions": "To connect Carta:\n1. You need a Carta developer portal invite or API access from Carta\n2. Create an OAuth app in the Carta developer portal at https://developers.app.carta.com\n3. Set the grant type to Authorization Code\n4. Add the CompAI callback URL to your allowed redirect URIs\n5. Select scopes: read_issuer_info and read_issuer_stakeholders\n6. Copy your Client ID and Client Secret into CompAI\n7. Click Connect to authorize access", + "scopes": [ + "read_issuer_info", + "read_issuer_stakeholders" + ], + "clientAuthMethod": "header", + "supportsRefreshToken": true + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "carta_app_availability", + "name": "App Availability", + "description": "Verifies that the Carta API connection is active and accessible by listing the issuers (companies) the authenticated user has access to.", + "defaultSeverity": "high", + "enabled": true + }, + { + "slug": "carta_employee_access", + "name": "Employee Access", + "description": "Lists stakeholders (equity holders) across all issuers the authenticated user has access to, showing their roles and relationships for compliance review.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 2, + "isActive": true +} diff --git a/integrations-catalog/integrations/cato-networks.json b/integrations-catalog/integrations/cato-networks.json index 3aa9d06cd7..2d4bcd000d 100644 --- a/integrations-catalog/integrations/cato-networks.json +++ b/integrations-catalog/integrations/cato-networks.json @@ -3,11 +3,27 @@ "name": "Cato Networks", "description": "SASE platform providing SD-WAN and security services through a global cloud network", "category": "Security", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://api.catonetworks.com/documentation/", + "baseUrl": "https://api.catonetworks.com", "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Log in to the Cato Management Application\n2. Go to Administration > API Keys\n3. Generate a new API key with read permissions\n4. Copy your Account ID from Administration > Account Info\n5. Enter both values below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Your Cato Networks API key from the Cato Management Application" + }, + { + "label": "Account ID", + "type": "text", + "required": true, + "helpText": "Your Cato Networks Account ID (found in Administration > Account Info)" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/chartmogul.json b/integrations-catalog/integrations/chartmogul.json index b88af1f362..20fe6cc003 100644 --- a/integrations-catalog/integrations/chartmogul.json +++ b/integrations-catalog/integrations/chartmogul.json @@ -6,15 +6,15 @@ "docsUrl": "https://dev.chartmogul.com/reference/introduction", "baseUrl": "https://api.chartmogul.com/", "authConfig": { - "type": "api_key", + "type": "custom", "config": { - "setupInstructions": "1. Log in to ChartMogul at https://app.chartmogul.com\n2. Go to Profile → View API Key\n3. Copy your API key\n4. Enter it below", + "setupInstructions": "1. Log in to ChartMogul at https://app.chartmogul.com\n2. Go to Profile -> View API Key\n3. Copy your API key\n4. Enter it below", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "Found in ChartMogul Profile → View API Key" + "helpText": "Found in ChartMogul Profile -> View API Key" } ] } diff --git a/integrations-catalog/integrations/checkly.json b/integrations-catalog/integrations/checkly.json index e24f1a96b2..dd9dc6361b 100644 --- a/integrations-catalog/integrations/checkly.json +++ b/integrations-catalog/integrations/checkly.json @@ -6,8 +6,24 @@ "docsUrl": "https://developers.checklyhq.com/reference/", "baseUrl": "https://api.checklyhq.com/", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Checkly at https://app.checklyhq.com\n2. Go to User Settings -> API Keys -> Create API key\n3. Copy the API key (shown only once)\n4. Go to Account Settings -> General to find your Account ID\n5. Enter both values below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Found in Checkly User Settings -> API Keys -> Create API key" + }, + { + "label": "Account ID", + "type": "text", + "required": true, + "helpText": "Found in Checkly Account Settings -> General (bottom of page)" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/checkr.json b/integrations-catalog/integrations/checkr.json index fe0a265a1c..149284f85c 100644 --- a/integrations-catalog/integrations/checkr.json +++ b/integrations-catalog/integrations/checkr.json @@ -6,8 +6,18 @@ "docsUrl": "https://docs.checkr.com/reference", "baseUrl": "https://api.checkr.com/", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Checkr at https://dashboard.checkr.com\n2. Go to Developer Settings -> API Keys\n3. Copy your API key\n4. Enter it below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Found in Checkr Dashboard -> Developer Settings -> API Keys" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/cisco-meraki.json b/integrations-catalog/integrations/cisco-meraki.json index c5c5cb2954..b232ccbdfd 100644 --- a/integrations-catalog/integrations/cisco-meraki.json +++ b/integrations-catalog/integrations/cisco-meraki.json @@ -6,17 +6,9 @@ "docsUrl": "https://developer.cisco.com/meraki/api-v1/", "baseUrl": "https://api.meraki.com", "authConfig": { - "type": "custom", + "type": "api_key", "config": { - "setupInstructions": "1. Log in to Meraki Dashboard\n2. Go to Organization → Settings\n3. Under API access, enable API and generate an API key\n4. Copy the key and paste it below", - "credentialFields": [ - { - "label": "API Key", - "type": "password", - "required": true, - "helpText": "Found in Meraki Dashboard → Organization → Settings → API access → Generate API key." - } - ] + "setupInstructions": "1. Log in to Meraki Dashboard at https://dashboard.meraki.com\n2. Go to Organization > API & Webhooks from the left nav\n3. Select API keys and access from the top tabs\n4. Generate a new API key\n5. Copy and paste it below\n\nNote: Treat your API key like a password. Store it securely." } }, "capabilities": [ diff --git a/integrations-catalog/integrations/cisco-secure-endpoint.json b/integrations-catalog/integrations/cisco-secure-endpoint.json index 436c6132fc..d8448c0431 100644 --- a/integrations-catalog/integrations/cisco-secure-endpoint.json +++ b/integrations-catalog/integrations/cisco-secure-endpoint.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Cisco Secure Endpoint console\n2. Go to Accounts > API Credentials\n3. Click New API Credential (3rd Party API type)\n4. Note the Client ID and API Key shown\n5. Enter Region hostname (api.amp.cisco.com for NA, api.eu.amp.cisco.com for EU, api.apjc.amp.cisco.com for APJC)\n6. Enter the Client ID and API Key below", "credentialFields": [ { "label": "Region", diff --git a/integrations-catalog/integrations/clerk.json b/integrations-catalog/integrations/clerk.json index 44c705a7e1..485eb4ce84 100644 --- a/integrations-catalog/integrations/clerk.json +++ b/integrations-catalog/integrations/clerk.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.clerk.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to your Clerk Dashboard at https://dashboard.clerk.com\n2. Select your application\n3. Go to API Keys in the left sidebar\n4. Copy the Secret Key (starts with sk_)\n5. Paste it below\n\nNote: Use the Secret Key (not the Publishable Key). The Secret Key provides backend API access." + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/clickhouse.json b/integrations-catalog/integrations/clickhouse.json index 899db86527..57a5e7b476 100644 --- a/integrations-catalog/integrations/clickhouse.json +++ b/integrations-catalog/integrations/clickhouse.json @@ -6,8 +6,12 @@ "docsUrl": "https://clickhouse.com/docs/en/cloud/manage/api/api-overview", "baseUrl": "https://api.clickhouse.cloud", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to ClickHouse Cloud console at https://console.clickhouse.cloud\n2. Go to API Keys in the left menu\n3. Click New API Key\n4. Set a name, choose Admin or Developer permissions, and set expiration\n5. Copy the Key ID and Key Secret (shown only once)\n6. Enter them below", + "usernameField": "key_id", + "passwordField": "key_secret" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/clockify.json b/integrations-catalog/integrations/clockify.json index 66a84d591e..b658ae6fde 100644 --- a/integrations-catalog/integrations/clockify.json +++ b/integrations-catalog/integrations/clockify.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.clockify.me", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Clockify at https://clockify.me\n2. Click your profile icon (top right) and select Profile Settings\n3. Scroll down to API section\n4. Click Generate to create an API key\n5. Copy and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/close.json b/integrations-catalog/integrations/close.json index c178080386..34eb8344a9 100644 --- a/integrations-catalog/integrations/close.json +++ b/integrations-catalog/integrations/close.json @@ -6,8 +6,18 @@ "docsUrl": "https://developer.close.com/", "baseUrl": "https://api.close.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Close at https://app.close.com\n2. Go to Settings > Developer > API Keys\n3. Create a new API key\n4. Copy the API key and paste it below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Found in Close Settings > Developer > API Keys" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/cobalt.json b/integrations-catalog/integrations/cobalt.json index bf2ff48b63..d33fb235ba 100644 --- a/integrations-catalog/integrations/cobalt.json +++ b/integrations-catalog/integrations/cobalt.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.cobalt.io", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Cobalt at https://app.cobalt.io\n2. Go to Settings > API > Generate API Token\n3. Copy the token and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/code42-incydr.json b/integrations-catalog/integrations/code42-incydr.json index 569104048c..16a58604a8 100644 --- a/integrations-catalog/integrations/code42-incydr.json +++ b/integrations-catalog/integrations/code42-incydr.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Code42 Incydr console\n2. Go to Settings > API Clients\n3. Create a new API client with appropriate permissions\n4. Copy the Client ID and Client Secret\n5. Select your region from the dropdown below", "credentialFields": [ { "label": "Client ID", diff --git a/integrations-catalog/integrations/codefresh.json b/integrations-catalog/integrations/codefresh.json index 369a972726..66310feea6 100644 --- a/integrations-catalog/integrations/codefresh.json +++ b/integrations-catalog/integrations/codefresh.json @@ -7,7 +7,9 @@ "baseUrl": "https://g.codefresh.io", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Codefresh at https://g.codefresh.io\n2. Click your avatar dropdown and select 'User Settings'\n3. Scroll down to 'API Keys' and click 'Generate'\n4. Name your key and select the required scopes (at minimum: Audit, Build, Pipeline)\n5. Copy the generated token" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/cohere.json b/integrations-catalog/integrations/cohere.json index fe555a31e4..24b8852b3c 100644 --- a/integrations-catalog/integrations/cohere.json +++ b/integrations-catalog/integrations/cohere.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.cohere.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to the Cohere Dashboard at https://dashboard.cohere.com\n2. Navigate to API Keys\n3. Click 'Create Trial Key' or use an existing production key\n4. Copy and paste the key below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/commvault.json b/integrations-catalog/integrations/commvault.json index 17f9969f25..3c9f3403a4 100644 --- a/integrations-catalog/integrations/commvault.json +++ b/integrations-catalog/integrations/commvault.json @@ -3,11 +3,12 @@ "name": "Commvault", "description": "Enterprise backup, recovery, and data management platform for cloud, virtual, and physical environments", "category": "Security", - "docsUrl": null, + "docsUrl": "https://api.commvault.com/", "baseUrl": "https://commvault.example.com", "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your Commvault Command Center\n2. Navigate to Manage > Security > Accounts\n3. Use an admin account with REST API access\n4. Enter the Web Console URL (e.g., https://commvault.company.com)\n5. Enter the admin username and password", "credentialFields": [ { "label": "Commvault Server URL", diff --git a/integrations-catalog/integrations/confluent-cloud.json b/integrations-catalog/integrations/confluent-cloud.json index d0c548fc79..5447af2771 100644 --- a/integrations-catalog/integrations/confluent-cloud.json +++ b/integrations-catalog/integrations/confluent-cloud.json @@ -6,8 +6,24 @@ "docsUrl": "https://docs.confluent.io/cloud/current/api.html", "baseUrl": "https://api.confluent.cloud", "authConfig": { - "type": "basic", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "Go to confluent.cloud, open the sidebar menu and click API keys (or go directly to confluent.cloud/settings/api-keys). Click Add API key, select My account or a Service account, choose Cloud resource management as the scope, then copy the API Key and Secret. The key needs OrganizationAdmin role to access users, environments, and clusters.", + "credentialFields": [ + { + "label": "Cloud API Key", + "type": "text", + "required": true, + "helpText": "Your Confluent Cloud API Key ID" + }, + { + "label": "Cloud API Secret", + "type": "password", + "required": true, + "helpText": "The API Secret shown once at key creation" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/connectwise-manage.json b/integrations-catalog/integrations/connectwise-manage.json index 5ff15888db..c6e3ff3760 100644 --- a/integrations-catalog/integrations/connectwise-manage.json +++ b/integrations-catalog/integrations/connectwise-manage.json @@ -4,10 +4,44 @@ "description": "ConnectWise PSA for service management and ticketing", "category": "Productivity", "docsUrl": "https://developer.connectwise.com/Products/Manage/REST", - "baseUrl": "https://placeholder.connectwise.com", + "baseUrl": "https://api-na.myconnectwise.net", "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Go to your ConnectWise Manage instance\n2. Navigate to System > Members > API Members\n3. Create or select an API member\n4. Generate API keys (public + private)\n5. Get your Client ID from developer.connectwise.com\n6. Your Company ID is shown in the login screen", + "credentialFields": [ + { + "label": "ConnectWise Site URL", + "type": "text", + "required": true, + "helpText": "Your ConnectWise Manage site URL (e.g., https://na.myconnectwise.net or https://api-na.myconnectwise.net)" + }, + { + "label": "Company ID", + "type": "text", + "required": true, + "helpText": "Your ConnectWise company identifier" + }, + { + "label": "Public Key", + "type": "text", + "required": true, + "helpText": "API member public key from ConnectWise" + }, + { + "label": "Private Key", + "type": "password", + "required": true, + "helpText": "API member private key from ConnectWise" + }, + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "ConnectWise Developer Client ID (from developer.connectwise.com)" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/contentstack.json b/integrations-catalog/integrations/contentstack.json index eccc74f04a..623dc1079e 100644 --- a/integrations-catalog/integrations/contentstack.json +++ b/integrations-catalog/integrations/contentstack.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Contentstack at https://app.contentstack.com\n2. Go to Account Settings → Tokens → Auth Tokens\n3. Generate a new auth token\n4. Enter it below", + "setupInstructions": "1. Log in to Contentstack at https://app.contentstack.com\n2. Go to Account Settings > Tokens > Auth Tokens\n3. Generate a new auth token\n4. Determine your region from your Contentstack URL:\n - US: api.contentstack.io\n - EU: eu-api.contentstack.com\n - AU: au-api.contentstack.com\n - Azure NA: azure-na-api.contentstack.com\n - Azure EU: azure-eu-api.contentstack.com\n5. Enter both values below", "credentialFields": [ { "label": "Auth Token", "type": "password", "required": true, "helpText": "Found in Contentstack Account → Tokens → Auth Tokens" + }, + { + "label": "API Region", + "type": "text", + "required": true, + "helpText": "Your Contentstack region API host. Examples: api.contentstack.io (US), eu-api.contentstack.com (EU), au-api.contentstack.com (AU)" } ] } diff --git a/integrations-catalog/integrations/coolify.json b/integrations-catalog/integrations/coolify.json index 531b2e1193..52ce11b692 100644 --- a/integrations-catalog/integrations/coolify.json +++ b/integrations-catalog/integrations/coolify.json @@ -6,8 +6,24 @@ "docsUrl": "https://coolify.io/docs/api-reference", "baseUrl": "https://app.coolify.io", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to your Coolify instance\n2. Go to Settings > API\n3. Generate a new API token\n4. Enter your instance URL and the API token below", + "credentialFields": [ + { + "label": "Coolify Instance URL", + "type": "text", + "required": true, + "helpText": "Your Coolify instance URL (e.g. https://coolify.example.com or https://app.coolify.io for Coolify Cloud)" + }, + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Go to your Coolify instance > Settings > API > Generate new token" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/coralogix.json b/integrations-catalog/integrations/coralogix.json index fab70b38d6..886b132bc6 100644 --- a/integrations-catalog/integrations/coralogix.json +++ b/integrations-catalog/integrations/coralogix.json @@ -19,8 +19,8 @@ { "label": "Region Endpoint", "type": "text", - "required": false, - "helpText": "Your region API host. Examples: api.coralogix.com (US), api.eu2.coralogix.com (EU), api.coralogixsg.com (AP)" + "required": true, + "helpText": "Your Coralogix API endpoint domain. Required. Examples: api.coralogix.com (US1), api.eu2.coralogix.com (EU2), api.coralogixsg.com (AP1), api.app.coralogix.in (AP2), api.eu1.coralogix.com (EU1)" } ] } diff --git a/integrations-catalog/integrations/coursera-business.json b/integrations-catalog/integrations/coursera-business.json index e86b2920b3..34252ca005 100644 --- a/integrations-catalog/integrations/coursera-business.json +++ b/integrations-catalog/integrations/coursera-business.json @@ -2,7 +2,7 @@ "slug": "coursera-business", "name": "Coursera for Business", "description": "Coursera for Business provides enterprise learning and compliance training, enabling organizations to upskill employees with courses from top universities and industry leaders.", - "category": "Security", + "category": "Productivity", "docsUrl": "https://dev.coursera.com/get-started", "baseUrl": "https://api.coursera.com/ent", "authConfig": { diff --git a/integrations-catalog/integrations/cronitor.json b/integrations-catalog/integrations/cronitor.json index 7cf10264aa..10e0dc197a 100644 --- a/integrations-catalog/integrations/cronitor.json +++ b/integrations-catalog/integrations/cronitor.json @@ -6,8 +6,19 @@ "docsUrl": "https://cronitor.io/docs/api", "baseUrl": "https://cronitor.io", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to Cronitor at https://cronitor.io\n2. Go to Settings - API Settings\n3. Copy your SDK Integration API Key (provides full access to monitors, sites, status pages)\n4. Enter it below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Found in Cronitor Settings - API Settings. Use the SDK Integration key for full API access." + } + ], + "usernameField": "api_key" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/crowdstrike.json b/integrations-catalog/integrations/crowdstrike.json index c60fed3844..a18abb9d4f 100644 --- a/integrations-catalog/integrations/crowdstrike.json +++ b/integrations-catalog/integrations/crowdstrike.json @@ -8,7 +8,7 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Falcon Console at https://falcon.crowdstrike.com\n2. Go to Support & Resources → API Clients and Keys\n3. Click Add new API client\n4. Enable scopes: Hosts (Read), User Management (Read), Prevention Policies (Read), Spotlight Vulnerabilities (Read)\n5. Copy the Client ID and Secret", + "setupInstructions": "1. Log in to Falcon Console at https://falcon.crowdstrike.com\n2. Go to Support & Resources - API Clients and Keys\n3. Click Add new API client\n4. Enable scopes: Hosts (Read), User Management (Read), Prevention Policies (Read), Spotlight Vulnerabilities (Read)\n5. Copy the Client ID and Secret\n6. Enter the API Base URL for your cloud region (default: api.crowdstrike.com for US-1). Other regions: US-2: api.us-2.crowdstrike.com, EU-1: api.eu-1.crowdstrike.com, US-GOV: api.laggar.gcw.crowdstrike.com", "credentialFields": [ { "label": "Client ID", @@ -21,6 +21,12 @@ "type": "password", "required": true, "helpText": "Generated when creating an API client in Falcon Console" + }, + { + "label": "API Base URL", + "type": "text", + "required": false, + "helpText": "Your CrowdStrike cloud region base URL. US-1: api.crowdstrike.com, US-2: api.us-2.crowdstrike.com, EU-1: api.eu-1.crowdstrike.com, US-GOV: api.laggar.gcw.crowdstrike.com" } ] } diff --git a/integrations-catalog/integrations/culture-amp.json b/integrations-catalog/integrations/culture-amp.json new file mode 100644 index 0000000000..f1fad5232a --- /dev/null +++ b/integrations-catalog/integrations/culture-amp.json @@ -0,0 +1,52 @@ +{ + "slug": "culture-amp", + "name": "Culture Amp", + "description": "Culture Amp is an employee engagement and performance management platform that helps organizations collect employee feedback, run performance reviews, and drive workplace culture improvements.", + "category": "HR & People", + "docsUrl": "https://docs.api.cultureamp.com/", + "baseUrl": "https://api.cultureamp.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Culture Amp as an Account Administrator\n2. Open Settings > Account > API\n3. Click to create a new API credential\n4. Select the 'employees-read' scope (and 'employee-demographics-read' if needed)\n5. Copy the Client ID and Client Secret\n6. Enter them below\n\nNote: The entity ID used in the OAuth scope (8ed17dce-...) is a Culture Amp platform-level constant for the production API, shared by all customers. It is NOT tenant-specific. See https://docs.api.cultureamp.com/docs/customer-guide-authorization-scopes for details.", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "Your Culture Amp API credential Client ID. Found in Culture Amp Settings > Account > API." + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "Your Culture Amp API credential Client Secret. Found in Culture Amp Settings > Account > API." + } + ] + } + }, + "capabilities": [ + "checks", + "sync" + ], + "supportsMultipleConnections": false, + "syncSupported": true, + "checks": [ + { + "slug": "culture_amp_employee_access", + "name": "Employee Access", + "description": "Lists all users/members in Culture Amp with their names, emails, and identifiers to verify employee access controls.", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "culture_amp_app_availability", + "name": "App Availability", + "description": "Verifies that the Culture Amp API is accessible and the provided credentials are valid by authenticating and making a test API call.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 2, + "isActive": true +} diff --git a/integrations-catalog/integrations/cyberark.json b/integrations-catalog/integrations/cyberark.json index 98c331f591..5c5c51bbb8 100644 --- a/integrations-catalog/integrations/cyberark.json +++ b/integrations-catalog/integrations/cyberark.json @@ -3,11 +3,12 @@ "name": "CyberArk", "description": "CyberArk Privileged Access Management (PAM) platform that secures, manages, and monitors privileged accounts across your infrastructure.", "category": "Identity & Access", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://docs.cyberark.com/pam-self-hosted/latest/en/content/webservices/implement-restapi.htm", + "baseUrl": "https://your-cyberark-instance.com", "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your CyberArk PVWA web interface\n2. Ensure the CyberArk user has API access permissions\n3. Enter your PVWA server URL (e.g., https://your-cyberark-instance.com)\n4. Enter the username and password for the API user", "credentialFields": [ { "type": "string", diff --git a/integrations-catalog/integrations/datto.json b/integrations-catalog/integrations/datto.json index a36c871e2a..583e1cfc49 100644 --- a/integrations-catalog/integrations/datto.json +++ b/integrations-catalog/integrations/datto.json @@ -6,8 +6,12 @@ "docsUrl": "https://portal.dattobackup.com/integrations/xml-api", "baseUrl": "https://api.datto.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to the Datto Partner Portal\n2. Navigate to Integrations > API Keys\n3. Generate a new API key pair\n4. Copy the Public Key and Secret Key below", + "usernameField": "public_key", + "passwordField": "secret_key" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/domo.json b/integrations-catalog/integrations/domo.json index c7146f4165..bf86fe9112 100644 --- a/integrations-catalog/integrations/domo.json +++ b/integrations-catalog/integrations/domo.json @@ -8,7 +8,7 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Domo at https://developer.domo.com\n2. Go to New Client → create a client with User Read scope\n3. Copy the Client ID and Client Secret\n4. Enter both below", + "setupInstructions": "1. Log in to Domo at your-instance.domo.com\n2. Go to Admin > Security > API Clients (or visit developer.domo.com and log in)\n3. Create a new client with User Read scope\n4. Copy the Client ID and Client Secret\n5. Enter both below", "credentialFields": [ { "label": "Client ID", diff --git a/integrations-catalog/integrations/druva.json b/integrations-catalog/integrations/druva.json index e0b72b4385..c27d750f45 100644 --- a/integrations-catalog/integrations/druva.json +++ b/integrations-catalog/integrations/druva.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Druva Cloud Platform Console at https://login.druva.com/\n2. Go to Administration > API Credentials\n3. Create new API credentials\n4. Copy the Client ID and Secret Key\n5. Enter both below\n\nNote: You must be a Druva Cloud Administrator to create API credentials.", "credentialFields": [ { "label": "Client ID", @@ -17,7 +18,7 @@ }, { "label": "Secret Key", - "type": "secret", + "type": "password", "required": true, "helpText": "Secret Key from Druva Cloud Platform Console > API Credentials" } diff --git a/integrations-catalog/integrations/egnyte.json b/integrations-catalog/integrations/egnyte.json index 8ae2cfda7b..f07f515f8a 100644 --- a/integrations-catalog/integrations/egnyte.json +++ b/integrations-catalog/integrations/egnyte.json @@ -3,7 +3,7 @@ "name": "Egnyte", "description": "Egnyte is an enterprise file sharing, storage, and governance platform. This integration monitors user access, role-based controls, and encryption compliance.", "category": "Cloud", - "docsUrl": null, + "docsUrl": "https://developers.egnyte.com/docs", "baseUrl": "https://placeholder.egnyte.com", "authConfig": { "type": "custom", diff --git a/integrations-catalog/integrations/employment-hero.json b/integrations-catalog/integrations/employment-hero.json index 3c4f461f81..eb65c9d182 100644 --- a/integrations-catalog/integrations/employment-hero.json +++ b/integrations-catalog/integrations/employment-hero.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Employment Hero\n2. Go to your profile menu > Developer Portal\n3. Register a new application or use an existing one\n4. Generate a Bearer token (OAuth2 access token)\n5. Find your Organisation ID via GET /api/v1/organisations\n6. Paste the Bearer token and Organisation ID below", "credentialFields": [ { "label": "API Token (Bearer Token)", diff --git a/integrations-catalog/integrations/endor-labs.json b/integrations-catalog/integrations/endor-labs.json index 5ec5d051af..fbc08324d3 100644 --- a/integrations-catalog/integrations/endor-labs.json +++ b/integrations-catalog/integrations/endor-labs.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Endor Labs\n2. Go to Settings → API Keys\n3. Create an API key\n4. Enter your namespace and paste the key below", + "setupInstructions": "1. Log in to Endor Labs\n2. Go to Settings > API Keys\n3. Click Create API Key, copy both the Key and Secret\n4. Enter your namespace (organization identifier) and paste the key and secret below", "credentialFields": [ { "label": "API Key", + "type": "text", + "required": true, + "helpText": "Endor Labs > Settings > API Keys > Create API key. Copy the Key value." + }, + { + "label": "API Secret", "type": "password", "required": true, - "helpText": "Endor Labs → Settings → API Keys → Create API key" + "helpText": "The secret value shown when you create the API key (shown once)." }, { "label": "Namespace", diff --git a/integrations-catalog/integrations/env0.json b/integrations-catalog/integrations/env0.json index 8345839602..8656a7c702 100644 --- a/integrations-catalog/integrations/env0.json +++ b/integrations-catalog/integrations/env0.json @@ -3,11 +3,15 @@ "name": "env0", "description": "Infrastructure automation platform. Monitor environments and deployments.", "category": "Infrastructure", - "docsUrl": "https://developer.env0.com/", + "docsUrl": "https://docs.env0.com/reference/authentication", "baseUrl": "https://api.env0.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to env0 at https://app.env0.com\n2. Go to Organization Settings > API Keys\n3. Click + Add API Key\n4. Give it a name and select Admin role (minimum)\n5. Copy the API Key ID and API Key Secret\n6. Paste them into the fields below", + "usernameField": "api_key_id", + "passwordField": "api_key_secret" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/factorial.json b/integrations-catalog/integrations/factorial.json index 96b2a5bdc2..e82a2ef39f 100644 --- a/integrations-catalog/integrations/factorial.json +++ b/integrations-catalog/integrations/factorial.json @@ -6,17 +6,9 @@ "docsUrl": "https://apidoc.factorialhr.com", "baseUrl": "https://api.factorialhr.com", "authConfig": { - "type": "custom", + "type": "api_key", "config": { - "setupInstructions": "1. Log in to Factorial\n2. Go to Settings → API\n3. Generate a new API key\n4. Paste it below", - "credentialFields": [ - { - "label": "API Key", - "type": "password", - "required": true, - "helpText": "Factorial → Settings → API → Generate API Key" - } - ] + "setupInstructions": "1. Log in to Factorial as an admin\n2. Go to Settings > API Keys\n3. Create a new API key\n4. Copy the key and paste it below\n\nNote: API Keys have full admin access. Store securely." } }, "capabilities": [ diff --git a/integrations-catalog/integrations/fireworks-ai.json b/integrations-catalog/integrations/fireworks-ai.json index c82176ccd6..bf858d61dc 100644 --- a/integrations-catalog/integrations/fireworks-ai.json +++ b/integrations-catalog/integrations/fireworks-ai.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.fireworks.ai", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Go to the Fireworks AI dashboard at https://app.fireworks.ai\n2. Navigate to Settings > API Keys\n3. Generate an API key\n4. Enter it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/fivetran.json b/integrations-catalog/integrations/fivetran.json index 09ca808d72..4bd35d0564 100644 --- a/integrations-catalog/integrations/fivetran.json +++ b/integrations-catalog/integrations/fivetran.json @@ -4,19 +4,13 @@ "description": "Monitor Fivetran data pipeline connectors and user access for data integration compliance", "category": "Cloud", "docsUrl": "https://fivetran.com/docs/rest-api", - "baseUrl": "https://api.fivetran.com/", + "baseUrl": "https://api.fivetran.com", "authConfig": { - "type": "custom", + "type": "basic", "config": { - "setupInstructions": "1. Go to Fivetran Dashboard → Settings → API Config\n2. Generate an API key and secret\n3. Encode them: base64('api_key:api_secret')\n4. Enter the encoded value below", - "credentialFields": [ - { - "label": "Encoded API Credentials", - "type": "password", - "required": true, - "helpText": "Base64 encode 'api_key:api_secret'. Command: echo -n 'key:secret' | base64" - } - ] + "setupInstructions": "1. Log in to Fivetran Dashboard\n2. Click your username in the top right\n3. Click API Key\n4. Generate an API key (or generate a new one)\n5. Note down both the API Key and API Secret\n6. Enter them below", + "usernameField": "api_key", + "passwordField": "api_secret" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/fleetdm.json b/integrations-catalog/integrations/fleetdm.json index 26496c96e6..8d55a7db34 100644 --- a/integrations-catalog/integrations/fleetdm.json +++ b/integrations-catalog/integrations/fleetdm.json @@ -3,11 +3,27 @@ "name": "FleetDM", "description": "Open-source device management platform for monitoring and securing endpoints", "category": "Security", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://fleetdm.com/docs/rest-api/rest-api", + "baseUrl": "https://fleet.example.com", "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Log in to your Fleet dashboard\n2. Go to My account (click your avatar)\n3. Click 'Get API token'\n4. Copy the token\n5. Enter your Fleet server URL and token below", + "credentialFields": [ + { + "label": "Fleet Server URL", + "type": "text", + "required": true, + "helpText": "The URL of your Fleet server (e.g. https://fleet.yourcompany.com)" + }, + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Your Fleet API token. Get it from My account > Get API token in the Fleet UI." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/fortinet-fortigate.json b/integrations-catalog/integrations/fortinet-fortigate.json index 8a149ff6a1..2f560dd20c 100644 --- a/integrations-catalog/integrations/fortinet-fortigate.json +++ b/integrations-catalog/integrations/fortinet-fortigate.json @@ -8,16 +8,19 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your FortiGate web UI\n2. Go to System > Administrators\n3. Click Create New > REST API Admin\n4. Set an admin profile with read permissions\n5. Copy the generated API token (shown only once)\n6. Enter your FortiGate URL and token below", "credentialFields": [ { - "label": "Api Token", - "type": "secret", - "required": true + "label": "FortiGate URL", + "type": "text", + "required": true, + "helpText": "The HTTPS URL of your FortiGate appliance (e.g. https://fortigate.yourcompany.com)" }, { - "label": "Server Url", - "type": "text", - "required": true + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Generate a REST API token in FortiGate: System > Administrators > Create New > REST API Admin" } ] } diff --git a/integrations-catalog/integrations/freshbooks.json b/integrations-catalog/integrations/freshbooks.json index f55c0bfc52..eac9ec51c0 100644 --- a/integrations-catalog/integrations/freshbooks.json +++ b/integrations-catalog/integrations/freshbooks.json @@ -6,17 +6,14 @@ "docsUrl": "https://www.freshbooks.com/api/start", "baseUrl": "https://api.freshbooks.com/", "authConfig": { - "type": "api_key", + "type": "oauth2", "config": { - "setupInstructions": "1. Log in to FreshBooks at https://my.freshbooks.com\n2. Go to Settings → Developer Portal\n3. Create an app and generate an OAuth access token\n4. Enter it below", - "credentialFields": [ - { - "label": "Access Token", - "type": "password", - "required": true, - "helpText": "OAuth access token from FreshBooks Developer Portal" - } - ] + "setupInstructions": "Go to https://my.freshbooks.com/developer to create OAuth app", + "scopes": [ + "user:profile:read" + ], + "clientAuthMethod": "body", + "supportsRefreshToken": true } }, "capabilities": [ diff --git a/integrations-catalog/integrations/freshdesk.json b/integrations-catalog/integrations/freshdesk.json index 0b759d2b18..29e8053f13 100644 --- a/integrations-catalog/integrations/freshdesk.json +++ b/integrations-catalog/integrations/freshdesk.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Go to Freshdesk Profile Settings (top-right avatar > Profile Settings)\n2. Copy your API Key\n3. Encode it: base64('your_api_key:X') — note the literal ':X' suffix\n4. Enter the encoded value below along with your subdomain", + "setupInstructions": "1. Log in to Freshdesk\n2. Click your avatar (top right) then Profile Settings\n3. Copy your API Key from the right side\n4. Enter your subdomain and API key below", "credentialFields": [ { - "label": "Encoded API Key", + "label": "Freshdesk Subdomain", + "type": "text", + "required": true, + "helpText": "Your Freshdesk subdomain (e.g. 'mycompany' for mycompany.freshdesk.com)" + }, + { + "label": "API Key", "type": "password", "required": true, - "helpText": "Base64 encode your API key followed by ':X'. Example: base64('your_api_key:X'). Use https://www.base64encode.org/" + "helpText": "Found in Freshdesk Profile Settings (top-right avatar > Profile Settings)" } ] } diff --git a/integrations-catalog/integrations/fullstory.json b/integrations-catalog/integrations/fullstory.json index e049de7128..a74c39f5d2 100644 --- a/integrations-catalog/integrations/fullstory.json +++ b/integrations-catalog/integrations/fullstory.json @@ -8,13 +8,13 @@ "authConfig": { "type": "api_key", "config": { - "setupInstructions": "1. Log in to FullStory at https://app.fullstory.com\n2. Go to Settings → Integrations → API Keys\n3. Generate a Server API key\n4. Copy and enter it below (the key itself, no encoding needed)", + "setupInstructions": "1. Log in to FullStory at https://app.fullstory.com\n2. Go to Settings > Integrations > API Keys\n3. Generate a Server API key\n4. Copy and enter it below (the key itself, no encoding needed)", "credentialFields": [ { "label": "Server API Key", "type": "password", "required": true, - "helpText": "Found in FullStory Settings → Integrations → API Keys (Server API key)" + "helpText": "Found in FullStory Settings > Integrations > API Keys (Server API key)" } ] } @@ -28,7 +28,7 @@ { "slug": "fullstory_employee_access", "name": "Employee Access", - "description": "Reviews FullStory users with access to session replay data", + "description": "Verifies account access to FullStory by listing segments", "defaultSeverity": "medium", "enabled": true }, diff --git a/integrations-catalog/integrations/gainsight.json b/integrations-catalog/integrations/gainsight.json new file mode 100644 index 0000000000..d3bd9fd36b --- /dev/null +++ b/integrations-catalog/integrations/gainsight.json @@ -0,0 +1,52 @@ +{ + "slug": "gainsight", + "name": "Gainsight", + "description": "Gainsight is a customer success platform that helps enterprise SaaS companies reduce churn, increase expansion, and drive product adoption. This integration verifies employee access and API availability.", + "category": "Productivity", + "docsUrl": "https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs", + "baseUrl": "https://gainsight.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to your Gainsight instance as a Super Admin\n2. Navigate to Administration > Connectors 2.0\n3. Click Create Connection\n4. Select 'Gainsight API' from the Connector dropdown\n5. Enter a name for the connection\n6. Select 'Access_Key' as the Authentication Type\n7. Click 'Generate Access Key'\n8. Copy the generated access key\n9. Paste your Gainsight instance URL (e.g., https://yourcompany.gainsight.com) and the access key below\n\nNote: Only Super Admins who are active in User Management can generate the API Access Key. The access key does not expire but can be regenerated.", + "credentialFields": [ + { + "label": "Gainsight Instance URL", + "type": "text", + "required": true, + "helpText": "Your Gainsight tenant URL (e.g., https://yourcompany.gainsight.com). Found in your browser address bar when logged into Gainsight." + }, + { + "label": "API Access Key", + "type": "password", + "required": true, + "helpText": "Found in Gainsight Administration > Connectors 2.0 > Create Connection > Gainsight API > Access_Key > Generate Access Key. Only Super Admins can generate this key." + } + ] + } + }, + "capabilities": [ + "checks", + "sync" + ], + "supportsMultipleConnections": false, + "syncSupported": true, + "checks": [ + { + "slug": "gainsight_app_availability", + "name": "Gainsight App Availability", + "description": "Verifies that the Gainsight REST API is accessible using the provided access key.", + "defaultSeverity": "high", + "enabled": true + }, + { + "slug": "gainsight_employee_access", + "name": "Gainsight Employee Access", + "description": "Lists all Gainsight users with their roles, license types, and active status to verify employee access controls.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 2, + "isActive": true +} diff --git a/integrations-catalog/integrations/go1.json b/integrations-catalog/integrations/go1.json index 7f976b0b8b..177fd1ae9b 100644 --- a/integrations-catalog/integrations/go1.json +++ b/integrations-catalog/integrations/go1.json @@ -3,8 +3,8 @@ "name": "Go1", "description": "Go1 is a learning content aggregator and training platform used for compliance training, L&D, and security awareness. Connect Go1 to verify employee access and training enrollment status.", "category": "Security", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://www.go1.com/developers", + "baseUrl": "https://gateway.go1.com", "authConfig": { "type": "oauth2", "config": { diff --git a/integrations-catalog/integrations/grain.json b/integrations-catalog/integrations/grain.json index 6845910380..7a218eff5f 100644 --- a/integrations-catalog/integrations/grain.json +++ b/integrations-catalog/integrations/grain.json @@ -4,7 +4,7 @@ "description": "Grain meeting recording and intelligence platform integration for monitoring meeting recordings, team access, and compliance", "category": "Productivity", "docsUrl": "https://developers.grain.com/", - "baseUrl": null, + "baseUrl": "https://api.grain.com", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/greenhouse.json b/integrations-catalog/integrations/greenhouse.json index 20ab67215a..c0137d5369 100644 --- a/integrations-catalog/integrations/greenhouse.json +++ b/integrations-catalog/integrations/greenhouse.json @@ -6,8 +6,12 @@ "docsUrl": "https://developers.greenhouse.io/harvest.html", "baseUrl": "https://harvest.greenhouse.io/", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to Greenhouse\n2. Go to Configure > Dev Center > API Credential Management\n3. Create a Harvest API Key (or use existing)\n4. Grant appropriate endpoint permissions\n5. Copy the API key and paste it below as the username (leave password blank)\n\nNote: The Harvest v1/v2 API will be deprecated on August 31, 2026. Greenhouse is transitioning to Harvest v3.", + "usernameField": "api_key", + "passwordField": "password" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/groq.json b/integrations-catalog/integrations/groq.json index 9a595db97e..53b2e9af0e 100644 --- a/integrations-catalog/integrations/groq.json +++ b/integrations-catalog/integrations/groq.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.groq.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Go to https://console.groq.com/keys\n2. Create a new API key\n3. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/hashicorp-vault.json b/integrations-catalog/integrations/hashicorp-vault.json index ffa0bec892..5f18a85077 100644 --- a/integrations-catalog/integrations/hashicorp-vault.json +++ b/integrations-catalog/integrations/hashicorp-vault.json @@ -7,7 +7,9 @@ "baseUrl": "https://vault.example.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Get a Vault token with appropriate permissions (read access to sys/health and sys/mounts)\n2. You can create a token using: vault token create -policy=\n3. Copy the token and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/hellosign.json b/integrations-catalog/integrations/hellosign.json index f0b6cf920c..d4eaa6208d 100644 --- a/integrations-catalog/integrations/hellosign.json +++ b/integrations-catalog/integrations/hellosign.json @@ -6,8 +6,12 @@ "docsUrl": "https://developers.hellosign.com/", "baseUrl": "https://api.hellosign.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "basic", + "config": { + "setupInstructions": "1. Log in to Dropbox Sign\n2. Go to Settings > Integrations > API\n3. Copy your API key and paste it below as the username (leave password blank)\n\nNote: This integration uses the hellosign slug. A separate 'dropbox-sign' integration also exists.", + "usernameField": "api_key", + "passwordField": "password" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/helpscout.json b/integrations-catalog/integrations/helpscout.json index c97d95ad68..19138cb568 100644 --- a/integrations-catalog/integrations/helpscout.json +++ b/integrations-catalog/integrations/helpscout.json @@ -6,15 +6,21 @@ "docsUrl": "https://developer.helpscout.com/mailbox-api/", "baseUrl": "https://api.helpscout.net/", "authConfig": { - "type": "api_key", + "type": "custom", "config": { - "setupInstructions": "1. Log in to Help Scout at https://secure.helpscout.net\n2. Go to Your Profile → API Keys\n3. Create a new API key\n4. Copy and enter it below", + "setupInstructions": "1. Log in to Help Scout at https://secure.helpscout.net\n2. Go to Your Profile > My Apps\n3. Click 'Create My App'\n4. Enter any name and a redirect URL (e.g. https://example.com)\n5. Copy the App ID and App Secret\n6. Enter them below", "credentialFields": [ { - "label": "API Key", + "label": "Application ID", + "type": "text", + "required": true, + "helpText": "Found in Help Scout Your Profile > My Apps" + }, + { + "label": "Application Secret", "type": "password", "required": true, - "helpText": "Found in Help Scout Profile → API Keys" + "helpText": "Found in Help Scout Your Profile > My Apps" } ] } diff --git a/integrations-catalog/integrations/huntress.json b/integrations-catalog/integrations/huntress.json index 54f1840ba4..4dc8c720f4 100644 --- a/integrations-catalog/integrations/huntress.json +++ b/integrations-catalog/integrations/huntress.json @@ -21,7 +21,9 @@ "required": true, "helpText": "Secret Key from Account Settings > API Credentials in Huntress portal" } - ] + ], + "usernameField": "api_key", + "passwordField": "secret_key" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/hyperproof.json b/integrations-catalog/integrations/hyperproof.json index 2abdabb442..23d9df1f48 100644 --- a/integrations-catalog/integrations/hyperproof.json +++ b/integrations-catalog/integrations/hyperproof.json @@ -6,8 +6,23 @@ "docsUrl": "https://developer.hyperproof.app/", "baseUrl": "https://api.hyperproof.app", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "OAuth2 Client ID from Hyperproof API settings" + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "OAuth2 Client Secret from Hyperproof API settings" + } + ] + } }, "capabilities": [ "checks" @@ -18,14 +33,14 @@ { "slug": "hyperproof_app_availability", "name": "Hyperproof App Availability", - "description": "Checks that the Hyperproof API is accessible.", + "description": "Checks that the Hyperproof API is accessible with the provided OAuth2 credentials.", "defaultSeverity": "medium", "enabled": true }, { "slug": "hyperproof_employee_access", "name": "Hyperproof Employee Access", - "description": "Verifies access to Hyperproof.", + "description": "Verifies user access to Hyperproof platform.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/incident-io.json b/integrations-catalog/integrations/incident-io.json index a398be4dfe..59f7398659 100644 --- a/integrations-catalog/integrations/incident-io.json +++ b/integrations-catalog/integrations/incident-io.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.incident.io/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to your incident.io dashboard\n2. Go to Settings > API keys\n3. Create a new API key with appropriate permissions\n4. Enter the API key below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/infisical.json b/integrations-catalog/integrations/infisical.json index f3d17e3260..2fc8fd91dc 100644 --- a/integrations-catalog/integrations/infisical.json +++ b/integrations-catalog/integrations/infisical.json @@ -7,7 +7,9 @@ "baseUrl": "https://app.infisical.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. In Infisical, go to Organization Settings > Access Control > Identities\n2. Create a Machine Identity with the 'Member' role\n3. Under Authentication, configure Universal Auth\n4. Note the Client ID and Client Secret\n5. Obtain an access token: POST https://app.infisical.com/api/v1/auth/universal-auth/login with clientId and clientSecret\n6. Paste the access token below\n\nNote: Access tokens expire (default 30 days). You may need to refresh periodically." + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/inngest.json b/integrations-catalog/integrations/inngest.json index 69171aeb77..bbb2715ac2 100644 --- a/integrations-catalog/integrations/inngest.json +++ b/integrations-catalog/integrations/inngest.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.inngest.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to your Inngest Cloud dashboard\n2. Go to Profile menu (bottom left) > API Keys\n3. Create a new API key (or use your environment signing key)\n4. Enter it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/instatus.json b/integrations-catalog/integrations/instatus.json index e580e6d348..a8b1fa5b00 100644 --- a/integrations-catalog/integrations/instatus.json +++ b/integrations-catalog/integrations/instatus.json @@ -8,13 +8,13 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Instatus\n2. Go to Account Settings\n3. Copy your API key\n4. Paste it below", + "setupInstructions": "1. Log in to Instatus\n2. Go to User Settings > Developer Settings\n3. Copy your API key\n4. Paste it below", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "Instatus → Account Settings → API Key" + "helpText": "Instatus > User Settings > Developer Settings (https://dashboard.instatus.com/developer)" } ] } diff --git a/integrations-catalog/integrations/it-glue.json b/integrations-catalog/integrations/it-glue.json index b3aca82a8e..2a0e5d7e4b 100644 --- a/integrations-catalog/integrations/it-glue.json +++ b/integrations-catalog/integrations/it-glue.json @@ -7,7 +7,23 @@ "baseUrl": null, "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Log in to IT Glue as an Administrator\n2. Go to Account > Settings > API Keys\n3. Generate a new API key (store it safely - it cannot be viewed again)\n4. Select your region (check your IT Glue login URL)\n5. Enter the API key and select your region below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Your IT Glue API key. Go to Account > Settings > API Keys to generate one." + }, + { + "label": "Region", + "type": "select", + "required": true, + "helpText": "Select the region where your IT Glue account is hosted" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/juro.json b/integrations-catalog/integrations/juro.json index 449fa54e0a..c026762ed8 100644 --- a/integrations-catalog/integrations/juro.json +++ b/integrations-catalog/integrations/juro.json @@ -3,7 +3,7 @@ "name": "Juro", "description": "Juro contract management and automation platform", "category": "Productivity", - "docsUrl": "https://developers.juro.com/", + "docsUrl": "https://juro.com/integrations", "baseUrl": "https://app.juro.com/api/v1", "authConfig": { "type": "custom", diff --git a/integrations-catalog/integrations/kenjo.json b/integrations-catalog/integrations/kenjo.json index d69ca0a399..6d891acd95 100644 --- a/integrations-catalog/integrations/kenjo.json +++ b/integrations-catalog/integrations/kenjo.json @@ -6,8 +6,18 @@ "docsUrl": "https://kenjo.readme.io/reference", "baseUrl": "https://api.kenjo.io", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Kenjo as an admin\n2. Go to Settings > Integrations > API keys\n3. Click GENERATE NEW API KEY\n4. Copy the API key immediately (it is shown only once)\n5. Paste it below\n\nNote: API access must be activated by the Kenjo Customer Success team first.", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Generated in Kenjo Settings > Integrations > API keys" + } + ] + } }, "capabilities": [ "checks", diff --git a/integrations-catalog/integrations/keycdn.json b/integrations-catalog/integrations/keycdn.json index 236a5e298a..870956db6f 100644 --- a/integrations-catalog/integrations/keycdn.json +++ b/integrations-catalog/integrations/keycdn.json @@ -8,13 +8,13 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to KeyCDN\n2. Go to Account → API\n3. Copy your API Key\n4. Paste it below\n\nNote: The API key is used with HTTP Basic Auth (pass 'api_key_here' as both username and empty password)", + "setupInstructions": "1. Log in to KeyCDN\n2. Go to Account > API\n3. Copy your API Key\n4. Paste it below\n\nNote: The API key is used with HTTP Basic Auth (API key as username with empty password).", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "KeyCDN → Account → API → API Key" + "helpText": "KeyCDN > Account > API > API Key" } ] } diff --git a/integrations-catalog/integrations/kolide.json b/integrations-catalog/integrations/kolide.json index 4f7c84f9ce..09b83abc23 100644 --- a/integrations-catalog/integrations/kolide.json +++ b/integrations-catalog/integrations/kolide.json @@ -4,7 +4,7 @@ "description": "Kolide device security and compliance for remote teams", "category": "Security", "docsUrl": "https://www.kolide.com/docs/developers/api", - "baseUrl": "https://k2.kolide.com/api/v0", + "baseUrl": "https://api.kolide.com", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/kombo.json b/integrations-catalog/integrations/kombo.json index fb667a1f79..16159a1650 100644 --- a/integrations-catalog/integrations/kombo.json +++ b/integrations-catalog/integrations/kombo.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Kombo\n2. Go to Settings → API Keys\n3. Create a new API key\n4. Paste it below", + "setupInstructions": "1. Log in to the Kombo Dashboard at https://app.kombo.dev\n2. Go to Secrets page and create or copy your API Key\n3. Go to Integrations, click the HRIS integration you want to monitor\n4. Copy the Integration ID from the details page\n5. Enter both values below", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "Kombo → Settings → API Keys → Create API Key" + "helpText": "Kombo Dashboard -> Secrets page -> Create API Key" + }, + { + "label": "Integration ID", + "type": "text", + "required": true, + "helpText": "Found in Kombo Dashboard -> Integrations -> click on the integration -> copy the ID" } ] } diff --git a/integrations-catalog/integrations/koyeb.json b/integrations-catalog/integrations/koyeb.json index 9f31bddf87..ea835994ea 100644 --- a/integrations-catalog/integrations/koyeb.json +++ b/integrations-catalog/integrations/koyeb.json @@ -7,7 +7,17 @@ "baseUrl": "https://app.koyeb.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Koyeb at https://app.koyeb.com\n2. Go to Account Settings -> API\n3. Create a new API token\n4. Copy and enter it below", + "credentialFields": [ + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Found in Koyeb Control Panel -> Account Settings -> API" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/kustomer.json b/integrations-catalog/integrations/kustomer.json index f840fe138c..c797293d40 100644 --- a/integrations-catalog/integrations/kustomer.json +++ b/integrations-catalog/integrations/kustomer.json @@ -8,7 +8,7 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Kustomer\n2. Settings → API Keys\n3. Create a key with read permissions\n4. Paste it below", + "setupInstructions": "1. Log in to Kustomer\n2. Go to Settings > Security > API Keys\n3. Create a new API key with read permissions\n4. Copy the key and paste it below", "credentialFields": [ { "label": "API Key", diff --git a/integrations-catalog/integrations/lacework.json b/integrations-catalog/integrations/lacework.json index 389cbfa83e..4c23cb1006 100644 --- a/integrations-catalog/integrations/lacework.json +++ b/integrations-catalog/integrations/lacework.json @@ -8,19 +8,25 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Lacework at https://YOUR_ACCOUNT.lacework.net\n2. Go to Settings → API Keys → Create New API Key\n3. Download the JSON with keyId and secret\n4. Generate an access token: POST /api/v2/access/tokens with keyId and secret\n5. Enter your account name and access token below", + "setupInstructions": "1. Log in to Lacework at https://YOUR_ACCOUNT.lacework.net\n2. Go to Settings -> API Keys -> Create New API Key\n3. Download the JSON key file\n4. Enter your account name, the keyId and secret from the key file below", "credentialFields": [ { - "label": "API Token", - "type": "password", + "label": "Account Name", + "type": "text", "required": true, - "helpText": "Access Token generated via Lacework API. Use your keyId and secret to get a token from POST /api/v2/access/tokens" + "helpText": "Your Lacework account subdomain (e.g. mycompany from mycompany.lacework.net)" }, { - "label": "Account Name", + "label": "API Key ID", "type": "text", "required": true, - "helpText": "Your Lacework account subdomain (e.g. mycompany from mycompany.lacework.net)" + "helpText": "Found in Lacework Settings -> API Keys -> download the JSON key file, use the keyId field" + }, + { + "label": "API Secret", + "type": "password", + "required": true, + "helpText": "Found in the downloaded JSON key file, use the secret field" } ] } diff --git a/integrations-catalog/integrations/lambdatest.json b/integrations-catalog/integrations/lambdatest.json index 1fc35e4cf9..da03d90bd0 100644 --- a/integrations-catalog/integrations/lambdatest.json +++ b/integrations-catalog/integrations/lambdatest.json @@ -6,17 +6,11 @@ "docsUrl": "https://www.lambdatest.com/support/api-doc/", "baseUrl": "https://api.lambdatest.com/", "authConfig": { - "type": "custom", + "type": "basic", "config": { - "setupInstructions": "1. Log in to LambdaTest at https://accounts.lambdatest.com\n2. Go to Profile → Access Key\n3. Note your Username and Access Key\n4. Base64 encode 'username:access_key'\n5. Enter the encoded value below", - "credentialFields": [ - { - "label": "Encoded Credentials", - "type": "password", - "required": true, - "helpText": "Base64 encode 'username:access_key'. Found in LambdaTest → Profile → Access Key. Command: echo -n 'username:access_key' | base64" - } - ] + "setupInstructions": "1. Log in to LambdaTest at https://accounts.lambdatest.com\n2. Go to Profile -> Access Key\n3. Copy your Username and Access Key\n4. Enter them below", + "usernameField": "username", + "passwordField": "access_key" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/logdna.json b/integrations-catalog/integrations/logdna.json index 59d2df355d..04f528740f 100644 --- a/integrations-catalog/integrations/logdna.json +++ b/integrations-catalog/integrations/logdna.json @@ -6,8 +6,18 @@ "docsUrl": "https://docs.mezmo.com/reference", "baseUrl": "https://api.mezmo.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Mezmo (formerly LogDNA)\n2. Go to Settings > Organization > API Keys\n3. Copy a Service Key (not an Ingestion Key)\n4. Paste it below", + "credentialFields": [ + { + "label": "Service Key", + "type": "password", + "required": true, + "helpText": "Found in Mezmo (LogDNA) Settings > Organization > API Keys. Copy a Service Key." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/logzio.json b/integrations-catalog/integrations/logzio.json index 01e9f34f5a..ddbbbe2bce 100644 --- a/integrations-catalog/integrations/logzio.json +++ b/integrations-catalog/integrations/logzio.json @@ -6,21 +6,21 @@ "docsUrl": "https://docs.logz.io/api/", "baseUrl": "https://api.logz.io/", "authConfig": { - "type": "api_key", + "type": "custom", "config": { - "setupInstructions": "1. Log in to Logz.io\n2. Go to Settings → Manage tokens → API tokens\n3. Create a new API token\n4. Select your region and enter the token below", + "setupInstructions": "1. Log in to Logz.io\n2. Go to Settings > Manage tokens > API tokens\n3. Create or copy an existing API token\n4. Select your region based on your Logz.io URL", "credentialFields": [ { "label": "API Token", "type": "password", "required": true, - "helpText": "Found in Logz.io Settings → Manage tokens → API tokens" + "helpText": "Found in Logz.io Settings > Manage tokens > API tokens" }, { - "label": "Region Base URL", - "type": "text", + "label": "Region", + "type": "select", "required": true, - "helpText": "Your Logz.io API base URL: api.logz.io (US), api-eu.logz.io (EU), api-nl.logz.io (EU2), api-ca.logz.io (CA)" + "helpText": "Your Logz.io API region. Found in your Logz.io URL (e.g., app.logz.io = US East)." } ] } diff --git a/integrations-catalog/integrations/lucid.json b/integrations-catalog/integrations/lucid.json index 5538d91847..43ae324048 100644 --- a/integrations-catalog/integrations/lucid.json +++ b/integrations-catalog/integrations/lucid.json @@ -6,8 +6,18 @@ "docsUrl": "https://developer.lucid.co/", "baseUrl": "https://api.lucid.co", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to your Lucid account as an admin\n2. Go to developer.lucid.co\n3. Create an API key with AccountReadonly grant\n4. Copy the API key and paste it below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Create an API key in the Lucid Developer Portal at developer.lucid.co. Requires AccountReadonly grant." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/lucidchart.json b/integrations-catalog/integrations/lucidchart.json index 65f95990f4..c1ea0469b7 100644 --- a/integrations-catalog/integrations/lucidchart.json +++ b/integrations-catalog/integrations/lucidchart.json @@ -4,7 +4,7 @@ "description": "Lucidchart visual collaboration platform for diagrams and flowcharts", "category": "Productivity", "docsUrl": "https://developer.lucid.co", - "baseUrl": "https://api.lucid.app", + "baseUrl": "https://api.lucid.co", "authConfig": { "type": "custom", "config": { diff --git a/integrations-catalog/integrations/mabl.json b/integrations-catalog/integrations/mabl.json index bf7c6fe58a..da4cebdf29 100644 --- a/integrations-catalog/integrations/mabl.json +++ b/integrations-catalog/integrations/mabl.json @@ -6,17 +6,25 @@ "docsUrl": "https://help.mabl.com/hc/en-us/articles/360017810591-Using-the-Mabl-REST-API", "baseUrl": "https://api.mabl.com/", "authConfig": { - "type": "custom", + "type": "basic", "config": { - "setupInstructions": "1. Log in to Mabl at https://app.mabl.com\n2. Go to Settings → API → API Keys\n3. Generate an API key\n4. Base64 encode 'key:your_api_key' (where 'key' is the literal username)\n5. Enter the encoded value below", + "setupInstructions": "1. Log in to mabl at https://app.mabl.com\n2. Go to Settings > API > API Keys\n3. Generate a new API key\n4. Enter \"key\" as the Username and paste the API key below", "credentialFields": [ { - "label": "Encoded API Key", + "label": "Username", + "type": "text", + "required": true, + "helpText": "Enter \"key\" (literal text). mabl uses the word \"key\" as the Basic auth username." + }, + { + "label": "API Key", "type": "password", "required": true, - "helpText": "Base64 encode 'key:your_api_key' (literally 'key' as username). Command: echo -n 'key:your_api_key' | base64" + "helpText": "Found in mabl Settings > API > API Keys. Generate a new key if needed." } - ] + ], + "usernameField": "username", + "passwordField": "api_key" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/mailchimp.json b/integrations-catalog/integrations/mailchimp.json index e2e3bdfd29..23bc011483 100644 --- a/integrations-catalog/integrations/mailchimp.json +++ b/integrations-catalog/integrations/mailchimp.json @@ -2,19 +2,25 @@ "slug": "mailchimp", "name": "Mailchimp", "description": "Monitor Mailchimp subscriber lists and data handling for email marketing compliance", - "category": "Productivity", + "category": "Communication", "docsUrl": "https://mailchimp.com/developer/marketing/api/", "baseUrl": "https://us1.api.mailchimp.com/", "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Go to Mailchimp > Profile > Extras > API keys\n2. Create a new API key\n3. Note your data center suffix from the key (e.g. 'us1' in 'xxx-us1')\n4. Encode: base64('anystring:your_api_key')\n5. Enter encoded value + data center below", + "setupInstructions": "1. Log in to Mailchimp\n2. Go to Account & billing > Extras > API keys\n3. Create a new API key\n4. Copy the full key (e.g., abc123def456-us1)\n5. Enter the key and the data center suffix (the part after the dash, e.g., us1)", "credentialFields": [ { - "label": "Encoded API Key", + "label": "API Key", "type": "password", "required": true, - "helpText": "Base64 encode 'anystring:your_api_key'. Example: base64('user:abc123def456-us1'). Use https://www.base64encode.org/" + "helpText": "Found in Mailchimp > Account & billing > Extras > API keys. The key looks like abc123def456-us1." + }, + { + "label": "Data Center", + "type": "text", + "required": true, + "helpText": "The data center suffix from your API key (the part after the dash, e.g., us1, us10, eu1)." } ] } diff --git a/integrations-catalog/integrations/mailgun.json b/integrations-catalog/integrations/mailgun.json new file mode 100644 index 0000000000..f4f222b4f0 --- /dev/null +++ b/integrations-catalog/integrations/mailgun.json @@ -0,0 +1,58 @@ +{ + "slug": "mailgun", + "name": "Mailgun", + "description": "Monitor Mailgun email infrastructure including account user access, API availability, and sending domain configuration and verification status", + "category": "Communication", + "docsUrl": "https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview", + "baseUrl": "https://{{credentials.region}}", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Mailgun Dashboard (https://app.mailgun.com).\n2. Go to Account Settings (top-right) > API Keys.\n3. Click the eye icon next to 'Private API key' to reveal it.\n4. Copy the key (starts with 'key-').\n5. Select your region (US or EU) based on where your sending domains are hosted.", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Your primary account API key. Found in Mailgun Dashboard > Account Settings > API Keys (Private API key)." + }, + { + "label": "Region", + "type": "select", + "required": true, + "helpText": "The region where your Mailgun domains are hosted." + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "mailgun_employee_access", + "name": "Employee Access", + "description": "Lists all users on the Mailgun account with their roles, activation status, and 2FA settings to verify access control.", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "mailgun_app_availability", + "name": "App Availability", + "description": "Verifies Mailgun API access by listing sending domains. A successful response confirms the API key is valid and the account is accessible.", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "mailgun_domain_configuration", + "name": "Domain Configuration", + "description": "Lists all sending domains and their verification status. Domains in 'unverified' or 'disabled' state are flagged as findings requiring attention.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 3, + "isActive": true +} diff --git a/integrations-catalog/integrations/malwarebytes.json b/integrations-catalog/integrations/malwarebytes.json index 1c3f60ce59..094149368b 100644 --- a/integrations-catalog/integrations/malwarebytes.json +++ b/integrations-catalog/integrations/malwarebytes.json @@ -3,29 +3,30 @@ "name": "Malwarebytes", "description": "Monitor Malwarebytes ThreatDown endpoint security for device protection, threat detection, and compliance", "category": "Security", - "docsUrl": "https://cloud.malwarebytes.com/api/v2/oneview/docs", - "baseUrl": "https://cloud.malwarebytes.com", + "docsUrl": "https://api.threatdown.com/docs/", + "baseUrl": "https://api.threatdown.com", "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to ThreatDown OneView at https://oneview.threatdown.com\n2. Go to Settings > API Access\n3. Create a new API client\n4. Copy the Client ID, Client Secret, and your Account ID\n5. Enter them below", "credentialFields": [ { "label": "Client ID", "type": "text", "required": true, - "helpText": "Found in Malwarebytes OneView > Settings > API Access" + "helpText": "Found in ThreatDown OneView > Settings > API Access" }, { "label": "Client Secret", "type": "password", "required": true, - "helpText": "Found in Malwarebytes OneView > Settings > API Access" + "helpText": "Found in ThreatDown OneView > Settings > API Access" }, { "label": "Account ID", "type": "text", "required": true, - "helpText": "Your Malwarebytes OneView account ID" + "helpText": "Your ThreatDown OneView account ID" } ] } @@ -37,23 +38,23 @@ "syncSupported": false, "checks": [ { - "slug": "device_list", + "slug": "malwarebytes_device_list", "name": "Device List", - "description": "List managed endpoints from Malwarebytes", + "description": "Lists managed endpoints from ThreatDown (Malwarebytes) to verify endpoint security coverage", "defaultSeverity": "medium", "enabled": true }, { - "slug": "secure_devices", + "slug": "malwarebytes_secure_devices", "name": "Secure Devices", - "description": "Check endpoint protection status", + "description": "Checks endpoint protection status across ThreatDown managed devices", "defaultSeverity": "high", "enabled": true }, { - "slug": "monitoring_alerts", + "slug": "malwarebytes_monitoring_alerts", "name": "Monitoring & Alerting", - "description": "Check threat detections and alerts", + "description": "Checks threat detections and alerts from ThreatDown", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/metabase.json b/integrations-catalog/integrations/metabase.json new file mode 100644 index 0000000000..7b6377b784 --- /dev/null +++ b/integrations-catalog/integrations/metabase.json @@ -0,0 +1,57 @@ +{ + "slug": "metabase", + "name": "Metabase", + "description": "Monitor Metabase business intelligence platform for user access management and instance availability compliance evidence", + "category": "Productivity", + "docsUrl": "https://www.metabase.com/docs/latest/api", + "baseUrl": "https://metabase.example.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. You need a Metabase admin account to use this integration\n2. Enter your Metabase instance URL (e.g. https://metabase.yourcompany.com)\n3. Enter the email and password of an admin user\n4. The integration will authenticate via the Metabase API using session tokens", + "credentialFields": [ + { + "label": "Metabase Instance URL", + "type": "text", + "required": true, + "helpText": "Your Metabase instance URL (e.g. https://metabase.yourcompany.com). No trailing slash." + }, + { + "label": "Username (Email)", + "type": "text", + "required": true, + "helpText": "The email address of a Metabase admin user." + }, + { + "label": "Password", + "type": "password", + "required": true, + "helpText": "The password for the Metabase admin user." + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "metabase_employee_access", + "name": "Employee Access", + "description": "List all Metabase users with their roles, active status, and group memberships to verify access compliance", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "metabase_app_availability", + "name": "App Availability", + "description": "Verify that the Metabase instance is accessible and responding to API requests", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 2, + "isActive": true +} diff --git a/integrations-catalog/integrations/metronome.json b/integrations-catalog/integrations/metronome.json index 5ed92e015e..cf1fb4f768 100644 --- a/integrations-catalog/integrations/metronome.json +++ b/integrations-catalog/integrations/metronome.json @@ -8,13 +8,13 @@ "authConfig": { "type": "api_key", "config": { - "setupInstructions": "1. Log in to Metronome at https://metronome.com\n2. Go to Settings → API Keys\n3. Create a new API key\n4. Enter it below", + "setupInstructions": "1. Log in to Metronome at https://metronome.com\n2. Go to Settings > API Keys\n3. Create a new API key\n4. Enter it below", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "Found in Metronome Settings → API Keys" + "helpText": "Found in Metronome Settings > API Keys" } ] } diff --git a/integrations-catalog/integrations/mintlify.json b/integrations-catalog/integrations/mintlify.json index 328f1b76f6..b5d6bd75dd 100644 --- a/integrations-catalog/integrations/mintlify.json +++ b/integrations-catalog/integrations/mintlify.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Mintlify\n2. Go to Dashboard → Settings → API Keys\n3. Create a new API key\n4. Paste it below", + "setupInstructions": "1. Log in to Mintlify Dashboard at https://dashboard.mintlify.com\n2. Go to Settings > Organization > API Keys\n3. Create a new admin API key (starts with 'mint_')\n4. Copy the API Key and the Project ID shown on that page\n5. Paste both values below", "credentialFields": [ { "label": "API Key", "type": "password", "required": true, - "helpText": "Mintlify → Dashboard → Settings → API Keys" + "helpText": "From Mintlify Dashboard > Settings > Organization > API Keys. Keys start with 'mint_'." + }, + { + "label": "Project ID", + "type": "text", + "required": true, + "helpText": "Found in Mintlify Dashboard > Settings > Organization > API Keys page, listed next to the key." } ] } diff --git a/integrations-catalog/integrations/miradore.json b/integrations-catalog/integrations/miradore.json index 539cac2bf8..6ef6ed93ba 100644 --- a/integrations-catalog/integrations/miradore.json +++ b/integrations-catalog/integrations/miradore.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your Miradore console at https://online.miradore.com\n2. Go to System > Infrastructure diagram\n3. Click 'Create key' to generate an API key\n4. Copy the API key\n5. Note your site name (the subdomain in your Miradore URL)\n6. Paste both values below\n\nNote: API access requires a Business or Enterprise plan.", "credentialFields": [ { "label": "Site Name", diff --git a/integrations-catalog/integrations/miro.json b/integrations-catalog/integrations/miro.json index 2bfbe2f7d1..d9f36346b0 100644 --- a/integrations-catalog/integrations/miro.json +++ b/integrations-catalog/integrations/miro.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.miro.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Miro at https://miro.com\n2. Go to your Profile Settings > Your apps (or https://miro.com/app/settings/user-profile/apps)\n3. Create a new app or use an existing one\n4. Under 'OAuth scopes', enable: boards:read, team:read\n5. Install the app to your team\n6. Copy the access token\n7. Paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/mosyle.json b/integrations-catalog/integrations/mosyle.json index c9f58eb284..129fccb0da 100644 --- a/integrations-catalog/integrations/mosyle.json +++ b/integrations-catalog/integrations/mosyle.json @@ -3,11 +3,39 @@ "name": "Mosyle", "description": "Apple Mobile Device Management (MDM) solution for managing iPads, iPhones, Macs, and Apple TVs in educational and enterprise environments.", "category": "Security", - "docsUrl": null, - "baseUrl": null, + "docsUrl": "https://mosyle.com", + "baseUrl": "https://businessapi.mosyle.com/v1", "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Log in to your Mosyle admin console\n2. Go to Organization > API Integration\n3. Enable the API and generate an Access Token\n4. Copy the Access Token\n5. Enter the token along with your admin email and password", + "credentialFields": [ + { + "label": "Mosyle Environment", + "type": "select", + "required": true, + "helpText": "Select your Mosyle product type" + }, + { + "label": "Access Token", + "type": "password", + "required": true, + "helpText": "API access token from Organization > API Integration" + }, + { + "label": "Admin Email", + "type": "text", + "required": true, + "helpText": "Email address of an admin user for API authentication" + }, + { + "label": "Admin Password", + "type": "password", + "required": true, + "helpText": "Password for the admin user account" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/n-able-n-sight.json b/integrations-catalog/integrations/n-able-n-sight.json index 9d62e9c8c6..23fab62115 100644 --- a/integrations-catalog/integrations/n-able-n-sight.json +++ b/integrations-catalog/integrations/n-able-n-sight.json @@ -8,17 +8,18 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to N-able N-sight RMM Dashboard\n2. Go to Settings > General Settings > API\n3. Enable API access if not already enabled\n4. Copy your API Key\n5. Determine your server URL based on your region\n6. Enter both below", "credentialFields": [ { "label": "Server URL", "type": "text", - "required": false, - "helpText": "Your N-sight RMM server URL (varies by region)" + "required": true, + "helpText": "Your N-sight RMM server URL (varies by region). Common servers: www.systemmonitor.co.uk (UK), www.systemmonitor.us (US), www.am.remote.management (APAC)." }, { "label": "API Key", "type": "password", - "required": false, + "required": true, "helpText": "API key from N-sight RMM Dashboard > Account Settings > API Access" } ] diff --git a/integrations-catalog/integrations/n8n.json b/integrations-catalog/integrations/n8n.json new file mode 100644 index 0000000000..f846821d2a --- /dev/null +++ b/integrations-catalog/integrations/n8n.json @@ -0,0 +1,58 @@ +{ + "slug": "n8n", + "name": "n8n", + "description": "Monitor n8n workflow automation platform for user access, instance availability, and workflow inventory", + "category": "Productivity", + "docsUrl": "https://docs.n8n.io/api/", + "baseUrl": null, + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to your n8n instance\n2. Go to Settings > n8n API\n3. Click 'Create an API key'\n4. Choose a label and set an expiration time\n5. Copy the API key\n6. Enter your n8n instance URL (e.g. https://yourinstance.app.n8n.cloud) and the API key below", + "credentialFields": [ + { + "label": "n8n Instance URL", + "type": "text", + "required": true, + "helpText": "Your n8n instance URL (e.g. https://yourinstance.app.n8n.cloud or https://n8n.yourcompany.com). No trailing slash." + }, + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Go to Settings > n8n API > Create an API key. Copy the key." + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "n8n_employee_access", + "name": "Employee Access", + "description": "Lists all n8n users with their roles to verify access control", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "n8n_app_availability", + "name": "App Availability", + "description": "Verifies the n8n instance is accessible and responding to API requests", + "defaultSeverity": "high", + "enabled": true + }, + { + "slug": "n8n_workflow_inventory", + "name": "Workflow Inventory", + "description": "Lists all workflows with their active status for automation governance", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 3, + "isActive": true +} diff --git a/integrations-catalog/integrations/netskope.json b/integrations-catalog/integrations/netskope.json index b38fa430e9..7977764c6a 100644 --- a/integrations-catalog/integrations/netskope.json +++ b/integrations-catalog/integrations/netskope.json @@ -13,12 +13,14 @@ { "label": "Tenant Name", "type": "text", - "required": true + "required": true, + "helpText": "Your Netskope tenant name (e.g. if your URL is mycompany.goskope.com, enter mycompany)" }, { "label": "API Token", "type": "password", - "required": true + "required": true, + "helpText": "REST API token from Netskope Admin Console" } ] } diff --git a/integrations-catalog/integrations/ngrok.json b/integrations-catalog/integrations/ngrok.json index 2adbfb46fa..6741bf6e3f 100644 --- a/integrations-catalog/integrations/ngrok.json +++ b/integrations-catalog/integrations/ngrok.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.ngrok.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to the ngrok Dashboard at https://dashboard.ngrok.com\n2. Navigate to API section at https://dashboard.ngrok.com/api\n3. Click \"Add API Key\" to generate a new API key\n4. Copy the key and paste it below\n\nNote: The API key is shown only once at creation. Store it securely." + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/northflank.json b/integrations-catalog/integrations/northflank.json index 6ae3941fdf..c22d240a82 100644 --- a/integrations-catalog/integrations/northflank.json +++ b/integrations-catalog/integrations/northflank.json @@ -7,7 +7,17 @@ "baseUrl": "https://api.northflank.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Northflank at https://app.northflank.com\n2. Go to Account Settings > API\n3. Click Create new token\n4. Give it a name and select Read permissions\n5. Copy the token and paste it below", + "credentialFields": [ + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Your Northflank API token. Go to Account Settings > API > Create new token." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/openphone.json b/integrations-catalog/integrations/openphone.json index 4602f2a27d..04af76451d 100644 --- a/integrations-catalog/integrations/openphone.json +++ b/integrations-catalog/integrations/openphone.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.openphone.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to OpenPhone at https://app.openphone.com\n2. Go to Settings > API tab (requires admin privileges)\n3. Click 'Generate API key' and provide a label\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/opsgenie.json b/integrations-catalog/integrations/opsgenie.json index c08f311e10..f11ceaf58d 100644 --- a/integrations-catalog/integrations/opsgenie.json +++ b/integrations-catalog/integrations/opsgenie.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.opsgenie.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Opsgenie at https://app.opsgenie.com\n2. Go to Settings > API key management\n3. Create a new API key with 'Read' access\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/orca-security.json b/integrations-catalog/integrations/orca-security.json index cee1262037..076983d9bd 100644 --- a/integrations-catalog/integrations/orca-security.json +++ b/integrations-catalog/integrations/orca-security.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Orca Security at https://app.us.orcasecurity.io\n2. Go to Settings → API Tokens\n3. Create a new token with read access\n4. Enter it below", + "setupInstructions": "1. Log in to Orca Security\n2. Go to Settings > API Tokens\n3. Create a new token with read access\n4. Select your region:\n - US: app.us.orcasecurity.io\n - EU: app.eu.orcasecurity.io\n5. Enter the token and region host", "credentialFields": [ { "label": "API Token", "type": "password", "required": true, - "helpText": "Found in Orca Security Settings → API Tokens" + "helpText": "Found in Orca Security Settings > API Tokens" + }, + { + "label": "Region Host", + "type": "text", + "required": true, + "helpText": "US: app.us.orcasecurity.io, EU: app.eu.orcasecurity.io" } ] } @@ -28,14 +34,14 @@ { "slug": "orca_monitoring", "name": "Monitoring & Alerting", - "description": "Verifies Orca Security is actively scanning cloud environments for threats", + "description": "Verifies Orca Security is actively scanning and checks for critical alerts", "defaultSeverity": "high", "enabled": true }, { - "slug": "orca_employee_access", - "name": "Employee Access", - "description": "Reviews Orca Security users with access to cloud security findings", + "slug": "orca_asset_inventory", + "name": "Asset Inventory", + "description": "Verifies Orca Security has visibility into cloud assets", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/outreach.json b/integrations-catalog/integrations/outreach.json index fe0fd6de75..f1c21e5cca 100644 --- a/integrations-catalog/integrations/outreach.json +++ b/integrations-catalog/integrations/outreach.json @@ -6,17 +6,14 @@ "docsUrl": "https://api.outreach.io/api/v2/docs", "baseUrl": "https://api.outreach.io/", "authConfig": { - "type": "api_key", + "type": "oauth2", "config": { - "setupInstructions": "1. Log in to Outreach at https://app.outreach.io\n2. Go to your Profile → API Tokens\n3. Create a new API token with read access\n4. Enter it below", - "credentialFields": [ - { - "label": "API Token", - "type": "password", - "required": true, - "helpText": "Found in Outreach Profile → API Tokens" - } - ] + "setupInstructions": "1. Go to https://developers.outreach.io and create a new OAuth app\n2. Set the redirect URI to the one provided by CompAI\n3. Copy the Client ID and Client Secret\n4. Enter them in CompAI to connect your Outreach account", + "scopes": [ + "users.read" + ], + "clientAuthMethod": "body", + "supportsRefreshToken": true } }, "capabilities": [ diff --git a/integrations-catalog/integrations/pagerduty.json b/integrations-catalog/integrations/pagerduty.json index 1b16542795..adfc1e963c 100644 --- a/integrations-catalog/integrations/pagerduty.json +++ b/integrations-catalog/integrations/pagerduty.json @@ -2,7 +2,7 @@ "slug": "pagerduty", "name": "PagerDuty", "description": "Monitor PagerDuty incident response configuration including services, escalation policies, and on-call schedules for compliance evidence", - "category": "Security", + "category": "Monitoring", "docsUrl": "https://developer.pagerduty.com/api-reference/", "baseUrl": "https://api.pagerduty.com", "authConfig": { diff --git a/integrations-catalog/integrations/palo-alto.json b/integrations-catalog/integrations/palo-alto.json index 0015158bd2..e91f954ef1 100644 --- a/integrations-catalog/integrations/palo-alto.json +++ b/integrations-catalog/integrations/palo-alto.json @@ -6,8 +6,30 @@ "docsUrl": "https://pan.dev/sase/api/", "baseUrl": "https://api.sase.paloaltonetworks.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Strata Cloud Manager (https://stratacloud.paloaltonetworks.com)\n2. Go to Settings - Identity & Access - Service Accounts\n3. Create a new Service Account and copy the Client ID and Client Secret\n4. Note your Tenant Service Group (TSG) ID from Multitenant Settings\n5. Assign appropriate roles to the service account\n6. Enter all values below", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "Service Account Client ID from Strata Cloud Manager" + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "Service Account Client Secret from Strata Cloud Manager" + }, + { + "label": "Tenant Service Group (TSG) ID", + "type": "text", + "required": true, + "helpText": "Your TSG ID from Strata Cloud Manager - Multitenant Settings" + } + ] + } }, "capabilities": [ "checks" @@ -18,14 +40,14 @@ { "slug": "palo_alto_app_availability", "name": "Palo Alto SASE App Availability", - "description": "Verifies Palo Alto SASE API is accessible.", + "description": "Verifies Palo Alto SASE API is accessible using OAuth2 client credentials.", "defaultSeverity": "medium", "enabled": true }, { "slug": "palo_alto_employee_access", "name": "Palo Alto SASE Employee Access", - "description": "Verifies access to Palo Alto SASE management.", + "description": "Verifies access to Palo Alto SASE management by listing service accounts.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/paychex.json b/integrations-catalog/integrations/paychex.json index 4d235f98bd..146a4968a2 100644 --- a/integrations-catalog/integrations/paychex.json +++ b/integrations-catalog/integrations/paychex.json @@ -3,18 +3,24 @@ "name": "Paychex", "description": "Monitor Paychex payroll platform for employee data access and HR compliance", "category": "HR & People", - "docsUrl": "https://developer.paychex.com/documentation", + "docsUrl": "https://developer.paychex.com/getting-started/authentication", "baseUrl": "https://api.paychex.com/", "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Sign up at https://developer.paychex.com\n2. Go to My Apps → Create App\n3. Copy Client ID and Client Secret\n4. Base64 encode 'client_id:client_secret': echo -n 'id:secret' | base64\n5. Enter the encoded value below", + "setupInstructions": "1. Sign up at https://developer.paychex.com\n2. Go to My Apps and create an App\n3. Copy Client ID and Client Secret\n4. Enter both values below", "credentialFields": [ { - "label": "Encoded Credentials", + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "From Paychex Developer Portal - My Apps" + }, + { + "label": "Client Secret", "type": "password", "required": true, - "helpText": "Base64 encode 'client_id:client_secret'. Found in Paychex Developer Portal → My Apps. Command: echo -n 'id:secret' | base64" + "helpText": "From Paychex Developer Portal - My Apps" } ] } diff --git a/integrations-catalog/integrations/persona.json b/integrations-catalog/integrations/persona.json index 7c447b7203..0288c465ea 100644 --- a/integrations-catalog/integrations/persona.json +++ b/integrations-catalog/integrations/persona.json @@ -7,7 +7,9 @@ "baseUrl": "https://withpersona.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to your Persona Dashboard at https://app.withpersona.com\n2. Go to Settings -> API Keys\n3. Create a new API key or copy an existing one\n4. The key starts with 'persona_key_...'\n5. Paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/personio.json b/integrations-catalog/integrations/personio.json index 33f4127070..3116178133 100644 --- a/integrations-catalog/integrations/personio.json +++ b/integrations-catalog/integrations/personio.json @@ -6,8 +6,24 @@ "docsUrl": "https://developer.personio.de/reference", "baseUrl": "https://api.personio.de/", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Personio\n2. Go to Settings > Integrations > API Credentials\n3. Generate new API credentials (or use existing ones)\n4. Copy the Client ID and Client Secret\n5. Enter them below\n\nNote: The API credentials need read access to employees.", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "Found in Personio Settings > API Access > API Credentials" + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "Found in Personio Settings > API Access > API Credentials" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/pinecone.json b/integrations-catalog/integrations/pinecone.json new file mode 100644 index 0000000000..53d51bdcb7 --- /dev/null +++ b/integrations-catalog/integrations/pinecone.json @@ -0,0 +1,44 @@ +{ + "slug": "pinecone", + "name": "Pinecone", + "description": "Monitor Pinecone vector database configuration including index inventory, collection backups, and API access verification for compliance evidence", + "category": "Cloud", + "docsUrl": "https://docs.pinecone.io/reference/api/introduction", + "baseUrl": "https://api.pinecone.io", + "authConfig": { + "type": "api_key", + "config": { + "setupInstructions": "1. Log in to the Pinecone console at https://app.pinecone.io\n2. Select your project\n3. Go to the 'API Keys' tab\n4. Create or copy an existing API key with at least ReadOnly control plane permissions\n5. Paste the API key below" + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "pinecone_app_availability", + "name": "App Availability", + "description": "Verify that Pinecone API access is working by listing indexes in the project", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "pinecone_index_inventory", + "name": "Index Inventory", + "description": "List all vector indexes in the project with their configuration details including dimensions, metric, and status", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "pinecone_collection_inventory", + "name": "Collection Inventory", + "description": "List all collections (pod-based index backups) in the project with their status and configuration", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 3, + "isActive": true +} diff --git a/integrations-catalog/integrations/pipedream.json b/integrations-catalog/integrations/pipedream.json index 341524def3..1869673c0c 100644 --- a/integrations-catalog/integrations/pipedream.json +++ b/integrations-catalog/integrations/pipedream.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.pipedream.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Pipedream at https://pipedream.com\n2. Go to Settings -> Account -> API Key\n3. Copy your API key\n4. Paste it below\n\nAlternatively, create an OAuth client in Settings -> API for scoped access." + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/plaid.json b/integrations-catalog/integrations/plaid.json new file mode 100644 index 0000000000..2d965f3f52 --- /dev/null +++ b/integrations-catalog/integrations/plaid.json @@ -0,0 +1,64 @@ +{ + "slug": "plaid", + "name": "Plaid", + "description": "Monitor Plaid financial data API platform for access control, API availability, and institution coverage compliance", + "category": "Security", + "docsUrl": "https://plaid.com/docs/api/", + "baseUrl": "https://sandbox.plaid.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "1. Log in to the Plaid Dashboard at https://dashboard.plaid.com\n2. Go to Developers -> Keys\n3. Copy your client_id (same across environments)\n4. Copy the secret for your chosen environment (Sandbox or Production)\n5. Enter the environment name: 'sandbox' or 'production'\n\nNote: Each environment has its own secret. The client_id is shared across environments.", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "Found in Plaid Dashboard -> Developers -> Keys. Your Plaid API client_id." + }, + { + "label": "Secret", + "type": "password", + "required": true, + "helpText": "Found in Plaid Dashboard -> Developers -> Keys. The secret for your chosen environment." + }, + { + "label": "Environment", + "type": "text", + "required": true, + "helpText": "The Plaid environment to connect to: 'sandbox' or 'production'. Each environment has its own secret." + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "plaid_app_availability", + "name": "App Availability", + "description": "Verifies Plaid API is accessible and credentials are valid by making an authenticated API call", + "defaultSeverity": "high", + "enabled": true + }, + { + "slug": "plaid_institution_access", + "name": "Institution Access Review", + "description": "Reviews accessible financial institutions and product coverage to verify appropriate API scope", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "plaid_api_key_configuration", + "name": "API Key Configuration", + "description": "Validates Plaid API key configuration by verifying credentials work across institution queries and checking environment consistency", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 3, + "isActive": true +} diff --git a/integrations-catalog/integrations/port-io.json b/integrations-catalog/integrations/port-io.json index 0ef9cef89c..36f61b1821 100644 --- a/integrations-catalog/integrations/port-io.json +++ b/integrations-catalog/integrations/port-io.json @@ -3,11 +3,33 @@ "name": "Port", "description": "Internal developer portal for service catalog and developer self-service.", "category": "Development", - "docsUrl": "https://docs.getport.io/api-reference/port-api", + "docsUrl": "https://docs.port.io/api-reference/port-api", "baseUrl": "https://api.getport.io", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Port at https://app.getport.io\n2. Click the ... button in the top right corner\n3. Click Credentials\n4. Copy the Client ID and Client Secret\n5. Enter your region: 'eu' (default) or 'us'\n6. Enter the values below", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "Found in Port > click ... (top right) > Credentials" + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "Found in Port > click ... (top right) > Credentials" + }, + { + "label": "Region", + "type": "text", + "required": false, + "helpText": "eu or us. Default: eu. US customers use api.us.port.io" + } + ] + } }, "capabilities": [ "checks" @@ -25,7 +47,7 @@ { "slug": "port_io_employee_access", "name": "Port Employee Access", - "description": "Verifies employee access to Port via API.", + "description": "Lists Port organization users to verify access management.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/postman.json b/integrations-catalog/integrations/postman.json index 069502a34c..113bb40e80 100644 --- a/integrations-catalog/integrations/postman.json +++ b/integrations-catalog/integrations/postman.json @@ -3,11 +3,21 @@ "name": "Postman", "description": "Monitor Postman workspaces and team API collections for development compliance", "category": "Development", - "docsUrl": "https://www.postman.com/postman/postman-postman/documentation/", + "docsUrl": "https://learning.postman.com/docs/developer/postman-api/authentication/", "baseUrl": "https://api.getpostman.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Postman\n2. Click Settings (gear icon) > Account Settings\n3. Go to API Keys\n4. Click Generate API Key\n5. Give it a name and copy the key\n6. Enter it below", + "credentialFields": [ + { + "label": "Postman API Key", + "type": "password", + "required": true, + "helpText": "Found in Postman Settings > Account Settings > API Keys" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/probely.json b/integrations-catalog/integrations/probely.json index a623165216..c12d78378b 100644 --- a/integrations-catalog/integrations/probely.json +++ b/integrations-catalog/integrations/probely.json @@ -7,7 +7,17 @@ "baseUrl": "https://api.probely.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Probely at https://plus.probely.app\n2. Go to Settings and generate an API Key\n3. Enter it below", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Generate an API key from the Probely app under Settings." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/proofpoint.json b/integrations-catalog/integrations/proofpoint.json index d5f9838fde..011e0e251c 100644 --- a/integrations-catalog/integrations/proofpoint.json +++ b/integrations-catalog/integrations/proofpoint.json @@ -6,17 +6,11 @@ "docsUrl": "https://help.proofpoint.com/Threat_Insight_Dashboard/API_Documentation/Threat_API", "baseUrl": "https://tap-api-v2.proofpoint.com/", "authConfig": { - "type": "custom", + "type": "basic", "config": { - "setupInstructions": "1. Log in to Proofpoint TAP at https://threatinsight.proofpoint.com\n2. Go to Settings → Connected Applications\n3. Create a new Service Principal\n4. Base64 encode 'service_principal:secret': echo -n 'principal:secret' | base64\n5. Enter the encoded value below", - "credentialFields": [ - { - "label": "Encoded Credentials", - "type": "password", - "required": true, - "helpText": "Base64 encode 'service_principal:secret'. Found in Proofpoint TAP dashboard → Settings → Connected Applications. Command: echo -n 'principal:secret' | base64" - } - ] + "setupInstructions": "1. Log in to Proofpoint TAP at https://threatinsight.proofpoint.com\n2. Go to Settings → Connected Applications\n3. Create a new Service Principal\n4. Copy the Service Principal (username) and Secret (password)\n5. Enter them below", + "usernameField": "service_principal", + "passwordField": "service_secret" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/pulumi-cloud.json b/integrations-catalog/integrations/pulumi-cloud.json index 5e7368f1ba..8b176415e7 100644 --- a/integrations-catalog/integrations/pulumi-cloud.json +++ b/integrations-catalog/integrations/pulumi-cloud.json @@ -7,7 +7,17 @@ "baseUrl": "https://api.pulumi.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Pulumi Cloud at https://app.pulumi.com\n2. Go to Account → Access Tokens\n3. Create a new token\n4. Enter it below", + "credentialFields": [ + { + "label": "Access Token", + "type": "password", + "required": true, + "helpText": "Found at https://app.pulumi.com/account/tokens" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/pulumi.json b/integrations-catalog/integrations/pulumi.json index 07e183df8f..b2b6689f81 100644 --- a/integrations-catalog/integrations/pulumi.json +++ b/integrations-catalog/integrations/pulumi.json @@ -7,7 +7,17 @@ "baseUrl": "https://api.pulumi.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Pulumi Cloud at https://app.pulumi.com\n2. Go to Account → Access Tokens\n3. Create a new token\n4. Enter it below", + "credentialFields": [ + { + "label": "Access Token", + "type": "password", + "required": true, + "helpText": "Found at https://app.pulumi.com/account/tokens" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/qase.json b/integrations-catalog/integrations/qase.json index 2b0eb43c98..8ecc79f0e9 100644 --- a/integrations-catalog/integrations/qase.json +++ b/integrations-catalog/integrations/qase.json @@ -7,7 +7,17 @@ "baseUrl": "https://api.qase.io/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Qase at https://app.qase.io\n2. Go to Settings → API Tokens\n3. Create a new token\n4. Enter it below", + "credentialFields": [ + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Found in Qase Settings → API Tokens" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/qovery.json b/integrations-catalog/integrations/qovery.json index 9059c82f2d..4582692c24 100644 --- a/integrations-catalog/integrations/qovery.json +++ b/integrations-catalog/integrations/qovery.json @@ -6,8 +6,18 @@ "docsUrl": "https://api-doc.qovery.com", "baseUrl": "https://api.qovery.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to the Qovery Console (console.qovery.com)\n2. Navigate to Organization Settings > API Tokens\n3. Click Generate Token\n4. Give your token a descriptive name and set appropriate permissions\n5. Copy the token (it will only be displayed once)\n6. Paste it below", + "credentialFields": [ + { + "label": "API Token", + "type": "password", + "required": true, + "helpText": "Qovery Console > Organization Settings > API Tokens > Generate Token" + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/qualys.json b/integrations-catalog/integrations/qualys.json index c6f84362aa..28daffc478 100644 --- a/integrations-catalog/integrations/qualys.json +++ b/integrations-catalog/integrations/qualys.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Qualys VMDR\n2. Go to Help > About to find your API server URL\n3. Enter your Qualys username and password\n4. Enter the API server URL (e.g. https://qualysapi.qualys.com)\n5. Ensure your account has API access enabled (contact your Qualys admin if needed)", "credentialFields": [ { "label": "Username", @@ -22,10 +23,10 @@ "helpText": "Your Qualys account password" }, { - "label": "API URL", + "label": "API Server URL", "type": "text", "required": true, - "helpText": "Your service region (e.g., us, eu, ap)" + "helpText": "Your Qualys API server URL (e.g. https://qualysapi.qualys.com). Find it under Help > About in Qualys." } ] } diff --git a/integrations-catalog/integrations/quave-cloud.json b/integrations-catalog/integrations/quave-cloud.json index c95c4ea891..9ac63135af 100644 --- a/integrations-catalog/integrations/quave-cloud.json +++ b/integrations-catalog/integrations/quave-cloud.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Quave Cloud dashboard\n2. Navigate to Settings > API Access\n3. Generate or copy your API token\n4. Enter your Account ID (found in the dashboard URL or account settings)\n5. Optionally enter specific App IDs (comma-separated) to restrict checks to certain apps", "credentialFields": [ { "label": "API Token", diff --git a/integrations-catalog/integrations/ramp.json b/integrations-catalog/integrations/ramp.json index 8ce9220534..dc10ee619f 100644 --- a/integrations-catalog/integrations/ramp.json +++ b/integrations-catalog/integrations/ramp.json @@ -8,6 +8,7 @@ "authConfig": { "type": "oauth2", "config": { + "setupInstructions": "1. Go to the Ramp Developer Portal (developer.ramp.com)\n2. Register a new application\n3. Set the redirect URI to: https://api.trycomp.ai/v1/integrations/oauth/callback\n4. Copy the Client ID and Client Secret\n5. Enter them in the CompAI admin panel\n6. Click Connect to authorize access to your Ramp account", "scopes": [ "users:read" ], diff --git a/integrations-catalog/integrations/rapid7.json b/integrations-catalog/integrations/rapid7.json index b80b62786b..45cf04ae2b 100644 --- a/integrations-catalog/integrations/rapid7.json +++ b/integrations-catalog/integrations/rapid7.json @@ -19,8 +19,8 @@ { "label": "Region", "type": "text", - "required": false, - "helpText": "Your Insight Platform region: us, us2, us3, eu, ca, au, ap (default: us)" + "required": true, + "helpText": "Your Insight Platform region code: us, us2, us3, eu, ca, au, ap, me1, aps2" } ] } diff --git a/integrations-catalog/integrations/readme.json b/integrations-catalog/integrations/readme.json index 855ffe0ec3..e62b8354d9 100644 --- a/integrations-catalog/integrations/readme.json +++ b/integrations-catalog/integrations/readme.json @@ -6,17 +6,10 @@ "docsUrl": "https://docs.readme.com/main/reference", "baseUrl": "https://dash.readme.com", "authConfig": { - "type": "custom", + "type": "basic", "config": { - "setupInstructions": "1. Log in to ReadMe\n2. Go to Configuration → API Key\n3. Copy your API key\n4. Paste it below as Basic Auth: run echo -n 'YOUR_API_KEY:' | base64 (or just paste the key — ReadMe supports it as Basic username)", - "credentialFields": [ - { - "label": "API Key", - "type": "password", - "required": true, - "helpText": "ReadMe → Configuration → API Key" - } - ] + "setupInstructions": "1. Log in to ReadMe\n2. Go to your project dashboard\n3. Click on Configuration > API Keys\n4. Copy your API key\n5. Paste it as the API Key below\n6. Leave the Password field empty (ReadMe uses the API key as the username with no password)", + "usernameField": "api_key" } }, "capabilities": [ diff --git a/integrations-catalog/integrations/remote.json b/integrations-catalog/integrations/remote.json index b186ed1d78..599286fe1d 100644 --- a/integrations-catalog/integrations/remote.json +++ b/integrations-catalog/integrations/remote.json @@ -7,7 +7,9 @@ "baseUrl": "https://gateway.remote.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Remote at https://remote.com\n2. Go to Company Settings → Integrations & APIs → Integrations\n3. Click on the Remote API card\n4. Click Generate API token\n5. Copy the token (starts with ra_live_) and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/roboflow.json b/integrations-catalog/integrations/roboflow.json index 8bee103fd5..4a7d7ddd55 100644 --- a/integrations-catalog/integrations/roboflow.json +++ b/integrations-catalog/integrations/roboflow.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.roboflow.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Roboflow at https://app.roboflow.com\n2. Go to Settings → API Keys (or Workspace Settings → Roboflow API)\n3. Copy your API key\n4. Paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/rollbar.json b/integrations-catalog/integrations/rollbar.json index c73eae5083..aad3f25af1 100644 --- a/integrations-catalog/integrations/rollbar.json +++ b/integrations-catalog/integrations/rollbar.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.rollbar.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Rollbar at https://rollbar.com\n2. Go to your project's Settings > Project Access Tokens\n3. Copy a token with 'read' scope\n4. Find your Project ID in Settings > General\n5. Enter both values below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/rubrik.json b/integrations-catalog/integrations/rubrik.json index 3f0d29b0ce..2fe0103725 100644 --- a/integrations-catalog/integrations/rubrik.json +++ b/integrations-catalog/integrations/rubrik.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to Rubrik Security Cloud (RSC)\n2. Go to Settings > Service Accounts\n3. Create a service account and note the Client ID and Client Secret\n4. Your RSC URL is your cloud URL (e.g. mycompany.my.rubrik.com)\n5. Enter all values below", "credentialFields": [ { "label": "RSC URL", diff --git a/integrations-catalog/integrations/rudderstack.json b/integrations-catalog/integrations/rudderstack.json index 67e5bd9b3e..a92b889c65 100644 --- a/integrations-catalog/integrations/rudderstack.json +++ b/integrations-catalog/integrations/rudderstack.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.rudderstack.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to your RudderStack dashboard at https://app.rudderstack.com\n2. Go to Settings > Service Access Tokens\n3. Generate a workspace-level Service Access Token\n4. Enter the token below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/scalefusion.json b/integrations-catalog/integrations/scalefusion.json index 1a431bbd24..44274c2bac 100644 --- a/integrations-catalog/integrations/scalefusion.json +++ b/integrations-catalog/integrations/scalefusion.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.scalefusion.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Scalefusion Dashboard at https://app.scalefusion.com\n2. Go to Settings > API Integration\n3. Generate an API token\n4. Copy the API token and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/secureframe.json b/integrations-catalog/integrations/secureframe.json index 03806eeb44..471412bf17 100644 --- a/integrations-catalog/integrations/secureframe.json +++ b/integrations-catalog/integrations/secureframe.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.secureframe.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Secureframe at https://app.secureframe.com\n2. Go to Settings > API Keys\n3. Generate a new API key with read access\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/servicenow.json b/integrations-catalog/integrations/servicenow.json index 676693ca6c..0fcb721bfd 100644 --- a/integrations-catalog/integrations/servicenow.json +++ b/integrations-catalog/integrations/servicenow.json @@ -8,13 +8,25 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Use a service account with REST API access in ServiceNow\n2. Encode credentials: base64('username:password')\n3. Enter the encoded value below along with your instance name", + "setupInstructions": "1. Use a service account with REST API access in ServiceNow\n2. Enter your instance name (the part before .service-now.com)\n3. Enter the username and password for the service account", "credentialFields": [ { - "label": "Encoded Credentials", + "label": "Instance Name", + "type": "text", + "required": true, + "helpText": "Your ServiceNow instance name (e.g., 'dev12345' from dev12345.service-now.com)" + }, + { + "label": "Username", + "type": "text", + "required": true, + "helpText": "ServiceNow service account username with REST API access" + }, + { + "label": "Password", "type": "password", "required": true, - "helpText": "Base64 encode your username:password. Example: base64('admin:yourpassword'). Use https://www.base64encode.org/" + "helpText": "ServiceNow service account password" } ] } diff --git a/integrations-catalog/integrations/sigma-computing.json b/integrations-catalog/integrations/sigma-computing.json index c2741e9c39..58e0e2f0b5 100644 --- a/integrations-catalog/integrations/sigma-computing.json +++ b/integrations-catalog/integrations/sigma-computing.json @@ -6,15 +6,21 @@ "docsUrl": "https://help.sigmacomputing.com/reference/overview-1", "baseUrl": "https://api.sigmacomputing.com/", "authConfig": { - "type": "api_key", + "type": "custom", "config": { - "setupInstructions": "1. Log in to Sigma at https://app.sigmacomputing.com\n2. Go to Administration → Developer Access → API Tokens\n3. Create a new API token\n4. Enter it below", + "setupInstructions": "1. Log in to Sigma Computing as an Admin\n2. Go to Administration > Developer Access\n3. Click 'Create new' to generate API client credentials\n4. Copy the Client ID and Client Secret\n5. Enter them below", "credentialFields": [ { - "label": "API Token", + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "From Sigma Administration > Developer Access > Create new client credentials" + }, + { + "label": "Client Secret", "type": "password", "required": true, - "helpText": "Found in Sigma Administration → Developer Access → API Tokens" + "helpText": "The secret generated with your Client ID" } ] } diff --git a/integrations-catalog/integrations/squarespace.json b/integrations-catalog/integrations/squarespace.json new file mode 100644 index 0000000000..6ece2aa18a --- /dev/null +++ b/integrations-catalog/integrations/squarespace.json @@ -0,0 +1,45 @@ +{ + "slug": "squarespace", + "name": "Squarespace", + "description": "Monitor Squarespace website configuration, commerce products, and orders for operational compliance.", + "category": "Productivity", + "docsUrl": "https://developers.squarespace.com/commerce-apis", + "baseUrl": "https://api.squarespace.com", + "authConfig": { + "type": "custom", + "config": { + "setupInstructions": "Requires: a Squarespace Commerce plan (Basic or Advanced) with Developer API Keys access.\n\n1. Log in to your Squarespace site\n2. In the left nav, click Settings, then scroll down and click Advanced\n3. Click Developer API Keys\n4. Click the GENERATE KEY button\n5. Enter a key name (e.g. CompAI) and select permissions: Products (Read Only)\n6. Record the generated key - it will only be shown once\n7. Paste the API key below\n\nNote: Each API key is specific to a single Squarespace website.", + "credentialFields": [ + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Your Squarespace Commerce API key. Generate it in Settings > Advanced > Developer API Keys." + } + ] + } + }, + "capabilities": [ + "checks" + ], + "supportsMultipleConnections": false, + "syncSupported": false, + "checks": [ + { + "slug": "squarespace_app_availability", + "name": "App Availability", + "description": "Verify Squarespace API access by retrieving basic site information via the Authorization API endpoint.", + "defaultSeverity": "medium", + "enabled": true + }, + { + "slug": "squarespace_commerce_configuration", + "name": "Commerce Configuration", + "description": "List products from the Squarespace Commerce API to verify e-commerce configuration and product catalog access.", + "defaultSeverity": "medium", + "enabled": true + } + ], + "checkCount": 2, + "isActive": true +} diff --git a/integrations-catalog/integrations/strongdm.json b/integrations-catalog/integrations/strongdm.json index e350bac995..d3d1bc5bfe 100644 --- a/integrations-catalog/integrations/strongdm.json +++ b/integrations-catalog/integrations/strongdm.json @@ -1,13 +1,15 @@ { "slug": "strongdm", "name": "StrongDM", - "description": "Infrastructure access management platform. Monitor resource access and audit logs.", + "description": "Infrastructure access management platform. Monitor user provisioning and access via SCIM API.", "category": "Security", - "docsUrl": "https://www.strongdm.com/docs/api/", - "baseUrl": "https://api.strongdm.com", + "docsUrl": "https://docs.strongdm.com/references/scim", + "baseUrl": "https://app.strongdm.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to StrongDM Admin UI\n2. Go to Settings > User Management > Provisioning\n3. Select the 'Generic' provider option\n4. Click 'Activate' to generate a bearer token\n5. Copy the generated token and paste it below" + } }, "capabilities": [ "checks" @@ -17,15 +19,15 @@ "checks": [ { "slug": "strongdm_app_availability", - "name": "StrongDM App Availability", - "description": "Checks that the StrongDM API is accessible.", + "name": "App Availability", + "description": "Verifies StrongDM SCIM API is accessible by listing users.", "defaultSeverity": "medium", "enabled": true }, { "slug": "strongdm_employee_access", - "name": "StrongDM Employee Access", - "description": "Verifies access to StrongDM.", + "name": "Employee Access", + "description": "Lists StrongDM users provisioned via SCIM to verify access management.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/sumo-logic.json b/integrations-catalog/integrations/sumo-logic.json index 80569f4c6a..e21f1cb6c8 100644 --- a/integrations-catalog/integrations/sumo-logic.json +++ b/integrations-catalog/integrations/sumo-logic.json @@ -6,15 +6,27 @@ "docsUrl": "https://help.sumologic.com/docs/api/", "baseUrl": "https://api.us2.sumologic.com", "authConfig": { - "type": "basic", + "type": "custom", "config": { - "setupInstructions": "1. Log in to Sumo Logic\n2. Go to Administration → Security → Access Keys\n3. Click + Add Access Key\n4. Copy the Access ID and Access Key\n5. Use Access ID as username and Access Key as password\n6. Determine your API URL from your login URL region\n7. Paste all values below", + "setupInstructions": "1. Log in to Sumo Logic\n2. Go to Administration > Security > Access Keys\n3. Click + Add Access Key\n4. Copy the Access ID and Access Key\n5. Determine your API URL from your login URL region (e.g. https://api.us2.sumologic.com)\n6. Enter all values below", "credentialFields": [ + { + "label": "Access ID", + "type": "text", + "required": true, + "helpText": "Your Sumo Logic Access ID. Go to Administration > Security > Access Keys." + }, + { + "label": "Access Key", + "type": "password", + "required": true, + "helpText": "Your Sumo Logic Access Key (generated with the Access ID)." + }, { "label": "API Endpoint URL", "type": "text", "required": true, - "helpText": "Your Sumo Logic API URL based on region (e.g. https://api.us2.sumologic.com, https://api.eu.sumologic.com)." + "helpText": "Your Sumo Logic API URL based on region (e.g. https://api.us2.sumologic.com, https://api.eu.sumologic.com). See docs for your deployment region." } ] } @@ -27,15 +39,15 @@ "checks": [ { "slug": "sumo_logic_app_availability", - "name": "Sumo Logic App Availability", + "name": "App Availability", "description": "Verifies Sumo Logic API is accessible.", "defaultSeverity": "medium", "enabled": true }, { "slug": "sumo_logic_monitoring", - "name": "Sumo Logic Monitoring", - "description": "Verifies log collection is active.", + "name": "Monitoring & Alerting", + "description": "Verifies log collection is active with Sumo Logic collectors.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/sumologic.json b/integrations-catalog/integrations/sumologic.json index ef5a3681ac..9c102865d7 100644 --- a/integrations-catalog/integrations/sumologic.json +++ b/integrations-catalog/integrations/sumologic.json @@ -3,24 +3,30 @@ "name": "Sumo Logic", "description": "Monitor Sumo Logic log management and analytics platform for user access and monitoring compliance", "category": "Monitoring", - "docsUrl": "https://api.sumologic.com/docs/", + "docsUrl": "https://help.sumologic.com/docs/api/", "baseUrl": "https://api.sumologic.com/", "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Sumo Logic\n2. Go to your name → Preferences → Access Keys\n3. Create a new access key — copy the Access ID and Access Key\n4. Base64 encode 'accessId:accessKey': echo -n 'id:key' | base64\n5. Find your API endpoint at https://help.sumologic.com/docs/api/getting-started/#sumo-logic-endpoints\n6. Enter both below", + "setupInstructions": "1. Log in to Sumo Logic\n2. Go to your name > Preferences > Access Keys\n3. Create a new access key - copy the Access ID and Access Key\n4. Find your API endpoint at https://help.sumologic.com/docs/api/getting-started/#sumo-logic-endpoints\n5. Enter all values below", "credentialFields": [ { - "label": "Encoded Credentials", + "label": "Access ID", + "type": "text", + "required": true, + "helpText": "Your Sumo Logic Access ID. Go to Preferences > Access Keys." + }, + { + "label": "Access Key", "type": "password", "required": true, - "helpText": "Base64 encode 'accessId:accessKey'. Found in Sumo Logic Preferences → Access Keys. Command: echo -n 'accessId:accessKey' | base64" + "helpText": "Your Sumo Logic Access Key (generated with the Access ID)." }, { "label": "API Endpoint", "type": "text", "required": true, - "helpText": "Your Sumo Logic API endpoint based on your deployment (e.g. api.us2.sumologic.com, api.eu.sumologic.com). See https://help.sumologic.com/docs/api/getting-started/#sumo-logic-endpoints" + "helpText": "Your Sumo Logic API endpoint based on deployment region (e.g. api.us2.sumologic.com). See https://help.sumologic.com/docs/api/getting-started/#sumo-logic-endpoints" } ] } @@ -41,7 +47,7 @@ { "slug": "sumologic_monitoring", "name": "Monitoring & Alerting", - "description": "Verifies Sumo Logic monitors are configured for log-based alerting", + "description": "Verifies Sumo Logic collectors are configured for log-based monitoring", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/tanium.json b/integrations-catalog/integrations/tanium.json index 7509c43cea..4f7635dfad 100644 --- a/integrations-catalog/integrations/tanium.json +++ b/integrations-catalog/integrations/tanium.json @@ -8,7 +8,7 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log into Tanium Console as Administrator\n2. Navigate to Administration > Permissions > API Tokens\n3. Click 'Create API Token'\n4. Set appropriate scopes and expiration\n5. Copy the generated token (shown only once)", + "setupInstructions": "1. Log into Tanium Console as Administrator\n2. Navigate to Administration > Permissions > API Tokens\n3. Click Create API Token\n4. Set appropriate scopes and expiration\n5. Copy the generated token (shown only once)", "credentialFields": [ { "label": "Tanium Server URL", @@ -41,21 +41,21 @@ { "slug": "secure_devices", "name": "Secure Devices", - "description": "Checks that endpoints managed by Tanium are secure and compliant with organizational policies", + "description": "Checks that endpoints managed by Tanium are secure and compliant", "defaultSeverity": "high", "enabled": true }, { "slug": "monitoring_alerting", "name": "Monitoring & Alerting", - "description": "Verifies monitoring capabilities and alerting configuration for security and compliance events", + "description": "Verifies monitoring capabilities and alerting configuration", "defaultSeverity": "medium", "enabled": true }, { "slug": "employee_access", "name": "Employee Access", - "description": "Reviews user accounts and access permissions in Tanium for proper role-based access control", + "description": "Lists Tanium platform users for access review and compliance", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/teamwork.json b/integrations-catalog/integrations/teamwork.json index 676219aa4a..182e14f508 100644 --- a/integrations-catalog/integrations/teamwork.json +++ b/integrations-catalog/integrations/teamwork.json @@ -4,10 +4,26 @@ "description": "Project management and team collaboration platform.", "category": "Productivity", "docsUrl": "https://developer.teamwork.com/", - "baseUrl": "https://api.teamwork.com", + "baseUrl": "https://{{credentials.site_name}}.teamwork.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to Teamwork at https://yoursite.teamwork.com\n2. Click your profile icon (top right) > Edit My Details\n3. Go to the 'API & Mobile' tab\n4. Click 'Show Your Token' to reveal your API key\n5. Your site name is the subdomain in your URL (e.g., 'mycompany' from mycompany.teamwork.com)\n6. Enter both values below", + "credentialFields": [ + { + "label": "Teamwork Site Name", + "type": "text", + "required": true, + "helpText": "Your Teamwork site name (the part before .teamwork.com). For example, if your URL is mycompany.teamwork.com, enter 'mycompany'." + }, + { + "label": "API Key", + "type": "password", + "required": true, + "helpText": "Found in Teamwork > Click your profile > Edit My Details > API & Mobile tab > Show Your Token." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/telnyx.json b/integrations-catalog/integrations/telnyx.json index 7ad202db65..c2ec4630fb 100644 --- a/integrations-catalog/integrations/telnyx.json +++ b/integrations-catalog/integrations/telnyx.json @@ -14,7 +14,7 @@ "label": "API Key", "type": "password", "required": true, - "helpText": "Telnyx → API Keys → Create API Key" + "helpText": "Telnyx > API Keys > Create API Key" } ] } @@ -35,7 +35,7 @@ { "slug": "telnyx_employee_access", "name": "Employee Access", - "description": "Lists Telnyx organization users", + "description": "Verifies account-level access to Telnyx messaging resources", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/tenable-cloud.json b/integrations-catalog/integrations/tenable-cloud.json index e4552fcfdb..0a9a83ad2c 100644 --- a/integrations-catalog/integrations/tenable-cloud.json +++ b/integrations-catalog/integrations/tenable-cloud.json @@ -12,7 +12,7 @@ "credentialFields": [ { "label": "Access Key", - "type": "text", + "type": "password", "required": true, "helpText": "Found in Tenable.io → Settings → My Account → API Keys." }, diff --git a/integrations-catalog/integrations/threatdown.json b/integrations-catalog/integrations/threatdown.json index eb4b874c19..0dcd3b63b6 100644 --- a/integrations-catalog/integrations/threatdown.json +++ b/integrations-catalog/integrations/threatdown.json @@ -17,7 +17,7 @@ }, { "label": "Client Secret", - "type": "secret", + "type": "password", "required": true, "helpText": "Your ThreatDown OAuth2 application client secret" }, diff --git a/integrations-catalog/integrations/together-ai.json b/integrations-catalog/integrations/together-ai.json index d2d0e4fb7a..18ad0f2219 100644 --- a/integrations-catalog/integrations/together-ai.json +++ b/integrations-catalog/integrations/together-ai.json @@ -4,10 +4,12 @@ "description": "AI inference and training platform. Monitor API access and usage.", "category": "Cloud", "docsUrl": "https://docs.together.ai/reference/", - "baseUrl": "https://api.together.xyz", + "baseUrl": "https://api.together.ai", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Together AI at https://api.together.ai\n2. Go to Settings > API Keys\n3. Click Create API Key and copy it\n4. Paste the API key below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/transcend.json b/integrations-catalog/integrations/transcend.json index 8b521df863..8420f4916a 100644 --- a/integrations-catalog/integrations/transcend.json +++ b/integrations-catalog/integrations/transcend.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.transcend.io", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Transcend at https://app.transcend.io\n2. Go to Infrastructure > Developer Tools > API Keys\n3. Click Add API Key and assign required scopes\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/trigger-dev.json b/integrations-catalog/integrations/trigger-dev.json index bac2f750b0..33b24d2102 100644 --- a/integrations-catalog/integrations/trigger-dev.json +++ b/integrations-catalog/integrations/trigger-dev.json @@ -8,13 +8,13 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Trigger.dev\n2. Go to Settings → Personal Access Tokens\n3. Generate a new token\n4. Paste it below", + "setupInstructions": "1. Log in to Trigger.dev\n2. For cross-project visibility: go to your profile settings and generate a Personal Access Token (tr_pat_...)\n3. For single-environment monitoring: go to Settings > API keys and copy the Secret Key for the environment you want to monitor (typically Production, tr_prod_...)\n4. Paste it below", "credentialFields": [ { - "label": "Personal Access Token", + "label": "Secret Key or Personal Access Token", "type": "password", "required": true, - "helpText": "Trigger.dev → Settings → Personal Access Tokens → Generate Token" + "helpText": "Use a Personal Access Token (tr_pat_...) to see all projects across your org, or a Secret Key (tr_dev_.../tr_prod_...) to monitor a single environment. Found in Settings > API keys (Secret Key) or your profile settings (PAT)." } ] } diff --git a/integrations-catalog/integrations/twingate.json b/integrations-catalog/integrations/twingate.json index 1bd066d0af..d04ae97e9d 100644 --- a/integrations-catalog/integrations/twingate.json +++ b/integrations-catalog/integrations/twingate.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to the Twingate Admin Console\n2. Go to Settings > API\n3. Click Generate Token to create a new API key\n4. Copy the API key and your network subdomain (the part before .twingate.com in your URL)\n5. Paste both values below", "credentialFields": [ { "label": "Twingate Network Subdomain", diff --git a/integrations-catalog/integrations/veeam.json b/integrations-catalog/integrations/veeam.json index 264f0b6a07..127c1d82ea 100644 --- a/integrations-catalog/integrations/veeam.json +++ b/integrations-catalog/integrations/veeam.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to your Veeam Backup & Replication console\n2. Ensure the REST API service is running (port 9419 by default)\n3. Use an administrator account with API access\n4. Enter your Veeam server URL (e.g. https://veeam.company.com:9419), username, and password below", "credentialFields": [ { "label": "Server URL", @@ -23,7 +24,7 @@ }, { "label": "Password", - "type": "secret", + "type": "password", "required": true, "helpText": "Veeam administrator password" } diff --git a/integrations-catalog/integrations/veracode.json b/integrations-catalog/integrations/veracode.json index 16f978332b..f29a69560b 100644 --- a/integrations-catalog/integrations/veracode.json +++ b/integrations-catalog/integrations/veracode.json @@ -7,7 +7,29 @@ "baseUrl": null, "authConfig": { "type": "custom", - "config": {} + "config": { + "setupInstructions": "1. Sign in to the Veracode Platform at https://analysiscenter.veracode.com (Commercial), https://analysiscenter.veracode.eu (EU), or https://analysiscenter.veracode.us (US Federal)\n2. From the user account dropdown, select API Credentials\n3. Click Create API Credentials and choose HMAC credentials\n4. Copy the API ID and API Key\n5. Select your region and paste the credentials below", + "credentialFields": [ + { + "label": "API ID", + "type": "text", + "required": true, + "helpText": "Your Veracode HMAC API ID. Found at Veracode Platform > API Credentials." + }, + { + "label": "API Key (Secret)", + "type": "password", + "required": true, + "helpText": "Your Veracode HMAC API Key. Found at Veracode Platform > API Credentials." + }, + { + "label": "Region", + "type": "select", + "required": true, + "helpText": "Your Veracode region. Check with your administrator if unsure." + } + ] + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/vultr.json b/integrations-catalog/integrations/vultr.json index b0f08d4f6b..6b42df0ae2 100644 --- a/integrations-catalog/integrations/vultr.json +++ b/integrations-catalog/integrations/vultr.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.vultr.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to my.vultr.com\n2. Go to Account > API\n3. Enable API access if not already enabled\n4. Copy the API key (or create a new one)\n5. Paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/wandb.json b/integrations-catalog/integrations/wandb.json index a184b18948..b10fb233f3 100644 --- a/integrations-catalog/integrations/wandb.json +++ b/integrations-catalog/integrations/wandb.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.wandb.ai", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to wandb.ai\n2. Click your avatar in the top right, then 'User Settings'\n3. Scroll to 'API Keys' and click 'Create new API key'\n4. Copy the API key and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/watchguard.json b/integrations-catalog/integrations/watchguard.json index 1a2cdeed60..fe0e61e859 100644 --- a/integrations-catalog/integrations/watchguard.json +++ b/integrations-catalog/integrations/watchguard.json @@ -8,6 +8,7 @@ "authConfig": { "type": "custom", "config": { + "setupInstructions": "1. Log in to WatchGuard Cloud at cloud.watchguard.com\n2. Go to Administration > Managed Access\n3. Create a new API credential or copy existing ones\n4. Note your Access ID, Access Password, and API Key\n5. Select your data region (USA, Europe, or Australia)\n6. Enter the credentials below", "credentialFields": [ { "label": "API Key", diff --git a/integrations-catalog/integrations/webex.json b/integrations-catalog/integrations/webex.json index 70ad2182c2..d00f59315e 100644 --- a/integrations-catalog/integrations/webex.json +++ b/integrations-catalog/integrations/webex.json @@ -7,7 +7,9 @@ "baseUrl": "https://webexapis.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to developer.webex.com\n2. Click your avatar, then 'My Webex Apps'\n3. Create a Bot or use a Personal Access Token\n4. Copy the access token and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/webflow.json b/integrations-catalog/integrations/webflow.json index e199724007..8525a5e265 100644 --- a/integrations-catalog/integrations/webflow.json +++ b/integrations-catalog/integrations/webflow.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.webflow.com/", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to webflow.com\n2. Go to Account Settings > Integrations > API Access\n3. Generate an API token with sites:read scope\n4. Copy the token and paste it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/workato.json b/integrations-catalog/integrations/workato.json index 8ba16dd76b..72a1038383 100644 --- a/integrations-catalog/integrations/workato.json +++ b/integrations-catalog/integrations/workato.json @@ -8,13 +8,19 @@ "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Workato at https://app.workato.com\n2. Go to Account Settings → API Token\n3. Copy your API token\n4. Enter it below", + "setupInstructions": "1. Log in to Workato\n2. Go to Workspace Admin > API Clients\n3. Create an API Client with appropriate client role\n4. Copy the API token\n5. Select your data center URL (US: https://www.workato.com, EU: https://app.eu.workato.com, etc.)\n6. Enter both below", "credentialFields": [ { - "label": "API Token", + "label": "Data Center", + "type": "text", + "required": true, + "helpText": "Your Workato data center base URL (e.g., https://www.workato.com for US, https://app.eu.workato.com for EU, https://app.jp.workato.com for JP, https://app.sg.workato.com for SG, https://app.au.workato.com for AU)" + }, + { + "label": "API Client Token", "type": "password", "required": true, - "helpText": "Found in Workato Account Settings → API token" + "helpText": "API Client token from Workspace Admin > API Clients. Requires appropriate client role." } ] } diff --git a/integrations-catalog/integrations/xero.json b/integrations-catalog/integrations/xero.json index 56fb07eb81..8f1c156549 100644 --- a/integrations-catalog/integrations/xero.json +++ b/integrations-catalog/integrations/xero.json @@ -14,6 +14,7 @@ "profile", "email", "accounting.contacts.read", + "accounting.settings.read", "offline_access" ], "clientAuthMethod": "body", diff --git a/integrations-catalog/integrations/zapier.json b/integrations-catalog/integrations/zapier.json index 680851c9e9..50789a65fa 100644 --- a/integrations-catalog/integrations/zapier.json +++ b/integrations-catalog/integrations/zapier.json @@ -7,7 +7,9 @@ "baseUrl": "https://api.zapier.com", "authConfig": { "type": "api_key", - "config": {} + "config": { + "setupInstructions": "1. Log in to Zapier at https://zapier.com\n2. Go to Developer API settings\n3. Generate an API key\n4. Enter it below" + } }, "capabilities": [ "checks" diff --git a/integrations-catalog/integrations/zscaler-zpa.json b/integrations-catalog/integrations/zscaler-zpa.json index 2e6c85375a..e7479677c7 100644 --- a/integrations-catalog/integrations/zscaler-zpa.json +++ b/integrations-catalog/integrations/zscaler-zpa.json @@ -1,13 +1,35 @@ { "slug": "zscaler-zpa", "name": "Zscaler Private Access", - "description": "Zero trust network access platform. Monitor application access and policies.", + "description": "Zero trust network access platform. Monitor application segments, access policies, app connectors, and admin users.", "category": "Security", "docsUrl": "https://help.zscaler.com/zpa/api", "baseUrl": "https://config.private.zscaler.com", "authConfig": { - "type": "api_key", - "config": {} + "type": "custom", + "config": { + "setupInstructions": "1. Log in to the ZPA Admin Portal\n2. Go to Administration > API Key Management\n3. Add a new API Key with Read-Only permissions\n4. Copy the Client ID and Client Secret\n5. Go to Administration > Company to find your Customer ID\n6. Enter all three values below", + "credentialFields": [ + { + "label": "Client ID", + "type": "text", + "required": true, + "helpText": "ZPA API Client ID. Found in ZPA Admin Portal > Administration > API Key Management." + }, + { + "label": "Client Secret", + "type": "password", + "required": true, + "helpText": "ZPA API Client Secret Key. Found in ZPA Admin Portal > Administration > API Key Management." + }, + { + "label": "Customer ID", + "type": "text", + "required": true, + "helpText": "Your ZPA tenant/customer ID. Found in ZPA Admin Portal > Administration > Company." + } + ] + } }, "capabilities": [ "checks" @@ -17,15 +39,15 @@ "checks": [ { "slug": "zscaler_zpa_app_availability", - "name": "Zscaler ZPA App Availability", - "description": "Checks that the Zscaler ZPA API is accessible.", - "defaultSeverity": "medium", + "name": "App Availability", + "description": "Verifies the Zscaler ZPA API is accessible by authenticating and retrieving application segments.", + "defaultSeverity": "high", "enabled": true }, { "slug": "zscaler_zpa_employee_access", - "name": "Zscaler ZPA Employee Access", - "description": "Verifies access to Zscaler ZPA.", + "name": "Employee Access", + "description": "Reviews ZPA app connectors to verify that the private access infrastructure is operational and connected.", "defaultSeverity": "medium", "enabled": true } diff --git a/integrations-catalog/integrations/zuora.json b/integrations-catalog/integrations/zuora.json index 952fd3b738..1454f49ef5 100644 --- a/integrations-catalog/integrations/zuora.json +++ b/integrations-catalog/integrations/zuora.json @@ -1,26 +1,32 @@ { "slug": "zuora", "name": "Zuora", - "description": "Zuora subscription management and recurring billing platform", + "description": "Zuora subscription management and recurring billing platform. Monitor API access and user management.", "category": "Productivity", "docsUrl": "https://developer.zuora.com", "baseUrl": "https://rest.zuora.com", "authConfig": { "type": "custom", "config": { - "setupInstructions": "1. Log in to Zuora\n2. Go to Settings → Administration → OAuth Client Management\n3. Create a new OAuth Client\n4. Enter the Client ID and Client Secret below", + "setupInstructions": "1. Log in to Zuora\n2. Go to Settings > Administration > OAuth Client Management\n3. Create a new OAuth Client with appropriate permissions\n4. Copy the Client ID and Client Secret\n5. If your Zuora tenant is not on US Cloud 2, enter your base URL (e.g. rest.eu.zuora.com for EU)\n6. Enter the values below", "credentialFields": [ { "label": "Client ID", "type": "text", "required": true, - "helpText": "Zuora → Settings → Administration → OAuth Client Management" + "helpText": "Zuora OAuth Client ID. Go to Settings > Administration > OAuth Client Management." }, { "label": "Client Secret", "type": "password", "required": true, - "helpText": "Zuora → Settings → Administration → OAuth Client Management" + "helpText": "Zuora OAuth Client Secret. Generated when creating an OAuth client." + }, + { + "label": "Zuora API Base URL", + "type": "text", + "required": false, + "helpText": "Your Zuora REST API base URL. Examples: rest.zuora.com (US Prod Cloud 2), rest.na.zuora.com (US Prod Cloud 1), rest.eu.zuora.com (EU), rest.ap.zuora.com (APAC), rest.sandbox.na.zuora.com (US Sandbox). Default: rest.zuora.com" } ] } @@ -34,14 +40,14 @@ { "slug": "zuora_app_availability", "name": "App Availability", - "description": "Verifies Zuora billing platform is accessible", + "description": "Verifies Zuora billing platform is accessible by authenticating via OAuth and checking the catalog.", "defaultSeverity": "medium", "enabled": true }, { "slug": "zuora_employee_access", "name": "Employee Access", - "description": "Lists Zuora users to verify billing access is managed", + "description": "Queries Zuora platform users to verify billing access is managed.", "defaultSeverity": "medium", "enabled": true } From dbea43c27e1b6b888b1486797a11c69f8407fe9f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 14:16:37 -0400 Subject: [PATCH 3/4] fix(app): add SOC 3 to Trust portal frameworks list * feat(db): new migration to add fields for SOC 3 * fix(api): support soc2 for trust-portal endpoints * fix(app): add SOC 3 to Trust portal frameworks list * working * fix(app): update badge image for SOC 3 in trust portal * fix(app): pass props to SOC 3 svg * fix(db): upgrade db version --------- Co-authored-by: chasprowebdev --- .../components/TrustPortalSwitch.tsx | 4 + .../portal-settings/components/logos.tsx | 96 +++++++++++++++++++ packages/db/package.json | 2 +- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx index 3448218e14..5c6d49369d 100644 --- a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx +++ b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.tsx @@ -59,6 +59,8 @@ import { SOC2Type1InProgress, SOC2Type2, SOC2Type2InProgress, + SOC3, + SOC3InProgress, } from './logos'; // Client-side form schema (includes all fields for form state) @@ -917,6 +919,8 @@ function ComplianceFrameworkLogo({ title, status, enabled }: { title: string; st LogoComponent = enabled && isInProgress ? NEN7510InProgress : NEN7510; } else if (title === 'ISO 9001') { LogoComponent = enabled && isInProgress ? ISO9001InProgress : ISO9001; + } else if (title === 'SOC 3') { + LogoComponent = enabled && isInProgress ? SOC3InProgress : SOC3; } else { LogoComponent = null; } diff --git a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx index aa0bfffe3a..cfc333204f 100644 --- a/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx +++ b/apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/logos.tsx @@ -849,3 +849,99 @@ export const ISO9001InProgress = (props: React.SVGProps) => ( ); + +export const SOC3 = (props: React.SVGProps) => ( + + + + + + + + + + + + + +); + +export const SOC3InProgress = (props: React.SVGProps) => ( + + + + + + + + + + + + + +); diff --git a/packages/db/package.json b/packages/db/package.json index 677692735a..33e7ed3f80 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,7 +1,7 @@ { "name": "@trycompai/db", "description": "Database package with Prisma client and schema for Comp AI", - "version": "2.0.1", + "version": "2.0.3", "dependencies": { "@prisma/adapter-pg": "7.6.0", "@prisma/client": "7.6.0", From a1a658682bb0146d1b8a5f46e6287d46b8076ce8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 14:37:05 -0400 Subject: [PATCH 4/4] fix: allow cx to bypass background checks for orgs * feat(db): add Organization.backgroundCheckStepEnabled Co-Authored-By: Claude Sonnet 4.6 * feat(api): gate BG-check requirement on backgroundCheckStepEnabled Co-Authored-By: Claude Sonnet 4.6 * test(api): cover all-pass case for BG-check gating, drop redundant mock Co-Authored-By: Claude Sonnet 4.6 * feat(api): thread backgroundCheckStepEnabled through getOverviewScores Co-Authored-By: Claude Sonnet 4.6 * refactor(api): align backgroundCheckStepEnabled derivation with sibling flags * feat(api): add admin setBackgroundCheckStep service method Extend getOrganization to return backgroundCheckStepEnabled in its select and add setBackgroundCheckStep(id, enabled) following the setAccess pattern. Co-Authored-By: Claude Sonnet 4.6 * feat(api): add PATCH /v1/admin/organizations/:id/background-check-step Co-Authored-By: Claude Sonnet 4.6 * feat(app): admin BG-check requirement toggle in org overview Co-Authored-By: Claude Sonnet 4.6 * test(app): cover BG-check toggle rollback on PATCH failure * feat(app): hide BG-check column in people table when bypassed Thread backgroundCheckStepEnabled from TeamMembers server component through TeamMembersClient to MemberRow; gate the BG-check task counter and BackgroundCheckVerifiedTick behind the flag. * fix(app): tighten BG-check bypass test assertion and parallelize org fetch Co-Authored-By: Claude Sonnet 4.6 * feat(app): show bypass info card on employee BG-check page when disabled When an org has backgroundCheckStepEnabled === false, replace the BG-check wizard with an info card on both the standalone /background-check page and the inline tab in the employee detail view. Threads the flag from the server pages through Employee.tsx down to EmployeeBackgroundCheck.tsx. Co-Authored-By: Claude Sonnet 4.6 * refactor(app): use design-system Information icon for BG-check bypass card * fix(test): use role and getAllByText queries in AdminOrgTabs tests to avoid ambiguous matches The org name appears in both the breadcrumb and the page heading, and "Active" appears in multiple badge/status locations. Switch to getByRole('heading') and getAllByText to avoid TestingLibraryElementError. Co-Authored-By: Claude Sonnet 4.6 * feat(app): hide BG-check tab and verified-tick badge when bypassed Gate the BackgroundCheckVerifiedTick badge behind backgroundCheckStepEnabled in EmployeePageHeader, and conditionally render the Background Check TabsTrigger and TabsContent in Employee.tsx using the same flag (matching the HIPAA tab pattern). Also guards the background-check tab default URL param navigation when the flag is off. Co-Authored-By: Claude Sonnet 4.6 * refactor(api): consolidate admin org endpoints into single PATCH Replace activate, deactivate, and background-check-step PATCH endpoints with a single PATCH /:id accepting UpdateAdminOrganizationDto. Forces future toggles to add fields to the DTO rather than creating one-off endpoints. Co-Authored-By: Claude Sonnet 4.6 * refactor(app): point admin org mutations at unified PATCH endpoint Update activate/deactivate calls to send hasAccess field to PATCH /:id, and update background-check toggle to send backgroundCheckStepEnabled field to the same endpoint. Update tests accordingly. Co-Authored-By: Claude Sonnet 4.6 * fix(app): skip BG-check SWR fetches when org has bypass enabled Pass null as the SWR key for both /background-check and /billing-status hooks when backgroundCheckStepEnabled is false. SWR's revalidate-on-mount and revalidate-on-focus would otherwise fire fetchers whose results are discarded by the bypass-card early-return immediately after. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Mariano Co-authored-by: Claude Sonnet 4.6 --- .../admin-organizations.controller.spec.ts | 54 ++++++++--- .../admin-organizations.controller.ts | 28 +++--- .../admin-organizations.service.spec.ts | 53 ++++++++--- .../admin-organizations.service.ts | 6 +- .../admin-security.spec.ts | 18 +--- .../dto/update-admin-organization.dto.ts | 20 ++++ .../frameworks-people-score.helper.spec.ts | 49 ++++++++++ .../frameworks-people-score.helper.ts | 11 ++- .../frameworks/frameworks-scores.helper.ts | 3 + .../components/AdminOrgTabs.test.tsx | 5 +- .../[adminOrgId]/components/AdminOrgTabs.tsx | 7 +- .../components/OrganizationDetail.test.tsx | 93 +++++++++++++++++++ .../components/OrganizationDetail.tsx | 55 ++++++++++- .../[employeeId]/background-check/page.tsx | 9 +- .../[employeeId]/components/Employee.tsx | 29 ++++-- .../EmployeeBackgroundCheck.test.tsx | 38 ++++++++ .../components/EmployeeBackgroundCheck.tsx | 31 ++++++- .../components/EmployeePageHeader.test.tsx | 16 ++++ .../components/EmployeePageHeader.tsx | 6 +- .../[orgId]/people/[employeeId]/page.tsx | 1 + .../people/all/components/MemberRow.test.tsx | 31 +++++++ .../people/all/components/MemberRow.tsx | 8 +- .../people/all/components/TeamMembers.tsx | 34 ++++--- .../all/components/TeamMembersClient.tsx | 3 + .../migration.sql | 2 + packages/db/prisma/schema/organization.prisma | 1 + 26 files changed, 523 insertions(+), 88 deletions(-) create mode 100644 apps/api/src/admin-organizations/dto/update-admin-organization.dto.ts create mode 100644 apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.test.tsx create mode 100644 packages/db/prisma/migrations/20260501143628_add_background_check_step_enabled/migration.sql diff --git a/apps/api/src/admin-organizations/admin-organizations.controller.spec.ts b/apps/api/src/admin-organizations/admin-organizations.controller.spec.ts index 2a2af65407..a53ff09b98 100644 --- a/apps/api/src/admin-organizations/admin-organizations.controller.spec.ts +++ b/apps/api/src/admin-organizations/admin-organizations.controller.spec.ts @@ -43,7 +43,7 @@ describe('AdminOrganizationsController', () => { const mockService = { listOrganizations: jest.fn(), getOrganization: jest.fn(), - setAccess: jest.fn(), + updateOrganization: jest.fn(), inviteMember: jest.fn(), listInvitations: jest.fn(), revokeInvitation: jest.fn(), @@ -134,24 +134,54 @@ describe('AdminOrganizationsController', () => { }); }); - describe('activate', () => { - it('should call setAccess with true', async () => { - mockService.setAccess.mockResolvedValue({ success: true }); + describe('update', () => { + it('PATCH with { hasAccess: true } calls service with (id, { hasAccess: true })', async () => { + mockService.updateOrganization.mockResolvedValue({ success: true }); - const result = await controller.activate('org_1'); + const result = await controller.update('org_1', { hasAccess: true }); - expect(mockService.setAccess).toHaveBeenCalledWith('org_1', true); + expect(mockService.updateOrganization).toHaveBeenCalledWith('org_1', { + hasAccess: true, + }); expect(result).toEqual({ success: true }); }); - }); - describe('deactivate', () => { - it('should call setAccess with false', async () => { - mockService.setAccess.mockResolvedValue({ success: true }); + it('PATCH with { hasAccess: false } calls service with (id, { hasAccess: false })', async () => { + mockService.updateOrganization.mockResolvedValue({ success: true }); + + const result = await controller.update('org_1', { hasAccess: false }); - const result = await controller.deactivate('org_1'); + expect(mockService.updateOrganization).toHaveBeenCalledWith('org_1', { + hasAccess: false, + }); + expect(result).toEqual({ success: true }); + }); + + it('PATCH with { backgroundCheckStepEnabled: false } calls service with correct body', async () => { + mockService.updateOrganization.mockResolvedValue({ success: true }); + + const result = await controller.update('org_1', { + backgroundCheckStepEnabled: false, + }); - expect(mockService.setAccess).toHaveBeenCalledWith('org_1', false); + expect(mockService.updateOrganization).toHaveBeenCalledWith('org_1', { + backgroundCheckStepEnabled: false, + }); + expect(result).toEqual({ success: true }); + }); + + it('PATCH with multiple fields passes both through', async () => { + mockService.updateOrganization.mockResolvedValue({ success: true }); + + const result = await controller.update('org_1', { + hasAccess: true, + backgroundCheckStepEnabled: false, + }); + + expect(mockService.updateOrganization).toHaveBeenCalledWith('org_1', { + hasAccess: true, + backgroundCheckStepEnabled: false, + }); expect(result).toEqual({ success: true }); }); }); diff --git a/apps/api/src/admin-organizations/admin-organizations.controller.ts b/apps/api/src/admin-organizations/admin-organizations.controller.ts index 172990faa2..6de51d6b21 100644 --- a/apps/api/src/admin-organizations/admin-organizations.controller.ts +++ b/apps/api/src/admin-organizations/admin-organizations.controller.ts @@ -21,6 +21,7 @@ import { PurgeOrganizationService } from './purge-organization.service'; import { AdminAuditLogInterceptor } from './admin-audit-log.interceptor'; import { SkipAdminAuditLog } from './skip-admin-audit-log.decorator'; import { InviteMemberDto } from './dto/invite-member.dto'; +import { UpdateAdminOrganizationDto } from './dto/update-admin-organization.dto'; import { PurgeOrganizationDto } from './dto/purge-organization.dto'; @ApiExcludeController() @@ -100,18 +101,21 @@ export class AdminOrganizationsController { return this.service.getOrganization(id); } - @Patch(':id/activate') - @ApiOperation({ summary: 'Activate organization access (platform admin)' }) - @Throttle({ default: { ttl: 60000, limit: 5 } }) - async activate(@Param('id') id: string) { - return this.service.setAccess(id, true); - } - - @Patch(':id/deactivate') - @ApiOperation({ summary: 'Deactivate organization access (platform admin)' }) - @Throttle({ default: { ttl: 60000, limit: 5 } }) - async deactivate(@Param('id') id: string) { - return this.service.setAccess(id, false); + @Patch(':id') + @ApiOperation({ summary: 'Update organization fields (platform admin)' }) + @Throttle({ default: { ttl: 60000, limit: 10 } }) + @UsePipes( + new ValidationPipe({ + whitelist: true, + forbidNonWhitelisted: true, + transform: true, + }), + ) + async update( + @Param('id') id: string, + @Body() body: UpdateAdminOrganizationDto, + ) { + return this.service.updateOrganization(id, body); } @Post(':id/invite') diff --git a/apps/api/src/admin-organizations/admin-organizations.service.spec.ts b/apps/api/src/admin-organizations/admin-organizations.service.spec.ts index 9af5e5f0e3..ca2e404039 100644 --- a/apps/api/src/admin-organizations/admin-organizations.service.spec.ts +++ b/apps/api/src/admin-organizations/admin-organizations.service.spec.ts @@ -183,6 +183,11 @@ describe('AdminOrganizationsService', () => { const result = await service.getOrganization('org_1'); expect(result.id).toBe('org_1'); expect(result.members).toHaveLength(1); + expect(mockDb.organization.findUnique).toHaveBeenCalledWith( + expect.objectContaining({ + select: expect.objectContaining({ backgroundCheckStepEnabled: true }), + }), + ); }); it('should throw NotFoundException for missing org', async () => { @@ -194,8 +199,8 @@ describe('AdminOrganizationsService', () => { }); }); - describe('setAccess', () => { - it('should activate an organization', async () => { + describe('updateOrganization', () => { + it('single-field update (hasAccess)', async () => { (mockDb.organization.findUnique as jest.Mock).mockResolvedValue({ id: 'org_1', }); @@ -204,7 +209,9 @@ describe('AdminOrganizationsService', () => { hasAccess: true, }); - const result = await service.setAccess('org_1', true); + const result = await service.updateOrganization('org_1', { + hasAccess: true, + }); expect(result.success).toBe(true); expect(mockDb.organization.update).toHaveBeenCalledWith({ @@ -213,30 +220,54 @@ describe('AdminOrganizationsService', () => { }); }); - it('should deactivate an organization', async () => { + it('single-field update (backgroundCheckStepEnabled)', async () => { (mockDb.organization.findUnique as jest.Mock).mockResolvedValue({ id: 'org_1', }); (mockDb.organization.update as jest.Mock).mockResolvedValue({ id: 'org_1', - hasAccess: false, + backgroundCheckStepEnabled: false, }); - const result = await service.setAccess('org_1', false); + const result = await service.updateOrganization('org_1', { + backgroundCheckStepEnabled: false, + }); expect(result.success).toBe(true); expect(mockDb.organization.update).toHaveBeenCalledWith({ where: { id: 'org_1' }, - data: { hasAccess: false }, + data: { backgroundCheckStepEnabled: false }, }); }); - it('should throw NotFoundException for missing org', async () => { + it('multi-field update', async () => { + (mockDb.organization.findUnique as jest.Mock).mockResolvedValue({ + id: 'org_1', + }); + (mockDb.organization.update as jest.Mock).mockResolvedValue({ + id: 'org_1', + hasAccess: true, + backgroundCheckStepEnabled: false, + }); + + const result = await service.updateOrganization('org_1', { + hasAccess: true, + backgroundCheckStepEnabled: false, + }); + + expect(result.success).toBe(true); + expect(mockDb.organization.update).toHaveBeenCalledWith({ + where: { id: 'org_1' }, + data: { hasAccess: true, backgroundCheckStepEnabled: false }, + }); + }); + + it('throws NotFoundException for missing org', async () => { (mockDb.organization.findUnique as jest.Mock).mockResolvedValue(null); - await expect(service.setAccess('org_missing', true)).rejects.toThrow( - NotFoundException, - ); + await expect( + service.updateOrganization('org_missing', { hasAccess: true }), + ).rejects.toThrow(NotFoundException); }); }); diff --git a/apps/api/src/admin-organizations/admin-organizations.service.ts b/apps/api/src/admin-organizations/admin-organizations.service.ts index ec3b9fa2a9..a1a5c33f5c 100644 --- a/apps/api/src/admin-organizations/admin-organizations.service.ts +++ b/apps/api/src/admin-organizations/admin-organizations.service.ts @@ -7,6 +7,7 @@ import { import { AuditLogEntityType, db } from '@db'; import { triggerEmail } from '../email/trigger-email'; import { InviteEmail } from '../email/templates/invite-member'; +import { UpdateAdminOrganizationDto } from './dto/update-admin-organization.dto'; @Injectable() export class AdminOrganizationsService { @@ -238,6 +239,7 @@ export class AdminOrganizationsService { hasAccess: true, onboardingCompleted: true, website: true, + backgroundCheckStepEnabled: true, members: { where: { isActive: true, deactivated: false }, select: { @@ -265,7 +267,7 @@ export class AdminOrganizationsService { return org; } - async setAccess(id: string, hasAccess: boolean) { + async updateOrganization(id: string, data: UpdateAdminOrganizationDto) { const org = await db.organization.findUnique({ where: { id } }); if (!org) { @@ -274,7 +276,7 @@ export class AdminOrganizationsService { await db.organization.update({ where: { id }, - data: { hasAccess }, + data, }); return { success: true }; diff --git a/apps/api/src/admin-organizations/admin-security.spec.ts b/apps/api/src/admin-organizations/admin-security.spec.ts index 04b3e6e343..41435770f6 100644 --- a/apps/api/src/admin-organizations/admin-security.spec.ts +++ b/apps/api/src/admin-organizations/admin-security.spec.ts @@ -155,24 +155,14 @@ describe('Admin controllers security baseline', () => { expect(AdminIntegrationsController).toBeDefined(); }); - describe('destructive endpoints have tighter rate limits', () => { - it('activate has a limit of 5 per minute', () => { + describe('update endpoint rate limits', () => { + it('update has a limit of 10 per minute', () => { const metadata = Reflect.getMetadata( 'THROTTLER:LIMIT', - AdminOrganizationsController.prototype.activate, + AdminOrganizationsController.prototype.update, ); if (metadata) { - expect(metadata).toBeLessThanOrEqual(5); - } - }); - - it('deactivate has a limit of 5 per minute', () => { - const metadata = Reflect.getMetadata( - 'THROTTLER:LIMIT', - AdminOrganizationsController.prototype.deactivate, - ); - if (metadata) { - expect(metadata).toBeLessThanOrEqual(5); + expect(metadata).toBeLessThanOrEqual(10); } }); }); diff --git a/apps/api/src/admin-organizations/dto/update-admin-organization.dto.ts b/apps/api/src/admin-organizations/dto/update-admin-organization.dto.ts new file mode 100644 index 0000000000..2026fee16f --- /dev/null +++ b/apps/api/src/admin-organizations/dto/update-admin-organization.dto.ts @@ -0,0 +1,20 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { IsBoolean, IsOptional } from 'class-validator'; + +export class UpdateAdminOrganizationDto { + @ApiPropertyOptional({ + description: + 'Whether the organization has platform access (controls dashboard login).', + }) + @IsOptional() + @IsBoolean() + hasAccess?: boolean; + + @ApiPropertyOptional({ + description: + 'When true, the organization requires background checks for people completion. When false, BG checks are bypassed and excluded from counts.', + }) + @IsOptional() + @IsBoolean() + backgroundCheckStepEnabled?: boolean; +} diff --git a/apps/api/src/frameworks/frameworks-people-score.helper.spec.ts b/apps/api/src/frameworks/frameworks-people-score.helper.spec.ts index 160df11f15..a2348bf4d8 100644 --- a/apps/api/src/frameworks/frameworks-people-score.helper.spec.ts +++ b/apps/api/src/frameworks/frameworks-people-score.helper.spec.ts @@ -62,6 +62,7 @@ describe('computePeopleScore', () => { employees: members, securityTrainingStepEnabled: false, deviceAgentStepEnabled: false, + backgroundCheckStepEnabled: true, hasHipaaFramework: false, }); @@ -76,4 +77,52 @@ describe('computePeopleScore', () => { distinct: ['memberId'], }); }); + + it('counts all employees when BG checks are enabled and all have completed checks', async () => { + (mockDb.backgroundCheckRequest.findMany as jest.Mock).mockResolvedValue([ + { memberId: 'mem_1' }, + { memberId: 'mem_2' }, + ]); + + const score = await computePeopleScore({ + organizationId: 'org_1', + allPolicies: [], + employees: members, + securityTrainingStepEnabled: false, + deviceAgentStepEnabled: false, + backgroundCheckStepEnabled: true, + hasHipaaFramework: false, + }); + + expect(score).toEqual({ total: 2, completed: 2 }); + }); + + it('treats employees as complete without a BG check when backgroundCheckStepEnabled is false', async () => { + // BG-check mock value is irrelevant — the bypass path never calls findMany. + const score = await computePeopleScore({ + organizationId: 'org_1', + allPolicies: [], + employees: members, + securityTrainingStepEnabled: false, + deviceAgentStepEnabled: false, + backgroundCheckStepEnabled: false, + hasHipaaFramework: false, + }); + + expect(score).toEqual({ total: 2, completed: 2 }); + }); + + it('skips the BG-check query entirely when backgroundCheckStepEnabled is false', async () => { + await computePeopleScore({ + organizationId: 'org_1', + allPolicies: [], + employees: members, + securityTrainingStepEnabled: false, + deviceAgentStepEnabled: false, + backgroundCheckStepEnabled: false, + hasHipaaFramework: false, + }); + + expect(mockDb.backgroundCheckRequest.findMany).not.toHaveBeenCalled(); + }); }); diff --git a/apps/api/src/frameworks/frameworks-people-score.helper.ts b/apps/api/src/frameworks/frameworks-people-score.helper.ts index 5d86a85cef..e313edf517 100644 --- a/apps/api/src/frameworks/frameworks-people-score.helper.ts +++ b/apps/api/src/frameworks/frameworks-people-score.helper.ts @@ -28,6 +28,7 @@ interface ComputePeopleScoreParams { employees: ScoreMember[]; securityTrainingStepEnabled: boolean; deviceAgentStepEnabled: boolean; + backgroundCheckStepEnabled: boolean; hasHipaaFramework: boolean; } @@ -37,6 +38,7 @@ export async function computePeopleScore({ employees, securityTrainingStepEnabled, deviceAgentStepEnabled, + backgroundCheckStepEnabled, hasHipaaFramework, }: ComputePeopleScoreParams) { const activeEmployees = await filterComplianceMembers( @@ -70,7 +72,9 @@ export async function computePeopleScore({ memberIds, needsCompletions: securityTrainingStepEnabled || hasHipaaFramework, }), - getMembersWithCompletedBackgroundChecks({ organizationId, memberIds }), + backgroundCheckStepEnabled + ? getMembersWithCompletedBackgroundChecks({ organizationId, memberIds }) + : Promise.resolve(new Set()), ]); const completed = activeEmployees.filter((employee) => { @@ -97,13 +101,16 @@ export async function computePeopleScore({ const hasInstalledDevice = deviceAgentStepEnabled ? membersWithInstalledDevices.has(employee.id) : true; + const hasCompletedBackgroundCheck = backgroundCheckStepEnabled + ? membersWithCompletedBackgroundChecks.has(employee.id) + : true; return ( hasAcceptedAllPolicies && hasCompletedAllTraining && hasCompletedHipaa && hasInstalledDevice && - membersWithCompletedBackgroundChecks.has(employee.id) + hasCompletedBackgroundCheck ); }).length; diff --git a/apps/api/src/frameworks/frameworks-scores.helper.ts b/apps/api/src/frameworks/frameworks-scores.helper.ts index 2d37e1ec12..6938b269ff 100644 --- a/apps/api/src/frameworks/frameworks-scores.helper.ts +++ b/apps/api/src/frameworks/frameworks-scores.helper.ts @@ -32,6 +32,7 @@ export async function getOverviewScores(organizationId: string) { select: { securityTrainingStepEnabled: true, deviceAgentStepEnabled: true, + backgroundCheckStepEnabled: true, }, }), db.frameworkInstance.findFirst({ @@ -42,6 +43,7 @@ export async function getOverviewScores(organizationId: string) { const securityTrainingStepEnabled = org?.securityTrainingStepEnabled === true; const deviceAgentStepEnabled = org?.deviceAgentStepEnabled === true; + const backgroundCheckStepEnabled = org?.backgroundCheckStepEnabled === true; const hasHipaaFramework = !!hipaaInstance; const publishedPolicies = allPolicies.filter((p) => p.status === 'published'); @@ -66,6 +68,7 @@ export async function getOverviewScores(organizationId: string) { employees, securityTrainingStepEnabled, deviceAgentStepEnabled, + backgroundCheckStepEnabled, hasHipaaFramework, }); diff --git a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.test.tsx b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.test.tsx index 06a0a1e4e7..644c7a9681 100644 --- a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.test.tsx +++ b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.test.tsx @@ -37,6 +37,7 @@ const mockOrg: AdminOrgDetail = { hasAccess: true, onboardingCompleted: true, website: 'https://test.com', + backgroundCheckStepEnabled: true, members: [ { id: 'mem_1', @@ -70,12 +71,12 @@ describe('AdminOrgTabs', () => { it('renders the page header with org name', () => { render(); - expect(screen.getByText('Test Org')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Test Org' })).toBeInTheDocument(); }); it('shows active badge for active org', () => { render(); - expect(screen.getByText('Active')).toBeInTheDocument(); + expect(screen.getAllByText('Active').length).toBeGreaterThanOrEqual(1); }); it('switches to findings tab on click', () => { diff --git a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.tsx b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.tsx index 5faab00b25..eca3df9bb5 100644 --- a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.tsx +++ b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/AdminOrgTabs.tsx @@ -58,6 +58,7 @@ export interface AdminOrgDetail { hasAccess: boolean; onboardingCompleted: boolean; website: string | null; + backgroundCheckStepEnabled: boolean; members: OrgMember[]; } @@ -86,7 +87,8 @@ export function AdminOrgTabs({ } setToggling(true); const res = await api.patch( - `/v1/admin/organizations/${org.id}/activate`, + `/v1/admin/organizations/${org.id}`, + { hasAccess: true }, ); if (!res.error) setHasAccess(true); setToggling(false); @@ -96,7 +98,8 @@ export function AdminOrgTabs({ setDeactivateDialogOpen(false); setToggling(true); const res = await api.patch( - `/v1/admin/organizations/${org.id}/deactivate`, + `/v1/admin/organizations/${org.id}`, + { hasAccess: false }, ); if (!res.error) setHasAccess(false); setToggling(false); diff --git a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.test.tsx b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.test.tsx new file mode 100644 index 0000000000..dbd1ade802 --- /dev/null +++ b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.test.tsx @@ -0,0 +1,93 @@ +import '@testing-library/jest-dom/vitest'; +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { OrganizationDetail } from './OrganizationDetail'; + +const patchMock = vi.fn(); +vi.mock('@/lib/api-client', () => ({ + apiClient: { + get: vi.fn().mockResolvedValue({ data: { data: [] } }), + patch: (...args: unknown[]) => patchMock(...args), + }, +})); + +const baseOrg = { + id: 'org_1', + name: 'Acme', + logo: null, + createdAt: new Date().toISOString(), + onboardingCompleted: true, + members: [], + backgroundCheckStepEnabled: true, +}; + +describe('OrganizationDetail — background-check toggle', () => { + beforeEach(() => { + patchMock.mockReset(); + patchMock.mockResolvedValue({ data: { success: true } }); + }); + + it('shows the toggle in its current state', () => { + render( + , + ); + + const toggle = screen.getByRole('switch', { + name: /require background checks/i, + }); + expect(toggle).toBeChecked(); + }); + + it('toggles off and PATCHes the new value', async () => { + const user = userEvent.setup(); + + render( + , + ); + + const toggle = screen.getByRole('switch', { + name: /require background checks/i, + }); + + await user.click(toggle); + + await waitFor(() => { + expect(patchMock).toHaveBeenCalledWith( + '/v1/admin/organizations/org_1', + { backgroundCheckStepEnabled: false }, + ); + }); + }); + + it('rolls back to checked state when PATCH fails', async () => { + patchMock.mockResolvedValue({ error: 'server error' }); + const user = userEvent.setup(); + + render( + , + ); + + const toggle = screen.getByRole('switch', { + name: /require background checks/i, + }); + await user.click(toggle); + + await waitFor(() => { + expect(toggle).toBeChecked(); + }); + }); +}); diff --git a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.tsx b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.tsx index 5ff438f574..0d9b21b3dc 100644 --- a/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.tsx +++ b/apps/app/src/app/(app)/[orgId]/admin/organizations/[adminOrgId]/components/OrganizationDetail.tsx @@ -1,5 +1,8 @@ 'use client'; +import { useState } from 'react'; +import { toast } from 'sonner'; +import useSWR from 'swr'; import { apiClient } from '@/lib/api-client'; import { RecentAuditLogs } from '@/components/RecentAuditLogs'; import type { AuditLogWithRelations } from '@/hooks/use-audit-logs'; @@ -7,9 +10,9 @@ import { Badge, Section, Stack, + Switch, Text, } from '@trycompai/design-system'; -import useSWR from 'swr'; interface AdminOrgDetail { id: string; @@ -18,6 +21,7 @@ interface AdminOrgDetail { createdAt: string; onboardingCompleted: boolean; members: { id: string }[]; + backgroundCheckStepEnabled: boolean; } export function OrganizationDetail({ @@ -28,6 +32,36 @@ export function OrganizationDetail({ currentOrgId: string; hasAccess: boolean; }) { + const [bgCheckEnabled, setBgCheckEnabled] = useState( + org.backgroundCheckStepEnabled, + ); + const [savingBgCheck, setSavingBgCheck] = useState(false); + + const handleToggleBgCheck = async (next: boolean) => { + const previous = bgCheckEnabled; + setBgCheckEnabled(next); + setSavingBgCheck(true); + + const res = await apiClient.patch( + `/v1/admin/organizations/${org.id}`, + { backgroundCheckStepEnabled: next }, + ); + + setSavingBgCheck(false); + + if (res.error) { + setBgCheckEnabled(previous); + toast.error('Failed to update background check setting'); + return; + } + + toast.success( + next + ? 'Background checks now required' + : 'Background checks bypassed for this organization', + ); + }; + const { data: logs = [], isLoading } = useSWR( `/v1/admin/organizations/${org.id}/audit-logs`, async (url: string) => { @@ -57,6 +91,25 @@ export function OrganizationDetail({ />
+
+
+
+ Require background checks + + When off, this org's members do not need to pass a background + check to count toward people completion. Existing requests stay + accessible. + +
+ +
+
+ {isLoading ? (
diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/background-check/page.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/background-check/page.tsx index d36a9217b4..1d67176648 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/background-check/page.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/background-check/page.tsx @@ -24,11 +24,17 @@ export default async function EmployeeBackgroundCheckPage({ notFound(); } - const [backgroundCheckRes, backgroundCheckBillingRes] = await Promise.all([ + const [backgroundCheckRes, backgroundCheckBillingRes, org] = await Promise.all([ serverApi.get(`/v1/people/${employeeId}/background-check`), serverApi.get('/v1/background-check-billing/status'), + db.organization.findUnique({ + where: { id: orgId }, + select: { backgroundCheckStepEnabled: true }, + }), ]); + const backgroundCheckStepEnabled = org?.backgroundCheckStepEnabled === true; + return ( ); diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/Employee.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/Employee.tsx index 683d346a5e..7cf635b1f4 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/Employee.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/Employee.tsx @@ -41,6 +41,7 @@ interface EmployeeProps { hipaaCompletedAt: Date | null; initialBackgroundCheck: BackgroundCheckRecord | null; initialBackgroundCheckBillingStatus: BackgroundCheckBillingStatus; + backgroundCheckStepEnabled: boolean; } export function Employee({ @@ -57,10 +58,12 @@ export function Employee({ hipaaCompletedAt, initialBackgroundCheck, initialBackgroundCheckBillingStatus, + backgroundCheckStepEnabled, }: EmployeeProps) { const searchParams = useSearchParams(); const querySelectedTab: EmployeeTab = - searchParams.get('background_check_step') || searchParams.get('background_check_billing') + backgroundCheckStepEnabled && + (searchParams.get('background_check_step') || searchParams.get('background_check_billing')) ? 'background-check' : 'details'; const [activeTab, setActiveTab] = useState(querySelectedTab); @@ -78,6 +81,7 @@ export function Employee({ employeeName={employee.user.name ?? 'Employee'} orgId={orgId} backgroundCheck={initialBackgroundCheck} + backgroundCheckStepEnabled={backgroundCheckStepEnabled} /> } > @@ -94,7 +98,9 @@ export function Employee({ Training Videos {hasHipaaFramework && HIPAA Training} Device - Background Check + {backgroundCheckStepEnabled && ( + Background Check + )} @@ -126,14 +132,17 @@ export function Employee({ fleetPolicies={fleetPolicies} /> - - - + {backgroundCheckStepEnabled && ( + + + + )} diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.test.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.test.tsx index d94ea6788c..7ebc6ca434 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.test.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.test.tsx @@ -68,6 +68,7 @@ function renderSection(props?: Partial , @@ -289,6 +290,43 @@ describe('EmployeeBackgroundCheck', () => { ).toBeNull(); }); + it('renders the bypass info card when backgroundCheckStepEnabled is false', () => { + render( + , + ); + + expect( + screen.getByText(/background checks are not required/i), + ).toBeInTheDocument(); + expect( + screen.queryByRole('button', { name: /get started/i }), + ).not.toBeInTheDocument(); + }); + + it('does not fetch background-check or billing data when bypassed', async () => { + render( + , + ); + + // Allow any pending microtasks/SWR scheduling to settle. + await Promise.resolve(); + await Promise.resolve(); + + expect(apiClient.get).not.toHaveBeenCalled(); + }); + it('shows an update payment dialog when payment fails', async () => { const user = userEvent.setup(); vi.mocked(apiClient.post) diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.tsx index 5caff177e8..36d5fc6fc8 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeeBackgroundCheck.tsx @@ -3,6 +3,8 @@ import { usePermissions } from '@/hooks/use-permissions'; import { apiClient } from '@/lib/api-client'; import type { Member, User } from '@db'; +import { Text } from '@trycompai/design-system'; +import { Information } from '@trycompai/design-system/icons'; import { zodResolver } from '@hookform/resolvers/zod'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import { useCallback, useEffect, useRef, useState } from 'react'; @@ -28,6 +30,7 @@ interface EmployeeBackgroundCheckProps { organizationId: string; initialBackgroundCheck: BackgroundCheckRecord | null; initialBillingStatus: BackgroundCheckBillingStatus; + backgroundCheckStepEnabled: boolean; } export function EmployeeBackgroundCheck({ @@ -35,6 +38,7 @@ export function EmployeeBackgroundCheck({ organizationId, initialBackgroundCheck, initialBillingStatus, + backgroundCheckStepEnabled, }: EmployeeBackgroundCheckProps) { const router = useRouter(); const pathname = usePathname(); @@ -52,7 +56,9 @@ export function EmployeeBackgroundCheck({ const { hasPermission } = usePermissions(); const { data: backgroundCheck, mutate: mutateBackgroundCheck } = useSWR( - [`/v1/people/${employee.id}/background-check`, organizationId], + backgroundCheckStepEnabled + ? [`/v1/people/${employee.id}/background-check`, organizationId] + : null, async ([endpoint]) => { const response = await apiClient.get(endpoint, organizationId); if (response.error) throw new Error('Failed to load background check'); @@ -62,7 +68,9 @@ export function EmployeeBackgroundCheck({ ); const { data: billingStatus, mutate: mutateBillingStatus } = useSWR( - ['/v1/background-check-billing/status', organizationId], + backgroundCheckStepEnabled + ? ['/v1/background-check-billing/status', organizationId] + : null, async ([endpoint]) => { const response = await apiClient.get(endpoint, organizationId); if (response.error || !response.data) { @@ -227,6 +235,25 @@ export function EmployeeBackgroundCheck({ await requestBackgroundCheck(values); }; + if (!backgroundCheckStepEnabled) { + return ( +
+ + + +
+ + Background checks are not required for your organization + + + Comp AI support disabled this requirement. Existing background-check + requests, if any, remain accessible from your billing portal. + +
+
+ ); + } + if (backgroundCheck) { return ( { employeeName="Jane Doe" orgId="org_123" backgroundCheck={backgroundCheck} + backgroundCheckStepEnabled={true} />, ); @@ -40,9 +41,24 @@ describe('EmployeePageHeader', () => { employeeName="Jane Doe" orgId="org_123" backgroundCheck={{ ...backgroundCheck, status: 'invited' }} + backgroundCheckStepEnabled={true} />, ); expect(screen.queryByLabelText('Employee has completed a background check')).not.toBeInTheDocument(); }); + + it('hides the verified tick when background checks are bypassed, even if the check is complete', () => { + render( + , + ); + + expect(screen.getByRole('heading', { name: 'Jane Doe' })).toBeInTheDocument(); + expect(screen.queryByLabelText('Employee has completed a background check')).not.toBeInTheDocument(); + }); }); diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeePageHeader.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeePageHeader.tsx index b59bab23de..2b797254be 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeePageHeader.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/components/EmployeePageHeader.tsx @@ -9,10 +9,12 @@ export function EmployeePageHeader({ employeeName, orgId, backgroundCheck, + backgroundCheckStepEnabled, }: { employeeName: string; orgId: string; backgroundCheck: BackgroundCheckRecord | null; + backgroundCheckStepEnabled: boolean; }) { const isVerified = backgroundCheck ? isCompletedBackgroundCheck(backgroundCheck.status) @@ -31,7 +33,9 @@ export function EmployeePageHeader({
{employeeName} - {isVerified && } + {backgroundCheckStepEnabled && isVerified && ( + + )}
); diff --git a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx index dd83679efd..216d8dd117 100644 --- a/apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx @@ -105,6 +105,7 @@ export default async function EmployeeDetailsPage({ setupAt: null, } } + backgroundCheckStepEnabled={organization.backgroundCheckStepEnabled === true} /> ); } diff --git a/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.test.tsx b/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.test.tsx index 635198bb29..d56c9de68c 100644 --- a/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.test.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.test.tsx @@ -214,4 +214,35 @@ describe('MemberRow device status', () => { expect(screen.getByText('Device 1/1')).toBeInTheDocument(); }); + + it('hides the background-check task counter and verified tick when bypassed', () => { + render( + + + + +
, + ); + + expect(screen.queryByText(/background check/i)).not.toBeInTheDocument(); + expect( + screen.queryByLabelText('Employee has completed a background check'), + ).not.toBeInTheDocument(); + }); }); diff --git a/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.tsx b/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.tsx index b643ce3687..c54b0d9f1d 100644 --- a/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.tsx @@ -58,6 +58,7 @@ interface MemberRowProps { deviceStatus?: 'compliant' | 'non-compliant' | 'stale' | 'not-installed'; isDeviceStatusLoading?: boolean; backgroundCheckStatus?: BackgroundCheckStatus; + backgroundCheckStepEnabled?: boolean; } function getInitials(name?: string | null, email?: string | null): string { @@ -122,6 +123,7 @@ export function MemberRow({ deviceStatus, isDeviceStatusLoading = false, backgroundCheckStatus, + backgroundCheckStepEnabled = true, }: MemberRowProps) { const { orgId } = useParams<{ orgId: string }>(); @@ -182,7 +184,7 @@ export function MemberRow({ }); } - if (shouldShowTaskRequirements) { + if (shouldShowTaskRequirements && backgroundCheckStepEnabled) { taskItems.push({ label: 'Background check', completed: hasCompletedBackgroundCheck ? 1 : 0, @@ -272,7 +274,9 @@ export function MemberRow({ > {memberName} - {hasCompletedBackgroundCheck && } + {backgroundCheckStepEnabled && hasCompletedBackgroundCheck && ( + + )}
{memberEmail} diff --git a/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembers.tsx b/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembers.tsx index 004903143a..ebfb9338ff 100644 --- a/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembers.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembers.tsx @@ -80,18 +80,23 @@ export async function TeamMembers(props: TeamMembersProps) { const employeeMembers = await filterComplianceMembers(members, organizationId); const complianceMemberIds = employeeMembers.map((m) => m.id); + const [orgFlags, hipaaInstance] = await Promise.all([ + db.organization.findUnique({ + where: { id: organizationId }, + select: { + securityTrainingStepEnabled: true, + backgroundCheckStepEnabled: true, + }, + }), + db.frameworkInstance.findFirst({ + where: { organizationId, framework: { name: 'HIPAA' } }, + select: { id: true }, + }), + ]); + const backgroundCheckStepEnabled = orgFlags?.backgroundCheckStepEnabled === true; + const hasHipaaFramework = !!hipaaInstance; + if (employeeMembers.length > 0) { - const [org, hipaaInstance] = await Promise.all([ - db.organization.findUnique({ - where: { id: organizationId }, - select: { securityTrainingStepEnabled: true }, - }), - db.frameworkInstance.findFirst({ - where: { organizationId, framework: { name: 'HIPAA' } }, - select: { id: true }, - }), - ]); - const hasHipaaFramework = !!hipaaInstance; const policies = await db.policy.findMany({ where: { @@ -103,21 +108,21 @@ export async function TeamMembers(props: TeamMembersProps) { }); const employeeIds = employeeMembers.map((m) => m.id); - const trainingCompletions = org?.securityTrainingStepEnabled + const trainingCompletions = orgFlags?.securityTrainingStepEnabled ? await db.employeeTrainingVideoCompletion.findMany({ where: { memberId: { in: employeeIds } }, }) : []; const totalPolicies = policies.length; - const totalTrainingVideos = org?.securityTrainingStepEnabled ? trainingVideosData.length : 0; + const totalTrainingVideos = orgFlags?.securityTrainingStepEnabled ? trainingVideosData.length : 0; const totalHipaaTraining = hasHipaaFramework ? 1 : 0; const totalTasks = totalPolicies + totalTrainingVideos + totalHipaaTraining; for (const employee of employeeMembers) { const policiesCompleted = policies.filter((p) => p.signedBy.includes(employee.id)).length; - const trainingsCompleted = org?.securityTrainingStepEnabled + const trainingsCompleted = orgFlags?.securityTrainingStepEnabled ? trainingCompletions.filter( (tc) => tc.memberId === employee.id && @@ -159,6 +164,7 @@ export async function TeamMembers(props: TeamMembersProps) { employeeSyncData={employeeSyncData} taskCompletionMap={taskCompletionMap} complianceMemberIds={complianceMemberIds} + backgroundCheckStepEnabled={backgroundCheckStepEnabled} /> ); } diff --git a/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembersClient.tsx b/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembersClient.tsx index 0e52f1646b..098a77ef72 100644 --- a/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembersClient.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/all/components/TeamMembersClient.tsx @@ -56,6 +56,7 @@ interface TeamMembersClientProps { employeeSyncData: EmployeeSyncConnectionsData; taskCompletionMap: Record; complianceMemberIds: string[]; + backgroundCheckStepEnabled: boolean; } export function TeamMembersClient({ @@ -66,6 +67,7 @@ export function TeamMembersClient({ employeeSyncData, taskCompletionMap, complianceMemberIds, + backgroundCheckStepEnabled, }: TeamMembersClientProps) { const { agentDevices, isLoading: isAgentDevicesLoading } = useAgentDevices(); const { fleetHosts, isLoading: isFleetHostsLoading } = useFleetHosts(); @@ -482,6 +484,7 @@ export function TeamMembersClient({ backgroundCheckStatus={ (item as MemberWithUser).backgroundCheckRequests?.[0]?.status } + backgroundCheckStepEnabled={backgroundCheckStepEnabled} /> ) : (