Merge pull request #93 from fosrl/dev

This commit is contained in:
Milo Schwartz
2026-04-03 17:29:32 -07:00
committed by GitHub
27 changed files with 398 additions and 46 deletions

View File

@@ -41,7 +41,8 @@
"manage/sites/install-kubernetes", "manage/sites/install-kubernetes",
"manage/sites/configure-site", "manage/sites/configure-site",
"manage/sites/update-site", "manage/sites/update-site",
"manage/sites/credentials" "manage/sites/credentials",
"manage/sites/site-provisioning"
] ]
}, },
{ {
@@ -117,9 +118,7 @@
"manage/identity-providers/auto-provisioning", "manage/identity-providers/auto-provisioning",
"manage/identity-providers/openid-connect", "manage/identity-providers/openid-connect",
"manage/identity-providers/google", "manage/identity-providers/google",
"manage/identity-providers/azure", "manage/identity-providers/azure"
"manage/identity-providers/pocket-id",
"manage/identity-providers/zitadel"
] ]
}, },
{ {
@@ -128,7 +127,9 @@
"pages": [ "pages": [
"manage/analytics/request", "manage/analytics/request",
"manage/analytics/access", "manage/analytics/access",
"manage/analytics/action" "manage/analytics/connection",
"manage/analytics/action",
"manage/analytics/streaming"
] ]
}, },
"manage/blueprints", "manage/blueprints",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

BIN
images/fixed-roles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
images/mapping-builder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

BIN
images/pending-sites.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

BIN
images/raw-expression.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
images/users-table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

View File

@@ -1,22 +1,26 @@
--- ---
title: "Create User" title: "Users and Roles"
description: "Add internal or external users to your organization" description: "Add internal or external users to your organization and manage roles"
--- ---
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx"; import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta /> <PangolinCloudTocCta />
## Users in Organizations
Users can be added to organizations. When a user is added to Pangolin, there is a global user object and an organizationspecific user object that links that user to the organization. This allows a user to exist in one or more organizations. Users can be added to organizations. When a user is added to Pangolin, there is a global user object and an organizationspecific user object that links that user to the organization. This allows a user to exist in one or more organizations.
<Tip> <Tip>
Because the root user exists and a perorganization user exists, a user invited to an organization may be able to create a new organization. You can disable this functionality via a flag in the config file in selfhosted Pangolin. [Check out the config file documentation](/self-host/advanced/config-file#feature-flags). Because the global user exists and a perorganization user exists, a user invited to an organization may be able to create a new organization. You can disable this functionality via a flag in the config file in selfhosted Pangolin. [Check out the config file documentation](/self-host/advanced/config-file#feature-flags).
</Tip> </Tip>
When removing a user from an organization, their account still exists. To completely delete their account, visit the server admin panel as the server admin and delete the global user in the users table. When removing a user from an organization, their account still exists. To completely delete their account, visit the server admin panel as the server admin and delete the global user in the users table.
<Frame>
<img src="/images/users-table.png" centered/>
</Frame>
### Internal Users ### Internal Users
An internal user is an identity managed by Pangolin only. When adding the user, you will receive an invite link. The user needs to use this link to either accept the invite, or create an account for the first time and accept the invite. An internal user is an identity managed by Pangolin only. When adding the user, you will receive an invite link. The user needs to use this link to either accept the invite, or create an account for the first time and accept the invite.
@@ -28,3 +32,17 @@ An external user is an identity managed by an external identity provider. When c
An identity provider may have autoprovisioning enabled. This means new users who log in with the IDP are automatically created and you do not need to manually create the user. [Check out the autoprovisioning documentation](/manage/identity-providers/auto-provisioning). An identity provider may have autoprovisioning enabled. This means new users who log in with the IDP are automatically created and you do not need to manually create the user. [Check out the autoprovisioning documentation](/manage/identity-providers/auto-provisioning).
Even if autoprovisioning is enabled, you can still manually create users. Even if autoprovisioning is enabled, you can still manually create users.
## Roles
Roles are how you group users in an organization. A user can belong to more than one role, for example Member, Admin, Contractor, Operations, or any custom roles you define. You use roles with RBAC on resources so access follows those groups: only Operations might reach production resources, while only Contractors might reach test environments, and so on.
On each resource, you define which roles are allowed to access it. A users effective access is the union of all resources their roles can reach: they can use any resource that at least one of their assigned roles is permitted to access.
You can create as many custom roles as you need in Pangolin. Each role has a name and a description. The name is the display label and also acts as the unique identifier, so two roles cannot share the exact same name.
To change which roles a user has, open that users settings and select the roles they should belong to.
<Note>
Assigning more than one role to a user is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition). In other editions, only one role per user is supported.
</Note>

View File

