---
title: "Blueprints"
description: "Define Pangolin resources and site settings declaratively with YAML or container labels"
---
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
Blueprints let you define Pangolin resources as code. Instead of configuring every site, target, and access rule manually in the dashboard, you describe the desired state in YAML or container labels and let Pangolin apply it consistently.
Use blueprints when you want:
- Repeatable rollouts across many sites
- Version control for infrastructure and access settings
- A source of truth that can be reviewed, templated, and automated
Some features in this documentation are marked with **(EE)**, which means they require [Enterprise Edition](/self-host/enterprise-edition).
## Blueprint Mental Model
A blueprint can contain up to four top-level sections:
- **`public-resources`**: Internet-facing HTTP, TCP, UDP, SSH, RDP, or VNC resources
- **`private-resources`**: Client-only access to hosts or CIDR ranges
- **`public-policies`**: Reusable authentication and access policy objects
- **`sites`**: Site-level settings such as container label discovery
```yaml
public-resources:
:
...
private-resources:
:
...
public-policies:
:
...
sites:
:
...
```
Think of the resource key as your stable ID inside the blueprint. The fields under that key describe what Pangolin should create or maintain.
These keys are the same idea as the **Identifier** shown in the Pangolin app, called `niceId` in the API. Choose readable, stable keys such as `warehouse-west` or `web-app`; blueprints use them to match and update the same sites and resources on later applies. For more detail, see [What is an identifier?](/manage/common-api-routes#what-is-an-identifier).
## Choose A Format
Pangolin supports two blueprint formats:
### YAML
Use YAML when you want a readable file that can be committed to git, applied through Newt, pasted into the UI, or sent through the API.
### Container Labels
Use container labels when the resource definition should live inside your Compose stack. This is especially useful when a container and its Pangolin resource should be managed together.
## How YAML Blueprints Are Applied
Paste YAML into **Settings > Blueprints** in the Pangolin dashboard.
Run Newt with `--blueprint-file` to keep the file declarative and continuously applied:
```bash
newt --blueprint-file /path/to/blueprint.yaml
```
If you only want a one-time bootstrap during provisioning, use [`--provisioning-blueprint-file`](/manage/sites/site-provisioning) instead.
Apply a blueprint through the Pangolin API with an API key. See the [API documentation](https://api.pangolin.net/v1/docs/#/Organization/put_org__orgId__blueprint).
`PUT /org/{orgId}/blueprint`
```json
{
"blueprint": "base64-encoded-json-content"
}
```
[Python example](https://github.com/fosrl/pangolin/blob/dev/blueprint.py)
Apply a blueprint directly from the Pangolin CLI when you want a one-off apply from a terminal, CI job, or local automation.
**Using your logged-in user account**
First log in and select the organization you want the blueprint applied to:
```bash
pangolin login
pangolin select org --org
```
Then apply the file:
```bash
pangolin apply blueprint --file /path/to/blueprint.yaml
```
The CLI uses your active account and selected organization. You can optionally set the saved blueprint name:
```bash
pangolin apply blueprint --file /path/to/blueprint.yaml --name production
```
**Using an Integration API key**
For non-interactive automation, pass an Integration API key, API endpoint, and organization ID together:
```bash
pangolin apply blueprint \
--file /path/to/blueprint.yaml \
--api-key \
--endpoint https://api.example.com \
--org
```
For Pangolin Cloud, use `https://api.pangolin.net` as the endpoint. For self-hosted Pangolin, use your API host, for example `https://api.your-domain.com`. See [Integration API](/manage/integration-api) for creating API keys and enabling the API on self-hosted deployments.
You can also pipe a blueprint through stdin. When using stdin, provide `--name` because there is no filename to derive it from:
```bash
render-blueprint | pangolin apply blueprint --file - --name production
```
`--blueprint-file` in Newt and container labels behave as an ongoing source of truth. Dashboard edits can be overwritten the next time the blueprint is applied. UI, API, and CLI applies are typically one-off operations.
## Quick Start YAML Example
This example shows three common top-level sections in one file:
```yaml
public-resources:
web-app:
name: Web App
mode: http
full-domain: app.example.com
auth:
sso-enabled: true
whitelist-users:
- admin@example.com
targets:
- site: my-site
hostname: app
port: 8080
method: http
healthcheck:
hostname: app
port: 8080
path: /health
private-resources:
ssh-host:
name: SSH Host
mode: host
sites:
- my-site
destination: 192.168.1.10
tcp-ports: "22"
roles:
- DevOps
sites:
my-site:
name: My Site
docker-socket-enabled: true
```
## Public Resources
Public resources expose services through Pangolin.
- Use **`http`** for websites, APIs, and dashboards
- Use **`tcp`** or **`udp`** for raw public services bound to a port on the Pangolin server
- Use **`ssh`**, **`rdp`**, or **`vnc`** for protocol-specific resources
Use `mode` for new blueprints. `protocol` is still accepted for backward compatibility and is normalized to `mode`.
### HTTP Resource Example
```yaml
public-resources:
app:
name: App
mode: http
full-domain: app.example.com
host-header: app.internal
tls-server-name: app.internal
headers:
- name: X-Env
value: production
rules:
- action: allow
match: country
value: US
- action: deny
match: path
value: /admin
auth:
sso-enabled: true
whitelist-users:
- admin@example.com
targets:
- site: my-site
hostname: app
port: 8080
method: http
```
When applying a blueprint via Newt (using `--blueprint-file` or container labels), `site` on each target is optional. If omitted, the target is assigned to the site of the Newt that applied the blueprint.
### Raw TCP Or UDP Example
```yaml
public-resources:
mqtt:
name: Mosquitto MQTT
mode: tcp
proxy-port: 1883
targets:
- site: my-site
hostname: mqtt-server
port: 1883
```
For raw resources:
- `proxy-port` is required
- Target `method` must not be set
- `auth` is not supported
### Targets-Only Resources
A public resource can contain only `targets`. This is useful when you want to add or manage targets for an existing resource definition without repeating all resource-level fields.
```yaml
public-resources:
extra-targets:
targets:
- site: secondary-site
hostname: app-2
port: 8080
method: http
- site: tertiary-site
hostname: app-3
port: 8080
method: http
```
When a resource is targets-only, `name` and `mode` are not required.
### Authentication Example
Authentication is configured inside `auth` and is supported only for HTTP resources.
```yaml
public-resources:
secure-app:
name: Secure App
mode: http
full-domain: secure.example.com
auth:
pincode: 123456
password: strong-password
basic-auth:
user: demo
password: change-me
sso-enabled: true
sso-roles:
- Member
sso-users:
- user@example.com
whitelist-users:
- admin@example.com
```
### Maintenance Page **(EE)**
The `maintenance` object lets you present a maintenance page for a public HTTP resource.
```yaml
public-resources:
app:
name: App
mode: http
full-domain: app.example.com
maintenance:
enabled: true
type: automatic
title: Scheduled Maintenance
message: We are upgrading the service.
estimated-time: 2 hours
targets:
- site: my-site
hostname: app
port: 8080
method: http
```
Maintenance `type` values:
- **`forced`**: Always show the maintenance page
- **`automatic`**: Show it only when all targets are unhealthy or the sites are offline
## Private Resources
Private resources define what Pangolin clients can reach after they connect to your organization.
- Use **`mode: host`** for a single host or DNS name
- Use **`mode: cidr`** for an entire network range
- Use **`mode: http`** to expose an internal HTTP endpoint to clients via a private domain
- Use **`mode: ssh`** for SSH access workflows (including native auth-daemon mode)
When applying a blueprint via Newt (using `--blueprint-file` or container labels), `sites` is optional. If omitted, the resource is assigned to the site of the Newt that applied the blueprint.
```yaml
private-resources:
internal-net:
name: Internal Network
mode: cidr
destination: 10.0.0.0/24
sites:
- my-site
tcp-ports: "22,443,8000-9000"
udp-ports: "53,123"
disable-icmp: false
alias: "*.internal.example.com"
roles:
- Developer
users:
- user@example.com
machines:
- machine-id-1
internal-app:
name: Internal App
mode: http
destination: 10.0.0.5
destination-port: 8080
sites:
- my-site
full-domain: app.internal.example.com
ssl: true
scheme: https
roles:
- Member
```
## Container Labels Format
Container labels are the same blueprint schema flattened into dot-separated keys:
- Start every label with `pangolin.`
- Keep the same object path as YAML
- Use array indexes for lists, such as `[0]`
Example YAML:
```yaml
public-resources:
my-app:
headers:
- name: X-Env
value: prod
```
Equivalent Compose labels:
```yaml
labels:
- pangolin.public-resources.my-app.headers[0].name=X-Env
- pangolin.public-resources.my-app.headers[0].value=prod
```
Container labels are continuously applied. Treat the Compose file as the source of truth because dashboard edits can be overwritten.
### Enable Container Label Discovery
To use container labels, Newt must be able to read the Docker socket:
```bash
newt --docker-socket /var/run/docker.sock
```
Or with an environment variable:
```bash
DOCKER_SOCKET=/var/run/docker.sock
```
### Docker Compose Example
```yaml
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- PANGOLIN_ENDPOINT=https://app.pangolin.net
- NEWT_ID=h1rbsgku89wf9z3
- NEWT_SECRET=z7g54mbcwkglpx1aau9gb8mzcccoof2fdbs97keoakg2pp5z
- DOCKER_SOCKET=/var/run/docker.sock
nginx1:
image: nginxdemos/hello
container_name: nginx1
labels:
- pangolin.public-resources.nginx.name=nginx
- pangolin.public-resources.nginx.full-domain=nginx.fosrl.io
- pangolin.public-resources.nginx.protocol=http
- pangolin.public-resources.nginx.headers[0].name=X-Example-Header
- pangolin.public-resources.nginx.headers[0].value=example-value
- pangolin.public-resources.nginx.targets[0].method=http
- pangolin.public-resources.nginx.targets[0].path=/path
- pangolin.public-resources.nginx.targets[0].path-match=prefix
nginx2:
image: nginxdemos/hello
container_name: nginx2
labels:
- pangolin.public-resources.nginx.targets[1].method=http
- pangolin.public-resources.nginx.targets[1].hostname=nginx2
- pangolin.public-resources.nginx.targets[1].port=80
networks:
default:
name: pangolin_default
```
This creates a single Pangolin resource with multiple targets:
### Container Label Behavior
If `hostname` or `port` are not set explicitly, Pangolin can detect them from the container configuration. The hostname typically defaults to the container name, and port detection is based on the container's `expose` configuration.
If no `site` is specified on a target (public resource) or on a private resource, it is assigned to the site of the Newt that applied the blueprint — whether through container labels or `--blueprint-file`.
Labels from multiple containers can be merged into one logical resource, which is useful when different containers contribute different targets.
## Configuration Reference
Use this section when you need the full schema. The order below mirrors the blueprint structure rather than the dashboard UI.
### Top-Level Object
```yaml
public-resources:
app:
name: App
mode: http
full-domain: app.example.com
targets:
- hostname: app
port: 80
method: http
private-resources:
ssh-host:
name: SSH Host
mode: host
sites:
- my-site
destination: 192.168.1.10
tcp-ports: "22"
public-policies:
default-member:
name: Default Member Policy
sso: true
apply-rules: false
rules: []
sites:
my-site:
name: My Site
docker-socket-enabled: true
```
Public proxy resources keyed by resource ID.
YAML: `public-resources: { web-app: { ... } }`
Container label: `pangolin.public-resources.web-app.name=Web App`
Private resources keyed by resource ID.
YAML: `private-resources: { internal-net: { ... } }`
Container label: `pangolin.private-resources.internal-net.mode=cidr`
Reusable policy definitions keyed by policy ID.
YAML: `public-policies: { default-member: { ... } }`
Container label: `pangolin.public-policies.default-member.name=Default Member Policy`
Site-level settings keyed by site ID.
YAML: `sites: { my-site: { name: My Site } }`
Container label: `pangolin.sites.my-site.name=My Site`
Display name for the site.
YAML: `name: My Site`
Container label: `pangolin.sites.my-site.name=My Site`
Enables blueprint discovery from container labels for that site.
**Default**: `true`
YAML: `docker-socket-enabled: true`
Container label: `pangolin.sites.my-site.docker-socket-enabled=true`
### Public Resource Object (`public-resources`)
```yaml
public-resources:
web-app:
name: Web App
mode: http
policy: default-member
full-domain: app.example.com
enabled: true
host-header: internal.example.local
tls-server-name: internal.example.local
headers:
- name: X-Env
value: prod
rules:
- action: allow
match: country
value: US
- action: deny
match: region
value: 019
auth:
pincode: 123456
sso-enabled: true
whitelist-users:
- admin@example.com
maintenance:
enabled: true
type: automatic
targets:
- site: my-site
hostname: app
port: 8080
method: http
path: /
path-match: prefix
rewrite-path: /
rewrite-match: prefix
healthcheck:
hostname: app
port: 8080
path: /health
```
A single public resource definition.
Human-readable resource name. Required unless the resource is targets-only.
YAML: `name: Web App`
Container label: `pangolin.public-resources.web-app.name=Web App`
Resource mode. Preferred over `protocol`.
**Options**: `http`, `tcp`, `udp`, `ssh`, `rdp`, `vnc`
YAML: `mode: http`
Container label: `pangolin.public-resources.web-app.mode=http`
Deprecated resource type field. Use `mode` instead.
**Options**: `http`, `tcp`, `udp`, `ssh`, `rdp`, `vnc`
YAML: `protocol: http`
Container label: `pangolin.public-resources.web-app.protocol=http`
Policy key to attach from `public-policies`.
YAML: `policy: default-member`
Container label: `pangolin.public-resources.web-app.policy=default-member`
Optional SSL/TLS flag present in the schema.
YAML: `ssl: true`
Container label: `pangolin.public-resources.web-app.ssl=true`
Public hostname for HTTP resources. Required when `protocol: http`.
YAML: `full-domain: app.example.com`
Container label: `pangolin.public-resources.web-app.full-domain=app.example.com`
Public port for raw TCP or UDP resources. Required when `mode` is `tcp` or `udp`.
YAML: `proxy-port: 3000`
Container label: `pangolin.public-resources.raw-api.proxy-port=3000`
Enables Proxy Protocol on TCP resources.
YAML: `proxy-protocol: true`
Container label: `pangolin.public-resources.raw-api.proxy-protocol=true`
Proxy Protocol version when `proxy-protocol` is enabled.
**Minimum**: `1`
YAML: `proxy-protocol-version: 1`
Container label: `pangolin.public-resources.raw-api.proxy-protocol-version=1`
Disables the resource without removing it.
YAML: `enabled: true`
Container label: `pangolin.public-resources.web-app.enabled=true`
Overrides the upstream `Host` header sent to the target.
YAML: `host-header: internal.example.local`
Container label: `pangolin.public-resources.web-app.host-header=internal.example.local`
Overrides the TLS SNI hostname used for upstream TLS connections.
YAML: `tls-server-name: internal.example.local`
Container label: `pangolin.public-resources.web-app.tls-server-name=internal.example.local`
Static headers added to proxied requests.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `headers: [{ name: X-Env, value: prod }]`
Container label: `pangolin.public-resources.web-app.headers[0].name=X-Env`
Header name.
YAML: `name: X-Env`
Container label: `pangolin.public-resources.web-app.headers[0].name=X-Env`
Header value.
YAML: `value: prod`
Container label: `pangolin.public-resources.web-app.headers[0].value=prod`
Ordered access rules for public resources.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `rules: [{ action: allow, match: country, value: US }]`
Container label: `pangolin.public-resources.web-app.rules[0].action=allow`
What Pangolin should do when the rule matches.
**Options**: `allow`, `deny`, `pass`
YAML: `action: allow`
Container label: `pangolin.public-resources.web-app.rules[0].action=allow`
Match type for the rule.
**Options**: `cidr`, `path`, `ip`, `country`, `asn`, `region`
YAML: `match: country`
Container label: `pangolin.public-resources.web-app.rules[0].match=country`
Value to compare against, such as an IP, CIDR, path, two letter country code, ASN, or region.
YAML: `value: US`
Container label: `pangolin.public-resources.web-app.rules[0].value=US`
When using match: region, the value must be a supported region code. The following region IDs are available, based on the United Nations geoscheme:
- 002: Africa
- 015: Northern Africa
- 014: Eastern Africa
- 017: Middle Africa
- 018: Southern Africa
- 011: Western Africa
- 019: Americas
- 029: Caribbean
- 013: Central America
- 005: South America
- 021: Northern America
- 142: Asia
- 143: Central Asia
- 030: Eastern Asia
- 035: South-Eastern Asia
- 034: Southern Asia
- 145: Western Asia
- 150: Europe
- 151: Eastern Europe
- 154: Northern Europe
- 039: Southern Europe
- 155: Western Europe
- 009: Oceania
- 053: Australia and New Zealand
- 054: Melanesia
- 057: Micronesia
- 061: Polynesia
Use the top-level code (e.g., 019 for all Americas) or a subregion code (e.g., 021 for Northern America) as needed.
Explicit rule priority. If omitted, priority is assigned from the rule order.
YAML: `priority: 10`
Container label: `pangolin.public-resources.web-app.rules[0].priority=10`
Enables or disables the rule.
**Default**: `true`
YAML: `enabled: true`
Container label: `pangolin.public-resources.web-app.rules[0].enabled=true`
Authentication settings for HTTP resources. Not allowed for `tcp` or `udp`.
Numeric PIN required before access is granted.
YAML: `pincode: 123456`
Container label: `pangolin.public-resources.web-app.auth.pincode=123456`
Shared password gate for the resource.
YAML: `password: super-secret`
Container label: `pangolin.public-resources.web-app.auth.password=super-secret`
Enables Pangolin sign-in for the resource.
YAML: `sso-enabled: true`
Container label: `pangolin.public-resources.web-app.auth.sso-enabled=true`
Roles allowed through SSO.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `sso-roles: [Member]`
Container label: `pangolin.public-resources.web-app.auth.sso-roles[0]=Member`
Specific user identifiers allowed through SSO.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `sso-users: [user@example.com]`
Container label: `pangolin.public-resources.web-app.auth.sso-users[0]=user@example.com`
Whitelisted emails or patterns allowed for email-based access flows.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `whitelist-users: [admin@example.com]`
Container label: `pangolin.public-resources.web-app.auth.whitelist-users[0]=admin@example.com`
Identity provider ID to redirect to automatically.
YAML: `auto-login-idp: 1`
Container label: `pangolin.public-resources.web-app.auth.auto-login-idp=1`
HTTP basic auth settings.
Basic auth username.
YAML: `user: demo`
Container label: `pangolin.public-resources.web-app.auth.basic-auth.user=demo`
Basic auth password.
YAML: `password: change-me`
Container label: `pangolin.public-resources.web-app.auth.basic-auth.password=change-me`
Compatibility flag for basic auth behavior.
**Default**: `true`
YAML: `extendedCompatibility: true`
Container label: `pangolin.public-resources.web-app.auth.basic-auth.extendedCompatibility=true`
Maintenance page configuration for public resources **(EE)**.
YAML: `maintenance: { enabled: true, type: forced }`
Container label: `pangolin.public-resources.web-app.maintenance.enabled=true`
Turns the maintenance page feature on for the resource.
When Pangolin should show the page.
**Options**: `forced`, `automatic`
Main heading shown on the maintenance page.
Message shown to users while the resource is unavailable.
Optional estimate for when the service will return.
Auth-daemon configuration for supported modes.
PAM behavior. Passthrough will require entering the username, password, or private key when connecting. Push will sync a Pangolin user with the configuration from the roles onto the auth-daemon and not prompt a log in.
**Options**: `passthrough`, `push`
**Default**: `passthrough`
Auth-daemon mode. To use the built in ssh server inside of the site connector use `native`. For external ssh servers, use `remote` or `site` depending on where the server is.
**Options**: `site`, `remote`, `native`
**Default**: `site`
Remote auth-daemon port. Required when `auth-daemon.mode` is `remote`.
Backend destinations for the resource.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `targets: [{ hostname: app, port: 8080, method: http }]`
Container label: `pangolin.public-resources.web-app.targets[0].hostname=app`
Site that hosts the target. Optional when deploying from a Newt — if omitted, the target is assigned to the site of the Newt that applied the blueprint.
YAML: `site: my-site`
Container label: `pangolin.public-resources.web-app.targets[0].site=my-site`
Upstream protocol for HTTP resources.
**Options**: `http`, `https`, `h2c`
YAML: `method: http`
Container label: `pangolin.public-resources.web-app.targets[0].method=http`
Target hostname or IP address.
YAML: `hostname: app`
Container label: `pangolin.public-resources.web-app.targets[0].hostname=app`
Target port.
YAML: `port: 8080`
Container label: `pangolin.public-resources.web-app.targets[0].port=8080`
Disables the target without deleting it.
YAML: `enabled: true`
Container label: `pangolin.public-resources.web-app.targets[0].enabled=true`
Internal port override used in container-oriented setups.
YAML: `internal-port: 8080`
Container label: `pangolin.public-resources.web-app.targets[0].internal-port=8080`
Path condition used for HTTP routing.
YAML: `path: /`
Container label: `pangolin.public-resources.web-app.targets[0].path=/`
Matching mode for `path`.
**Options**: `exact`, `prefix`, `regex`
Replacement path or prefix used during path rewriting.
YAML: `rewrite-path: /`
Container label: `pangolin.public-resources.web-app.targets[0].rewrite-path=/`
Deprecated alias for `rewrite-path`.
Rewrite mode.
**Options**: `exact`, `prefix`, `regex`, `stripPrefix`
Target priority used in routing decisions.
**Range**: `1-1000`
**Default**: `100`
YAML: `priority: 100`
Container label: `pangolin.public-resources.web-app.targets[0].priority=100`
Health monitoring for the target.
Hostname or IP used for the health check.
Port used for the health check.
Enables health checking for the target.
HTTP path to check, such as `/health`.
Scheme to use for the check.
Health check mode supported by the schema.
Check interval while the target is healthy.
Check interval while the target is unhealthy.
Deprecated alias for `unhealthy-interval`.
Timeout for each health check attempt.
Headers sent with the health check request.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `headers: [{ name: X-Health-Check, value: true }]`
Container label: `pangolin.public-resources.web-app.targets[0].healthcheck.headers[0].name=X-Health-Check`
Header name.
Header value.
Whether redirects should be followed.
Deprecated alias for `follow-redirects`.
HTTP method for the check request.
Expected HTTP status code.
### Private Resource Object (`private-resources`)
```yaml
private-resources:
internal-net:
name: Internal Network
mode: cidr
sites:
- my-site
destination: 10.0.0.0/24
tcp-ports: "22,443"
udp-ports: "53"
disable-icmp: false
alias: "*.internal.example.com"
roles:
- Member
users:
- user@example.com
machines:
- machine-id-1
internal-app:
name: Internal App
mode: http
sites:
- my-site
destination: 10.0.0.5
destination-port: 8080
full-domain: app.internal.example.com
ssl: true
scheme: https
```
A single private resource definition.
Display name for the resource.
YAML: `name: Internal Network`
Container label: `pangolin.private-resources.internal-net.name=Internal Network`
Private resource type.
**Options**: `host`, `cidr`, `http`, `ssh`
- `host`: A single host or IP. If `destination` is a domain, `alias` is required.
- `cidr`: An entire IPv4 or IPv6 CIDR range.
- `http`: An internal HTTP endpoint exposed to clients via `full-domain`.
- `ssh`: SSH access resource. `destination` may be omitted only when `auth-daemon.mode` is `native` (or when `auth-daemon` is omitted).
YAML: `mode: cidr`
Container label: `pangolin.private-resources.internal-net.mode=cidr`
Sites that host the resource. Optional when deploying from a Newt — if omitted, the resource is assigned to the site of the Newt that applied the blueprint.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `sites: [my-site]`
Container label: `pangolin.private-resources.internal-net.sites[0]=my-site`
Deprecated. Use `sites` instead.
YAML: `site: my-site`
Container label: `pangolin.private-resources.internal-net.site=my-site`
Host, IP, or CIDR block the client should reach. The accepted format depends on `mode`:
- `host`: a valid IPv4/IPv6 address, or a hostname/domain (when using a domain, `alias` must also be set)
- `cidr`: a valid IPv4 or IPv6 CIDR block
- `http`: a host or IP for the upstream HTTP endpoint
- `ssh`: optional only for `auth-daemon.mode: native`; required otherwise
YAML: `destination: 10.0.0.0/24`
Container label: `pangolin.private-resources.internal-net.destination=10.0.0.0/24`
Auth-daemon configuration.
PAM behavior. Passthrough will require entering the username, password, or private key when connecting. Push will sync a Pangolin user with the configuration from the roles onto the auth-daemon and not prompt a log in.
**Options**: `passthrough`, `push`
**Default**: `passthrough`
Auth-daemon mode. To use the built in ssh server inside of the site connector use `native`. For external ssh servers, use `remote` or `site` depending on where the server is.
**Options**: `site`, `remote`, `native`
**Default**: `site`
Remote auth-daemon port. Required when `auth-daemon.mode` is `remote`.
Upstream port for the destination. Typically used with `mode: http` to point at the internal HTTP endpoint's port.
YAML: `destination-port: 8080`
Container label: `pangolin.private-resources.internal-app.destination-port=8080`
Internal domain used to expose an HTTP private resource to clients. Applies when `mode: http`.
YAML: `full-domain: app.internal.example.com`
Container label: `pangolin.private-resources.internal-app.full-domain=app.internal.example.com`
Whether SSL/TLS should be used when serving the private HTTP resource.
YAML: `ssl: true`
Container label: `pangolin.private-resources.internal-app.ssl=true`
Upstream scheme used by Pangolin to reach the destination for HTTP private resources.
**Options**: `http`, `https`
YAML: `scheme: https`
Container label: `pangolin.private-resources.internal-app.scheme=https`
Allowed TCP ports or ranges. Use comma-separated values for multiple ports or ranges, such as `22,443,8000-9000` or `*` for all ports or leave empty for no ports.
**Default**: `*`
YAML: `tcp-ports: "22,443"`
Container label: `pangolin.private-resources.internal-net.tcp-ports=22,443`
Allowed UDP ports or ranges. Use comma-separated values for multiple ports or ranges, such as `22,443,8000-9000` or `*` for all ports or leave empty for no ports.
**Default**: `*`
YAML: `udp-ports: "53"`
Container label: `pangolin.private-resources.internal-net.udp-ports=53`
Prevents ICMP traffic such as ping.
**Default**: `false`
YAML: `disable-icmp: false`
Container label: `pangolin.private-resources.internal-net.disable-icmp=false`
Internal DNS alias for the resource. Must be a fully qualified domain name and may include wildcards (`*`, `?`), e.g. `example.com`, `*.example.com`, or `host-0?.example.internal`. Required when `mode: host` and `destination` is a domain.
YAML: `alias: "*.internal.example.com"`
Container label: `pangolin.private-resources.internal-net.alias=*.internal.example.com`
Roles allowed to access the resource. The `Admin` role is reserved and cannot be listed here.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `roles: [Member]`
Container label: `pangolin.private-resources.internal-net.roles[0]=Member`
Individual users allowed to access the resource.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `users: [user@example.com]`
Container label: `pangolin.private-resources.internal-net.users[0]=user@example.com`
Machine identities allowed to access the resource.
Container labels for arrays must include an index (`[0]`, `[1]`, ...).
YAML: `machines: [machine-id-1]`
Container label: `pangolin.private-resources.internal-net.machines[0]=machine-id-1`
### Resource Policy Object (`public-policies`)
```yaml
public-policies:
default-member:
name: Default Member Policy
sso: true
auto-login-idp: null
sso-roles:
- Member
sso-users: []
password: null
pincode: null
basic-auth: null
email-whitelist-enabled: false
whitelist-users:
- "*@example.com"
apply-rules: true
rules:
- action: allow
match: country
value: US
enabled: true
```
A reusable policy definition that can be referenced by public resources via `policy`.
Display name for the policy.
Enables SSO for the policy.
**Default**: `true`
Identity provider ID to redirect to automatically.
Roles allowed by this policy. `Admin` is not allowed.
Specific users allowed by this policy.
Optional shared password.
Optional 6-digit PIN.
Optional basic-auth gate.
Basic auth username.
Basic auth password.
Compatibility flag for basic auth behavior.
**Default**: `true`
Enables email whitelist matching.
**Default**: `false`
Allowed email addresses or wildcard-domain entries like `*@example.com`.
Enables rule evaluation.
**Default**: `false`
Policy rule list using the same rule schema as public resource rules.
## Validation Rules And Constraints
### Core Rules
1. A public resource can be **targets-only**. In that case it may contain only `targets`, and `name` plus `mode` are not required.
2. For full public resources, `name` plus (`mode` or deprecated `protocol`) are required.
3. When mode/protocol is `http`, the resource must have `full-domain` and each target must include `method`.
4. When mode/protocol is `tcp` or `udp`, the resource must have `proxy-port`, targets must not include `method`, and `auth` is not allowed.
5. `proxy-protocol` and `proxy-protocol-version` are only valid when mode/protocol is `tcp`.
6. If `auth-daemon.mode` is `remote`, `auth-daemon.port` is required.
7. In private resources, `destination` is required unless `mode: ssh` with native auth-daemon mode.
8. `full-domain` values must be unique across public resources.
9. `proxy-port` values must be unique per protocol within `public-resources`. TCP `3000` and UDP `3000` can coexist, but two TCP resources cannot both use `3000`.
10. `alias` values must be unique across private resources in the blueprint.
### Common Validation Errors
### "Admin role cannot be included in sso-roles"
`Admin` is reserved and cannot be used in `auth.sso-roles`.
### "Duplicate 'full-domain' values found"
Every public HTTP resource must have its own unique `full-domain`.
### "Duplicate 'proxy-port' values found in public-resources"
Two public resources with the same protocol cannot reuse the same `proxy-port`.
### "When protocol is 'http', all targets must have a 'method' field"
Each HTTP target must specify `http`, `https`, or `h2c`.
### "When protocol is 'tcp' or 'udp', targets must not have a 'method' field"
Raw targets do not use HTTP methods.
### "When protocol is 'tcp' or 'udp', 'auth' must not be provided"
Authentication settings apply only to HTTP public resources.
### "'proxy-protocol' and 'proxy-protocol-version' can only be set when mode is 'tcp'"
Only TCP public resources can define proxy protocol behavior.
### "port is required when auth-daemon mode is 'remote'"
Set `auth-daemon.port` whenever `auth-daemon.mode: remote` is used.
### "destination is required unless mode is 'ssh' with auth-daemon mode 'native'"
For private SSH resources, `destination` can be omitted only for native auth-daemon mode.
### "Resource must either be targets-only or have both 'name' and 'protocol' fields"
Provide both fields for a full public resource definition, or remove everything except `targets`.
### "Duplicate 'alias' values found in private-resources"
Private resource aliases must be unique within the blueprint.
### "Destination must be a valid IP address or valid domain AND alias is required"
In `host` mode, the destination must be a valid host or IP. If you use a domain, provide `alias` as well.
### "Destination must be a valid CIDR notation for cidr mode"
In `cidr` mode, `destination` must be a valid CIDR block such as `10.0.0.0/24`.
### "Admin role cannot be included in roles"
`Admin` is reserved and cannot be used in private resource `roles`.