AI Gateway is now available: identity-aware access to any AI provider, eliminate API keys, and tunnel to self-hosted models. Get started

Blueprints

Blueprints

Define Pangolin resources and site settings declaratively with YAML or container labels

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.

Benefits

  • Roll out the same resources and access settings across many sites without repeating dashboard work.
  • Keep infrastructure and access settings in version control, where changes can be reviewed and rolled back.
  • Template and automate configuration from CI, scripts, or provisioning tools.
  • Keep a resource's definition next to the container it exposes with container labels.

Use Cases

  • Stamp out an identical set of resources for every store, branch office, or customer site.
  • Manage Pangolin resources through pull requests in a GitOps workflow.
  • Define resources next to the Docker Compose services they expose, using container labels.
  • Bootstrap new sites with their resources during provisioning.

How Blueprints Work

You describe the desired state in YAML or container labels and apply it through the dashboard, a site, the API, or the CLI. Pangolin matches each entry to an existing site, resource, or policy by its key and creates or updates it to match. A blueprint applied from a site file or container labels acts as an ongoing source of truth, while dashboard, API, and CLI applies are one-off. See How YAML Blueprints Are Applied.

Some features in this documentation are marked with (EE), which means they require 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, CIDR ranges, or an exit node
  • public-policies: Reusable authentication and access policy objects
  • sites: Site-level settings such as container label discovery
public-resources:
  <resource_key>:
    ...

private-resources:
  <resource_key>:
    ...

public-policies:
  <policy_key>:
    ...

sites:
  <site_key>:
    ...

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?.

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 a site, 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

UI

Paste YAML into Settings > Blueprints in the Pangolin dashboard.

Blueprint creation page in the Pangolin dashboard

Site

Run a site with --blueprint-file to keep the file declarative and continuously applied:

pangolin up site --blueprint-file /path/to/blueprint.yaml --id <id> --secret <secret> --endpoint https://app.pangolin.net

If you only want a one-time bootstrap during provisioning, use --provisioning-blueprint-file instead.

API

Apply a blueprint through the Pangolin API with an API key. See the API documentation.

PUT /org/{orgId}/blueprint

{
  "blueprint": "base64-encoded-json-content"
}

Python example

CLI

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:

pangolin login
pangolin select org --org <org_id>

Then apply the file:

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:

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:

pangolin apply blueprint \
  --file /path/to/blueprint.yaml \
  --api-key <api_key_id.api_key_secret> \
  --endpoint https://api.example.com \
  --org <org_id>

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 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:

render-blueprint | pangolin apply blueprint --file - --name production

--blueprint-file on a site 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:

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 inference for an AI Gateway resource that proxies requests to one or more attached AI providers

Use mode for new blueprints. protocol is still accepted for backward compatibility and is normalized to mode.

HTTP Resource Example

public-resources:
  app:
    name: App
    mode: http
    full-domain: app.example.com
    host-header: app.internal
    tls-server-name: app.internal
    response-headers:
      - name: Access-Control-Allow-Origin
        value: *
    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 from a site (using --blueprint-file or container labels), site on each target is optional. If omitted, the target is assigned to the site that applied the blueprint.

Raw TCP Or UDP Example

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.

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.

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.

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

AI Gateway (Inference) Example

Set mode: inference to turn a public resource into an AI Gateway that proxies requests to one or more AI providers already configured in the organization. Inference resources do not take targets.

public-resources:
  ai-gateway:
    name: AI Gateway
    mode: inference
    full-domain: ai.example.com
    ai-providers:
      - provider: openai-prod
        access-mode: select
        models:
          - gpt-4o
      - provider: anthropic-prod
        access-mode: inherit
    ai-budget:
      - amount: 100
        unit: usd
        period: monthly
        enforcement: hard
  • ai-providers references AI providers by their identifier and is only allowed when mode: inference.
  • access-mode: select limits the resource to the listed models, which must already be on the provider's allow list. access-mode: inherit uses the provider's own allow and block lists. See Model Routing for details.
  • ai-budget is a list of spend or usage limits enforced on the resource. Only one budget per unit/period combination is allowed.

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)
  • Use mode: inference for a private AI Gateway resource reachable only by Pangolin clients, not the public internet
  • Use mode: exit-node to send all of a client's internet traffic out through the site network

When applying a blueprint from a site (using --blueprint-file or container labels), sites is optional. If omitted, the resource is assigned to the site that applied the blueprint.

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