@@ -12,7 +12,7 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
Access logs provide detailed information about each access attempt made to your Pangolin resources. These logs help you monitor and analyze user activity each time they attempt to authenticate. Access logs provide detailed information about each access attempt made to your Pangolin resources. These logs help you monitor and analyze user activity each time they attempt to authenticate.
<Note> <Note>
Access logs are an [Enterprise Edition](/self-host/enterprise-edition)-only feature. Access logs are only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note> </Note>
## What are Access Logs? ## What are Access Logs?

View File

@@ -12,7 +12,7 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
Action logs provide an audit trail of administrative actions and configuration changes made within your Pangolin organization. These logs help you track who made what changes and when. Action logs provide an audit trail of administrative actions and configuration changes made within your Pangolin organization. These logs help you track who made what changes and when.
<Note> <Note>
Action logs are an [Enterprise Edition](/self-host/enterprise-edition)-only feature. Action logs are only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note> </Note>
## What are Action Logs? ## What are Action Logs?

View File

@@ -0,0 +1,55 @@
---
title: "Connection Logs"
description: "Connection logs are a record of TCP and UDP sessions between Pangolin clients and private site resources"
---
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta />
Connection logs record each TCP and UDP session that traverses the tunnel between Pangolin clients and resources on your sites. They apply to private resources reached through the Pangolin client (and related tunnel traffic), not to public resources served only through the reverse proxy. You can see which clients and users opened sessions to which private resources, the source and destination addresses and protocols (TCP and UDP), the start and end times of the sessions, and more.
<Note>
Connection logs are only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note>
## What are Connection Logs?
Connection logs capture tunnel sessions from clients to private resources. They are useful for:
- Observing which clients and users opened sessions to which private resources
- Reviewing source and destination addresses and protocols (TCP and UDP)
- Measuring traffic volume with transmitted and received byte counts
- Auditing session start and end times for troubleshooting and compliance
<Tip>Make sure to enable connection logging in the org settings</Tip>
## Connection Log Fields
Each connection log entry contains the following fields:
| Field | Type | Description |
|-------|------|-------------|
| `timestamp` | number | Unix timestamp (in seconds) when the session started |
| `protocol` | string | Transport protocol for the session (`tcp` or `udp`) |
| `siteResourceId` | number \| null | The ID of the [private resource](/manage/resources/understanding-resources) for the session (if applicable) |
| `clientId` | number \| null | The Pangolin [client ID](/manage/clients/understanding-clients) for the session |
| `userId` | string \| null | The user ID when the session is tied to an authenticated user |
| `sourceAddr` | string | Source address for the session (typically the client-side endpoint) |
| `destAddr` | string | Destination address for the session (typically the resource-side endpoint) |
| `duration` | number \| null | How long the session lasted (in seconds), when the session has ended |
| `bytesTx` | number \| null | Bytes transmitted in the session |
| `bytesRx` | number \| null | Bytes received in the session |
## Log Retention
Connection log retention is controlled by the organization setting. By default, connection logs are retained for 0 days (disabled).
<Note>
Connection logs can generate significant data volume depending on session churn and traffic. Consider your storage capacity when configuring retention periods.
</Note>
## Exporting
Logs can be exported into CSV format for external analysis and archival. Logs can be exported from the table view in the Pangolin dashboard or via the Pangolin API. When exporting, you can specify date ranges and filters to narrow down the logs you need.

View File

@@ -0,0 +1,61 @@
---
title: "Log Streaming"
description: "Stream Pangolin log events to external collectors and SIEM tools"
---
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta />
Log streaming sends your organizations log events to third-party data collectors such as Datadog, Splunk, or Microsoft Sentinel—often used for SIEM-style monitoring and analysis. You define a destination, a delivery method (for example HTTP, S3, or a vendor-specific integration), and which Pangolin log types to forward: access logs, action logs, connection logs, or request logs. Pangolin pushes events to your external service as they are generated.
<Note>
Log streaming is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note>
## Event Streaming in the dashboard
In the dashboard, this feature appears under Organization → Logs & Analytics → Streaming as Event Streaming. From there you add destinations and configure how events are delivered.
## HTTP destination (example)
The steps below use an HTTP webhook only as an example. Other destination types (object storage, vendor APIs, and so on) follow the same general idea—pick a destination, configure connection details, and choose log types—but the exact fields and options differ by implementation.
### Choose a destination type
Open Add Destination and select how events should be delivered. HTTP webhook is one option; additional destination types may appear over time.
<Frame>
<img src="/images/streaming-add-destination.png" centered />
</Frame>
### Configure the connection
On the Settings tab, set a name, the endpoint URL, and authentication (none, bearer token, basic auth, or a custom header). Requests use JSON by default unless you change it elsewhere.
<Frame>
<img src="/images/streaming-http-settings.png" centered />
</Frame>
### Headers, body, and log types
- **Headers** — Optional custom headers on every request (for example static API keys or a non-default `Content-Type`). By default, `Content-Type: application/json` is sent.
- **Body** — Optionally use a custom JSON body template with variables; you can also choose how batched events are serialized (for example a JSON array versus newline-delimited JSON for tools that expect that format).
<Frame>
<img src="/images/streaming-http-headers.png" centered />
</Frame>
<Frame>
<img src="/images/streaming-http-body.png" centered />
</Frame>
On the Logs tab, choose which log categories are forwarded to this destination. Only log types that are enabled for your organization can be streamed.
<Frame>
<img src="/images/streaming-log-types.png" centered />
</Frame>
## Vendor-specific setups
For Amazon S3, Datadog, Microsoft Sentinel, or other provider-specific implementations and guidance, contact [sales@pangolin.net](mailto:sales@pangolin.net).

