By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Description
Blueprints can now configure the "Auto Login with External IDP" feature via the auto-login-idp field in the auth section.
Changes
Schema: Added auto-login-idp optional integer field to AuthSchema in blueprint types
Processing: Sets skipToIdpId directly from the blueprint field in proxyResources.ts
Uses IDP ID directly without lookup to avoid issues with duplicate IDP names
Sets skipToIdpId on resource creation/update when field is present
Example: Updated blueprint.yaml with usage example
Usage
proxy-resources:my-app:name:My Applicationprotocol:httpfull-domain:app.example.comauth:sso-enabled:trueauto-login-idp:1# IDP ID (integer), shown in frontendsso-roles:- Membertargets:[...]
IDPs are referenced by ID (integer) to avoid duplicate name issues. The IDP ID is displayed in the frontend for users to reference.
I'd like to be able to enable the Auto Login with External IDP setting either via:
an org level setting making it default behavior
setting a relevant auth config label blueprint on the container
Motivation
I don't want to set the "Auto Login with External IDP" setting on every resource in the UI when I already use blueprints to convey similar config state to Pangolin. And I don't want to write and manage a separate script just to ensure new resources are configured with the setting.
Proposed Solution
I reviewed the NextJS frontend to understand how it determines the state of the UI element in the resource auth configuration dashboard. I see here it posts to the resource to essentially patch it with skipToIdpId: selectedIdpId. This exposes it in the resource schema like this:
$xhhttps://api.pangolin.net/v1/resource/123456789 -A bearer -a $PANGOLIN_API | jq '.data'
{"resourceId":123456789,"resourceGuid":"foobar","orgId":"org_foobarbaz","niceId":"foobar","name":"FooBar",..."setHostHeader":null,"enableProxy":true,"skipToIdpId":123456,"headers":null}
Clearly the resource model already supports it and there's an endpoint to set and update the key. So it seems this setting just needs exposed and wired up in the relevant blueprint model. I found that here in server/lib/blueprints/types.ts:
export const AuthSchema = z.object({
// pincode has to have 6 digits
pincode: z.number().min(100000).max(999999).optional(),
password: z.string().min(1).optional(),
"basic-auth": z.object({
user: z.string().min(1),
password: z.string().min(1)
}).optional(),
"sso-enabled": z.boolean().optional().default(false),
+ "sso-redirect-idp": z.number().int().positive().optional().nullable(),
"sso-roles": z
.array(z.string())
.optional()
.default([])
.refine((roles) => !roles.includes("Admin"), {
message: "Admin role cannot be included in sso-roles"
}),
"sso-users": z.array(z.string().email()).optional().default([]),
"whitelist-users": z.array(z.string().email()).optional().default([]),
});
Then I think it needs wired to the resource creation in server/lib/blueprints/proxyResources.ts here and similarly during the resource update here.
I could easily script setting the configuration via the API. It's just another thing to manage and remember, when I prefer to consolidate the resource config within the Docker labels. Keeping it in sync becomes another thing to deal with also.
It's worth considering if it should be an org or other higher level setting, or such a higher setting that can override at the resource level.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/fosrl/pangolin/pull/1896
**Author:** [@Copilot](https://github.com/apps/copilot-swe-agent)
**Created:** 11/19/2025
**Status:** ✅ Merged
**Merged:** 11/19/2025
**Merged by:** [@oschwartz10612](https://github.com/oschwartz10612)
**Base:** `main` ← **Head:** `copilot/configure-auto-login-idp-blueprints`
---
### 📝 Commits (3)
- [`8f9b665`](https://github.com/fosrl/pangolin/commit/8f9b665bef763c37db227ec785cc694a7fc60178) Initial plan
- [`01b5158`](https://github.com/fosrl/pangolin/commit/01b5158b73105f4792c2aaa0c96f1a723bfc51fe) Add auto-login-idp support to blueprints
- [`6da531e`](https://github.com/fosrl/pangolin/commit/6da531e99b459b2a244d7f95b20622707e98ea48) Use IDP ID instead of IDP name for auto-login-idp
### 📊 Changes
**3 files changed** (+4 additions, -0 deletions)
<details>
<summary>View changed files</summary>
📝 `blueprint.yaml` (+1 -0)
📝 `server/lib/blueprints/proxyResources.ts` (+2 -0)
📝 `server/lib/blueprints/types.ts` (+1 -0)
</details>
### 📄 Description
## Community Contribution License Agreement
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
## Description
Blueprints can now configure the "Auto Login with External IDP" feature via the `auto-login-idp` field in the auth section.
### Changes
- **Schema**: Added `auto-login-idp` optional integer field to `AuthSchema` in blueprint types
- **Processing**: Sets `skipToIdpId` directly from the blueprint field in `proxyResources.ts`
- Uses IDP ID directly without lookup to avoid issues with duplicate IDP names
- Sets `skipToIdpId` on resource creation/update when field is present
- **Example**: Updated `blueprint.yaml` with usage example
### Usage
```yaml
proxy-resources:
my-app:
name: My Application
protocol: http
full-domain: app.example.com
auth:
sso-enabled: true
auto-login-idp: 1 # IDP ID (integer), shown in frontend
sso-roles:
- Member
targets: [...]
```
IDPs are referenced by ID (integer) to avoid duplicate name issues. The IDP ID is displayed in the frontend for users to reference.
- Fixes fosrl/pangolin#1895
## How to test?
1. Create a blueprint YAML with the `auto-login-idp` field set to an IDP ID (integer)
2. Apply the blueprint via the API
3. Verify that the resource's `skipToIdpId` field is set correctly in the database
4. Access the resource and confirm automatic redirect to the specified IDP occurs
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>Configure 'Auto Login with External IDP' via blueprints</issue_title>
<issue_description>
### Discussed in https://github.com/orgs/fosrl/discussions/1761
<div type='discussions-op-text'>
<sup>Originally posted by **dephekt** October 27, 2025</sup>
### Summary
I'd like to be able to enable the Auto Login with External IDP setting either via:
- an org level setting making it default behavior
- setting a relevant auth config label blueprint on the container
### Motivation
I don't want to set the "Auto Login with External IDP" setting on every resource in the UI when I already use blueprints to convey similar config state to Pangolin. And I don't want to write and manage a separate script just to ensure new resources are configured with the setting.
### Proposed Solution
I reviewed the NextJS frontend to understand how it determines the state of the UI element in the resource auth configuration dashboard. I see [here](https://github.com/fosrl/pangolin/blob/cabf3e96952cfcdc40452f1a4e39800129025801/src/app/%5BorgId%5D/settings/resources/%5BniceId%5D/authentication/page.tsx#L340-L344) it posts to the resource to essentially patch it with `skipToIdpId: selectedIdpId`. This exposes it in the resource schema like this:
```json
$ xh https://api.pangolin.net/v1/resource/123456789 -A bearer -a $PANGOLIN_API | jq '.data'
{
"resourceId": 123456789,
"resourceGuid": "foobar",
"orgId": "org_foobarbaz",
"niceId": "foobar",
"name": "FooBar",
...
"setHostHeader": null,
"enableProxy": true,
"skipToIdpId": 123456,
"headers": null
}
```
Clearly the resource model already supports it and there's an endpoint to set and update the key. So it seems this setting just needs exposed and wired up in the relevant blueprint model. I found that [here](https://github.com/fosrl/pangolin/blob/cabf3e96952cfcdc40452f1a4e39800129025801/server/lib/blueprints/types.ts#L41-L59) in server/lib/blueprints/types.ts:
```diff
export const AuthSchema = z.object({
// pincode has to have 6 digits
pincode: z.number().min(100000).max(999999).optional(),
password: z.string().min(1).optional(),
"basic-auth": z.object({
user: z.string().min(1),
password: z.string().min(1)
}).optional(),
"sso-enabled": z.boolean().optional().default(false),
+ "sso-redirect-idp": z.number().int().positive().optional().nullable(),
"sso-roles": z
.array(z.string())
.optional()
.default([])
.refine((roles) => !roles.includes("Admin"), {
message: "Admin role cannot be included in sso-roles"
}),
"sso-users": z.array(z.string().email()).optional().default([]),
"whitelist-users": z.array(z.string().email()).optional().default([]),
});
```
Then I think it needs wired to the resource creation in server/lib/blueprints/proxyResources.ts [here](https://github.com/fosrl/pangolin/blob/cabf3e96952cfcdc40452f1a4e39800129025801/server/lib/blueprints/proxyResources.ts#L581-L602) and similarly during the resource update [here](https://github.com/fosrl/pangolin/blob/cabf3e96952cfcdc40452f1a4e39800129025801/server/lib/blueprints/proxyResources.ts#L213).
```diff
const [newResource] = await trx
.insert(resources)
.values({
orgId,
niceId: resourceNiceId,
name: resourceData.name || "Unnamed Resource",
protocol: protocol || "tcp",
http: http,
proxyPort: http ? null : resourceData["proxy-port"],
fullDomain: http ? resourceData["full-domain"] : null,
subdomain: domain ? domain.subdomain : null,
domainId: domain ? domain.domainId : null,
enabled: resourceEnabled,
sso: resourceData.auth?.["sso-enabled"] || false,
+ skipToIdpId: resourceData.auth?.["sso-redirect-idp"] || null,
setHostHeader: resourceData["host-header"] || null,
tlsServerName: resourceData["tls-server-name"] || null,
ssl: resourceSsl,
headers: headers || null,
applyRules:
resourceData.rules && resourceData.rules.length > 0
})
```
### Alternatives Considered
I could easily script setting the configuration via the API. It's just another thing to manage and remember, when I prefer to consolidate the resource config within the Docker labels. Keeping it in sync becomes another thing to deal with also.
It's worth considering if it should be an org or other higher level setting, or such a higher setting that can override at the resource level.
### Additional Context
_No response_</div></issue_description>
## Comments on th...
</details>
- Fixes fosrl/pangolin#1895
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for you](https://github.com/fosrl/pangolin/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/fosrl/pangolin/pull/1896
Author: @Copilot
Created: 11/19/2025
Status: ✅ Merged
Merged: 11/19/2025
Merged by: @oschwartz10612
Base:
main← Head:copilot/configure-auto-login-idp-blueprints📝 Commits (3)
8f9b665Initial plan01b5158Add auto-login-idp support to blueprints6da531eUse IDP ID instead of IDP name for auto-login-idp📊 Changes
3 files changed (+4 additions, -0 deletions)
View changed files
📝
blueprint.yaml(+1 -0)📝
server/lib/blueprints/proxyResources.ts(+2 -0)📝
server/lib/blueprints/types.ts(+1 -0)📄 Description
Community Contribution License Agreement
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Description
Blueprints can now configure the "Auto Login with External IDP" feature via the
auto-login-idpfield in the auth section.Changes
auto-login-idpoptional integer field toAuthSchemain blueprint typesskipToIdpIddirectly from the blueprint field inproxyResources.tsskipToIdpIdon resource creation/update when field is presentblueprint.yamlwith usage exampleUsage
IDPs are referenced by ID (integer) to avoid duplicate name issues. The IDP ID is displayed in the frontend for users to reference.
How to test?
auto-login-idpfield set to an IDP ID (integer)skipToIdpIdfield is set correctly in the databaseOriginal prompt
This section details on the original issue you should resolve
<issue_title>Configure 'Auto Login with External IDP' via blueprints</issue_title>
<issue_description>
Discussed in https://github.com/orgs/fosrl/discussions/1761
Originally posted by dephekt October 27, 2025
Summary
I'd like to be able to enable the Auto Login with External IDP setting either via:
Motivation
I don't want to set the "Auto Login with External IDP" setting on every resource in the UI when I already use blueprints to convey similar config state to Pangolin. And I don't want to write and manage a separate script just to ensure new resources are configured with the setting.
Proposed Solution
I reviewed the NextJS frontend to understand how it determines the state of the UI element in the resource auth configuration dashboard. I see here it posts to the resource to essentially patch it with
skipToIdpId: selectedIdpId. This exposes it in the resource schema like this:Clearly the resource model already supports it and there's an endpoint to set and update the key. So it seems this setting just needs exposed and wired up in the relevant blueprint model. I found that here in server/lib/blueprints/types.ts:
Then I think it needs wired to the resource creation in server/lib/blueprints/proxyResources.ts here and similarly during the resource update here.
Alternatives Considered
I could easily script setting the configuration via the API. It's just another thing to manage and remember, when I prefer to consolidate the resource config within the Docker labels. Keeping it in sync becomes another thing to deal with also.
It's worth considering if it should be an org or other higher level setting, or such a higher setting that can override at the resource level.
Additional Context
No response
Comments on th...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.