# Dev Tunnels integration

<Image
  src={devTunnelsIcon}
  alt="Dev Tunnels logo"
  width={80}
  height={80}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

[Dev tunnels](https://learn.microsoft.com/azure/developer/dev-tunnels/overview) allow developers to securely share local web services across the internet. Enabling you to connect your local development environment with cloud services, share work in progress with colleagues or aid in building webhooks. Dev tunnels is for adhoc testing and development, not for production workloads.
**Danger:** Dev tunnels are for ad-hoc testing and development, not for production
  workloads.

Dev tunnels are useful for:

- Sharing a running local service (for example, a Web API) with teammates, mobile devices, or webhooks
- Testing incoming callbacks from external SaaS systems (GitHub / Stripe / etc.) without deploying
- Quickly publishing a temporary, TLS-terminated endpoint during development
**Note:** By default tunnels require authentication and are available only to the user
  who created them. You can selectively enable anonymous (public) access per
  tunnel or per individual port.

## Prerequisites

Before you create a dev tunnel, you first need to download and install the devtunnel CLI (Command Line Interface) tool that corresponds to your operating system. See the [devtunnel CLI installation documentation](https://learn.microsoft.com/azure/developer/dev-tunnels/get-started#install) for more details.

## Hosting integration

To get started with the Dev Tunnels integration, install the [📦 Aspire.Hosting.DevTunnels](https://www.nuget.org/packages/Aspire.Hosting.DevTunnels) NuGet package in the AppHost project:

<InstallPackage
  packageName="Aspire.Hosting.DevTunnels"
  shortName="devtunnels"
  prerelease={true}
/>

### Add a dev tunnel resource

In the AppHost project, add a dev tunnel and configure it to expose specific resources:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var web = builder.AddProject<Projects.Web>("web");

var tunnel = builder.AddDevTunnel("my-tunnel")
                    .WithReference(web);
```

When you run the AppHost, the dev tunnel is created to expose the web application endpoints publicly. The tunnel URLs are shown in the Aspire dashboard. By default, the tunnel requires authentication and is available only to the user who created it.

### Allow anonymous access

To allow anonymous (public) access to the entire tunnel, chain a call to the `WithAnonymousAccess` method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var web = builder.AddProject<Projects.Web>("web");

var tunnel = builder.AddDevTunnel("public-api")
                    .WithReference(web)
                    .WithAnonymousAccess();
```

### Configure dev tunnel options

To configure other options for the dev tunnel, provide the `DevTunnelOptions` to the `AddDevTunnel` method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var web = builder.AddProject<Projects.Web>("web");

var options = new DevTunnelOptions
{
    TunnelId = "my-tunnel-id",
    Description = "QA environment tunnel",
    Labels = new[] { "qa", "testing" },
    AllowAnonymous = false
};

var tunnel = builder.AddDevTunnel("qa", options)
                    .WithReference(web);
```

### Configure for mixed access

To allow anonymous access to specific endpoints, use the appropriate `WithReference` overload:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var api = builder.AddProject<Projects.Api>("api");

var tunnel = builder.AddDevTunnel("mixed-access")
                    .WithReference(api, "public", allowAnonymous: true)
                    .WithReference(api, "admin", allowAnonymous: false);
```

The preceding code exposes:

- The `public` endpoint of the `api` project with anonymous access
- The `admin` endpoint of the `api` project that requires authentication

### Service discovery integration

When another resource references a dev tunnel, environment variables are injected using the Aspire service discovery configuration format:

```dotenv
WEB_HTTPS=https://myweb-1234.westeurope.devtunnels.ms/
services__web__https__0=https://myweb-1234.westeurope.devtunnels.ms/
```

This lets downstream resources use the tunneled address exactly like any other Aspire service discovery entry.
**Note:** Referencing a tunnel delays the consumer resource's start until the tunnel has
  started and its endpoint is fully allocated.
**Danger:** Dev tunnels are a development time concern only and aren't included when
  publishing or deploying an AppHost, including any service discovery
  information.

## Configuration

### Dev tunnel options

The `DevTunnelOptions` class provides several configuration options:

| Property         | Description                                                            |
| ---------------- | ---------------------------------------------------------------------- |
| `Description`    | A description for the tunnel that appears in the dev tunnels service   |
| `Labels`         | A list of labels to apply to the tunnel for organization and filtering |
| `AllowAnonymous` | Whether to allow anonymous access to the entire tunnel                 |

### Dev tunnel port options

The `DevTunnelPortOptions` class provides configuration for individual tunnel ports:

| Property         | Description                                                                                    |
| ---------------- | ---------------------------------------------------------------------------------------------- |
| `Protocol`       | The protocol to use (`http`, `https`, or `auto`). If not specified, uses the endpoint's scheme |
| `Description`    | A description for this specific port                                                           |
| `Labels`         | Labels to apply to this port                                                                   |
| `AllowAnonymous` | Whether to allow anonymous access to this specific port                                        |

### Security considerations

- Prefer authenticated tunnels during normal development
- Only enable anonymous access for endpoints that are safe to expose publicly
- Treat public tunnel URLs as temporary & untrusted (rate limit / validate input server-side)

### Tunnel lifecycle

Dev tunnels automatically:

- Install the devtunnel CLI if not already available
- Ensure the user is logged in to the dev tunnels service
- Create and manage tunnel lifecycle
- Clean up unmodeled ports from previous runs
- Provide detailed logging and diagnostics

Tunnels will expire after not being hosted for 30 days by default, so they won't be forcibly deleted when the resource or AppHost is stopped.

### Troubleshooting

#### Authentication required

If you see authentication errors, ensure you're logged in to the dev tunnels service:

```bash
devtunnel user login
```

#### Port conflicts

If you encounter port binding issues, check that no other processes are using the same ports, or configure different ports for your endpoints.

#### Tunnel not accessible

Verify that:

- The tunnel is running and healthy in the Aspire dashboard
- You're using the correct tunnel URL
- Anonymous access is configured correctly if accessing without authentication