View File

@@ -7,8 +7,6 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta /> <PangolinCloudTocCta />
Identity providers allow your users to log into Pangolin and Pangolin resources using their existing accounts from external identity systems like Google, Microsoft Azure, or Okta. Instead of creating separate Pangolin accounts, users can authenticate with their familiar work or personal credentials. Identity providers allow your users to log into Pangolin and Pangolin resources using their existing accounts from external identity systems like Google, Microsoft Azure, or Okta. Instead of creating separate Pangolin accounts, users can authenticate with their familiar work or personal credentials.
Here is an example using Microsoft Azure Entra ID as SSO for Pangolin: Here is an example using Microsoft Azure Entra ID as SSO for Pangolin:
@@ -19,6 +17,10 @@ Here is an example using Microsoft Azure Entra ID as SSO for Pangolin:
- You need to control who can access Pangolin resources through your existing user directory - You need to control who can access Pangolin resources through your existing user directory
- You want users to access Pangolin using their existing credentials without creating new passwords - You want users to access Pangolin using their existing credentials without creating new passwords
<Note>
Assigning more than one role per user is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note>
<Frame> <Frame>
<img src="/images/create-idp.png" /> <img src="/images/create-idp.png" />
</Frame> </Frame>
@@ -29,6 +31,8 @@ Here is an example using Microsoft Azure Entra ID as SSO for Pangolin:
Organization identity providers are configured per organization and only apply to that specific organization. Each org can have its own identity providers, allowing for authentication methods based on the organization's needs. Organization identity providers are configured per organization and only apply to that specific organization. Each org can have its own identity providers, allowing for authentication methods based on the organization's needs.
Organization only identity providers appear only on the organization login page.
<Note> <Note>
Available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) and [Enterprise Edition](/self-host/enterprise-edition). For [Enterprise Edition](/self-host/enterprise-edition), you must set `app.identity_provider_mode: "org"` in the [private config file](/self-host/advanced/private-config-file#param-identity-provider-mode) `privateConfig.yml`. Available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) and [Enterprise Edition](/self-host/enterprise-edition). For [Enterprise Edition](/self-host/enterprise-edition), you must set `app.identity_provider_mode: "org"` in the [private config file](/self-host/advanced/private-config-file#param-identity-provider-mode) `privateConfig.yml`.
</Note> </Note>
@@ -37,6 +41,8 @@ Organization identity providers are configured per organization and only apply t
Global identity providers are managed at the server level and not the individual organization. They can apply to all or some organizations on the server. This means you must define policies per organization to map users to specific organizations and roles within those organizations. Global identity providers are managed at the server level and not the individual organization. They can apply to all or some organizations on the server. This means you must define policies per organization to map users to specific organizations and roles within those organizations.
Global identity providers appear on the global server login page.
<Tip> <Tip>
Global identity providers are the only supported method in Pangolin Community. Global identity providers are the only supported method in Pangolin Community.
</Tip> </Tip>
@@ -55,7 +61,7 @@ This can be used to connect to any external identity provider that supports the
### Google ### Google
<Note> <Note>
Google IdP is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition) with organization identity providers. See above to enable. Google IdP is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note> </Note>
Easily set up Google Workspace authentication for your organization. Users can sign in with their Google accounts and access Pangolin resources using their existing Google credentials. Perfect for organizations already using Google Workspace for email, calendar, and other services. Easily set up Google Workspace authentication for your organization. Users can sign in with their Google accounts and access Pangolin resources using their existing Google credentials. Perfect for organizations already using Google Workspace for email, calendar, and other services.
@@ -63,7 +69,7 @@ Easily set up Google Workspace authentication for your organization. Users can s
### Azure Entra ID ### Azure Entra ID
<Note> <Note>
Azure Entra ID IdP is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition) with organization identity providers. See above to enable. Azure Entra ID IdP is only available in [Pangolin Cloud](https://app.pangolin.net/auth/signup) or self-hosted [Enterprise Edition](/self-host/enterprise-edition).
</Note> </Note>
Integrate with Microsoft's enterprise identity platform to allow users to authenticate using their Azure Active Directory accounts. Ideal for organizations using Microsoft 365 or other Azure services, providing seamless single sign-on across your Microsoft ecosystem. Integrate with Microsoft's enterprise identity platform to allow users to authenticate using their Azure Active Directory accounts. Ideal for organizations using Microsoft 365 or other Azure services, providing seamless single sign-on across your Microsoft ecosystem.
@@ -90,7 +96,7 @@ When using global IDPs, identity providers are created and managed via the Serve
<Step title="Set up Auto Provisioning (Optional)"> <Step title="Set up Auto Provisioning (Optional)">
Select the "Auto Provision Users" checkbox to automatically provision users and assign roles in Pangolin when they log in using an external identity provider. See [Auto Provision](/manage/identity-providers/auto-provisioning) for more information. Select the "Auto Provision Users" checkbox to automatically provision users and assign roles in Pangolin when they log in using an external identity provider. See [Auto Provision](/manage/identity-providers/auto-provisioning) for more information.
If this is disabled, you will need to pre-provision a user in Pangolin before they can log in using an external identity provider. If this is disabled, you will need to pre-provision a user in Pangolin before they can log in using an external identity provider. Pre-provision means creating a user in Pangolin with a role and organization before they log in using an external identity provider.
</Step> </Step>
<Step title="Configure Settings"> <Step title="Configure Settings">

View File

@@ -7,9 +7,7 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta /> <PangolinCloudTocCta />
Auto provisioning is a feature that allows you to automatically create and manage user accounts in Pangolin when they log in using an external identity provider rather than pre-provisioning (manually creating) a user with a role and organization. This is useful for organizations that want to streamline the onboarding process for new users and ensure that their user accounts are always up-to-date.
Auto provisioning is a feature that allows you to automatically create and manage user accounts in Pangolin when they log in using an external identity provider rather than pre-provisioning a user with a role. This is useful for organizations that want to streamline the onboarding process for new users and ensure that their user accounts are always up-to-date.
You will be able to programmatically decide the roles and organizations for new users based on the information provided by the identity provider. You will be able to programmatically decide the roles and organizations for new users based on the information provided by the identity provider.
@@ -18,7 +16,7 @@ You will be able to programmatically decide the roles and organizations for new
Toggle the "Auth Provision Users" switch when creating or editing an identity provider. Toggle the "Auth Provision Users" switch when creating or editing an identity provider.
<Frame> <Frame>
<img src="/images/auto-provision.png" /> <img src="/images/mapping-builder.png" />
</Frame> </Frame>
## What if Auto Provisioning is Disabled? ## What if Auto Provisioning is Disabled?
@@ -29,34 +27,58 @@ If auto provision is disabled, organization admins will need to manually create
<img src="/images/create-idp-user.png" /> <img src="/images/create-idp-user.png" />
</Frame> </Frame>
## Configuration Options ## Role mappings
## Selecting Roles When you configure role mappings in auto provisioning settings, you use one of three approaches: fixed roles, mapping builder, or raw expression. These options are available for global identity providers and for organization-only identity providers.
You can choose between "Select a Role" and "Expression". Selecting a role will apply that role to all auto provisioned users. The expression will be evaluated against the token response from the IdP on each login (see examples below). You can always manually change the role of the user after they're provisioned. <Note>
Auto provisioning does not create roles in Pangolin. Every role you assign whether you pick fixed roles, map IdP values in the builder, or return names from a raw expression must already exist in the target organization, and the name you use must match that roles name exactly (character-for-character). This one-to-one name match applies to all three mapping types. If a name does not match an existing role, the user will not receive that role (and may not be added to the organization, depending on your setup).
</Note>
### Expressions ### Fixed roles
Use JMESPath to map attributes from the identity provider to roles in Pangolin. See [JMESPath](https://jmespath.org/) for more information on how to use JMESPath. Fixed roles is the simplest option. Every user who signs in through the identity provider receives the same set of roles. The roles you select must already exist in Pangolin, and you must choose them by their exact names in that organization. Use this when you do not need dynamic mapping and a single role assignment for everyone is enough. You can still change roles on individual users after they have been auto-provisioned. This is the easiest way to get started.
The expression will be matched against each organization. Meaning: <Frame>
<img src="/images/fixed-roles.png" />
</Frame>
- The result of the expression must return the exact string of the role name as it is defined in the organization. ### Mapping builder
- If no matching role is found, the user will not be added to the organization.
### Example: Role Selection The mapping builder lets you map roles from your identity provider to Pangolin roles without writing expressions. For example, a user might sign in from Azure and belong to several groups there. Azure identifies those groups with its own internal ID strings. With the mapping builder, you translate those IDs to Pangolin role names in the UI.
First, choose the claim in the OIDC token where roles or groups are provided such as `groups`. Then define a one-to-one mapping for each role: on one side, the role or group ID from the identity provider; on the other, the Pangolin role name that already exists in the organization. The Pangolin side must match that roles name exactly (same spelling, spacing, and casing).
<Frame>
<img src="/images/mapping-builder.png" />
</Frame>
### Raw expression
Raw expression is the most flexible option and the most complex. It matches how many users previously defined mappings in Pangolin. You provide a [JMESPath](https://jmespath.org/) expression that must evaluate to a string or array of strings. Each value must be the exact name of a role that already exists in the organization. If you can express the logic in JMESPath, it will work (for example, combining conditions on name, email, and other claims).
The expression is evaluated against the token from the identity provider on each login. Results are matched per organization:
- Each returned string must be the exact name of a role that already exists in that organization (same rules as fixed roles and the mapping builder).
- If no matching role is found for the resolved names, the user is not added to the organization.
<Frame>
<img src="/images/raw-expression.png" />
</Frame>
#### Raw Expression Example: JMESPath role selection
**Expression:** **Expression:**
<Note> <Note>
When entering in a string, JMESPatch requires it be surrounded by `'` (single quotes). See below: When entering a string literal in JMESPath, surround it with `'` (single quotes), as in the example below.
</Note> </Note>
``` ```
contains(groups, 'admin') && 'Admin' || 'Member' contains(groups, 'admin') && 'Admin' || 'Member'
``` ```
**Identity Provider Data:** **Identity provider token (excerpt):**
```json ```json
{ {
... ...
@@ -75,11 +97,11 @@ contains(groups, 'admin') && 'Admin' || 'Member'
} }
``` ```
This example will return the string "Admin". If the user is not a member of the "admin" group, it will return "Member". This expression returns `"Admin"` when the user is in the `admin` group, and `"Member"` otherwise.
## Global Identity Providers ## Global Identity Providers
After you create an IdP, on the edit page, you can manage organization policies via the "Organization Policies" tab. You can set default (fallback) policies, or define them on a per org basis. After you create a global IdP, on the edit page you can manage organization policies from the Auto Provisioning tab. You can set a default (fallback) role mapping and organization rules, and you can add per-organization mappings that override or extend behavior for specific organizations. The fixed roles, mapping builder, and raw expression options apply both here (default and per org) and in organization-only identity providers.
### How Organization Policies Are Evaluated ### How Organization Policies Are Evaluated
@@ -95,17 +117,17 @@ It is helpful to think of the auto provisioning process as follows:
</Step> </Step>
<Step title="Organization Evaluation"> <Step title="Organization Evaluation">
Pangolin will loop through each organization and evaluate the JMESPath expression for the organization. If the expression does not return true or the same ID as the current organization, the user will not be added to the organization. Pangolin loops through each organization and evaluates the JMESPath expression for organization membership. If the expression does not return true or the same ID as the current organization, the user will not be added to the organization.
</Step> </Step>
<Step title="Role Assignment"> <Step title="Role Assignment">
For each organization, Pangolin will evaluate the JMESPath expression for the role. If no role is found with the exact name in that organization, the user will not be added to the organization. For each organization, Pangolin applies the configured role mapping (fixed roles, mapping builder, or raw expression). Resolved names must match existing Pangolin roles exactly; otherwise those assignments do not apply, and the user may not be added to the organization.
</Step> </Step>
</Steps> </Steps>
### Selecting Roles ### Role mappings for global IdPs
See above examples. Use a default policy, per-organization policies, or both. Role mapping options (fixed roles, mapping builder, raw expression) work the same way as described in [Role mappings](#role-mappings).
### Selecting Organizations ### Selecting Organizations
@@ -149,7 +171,7 @@ This example will return true since the user is a member of the "home-lab" group
### Example 2: Fixed Organization ### Example 2: Fixed Organization
<Note> <Note>
When entering in a string, JMESPatch requires it be surrounded by `'` (single quotes). See below: When entering a string literal in JMESPath, surround it with `'` (single quotes). See below:
</Note> </Note>
**Expression:** **Expression:**

View File

@@ -15,7 +15,7 @@ Pangolin is in heavy development. The REST API routes and behavior may include b
The API is REST-based and supports many operations available through the web interface. Authentication uses Bearer tokens, and you can create multiple API keys with specific permissions for different use cases. The API is REST-based and supports many operations available through the web interface. Authentication uses Bearer tokens, and you can create multiple API keys with specific permissions for different use cases.
For Pangolin Community Edition, the integration API must be enabled. Check out [the documentation](/self-host/advanced/integration-api) for how to enable the integration API. For self-hosted editions, the integration API must be enabled. Check out [the documentation](/self-host/advanced/integration-api) for how to enable the integration API.
## Authentication ## Authentication

View File

@@ -33,6 +33,30 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
**Example**: `https://pangolin.example.com` **Example**: `https://pangolin.example.com`
</ResponseField> </ResponseField>
<ResponseField name="name" type="string">
Site name to use when provisioning with a provisioning key. Supports `{{env.VARIABLE_NAME}}` templating from the process environment. If omitted, Pangolin assigns a random animal-based name (changeable in the dashboard).
**Example**: `my-edge-site` or `'{{env.SERIAL_NUMBER}}-edge'`
</ResponseField>
<ResponseField name="provisioning-blueprint-file" type="string">
Path to a blueprint YAML file applied **once** at provisioning (imperative bootstrap). Unlike `--blueprint-file`, Newt does not keep reapplying it, so resources you edit in the dashboard are not overwritten on later runs. See [Site provisioning keys](/manage/sites/site-provisioning).
**Example**: `/path/to/bootstrap.yaml`
</ResponseField>
<ResponseField name="provisioning-key" type="string">
Provisioning key from Pangolin (alternative to a `provisioningKey` field inside the config file). Newt exchanges it once for site credentials, then persists `id` and `secret` to the config file and ignores the key on later runs. See [Site provisioning keys](/manage/sites/site-provisioning).
**Example**: `spk_...`
</ResponseField>
<ResponseField name="config-file" type="string">
Path to a JSON file where Newt reads and persists settings (`endpoint`, `id`, `secret`, optional `provisioningKey`, and other options). When you use [site provisioning](/manage/sites/site-provisioning), Newt writes `id` and `secret` into this file after a successful exchange.
**Example**: `/var/newt.json`
</ResponseField>
<ResponseField name="port" type="integer"> <ResponseField name="port" type="integer">
Port for the peers to connect to Newt on. This can be used to keep a static port open in firewalls instead of default random ports. Port for the peers to connect to Newt on. This can be used to keep a static port open in firewalls instead of default random ports.
@@ -96,7 +120,7 @@ import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
</ResponseField> </ResponseField>
<ResponseField name="blueprint-file" type="string"> <ResponseField name="blueprint-file" type="string">
Path to blueprint file to define Pangolin resources and configurations. Path to a blueprint file that defines Pangolin resources and settings. This mode is declarative: Newt keeps applying the file, and it remains the source of truth (dashboard changes can be overwritten on the next apply). For a one-time bootstrap blueprint with provisioning keys, use `--provisioning-blueprint-file` instead.
**Example**: `/path/to/blueprint.yaml` **Example**: `/path/to/blueprint.yaml`
</ResponseField> </ResponseField>
@@ -205,6 +229,24 @@ When both environment variables and CLI arguments are provided, CLI arguments ta
Newt secret for authentication (equivalent to `--secret`) Newt secret for authentication (equivalent to `--secret`)
</ResponseField> </ResponseField>
<ResponseField name="NEWT_NAME" type="string">
Site name when provisioning with a provisioning key (equivalent to `--name`). Supports `{{env.VARIABLE_NAME}}` templating from the environment.
</ResponseField>
<ResponseField name="NEWT_PROVISIONING_KEY" type="string">
Provisioning key string (equivalent to `--provisioning-key`). See [Site provisioning keys](/manage/sites/site-provisioning).
</ResponseField>
<ResponseField name="PROVISIONING_BLUEPRINT_FILE" type="string">
Path to a bootstrap-only blueprint file (equivalent to `--provisioning-blueprint-file`). See [Site provisioning keys](/manage/sites/site-provisioning).
</ResponseField>
<ResponseField name="CONFIG_FILE" type="string">
Path to the JSON config file where Newt loads and persists settings (equivalent to `--config-file`). Use this instead of the default location under the home folder when you want a fixed path (typical for containers and provisioning).
**Example**: `/var/newt.json`
</ResponseField>
<ResponseField name="PORT" type="integer"> <ResponseField name="PORT" type="integer">
Port for the peers to connect to Newt on (equivalent to `--port`) Port for the peers to connect to Newt on (equivalent to `--port`)
</ResponseField> </ResponseField>
@@ -221,10 +263,6 @@ When both environment variables and CLI arguments are provided, CLI arguments ta
**Default**: `9.9.9.9` **Default**: `9.9.9.9`
</ResponseField> </ResponseField>
<ResponseField name="CONFIG_FILE" type="string">
Load the config JSON from this file instead of in the home folder.
</ResponseField>
<ResponseField name="BLUEPRINT_FILE" type="string"> <ResponseField name="BLUEPRINT_FILE" type="string">
Path to blueprint file to define Pangolin resources and configurations (equivalent to `--blueprint-file`). Path to blueprint file to define Pangolin resources and configurations (equivalent to `--blueprint-file`).
</ResponseField> </ResponseField>
@@ -335,7 +373,7 @@ When both environment variables and CLI arguments are provided, CLI arguments ta
## Loading secrets from files ## Loading secrets from files
You can use `CONFIG_FILE` to define a location of a config file to store the credentials between runs. You can use `--config-file` or the `CONFIG_FILE` environment variable to set the path of the config file where Newt stores credentials and other settings between runs.
``` ```
$ cat ~/.config/newt-client/config.json $ cat ~/.config/newt-client/config.json

View File

@@ -39,6 +39,10 @@ Example: `https://app.pangolin.net` or `https://pangolin.my-server.com`
The endpoint is how the site knows which server to connect to. This is the fully qualified hostname of the Pangolin server (the URL you use to access the dashboard). For Pangolin cloud, the endpoint is `https://app.pangolin.net`. The site uses this endpoint to establish a websocket connection and receive control messages from the server. The endpoint is how the site knows which server to connect to. This is the fully qualified hostname of the Pangolin server (the URL you use to access the dashboard). For Pangolin cloud, the endpoint is `https://app.pangolin.net`. The site uses this endpoint to establish a websocket connection and receive control messages from the server.
## Provisioning keys at scale
If you deploy many sites (for example IoT devices, golden images, or scripted installs), managing a unique ID and secret per host before first boot can be awkward. **[Site provisioning keys](/manage/sites/site-provisioning)** let each Newt instance exchange a single long-lived token for its own ID and secret on first connect, so you do not have to pre-create and distribute credentials for every machine individually.
## Rotating and Regenerating Credentials ## Rotating and Regenerating Credentials
<Note> <Note>

View File

@@ -0,0 +1,147 @@
---
title: "Site Provisioning Keys"
description: "Use long-lived provisioning tokens to bootstrap Pangolin sites at scale without pre-creating ID-secret pairs for every host"
---
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
<PangolinCloudTocCta />
## Why provisioning keys exist
As described in [Site credentials](/manage/sites/credentials), each Pangolin site authenticates with an ID and secret (random strings you get when a site is first created) plus an endpoint pointing at your Pangolin server. That model is simple for a handful of sites, but it breaks down quickly when you must issue and distribute unique credentials for many machines.
**IoT and edge fleets** are the classic case: hundreds or thousands of devices each need their own site identity. Before provisioning keys, you typically scripted against the API to mint an ID-secret pair per device, then pushed those secrets through your device-management or OTA layer so each unit could connect. That works, but it multiplies secret-handling paths and makes rotation and auditing harder.
The same friction shows up in other scenarios:
- **Golden images and OS images**: You want one trusted image (or cloud-init payload) shared across a class of machines, not a unique secret baked into every build artifact. A single provisioning key in the image, or injected at first boot, lets each instance obtain its own credentials the first time Newt starts.
- **Scripted and CI-driven installs**: Ansible, Terraform, cloud-init, or installer scripts can drop the same provisioning key everywhere (or fetch it from a vault once) instead of coordinating “create site N, copy credentials to host N” for every node.
- **Developer and lab environments**: Spin up VMs or containers repeatedly without clicking through the dashboard for each site; tear them down and provision again with bounded keys (usage limits and expiry; see below).
- **MSP and multi-customer rollouts**: Standardize your onboarding bundle (endpoint + provisioning key + blueprint) while still giving each customer site isolated credentials after exchange.
With provisioning keys, you create one long-lived token in Pangolin, embed it in your image or distribute it with a single script, and each Newt instance exchanges that token for its own [site ID and secret](/manage/sites/credentials) on first connect.
## How provisioning works
You can supply the provisioning key in either of two ways:
**1. Config file**
Put the key in a JSON config file in a `provisioningKey` field (the value is the key string from Pangolin, often shown with an `spk` prefix) and point Newt at that file:
```bash
newt --config-file /var/newt.json
```
```json
{
"endpoint": "https://app.pangolin.net",
"provisioningKey": "spk_..."
}
```
**2. Command line**
Pass the key with **`--provisioning-key`** instead of storing it in the file. You still use **`--config-file`** so Newt has a path to write and persist settings; see [Configure Sites](/manage/sites/configure-site) for the rest):
```bash
newt --config-file /var/newt.json --endpoint https://app.pangolin.net --provisioning-key 'spk_...'
```
**After the site is provisioned**, Newt writes the new `id` and `secret` into that config file. On later runs, Newt uses those credentials and ignores the provisioning key (CLI flag or file field), because valid ID and secret are already present. If you used `provisioningKey` in JSON, that entry is removed when the file is updated, so the long-lived token is not left on disk.
From there Newt authenticates over the websocket, optionally applies a blueprint if you passed one, then brings the tunnel online. The high-level sequence is summarized below.
<Frame>
<img src="/images/site-provisioning-flow.png" alt="Flow: provision with pre-shared key, exchange for ID and secret, apply YAML, pending approval, admin approves" centered />
</Frame>
<Note>
[Pangolin Blueprints](/manage/blueprints) are not required when using provisioning keys. You can provision with the key only and manage resources in the dashboard afterward. Blueprints are optional but convenient when you want resources and settings created automatically from YAML as soon as the site connects.
</Note>
### `--provisioning-blueprint-file` vs `--blueprint-file`
When you run Newt with a provisioning key, you can attach a blueprint YAML file in two different ways:
| Flag | Behavior |
|------|------------|
| **`--blueprint-file`** | **Declarative.** The blueprint is the ongoing source of truth. Newt keeps applying it, and changes you make in the dashboard can be overwritten the next time the blueprint is applied. |
| **`--provisioning-blueprint-file`** | **Imperative (bootstrap only).** The file is applied once, at provisioning time. After that, Newt does not keep reapplying it. You can edit resources in the dashboard and those edits will not be overridden by that YAML on later runs. |
Use **`--provisioning-blueprint-file`** when you want automation to create an initial set of resources (for example from a fleet template) but you intend to manage or tune them in the UI afterward. Use `--blueprint-file` when you want the file to remain authoritative, the same as on a normal site without provisioning keys.
```bash
newt --config-file /var/newt.json --provisioning-blueprint-file /path/to/bootstrap.yaml
```
If you do use blueprints together with provisioning keys, you get a repeatable pattern for large fleets: one key (with appropriate limits), a blueprint file, and optional environment-specific values so each host gets distinct resource names or domains without maintaining separate YAML per device. Pick the flag above based on whether that YAML should keep governing the site or only run at first connect.
### Blueprint example and environment templating
Blueprints can reference environment variables using `{{env.VARIABLE_NAME}}` syntax. At apply time, those placeholders are filled from the process environment running Newt (for example a serial number, hostname, or customer slug exported before start). That lets one blueprint drive many sites: each host sets `SERIAL_NUMBER`, `CUSTOMER_ID`, or similar, and the resolved YAML defines unique site names, domains, or role assignments.
Below, `{{env.SERIAL_NUMBER}}` ties the private resources site field and the public resources hostname to the same per-device identity:
```yaml
private-resources:
ssh-resource:
name: SSH Server
mode: host
destination: localhost
site: "{{env.SERIAL_NUMBER}}-site"
tcp-ports: "22,3389"
udp-ports: "*"
disable-icmp: false
roles:
- Customer1
- DevOps
users:
- user@example.com
public-resources:
secure-resource:
name: Web Resource
protocol: http
full-domain: "{{env.SERIAL_NUMBER}}.example.com"
auth:
sso-enabled: true
sso-roles:
- Member
- Admin
sso-users:
- user@example.com
```
Use whatever variables match your deployment (for example asset tags or cloud instance IDs). Ensure those variables are set in the environment where Newt runs before it applies the blueprint. For more on blueprint structure and applying YAML from Newt, see the [Blueprints](/manage/blueprints) documentation.
### Optional site name (`--name`)
You can pass `--name` to Newt when provisioning so the new site gets a specific name. The value supports the same `{{env.VARIABLE_NAME}}` templating as blueprints: placeholders are expanded from the environment where Newt runs before the site is created (for example per-device serials or hostnames).
```bash
newt --config-file /var/newt.json --name '{{env.SERIAL_NUMBER}}-edge'
```
If you omit `--name`, Pangolin assigns a random animal-based name, which you can change later in the dashboard. Explicit or templated names help when your automation or blueprint references the site by a stable label.
## Limits, expiry, and security model
Provisioning keys support a maximum usage count and an expiration time. For example, to roll out 250 devices over a week, set max usage to `250` and expiry to one week. When either limit is reached, the key becomes inactive and the server rejects further exchange attempts.
<Tip>
Provisioning keys are not API keys. They cannot authorize arbitrary Pangolin API calls; they exist only to bootstrap sites through the provisioning exchange.
</Tip>
## Creating a key and pending approval
In the Pangolin admin UI, create a provisioning key from the provisioning settings (including usage and expiration as needed). The flow is illustrated below.
<Frame>
<img src="/images/create-provisioning-key.png" alt="Create a provisioning key in the Pangolin dashboard" centered />
</Frame>
Optionally, sites provisioned with a key can be placed into a pending state. They appear under the Pending Sites tab on the provisioning page so administrators can review new sites and approve them before they are treated as fully active in production.
<Frame>
<img src="/images/pending-sites.png" alt="Pending sites listed for admin review" centered />
</Frame>