Exit Node Example

Set mode: exit-node to turn a site into an exit node. Clients with access to the resource route all of their internet traffic through the site network, so it egresses from the site instead of the client's local connection.

private-resources:
  office-exit:
    name: Office Exit Node
    mode: exit-node
    sites:
      - office-site
    roles:
      - Developer
    users:
      - user@example.com
  • destination is not needed. An exit node always routes the full range (0.0.0.0/0), and any destination you set is ignored.
  • All TCP and UDP ports and ICMP are always allowed. tcp-ports, udp-ports, and disable-icmp are ignored.
  • gateway is accepted as an equivalent value for mode.

Resource Labels

Attach labels to public and private resources to organize and filter them in the dashboard. These are the same labels manageable from Settings > Labels - not to be confused with the Docker container labels used to define blueprints from Compose.

public-resources:
  app:
    name: App
    mode: http
    full-domain: app.example.com
    labels:
      - production
      - team-infra
    targets:
      - site: my-site
        hostname: app
        port: 8080
        method: http
  • Label names are matched case-insensitively against existing labels in the organization.
  • If a label with that name doesn't already exist yet, Pangolin creates it automatically.
  • Each apply replaces the resource's full label list with the list in the blueprint.
  • Labels are not synced for targets-only public resources - omitting labels on a targets-only update leaves existing labels untouched.

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:

public-resources:
  my-app:
    request-headers:
      - name: X-Env
        value: prod

Equivalent Compose labels:

labels:
  - pangolin.public-resources.my-app.request-headers[0].name=X-Env
  - pangolin.public-resources.my-app.request-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, the site must be able to read the Docker socket:

pangolin up site --docker-socket /var/run/docker.sock --id <id> --secret <secret> --endpoint https://app.pangolin.net

Or with an environment variable:

DOCKER_SOCKET=/var/run/docker.sock

Docker Compose Example

services:
  pangolin-site:
    image: fosrl/pangolin-cli
    container_name: pangolin-site
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - PANGOLIN_ENDPOINT=https://app.pangolin.net
      - SITE_ID=h1rbsgku89wf9z3
      - SITE_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.request-headers[0].name=X-Example-Header
      - pangolin.public-resources.nginx.request-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:

Example resource
Pangolin UI showing Docker Compose blueprint example

Container Label Behavior

Automatic Discovery

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.

Site Assignment

If no site is specified on a target (public resource) or on a private resource, it is assigned to the site that applied the blueprint, whether through container labels or --blueprint-file.

Merged Configuration

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

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
Show Top-level object referenceHide Top-level object reference
public-resourcesobject

Public proxy resources keyed by resource ID.

YAML: public-resources: { web-app: { ... } }
Container label: pangolin.public-resources.web-app.name=Web App

private-resourcesobject

Private resources keyed by resource ID.

YAML: private-resources: { internal-net: { ... } }
Container label: pangolin.private-resources.internal-net.mode=cidr

public-policiesobject

Reusable policy definitions keyed by policy ID.

YAML: public-policies: { default-member: { ... } }
Container label: pangolin.public-policies.default-member.name=Default Member Policy

sitesobject

Site-level settings keyed by site ID.

YAML: sites: { my-site: { name: My Site } }
Container label: pangolin.sites.my-site.name=My Site

Show Site objectHide Site object
namestringrequired

Display name for the site.

YAML: name: My Site
Container label: pangolin.sites.my-site.name=My Site

docker-socket-enabledboolean

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)

public-resources:
  web-app:
    name: Web App
    mode: http
    policy: default-member
    full-domain: app.example.com
    enabled: true
    labels:
      - production
    host-header: internal.example.local
    tls-server-name: internal.example.local
    request-headers:
      - name: X-Env
        value: prod
    response-headers:
      - name: Access-Control-Allow-Origin
        value: *
    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
Show Public resource referenceHide Public resource reference
<resource_key>object

A single public resource definition.

Show Resource fieldsHide Resource fields
namestring

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

modestring

Resource mode. Preferred over protocol.

Options: http, tcp, udp, ssh, rdp, vnc, inference

inference turns the resource into an AI Gateway that proxies to attached ai-providers instead of targets.

YAML: mode: http
Container label: pangolin.public-resources.web-app.mode=http

protocolstringdeprecated

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

policystring

Policy key to attach from public-policies.

YAML: policy: default-member
Container label: pangolin.public-resources.web-app.policy=default-member

