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
networkblock 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.
| Exposure | What the name refers to |
|---|---|
apps | Top-level app blocks |
channels | mcp, web, or swirls channel blocks with a Swirls-hosted interface |
forms | Top-level form blocks |
webhooks | Top-level webhook blocks |
databases | A managed database plus the exact nested named connections to expose |
services | Reserved 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.
Related
- Connections: OAuth and self-managed API credential slots
- MCP servers: Remote tools agents consume
- Postgres: Existing databases a workflow queries
- Managed databases: Databases Swirls provisions, including named connections
Actions and the catalog
Typed provider operations installed with swirls add. Browse the integration catalog, install action blocks, generate them from any API spec, and request new providers.
Access
Declare who can run what. role blocks derive roles from verified identity attributes, and policy grants map those roles to agents, workflows, and tools.