Connections

Project Networks

Declare private connectivity boundaries, expose selected project interfaces, and identify outbound consumers that need a tailnet route.

A network block declares the private connectivity a project needs. Multiple named networks can be represented in the source and inspected in Cloud.

Current availability: named tailnet binding, private ingress publication, and execution gateways are not implemented yet. Declaring a network does not create a working private route. Consumers with network: fail before dialing; they do not fall back to the public internet.

Declare the intended network boundary when customers need to reach a Swirls app, form, webhook, MCP channel, or database without publishing it to the public internet, or when a Swirls workflow or agent must call an on-prem or tailnet-only service.

Project Networks separate two decisions:

  • The network block owns what Swirls exposes into that private network.
  • Each outbound consumer chooses the network it reaches through with network: <name>.

Declare a network

network corporate {
  label: "Corporate network"
  description: "Private operations and internal systems"

  expose: {
    apps: [operations]
    channels: [support_mcp]
    forms: [employee_intake]
    webhooks: [internal_events]
    databases: [
      {
        database: crm
        connections: [application, analytics]
      }
    ]
  }
}

label, description, and the entire expose block are optional. An empty network is useful when the project only needs outbound access.

ExposureWhat the name refers to
appsTop-level app blocks
channelsmcp, web, or swirls channel blocks with a Swirls-hosted interface
formsTop-level form blocks
webhooksTop-level webhook blocks
databasesA managed database plus the exact nested named connections to expose
servicesReserved for the service primitive; currently rejected by validation

Select the named database connections to expose. Declaring a database alone does not expose it to the network.

Reach private services

Set network: on the consumer that owns the destination. The following node belongs inside a workflow:

node fetch_customer {
  type: http
  url: "https://crm.internal/api/customer"
  network: corporate
}

MCP and Postgres resources are top-level declarations:

mcp operations_tools {
  url: "https://mcp.internal/mcp"
  auth: static
  network: corporate
}

postgres warehouse {
  connection: WAREHOUSE_DATABASE_URL
  network: corporate

  table events {
    schema: @json { { "type": "object" } }
  }
}

Self-managed connection blocks also accept network: when they declare base_url: and auth:. Managed OAuth connections do not: their provider transport remains Swirls-managed.

A network-aware HTTP node must use a static absolute http or https URL. A dynamic @ts URL is rejected because Swirls must know the destination before it selects a private route.

Cloud inventory and bindings

After deployment, the project's Networks page shows every named declaration, the interfaces it exposes, and the outbound resources that consume it. This makes the private connectivity contract reviewable before infrastructure is attached.

The Bind network control is not available yet. The legacy project-network API configures shared transport but does not activate named DSL networks.

Multiple networks

Declare as many networks as the project needs. For example, corporate might connect employee systems while customer_acme reaches a customer's tailnet. An interface or consumer is attached only where it is named, which keeps boundaries explicit in source review.

On this page