sslboolean

Optional SSL/TLS flag present in the schema.

YAML: ssl: true
Container label: pangolin.public-resources.web-app.ssl=true

full-domainstring

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

proxy-portinteger

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

proxy-protocolboolean

Enables Proxy Protocol on TCP resources.

YAML: proxy-protocol: true
Container label: pangolin.public-resources.raw-api.proxy-protocol=true

proxy-protocol-versioninteger

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

enabledboolean

Disables the resource without removing it.

YAML: enabled: true
Container label: pangolin.public-resources.web-app.enabled=true

labelsarray of strings

Resource labels to attach, by name. Labels that don't already exist in the organization are created automatically. Not synced when the resource is targets-only.

Container labels for arrays must include an index ([0], [1], ...).

YAML: labels: [production]
Container label: pangolin.public-resources.web-app.labels[0]=production

ai-providersarray of objects

AI providers attached to an AI Gateway resource. Only allowed when mode: inference.

Container labels for arrays must include an index ([0], [1], ...).

YAML: ai-providers: [{ provider: openai-prod, access-mode: inherit }]
Container label: pangolin.public-resources.ai-gateway.ai-providers[0].provider=openai-prod

Show AI provider attachment objectHide AI provider attachment object
providerstringrequired

Identifier of an AI provider already configured in the organization.

YAML: provider: openai-prod
Container label: pangolin.public-resources.ai-gateway.ai-providers[0].provider=openai-prod

access-modestring

How the resource uses the provider's model lists. select requires models to be set; inherit requires models to be empty.

Options: inherit, select
Default: inherit

YAML: access-mode: select
Container label: pangolin.public-resources.ai-gateway.ai-providers[0].access-mode=select

enabledboolean

Enables or disables this provider attachment.

Default: true

YAML: enabled: true
Container label: pangolin.public-resources.ai-gateway.ai-providers[0].enabled=true

modelsarray of strings

Subset of the provider's allow-listed model keys exposed by this resource. Only valid when access-mode: select.

Container labels for arrays must include an index ([0], [1], ...).

YAML: models: [gpt-4o]
Container label: pangolin.public-resources.ai-gateway.ai-providers[0].models[0]=gpt-4o

ai-budgetarray of objects

Spend or usage budgets enforced on an AI Gateway resource. Each entry must use a unique unit/period combination.

Container labels for arrays must include an index ([0], [1], ...).

YAML: ai-budget: [{ amount: 100, unit: usd, period: monthly }]
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].amount=100

Show AI budget objectHide AI budget object
amountnumberrequired

Budget limit. Must be positive.

YAML: amount: 100
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].amount=100

unitstringrequired

Unit the budget is measured in.

Options: usd, tokens

YAML: unit: usd
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].unit=usd

periodstring

Rolling window the budget resets on.

Options: hourly, daily, weekly, monthly, yearly, lifetime
Default: monthly

YAML: period: monthly
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].period=monthly

enforcementstring

What happens once the budget is exceeded. hard blocks further requests; soft allows them to continue.

Options: hard, soft
Default: hard

YAML: enforcement: hard
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].enforcement=hard

enabledboolean

Enables or disables this budget.

Default: true

YAML: enabled: true
Container label: pangolin.public-resources.ai-gateway.ai-budget[0].enabled=true

host-headerstring

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

tls-server-namestring

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

request-headersarray of objects

Static headers added to proxied requests.

Container labels for arrays must include an index ([0], [1], ...).

YAML: request-headers: [{ name: X-Env, value: prod }]
Container label: pangolin.public-resources.web-app.request-headers[0].name=X-Env

Show Header objectHide Header object
namestringrequired

Header name.

YAML: name: X-Env
Container label: pangolin.public-resources.web-app.request-headers[0].name=X-Env

valuestringrequired

Header value.

YAML: value: prod
Container label: pangolin.public-resources.web-app.request-headers[0].value=prod

response-headersarray of objects

Static headers added to proxied responses.

Container labels for arrays must include an index ([0], [1], ...).

YAML: response-headers: [{ name: Cache-Control, value: no-cache }]
Container label: pangolin.public-resources.web-app.response-headers[0].name=Cache-Control

Show Header objectHide Header object
namestringrequired

Header name.

YAML: name: Cache-Control
Container label: pangolin.public-resources.web-app.response-headers[0].name=Cache-Control

valuestringrequired

