-
Notifications
You must be signed in to change notification settings - Fork 575
fix(integrations): Add Passportal integration #4942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
519d1f9
c32efb9
0330947
a01d162
bf3a756
ddf3083
97cc7fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| --- | ||
| title: Passportal | ||
| sidebarTitle: Passportal | ||
| --- | ||
|
|
||
| import Overview from "/snippets/overview.mdx" | ||
| import PreBuiltTooling from "/snippets/generated/passportal/PreBuiltTooling.mdx" | ||
| import PreBuiltUseCases from "/snippets/generated/passportal/PreBuiltUseCases.mdx" | ||
|
|
||
| <Overview /> | ||
| <PreBuiltTooling /> | ||
| <PreBuiltUseCases /> | ||
|
|
||
| ## Access requirements | ||
| | Pre-Requisites | Status | Comment| | ||
propel-code-bot[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| | - | - | - | | ||
| | Paid dev account | ✅ | Passportal account required for API access | | ||
| | Paid test account | ✅ | Passportal account required for testing | | ||
| | Partnership | ❌ | Not required | | ||
| | App review | ❌ | Not required | | ||
| | Security audit | ❌ | Not required | | ||
|
|
||
| ## Setup guide | ||
| <Steps> | ||
| <Step title="Create a Passportal account"> | ||
| Sign up for a [Passportal account](https://www.n-able.com/products/passportal) if you don't already have one. | ||
| </Step> | ||
| <Step title="Generate API Access Key ID and Secret Access Key"> | ||
| 1. Log into your Passportal dashboard | ||
| 2. In the left pane go to **Settings** > **API Keys** | ||
| 3. Click **Create access key** | ||
| 4. View the **Access key ID** then click **Show key** to reveal the **Secret access key** | ||
| 5. Copy both the **Access key ID** and **Secret access key** to a secure location | ||
|
|
||
| **Important**: The Secret access key is only viewable in the Create access key dialog. After closing this dialog, the Secret access key is no longer accessible. | ||
|
|
||
| See the [API Key Management guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_key_management.htm) for more details. | ||
| </Step> | ||
| <Step title="Generate HMAC Token"> | ||
| You need to create an HMAC-SHA256 token using: | ||
| - **Plain text message**: Choose a content string (e.g., 'api-content-hash') | ||
| - **Secret key**: Your Secret access key from the previous step | ||
| - **Algorithm**: SHA-256 | ||
|
|
||
| You can generate the HMAC token using Python: | ||
|
|
||
| ```python | ||
| import hmac | ||
| import hashlib | ||
|
|
||
| secret_key = "YOUR_SECRET_ACCESS_KEY" | ||
| content = "api-content-hash" | ||
| hmac_token = hmac.new(secret_key.encode(), content.encode(), hashlib.sha256).hexdigest() | ||
| print(hmac_token) | ||
| ``` | ||
|
|
||
| Or using an online HMAC generator: | ||
| 1. Use an HMAC generator (many are available online) | ||
| 2. Enter your chosen content string as the message | ||
| 3. Enter your Secret access key as the key | ||
| 4. Select SHA-256 as the algorithm | ||
| 5. Generate the HMAC hash in hexadecimal form | ||
| 6. Store the HMAC token securely | ||
|
|
||
| _Note: online HMAC generators are not recommended - what if the website has been secretly compromised?_ | ||
|
|
||
| See the [Create HMAC Token guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_create_hmac.htm) for more details. | ||
| </Step> | ||
| <Step title="Next"> | ||
| Follow the [_Quickstart_](/getting-started/quickstart). | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ## Useful links | ||
|
|
||
| - [Passportal API Documentation](https://documentation.n-able.com/passportal/userguide/Content/api/api_information.htm) | ||
| - [API Key Management Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_key_management.htm) | ||
| - [Create HMAC Token Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_create_hmac.htm) | ||
| - [Generate API Access Token](https://documentation.n-able.com/passportal/userguide/Content/api/api_authorization.htm) | ||
|
|
||
| <Note>Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs/integrations/all/passportal.mdx)</Note> | ||
|
|
||
| ## API gotchas | ||
|
|
||
| - Passportal uses instance-specific base URLs. Example: `mycompany.mypasswordapp.com` or `instance.passportalmsp.com` | ||
| - Authentication requires a POST request to `/api/v2/auth/client_token` with the API Access Key ID in the `x-key` header | ||
| - The `x-hash` header must contain a pre-generated HMAC-SHA256 token (hash of content string, base64 encoded) | ||
propel-code-bot[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Generate your HMAC token offline before configuring the integration | ||
| - You must provide the same content string that was used to generate the HMAC token in the request body | ||
| - The token request must include `scope: "docs_api"` in the body | ||
| - The access token expires and should be refreshed using the provided refresh token | ||
| - All API requests must include the access token in the Authorization Bearer header | ||
|
|
||
| <Note>Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs/integrations/all/passportal.mdx)</Note> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,78 @@ | ||||||
| --- | ||||||
| title: Passportal - How do I link my account? | ||||||
| sidebarTitle: Passportal | ||||||
| --- | ||||||
|
|
||||||
| # Overview | ||||||
|
|
||||||
| To authenticate with Passportal, you need: | ||||||
| 1. **Base URL** – Your Passportal instance domain (e.g., `mycompany.passportalmsp.com`). | ||||||
jeremydhoon marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| 2. **API Access Key ID** – Your Passportal API Access Key ID. | ||||||
| 3. **HMAC Token** – A pre-generated HMAC-SHA256 hash token (base64 encoded). | ||||||
|
||||||
| 4. **Content String** – The plain text message used to compute the HMAC token. | ||||||
|
|
||||||
| This guide walks you through generating your API credentials and HMAC token for Passportal. | ||||||
|
|
||||||
| ### Prerequisites: | ||||||
|
|
||||||
| - Access to your Passportal account with API permissions. | ||||||
|
|
||||||
| ### Step 1: Find your Passportal base URL | ||||||
|
|
||||||
| Your base URL name is the domain in your Passportal URL: | ||||||
|
|
||||||
| - If your URL is `https://mycompany.passportalmsp.com/dashboard` → Your base URL is `mycompany.passportalmsp.com` | ||||||
| - If your URL is `https://instance.passportalmsp.com/dashboard` → Your instance is `instance.passportalmsp.com` | ||||||
|
||||||
|
|
||||||
| ### Step 2: Generate API Access Key ID and Secret Access Key | ||||||
|
|
||||||
| 1. Log into your Passportal dashboard. | ||||||
| 2. In the left pane, go to **Settings** > **API Keys**. | ||||||
| <img src="/integrations/all/passportal/passportal-settings.png" style={{maxWidth: "450px" }}/> | ||||||
|
||||||
| <img src="/integrations/all/passportal/passportal-settings.png" style={{maxWidth: "450px" }}/> | |
| <img src="/integrations/all/passportal/passportal-settings.png"/> |
same as the rest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the style={{...}} attributes.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Documentation]
Broken image path: File added is "passportal-api-keys.png" but the source here points to "api-keys.png". Update the filename or path so the image loads.
Context for Agents
[**Documentation**]
Broken image path: File added is "passportal-api-keys.png" but the source here points to "api-keys.png". Update the filename or path so the image loads.
File: docs/integrations/all/passportal/connect.mdx
Line: 40
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn’t match the Connect UI form fields. To be determined based on the comment regarding base_url vs. subdomain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. This has been made consistent, including a consistent order between fields in the docs and fields in the connect modal form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to include the form screenshot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| ## Pre-built tooling | ||
| <AccordionGroup> | ||
| <Accordion title="✅ Authorization"> | ||
| | Tools | Status | | ||
| | - | - | | ||
| | Pre-built authorization (Two Step) | ✅ | | ||
| | Pre-built authorization UI | ✅ | | ||
| | Custom authorization UI | ✅ | | ||
| | End-user authorization guide | ✅ | | ||
| | Expired credentials detection | ✅ | | ||
| </Accordion> | ||
| <Accordion title="✅ Read & write data"> | ||
| | Tools | Status | | ||
| | - | - | | ||
| | Pre-built integrations | 🚫 (time to contribute: <48h) | | ||
| | API unification | ✅ | | ||
| | 2-way sync | ✅ | | ||
| | Webhooks from Nango on data modifications | ✅ | | ||
| | Real-time webhooks from 3rd-party API | 🚫 (time to contribute: <48h) | | ||
| | Proxy requests | ✅ | | ||
| </Accordion> | ||
| <Accordion title="✅ Observability & data quality"> | ||
| | Tools | Status | | ||
| | - | - | | ||
| | HTTP request logging | ✅ | | ||
| | End-to-type type safety | ✅ | | ||
jeremydhoon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| | Data runtime validation | ✅ | | ||
| | OpenTelemetry export | ✅ | | ||
| | Slack alerts on errors | ✅ | | ||
| | Integration status API | ✅ | | ||
| </Accordion> | ||
| <Accordion title="✅ Customization"> | ||
| | Tools | Status | | ||
| | - | - | | ||
| | Create or customize use-cases | ✅ | | ||
| | Pre-configured pagination | 🚫 (time to contribute: <48h) | | ||
| | Pre-configured rate-limit handling | 🚫 (time to contribute: <48h) | | ||
| | Per-customer configurations | ✅ | | ||
| </Accordion> | ||
| </AccordionGroup> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ## Pre-built integrations | ||
|
|
||
| _No pre-built integration yet (time to contribute: <48h)_ | ||
|
|
||
| <Tip>Not seeing the integration you need? [Build your own](https://nango.dev/docs/guides/platform/functions) independently.</Tip> |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -9187,6 +9187,63 @@ pandadoc-api-key: | |||||||
| example: 3039ba033eb1410caa0a2227158d63c9d6502cd8 | ||||||||
| pattern: '^[a-fA-F0-9]+$' | ||||||||
|
|
||||||||
| passportal: | ||||||||
| display_name: Passportal | ||||||||
| categories: | ||||||||
| - support | ||||||||
| auth_mode: TWO_STEP | ||||||||
| token_url: https://${connectionConfig.base_url}/api/v2/auth/client_token | ||||||||
| token_headers: | ||||||||
| x-key: ${credentials.apiKey} | ||||||||
| x-hash: ${credentials.hmacToken} | ||||||||
| content-type: application/json | ||||||||
| token_params: | ||||||||
| scope: docs_api | ||||||||
| content: ${credentials.content} | ||||||||
| token_response: | ||||||||
| token: access_token | ||||||||
| token_expiration: data.expiry_time | ||||||||
|
||||||||
| token_expiration: data.expiry_time | |
| token_expiration: expiry_time |
You can verify this by checking the Access Token Expiration under connection in the Nango dashboard. I would also check if the token refreshes when you manually refresh from nango ui.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the base_url always have a suffix passportalmsp.com, if so you can just request for the subdomain instead. with prefix: https:// and suffix : passportalmsp.com
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately the base_url is not constrained to a single suffix; Passportal's documentation shows a different suffix to our domain's suffix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| format: hostname | |
| format: hostname | |
| prefix: https:// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to a add an example and pattern for both apiKey and hmacToken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I've added these.
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the logo should have a maximum width or height of 44px and be centered within a 62x62px container. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If Claude Code is to be believed, the SVG should now meet these requirements. |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a new docs style,take a look at Sellsy (Client Credentials) as an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved to this new style.