
Pangolin 1.17 brings a wave of quality-of-life improvements that strengthen existing functionality around roles, identity providers, site provisioning, logging, and more. Let's dig in!
Pangolin has always let you define as many custom roles as you'd like, but believe it or not, for over a year Pangolin only supported one role per user - a strict one-to-one relationship. This made it surprisingly difficult to map your team's real-world structure to access controls in Pangolin. What if a user spans the dev team, the DevOps team, and also needs access to the support team's resources?
Now, each user can be a member of one or many roles - there's no limit. This brings full RBAC to Pangolin. Create a role for developers, DevOps, and support, then place your users accordingly. At the resource level, simply define which roles have access, and a user will be able to reach any resource that falls within the union of all their assigned roles.

With the addition of multiple roles, identity provider role mapping had to be updated as well. Role mapping here refers to the configuration admins set up when enabling auto-provisioning, so that users synced from the identity provider at login are automatically placed into the appropriate Pangolin roles based on data returned from the provider.
There are now three options when configuring role mappings in auto-provisioning settings: fixed roles, the mapping builder, and raw expression.
Fixed roles is the simplest option. It places all users who log in through the identity provider into the same set of roles. Use this when you don't need dynamic mapping and it's fine to apply a blanket role assignment across everyone. You can always manually adjust roles on individual users after they've been auto-provisioned. This is the easiest, lowest-friction way to get started.

The mapping builder is a new addition that makes it easy to dynamically map roles from your identity provider to Pangolin roles. Say a user logs in from Azure and belongs to several groups there. Azure identifies those groups with its own internal ID strings. The mapping builder is how you translate those to Pangolin roles without writing any expressions. First, pick the claim in the OIDC token where roles are passed - often groups. Then define a 1:1 mapping for each role: on the left, the role ID from the identity provider; on the right, the equivalent role name in Pangolin.

The raw expression option is the most flexible - and the most complex. This is how most users previously defined mappings in Pangolin. You provide a raw JMESPath expression that must return a string or array of strings representing the roles the user should be placed into. This enables nearly infinite possibilities. If you can write a logical expression for it, it will work. You could do something like: if the user's first name starts with "B," their email ends in @domain.com, and their last name is exactly six characters long, add them to the admin group. Not sure why you'd ever need that, but you get the idea.

Read more about identity providers and auto provisioning in the docs.
We've added Google and Azure as built-in templates for the global identity provider type. For those unfamiliar, Pangolin supports two types of identity providers: global and organization-level. Organization-level providers are scoped to a single organization and are useful when a tenant has their own identity provider that shouldn't appear on the main login page. Global providers are server-level and show up on the main login page for all users.
Google and Azure templates have been available for organization-level providers for a while - we've now brought them to the global level as well, making setup easier for those who need it there.
As you may already know, a Pangolin site authenticates using two components: an ID and a secret - both randomly generated strings you receive when creating a site for the first time. This works fine at small scale, but gets unwieldy fast.
This is especially common in IoT scenarios, where sites are deployed to fleets of edge devices and each device needs its own credentials. Previously, you'd have to script against the API to generate an ID-secret pair per site, then find a way to push those credentials to each device individually. With provisioning keys, you can generate a single long-lived token, embed it into your device image before deployment, or push it to every device with one script.

When a site (Newt) starts up with a provisioning key, it reaches out to Pangolin, exchanges the key for an ID-secret pair, replaces the provisioning key with the new credentials, and immediately comes online. Combine this with Pangolin Blueprints for declarative configuration, and you have a straightforward way to provision large fleets of Pangolin sites for remote connectivity.
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.comProvisioning keys also support a maximum usage count and an expiration time. Say you need to provision 250 devices over the course of a week - set the max usage to 250 and the expiration to one week. Once either threshold is met, the key becomes inactive and the Pangolin server will reject it. It's worth noting that provisioning keys are not API keys - they cannot be used for any other actions in Pangolin and exist solely for this one purpose.
Optionally, sites provisioned via a provisioning key can be placed into a pending state. These will appear under the Pending Sites tab on the provisioning page, giving admins a single place to review newly provisioned sites and manually approve them before they move into production.

Read more about site provisioning keys in the docs.
Pangolin now logs raw TCP and UDP sessions between the Pangolin client (CLI, Mac, Windows, iOS, Android, etc.) and private resources. This applies to zero-trust private resources accessed over the Pangolin network - not public, browser-based resources, which have had access logs for some time.
Use connection logs as an audit trail to understand which users are accessing which private resources, when, and for how long.
Read more about connection logs in the docs.
Pangolin now supports streaming log events to third-party data collectors like Datadog, Splunk, or Microsoft Sentinel - commonly referred to as SIEM integration. You define a destination, a push method (HTTP, S3, etc.), and which Pangolin log types to forward: access logs, action logs, connection logs, or request logs. Pangolin will automatically push events to your external service as they're generated.


Read more about log streaming in the docs.
We're expecting to pick up the pace of releases compared to the stretches between 1.15, 1.16, and 1.17. There's a lot in development and a lot on the horizon - we can't wait to get it all out into the open.
If you love Pangolin - or even just like it - and haven't starred us on GitHub yet, please take a moment to do so. It genuinely helps keep us motivated.
Give us a star: https://github.com/fosrl/pangolin
Stay tuned!