Header value.

YAML: value: no-cache
Container label: pangolin.public-resources.web-app.response-headers[0].value=no-cache

headersarray of objectsdeprecated

Deprecated alias for request-headers.

rulesarray of objects

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

Show Rule objectHide Rule object
actionstringrequired

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

matchstringrequired

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

valuestringrequired

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.

priorityinteger

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

enabledboolean

Enables or disables the rule.

Default: true
YAML: enabled: true
Container label: pangolin.public-resources.web-app.rules[0].enabled=true

authobject

Authentication settings for HTTP resources. Not allowed for tcp or udp.

Show Auth objectHide Auth object
pincodenumber

Numeric PIN required before access is granted.

YAML: pincode: 123456
Container label: pangolin.public-resources.web-app.auth.pincode=123456

passwordstring

Shared password gate for the resource.

YAML: password: super-secret
Container label: pangolin.public-resources.web-app.auth.password=super-secret

sso-enabledboolean

Enables Pangolin sign-in for the resource.

YAML: sso-enabled: true
Container label: pangolin.public-resources.web-app.auth.sso-enabled=true

sso-rolesarray of strings

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

sso-usersarray of strings

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

whitelist-usersarray of strings

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

auto-login-idpinteger

Identity provider ID to redirect to automatically.

YAML: auto-login-idp: 1
Container label: pangolin.public-resources.web-app.auth.auto-login-idp=1

basic-authobject

HTTP basic auth settings.

Show Basic authHide Basic auth
userstringrequired

Basic auth username.

YAML: user: demo
Container label: pangolin.public-resources.web-app.auth.basic-auth.user=demo

passwordstringrequired

Basic auth password.

YAML: password: change-me
Container label: pangolin.public-resources.web-app.auth.basic-auth.password=change-me

extendedCompatibilityboolean

Compatibility flag for basic auth behavior.

Default: true

YAML: extendedCompatibility: true
Container label: pangolin.public-resources.web-app.auth.basic-auth.extendedCompatibility=true

maintenanceobject

Maintenance page configuration for public resources (EE).

YAML: maintenance: { enabled: true, type: forced }
Container label: pangolin.public-resources.web-app.maintenance.enabled=true

Show Maintenance objectHide Maintenance object
enabledboolean

Turns the maintenance page feature on for the resource.

typestring

When Pangolin should show the page.

Options: forced, automatic

titlestring

Main heading shown on the maintenance page.

messagestring

Message shown to users while the resource is unavailable.

estimated-timestring

Optional estimate for when the service will return.

auth-daemonobject

Auth-daemon configuration for supported modes.

Show Auth-daemon objectHide Auth-daemon object
pamstring

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

modestring

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

portinteger

Remote auth-daemon port. Required when auth-daemon.mode is remote.

targetsarray of objects

Backend destinations for the resource. Not allowed when mode: inference.

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

Show Target objectHide Target object
sitestring

Site that hosts the target. Optional when deploying from a site. If omitted, the target is assigned to the site that applied the blueprint.

YAML: site: my-site
Container label: pangolin.public-resources.web-app.targets[0].site=my-site

methodstring

Upstream protocol for HTTP resources.

Options: http, https, h2c

YAML: method: http
Container label: pangolin.public-resources.web-app.targets[0].method=http

hostnamestringrequired

Target hostname or IP address.

YAML: hostname: app
Container label: pangolin.public-resources.web-app.targets[0].hostname=app

portintegerrequired

Target port.

YAML: port: 8080
Container label: pangolin.public-resources.web-app.targets[0].port=8080

enabledboolean

Disables the target without deleting it.

YAML: enabled: true
Container label: pangolin.public-resources.web-app.targets[0].enabled=true

internal-portinteger

Internal port override used in container-oriented setups.

YAML: internal-port: 8080
Container label: pangolin.public-resources.web-app.targets[0].internal-port=8080

pathstring

Path condition used for HTTP routing.

YAML: path: /
Container label: pangolin.public-resources.web-app.targets[0].path=/

path-matchstring

Matching mode for path.

Options: exact, prefix, regex

rewrite-pathstring

Replacement path or prefix used during path rewriting.

YAML: rewrite-path: /
Container label: pangolin.public-resources.web-app.targets[0].rewrite-path=/

rewritePathstringdeprecated

Deprecated alias for rewrite-path.

rewrite-matchstring

Rewrite mode.

Options: exact, prefix, regex, stripPrefix

priorityinteger

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

healthcheckobject

Health monitoring for the target.

Show Healthcheck objectHide Healthcheck object
hostnamestringrequired

Hostname or IP used for the health check.

portintegerrequired

Port used for the health check.

enabledboolean

Enables health checking for the target.

pathstringrequired

HTTP path to check, such as /health.

schemestring

Scheme to use for the check.

modestring

Health check mode supported by the schema.

intervalinteger

Check interval while the target is healthy.

unhealthy-intervalinteger

Check interval while the target is unhealthy.

unhealthyIntervalintegerdeprecated

Deprecated alias for unhealthy-interval.

timeoutinteger

Timeout for each health check attempt.

headersarray of objects

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

Show Healthcheck header objectHide Healthcheck header object
namestringrequired

Header name.

valuestringrequired

Header value.

follow-redirectsboolean

Whether redirects should be followed.

followRedirectsbooleandeprecated

Deprecated alias for follow-redirects.

methodstring

HTTP method for the check request.

statusinteger

Expected HTTP status code.

Private Resource Object (private-resources)

private-resources:
  internal-net:
    name: Internal Network
    mode: cidr
    sites:
      - my-site
    destination: 10.0.0.0/24
    enabled: true
    tcp-ports: "22,443"
    udp-ports: "53"
    disable-icmp: false
    alias: "*.internal.example.com"
    roles:
      - Member
    users:
      - user@example.com
    machines:
      - machine-id-1
    labels:
      - production

  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
    enabled: true
Show Private resource referenceHide Private resource reference
<resource_key>object

A single private resource definition.

Show Resource fieldsHide Resource fields
namestringrequired

Display name for the resource.

YAML: name: Internal Network
Container label: pangolin.private-resources.internal-net.name=Internal Network

modestringrequired

Private resource type.

Options: host, cidr, http, ssh, inference, exit-node

  • 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).
  • inference: A private AI Gateway exposed to clients via full-domain, proxying to attached ai-providers instead of a destination.
  • exit-node: Sends all of a client's internet traffic out through the site network. Does not take a destination; all ports and ICMP are always allowed. gateway is accepted as an alias.

YAML: mode: cidr
Container label: pangolin.private-resources.internal-net.mode=cidr

sitesarray of strings

Sites that host the resource. Optional when deploying from a site. If omitted, the resource is assigned to the site 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

sitestringdeprecated

Deprecated. Use sites instead.

YAML: site: my-site
Container label: pangolin.private-resources.internal-net.site=my-site

destinationstring

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
  • inference: not used; the resource proxies to ai-providers instead
  • exit-node: not used; always routes 0.0.0.0/0

YAML: destination: 10.0.0.0/24
Container label: pangolin.private-resources.internal-net.destination=10.0.0.0/24

auth-daemonobject

Auth-daemon configuration.

Show Auth-daemon objectHide Auth-daemon object
pamstring

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

modestring

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

portinteger

Remote auth-daemon port. Required when auth-daemon.mode is remote.

destination-portinteger

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

full-domainstring

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

sslboolean

Whether SSL/TLS should be used when serving the private HTTP resource.

YAML: ssl: true
Container label: pangolin.private-resources.internal-app.ssl=true

schemestring

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

enabledboolean

Disables the resource without removing it.

YAML: enabled: true
Container label: pangolin.private-resources.internal-net.enabled=true

tcp-portsstring

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

udp-portsstring

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

disable-icmpboolean

Prevents ICMP traffic such as ping.

Default: false

YAML: disable-icmp: false
Container label: pangolin.private-resources.internal-net.disable-icmp=false

aliasstring

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

rolesarray of strings

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

usersarray of strings

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

machinesarray of strings

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

labelsarray of strings

Resource labels to attach, by name. Labels that don't already exist in the organization are created automatically.

Container labels for arrays must include an index ([0], [1], ...).

YAML: labels: [production]
Container label: pangolin.private-resources.internal-net.labels[0]=production

ai-providersarray of objects

AI providers attached to an AI Gateway resource. Only allowed when mode: inference. Same shape as ai-providers on public resources.

Container labels for arrays must include an index ([0], [1], ...).

YAML: ai-providers: [{ provider: openai-prod, access-mode: inherit }]
Container label: pangolin.private-resources.ai-gateway.ai-providers[0].provider=openai-prod

ai-budgetarray of objects

Spend or usage budgets enforced on an AI Gateway resource. Each entry must use a unique unit/period combination. Same shape as ai-budget on public resources.

Container labels for arrays must include an index ([0], [1], ...).

YAML: ai-budget: [{ amount: 100, unit: usd, period: monthly }]
Container label: pangolin.private-resources.ai-gateway.ai-budget[0].amount=100

Resource Policy Object (public-policies)

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
Show Resource policy referenceHide Resource policy reference
<policy_key>object

A reusable policy definition that can be referenced by public resources via policy.

Show Policy fieldsHide Policy fields
namestringrequired

Display name for the policy.

ssoboolean

Enables SSO for the policy.

Default: true

auto-login-idpinteger | null

Identity provider ID to redirect to automatically.

sso-rolesarray of strings

Roles allowed by this policy. Admin is not allowed.

sso-usersarray of strings

Specific users allowed by this policy.

passwordstring | null

Optional shared password.

pincodestring | null

Optional 6-digit PIN.

basic-authobject | null

Optional basic-auth gate.

Show Basic auth objectHide Basic auth object
userstringrequired

Basic auth username.

passwordstringrequired

Basic auth password.

extended-compatibilityboolean

Compatibility flag for basic auth behavior.

Default: true

email-whitelist-enabledboolean

Enables email whitelist matching.

Default: false

whitelist-usersarray of strings

Allowed email addresses or wildcard-domain entries like *@example.com.

apply-rulesboolean

Enables rule evaluation.

Default: false

rulesarray of rule objects

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, mode: inference, or mode: exit-node.
  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.
  11. mode: inference (public or private) requires full-domain, must not have targets, and is the only mode that may set ai-providers.
  12. ai-budget entries on a resource must each use a unique unit/period combination.

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', 'inference', or 'gateway'"

Private resources need a destination except for SSH resources using native auth-daemon mode, inference resources, and exit-node (gateway) resources.

"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.

"'ai-providers' can only be set when mode is 'inference'"

ai-providers is only valid on public or private resources with mode: inference.

"When mode is 'inference', 'targets' must not be provided"

Public resources with mode: inference proxy to ai-providers and cannot also define targets.

"'ai-budget' entries must not overlap: only one budget per unit/period combination is allowed"

Each entry in ai-budget must use a distinct unit/period pair, such as one usd/monthly budget and one tokens/daily budget on the same resource.

"'models' can only be set on a provider with access-mode 'select'"

Set models only when the ai-providers entry uses access-mode: select. Entries using access-mode: inherit must leave models empty.

Was this page helpful?

⌘I

On this page

BenefitsUse CasesHow Blueprints WorkBlueprint Mental ModelChoose A FormatYAMLContainer LabelsHow YAML Blueprints Are AppliedQuick Start YAML ExamplePublic ResourcesHTTP Resource ExampleRaw TCP Or UDP ExampleTargets-Only ResourcesAuthentication ExampleMaintenance Page (EE)AI Gateway (Inference) ExamplePrivate ResourcesExit Node ExampleResource LabelsContainer Labels FormatEnable Container Label DiscoveryDocker Compose ExampleContainer Label BehaviorConfiguration ReferenceTop-Level ObjectPublic Resource Object (public-resources)Private Resource Object (private-resources)Resource Policy Object (public-policies)Validation Rules And ConstraintsCore RulesCommon Validation Errors"Admin role cannot be included in sso-roles""Duplicate 'full-domain' values found""Duplicate 'proxy-port' values found in public-resources""When protocol is 'http', all targets must have a 'method' field""When protocol is 'tcp' or 'udp', targets must not have a 'method' field""When protocol is 'tcp' or 'udp', 'auth' must not be provided""'proxy-protocol' and 'proxy-protocol-version' can only be set when mode is 'tcp'""port is required when auth-daemon mode is 'remote'""destination is required unless mode is 'ssh' with auth-daemon mode 'native', 'inference', or 'gateway'""Resource must either be targets-only or have both 'name' and 'protocol' fields""Duplicate 'alias' values found in private-resources""Destination must be a valid IP address or valid domain AND alias is required""Destination must be a valid CIDR notation for cidr mode""Admin role cannot be included in roles""'ai-providers' can only be set when mode is 'inference'""When mode is 'inference', 'targets' must not be provided""'ai-budget' entries must not overlap: only one budget per unit/period combination is allowed""'models' can only be set on a provider with access-mode 'select'"