Guides

Dashboard

Overview

The ASD Dashboard is a browser-based control panel for monitoring and managing your exposed services. It runs locally at http://asd.localhost/ and is also available as a hosted version at https://dashboard.asd.engineer.

Open the local dashboard by running:

asd net

The asd net TUI shows all registered services with their status, URLs, and quick actions. Press Enter on any service to open an actions menu. The browser-based dashboard at http://asd.localhost/ provides the same information in a widget layout where each service gets its own card.

Fragment URL Strategy

The ASD Dashboard uses a privacy-first architecture based on fragment URLs. This is a deliberate design choice that sets it apart from typical dashboards where service data lives on the server.

How It Works

When you open the dashboard or share a service URL, all sensitive data is encoded in the URL fragment (the part after #):

https://dashboard.asd.engineer/#eyJzZXJ2aWNlcyI6W3sibmFtZSI6Im...

The fragment is never sent to the server. This is a fundamental property of URLs defined in RFC 3986: browsers do not include the fragment in HTTP requests. The dashboard server receives a request for / and serves the static HTML/JS application. All service data, credentials, and configuration stay entirely in your browser.

What This Means

AspectTraditional DashboardASD Fragment Dashboard
Service data storageServer databaseYour browser only
Server knows your servicesYesNo
URL sharingRequires accountCopy and paste the URL
PrivacyDepends on server trustCryptographically guaranteed
Offline supportNoYes (cached app shell)

The backend serves only static assets. It has no database, no user accounts, no session storage. It literally cannot see your service data because the fragment never reaches it.

Sharing Services

To share your service dashboard with a teammate:

  1. Open asd net and select a service
  2. Choose “Copy Dashboard URL”
  3. Send the URL to your teammate

The recipient opens the URL, the fragment is decoded client-side, and they see your service status. No account needed, no server involved.

Encoding Format

The fragment contains a base64-encoded JSON payload:

{
  "services": [
    {
      "name": "frontend",
      "localUrl": "http://localhost:5173",
      "caddyUrl": "http://app.localhost",
      "tunnelUrl": "https://app-abc123.eu1.tn.asd.engineer",
      "status": "online"
    }
  ],
  "settings": {
    "theme": "dark"
  }
}

This means:

  • Bookmarking a dashboard URL preserves the full state
  • Sharing a URL shares the exact view
  • No synchronization needed between devices
  • The server never processes or stores this data

Dashboard Configuration in asd.yaml

Configure the dashboard layout through the hub: section in your asd.yaml:

hub:
  globalSettings:
    theme: "dark"
    hideBoardControl: true
    hideViewControl: true
    hideServiceControl: false
    showMenuWidget: false
    views:
      showViewOptionsAsButtons: true
      viewToShow: "Terminal"

  boards:
    - name: "Development"
      order: 1
      views:
        - name: "Services"
          maxInstances: 10
          widgets:
            - type: "service"
              serviceId: "frontend"
              columns: 4
              rows: 4
              order: "0"
            - type: "service"
              serviceId: "api"
              columns: 4
              rows: 4
              order: "1"

Global Settings

PropertyTypeDescription
theme"dark" or "light"Dashboard color theme
hideBoardControlbooleanHide the board switcher
hideViewControlbooleanHide the view mode switcher
hideServiceControlbooleanHide per-service action buttons
showMenuWidgetbooleanShow the navigation menu widget

Boards and Views

The dashboard organizes services into boards. Each board contains views, and each view contains widgets.

A widget represents one service card in the dashboard:

PropertyTypeDescription
type"service"Widget type
serviceIdstringService ID from your asd.yaml
columnsnumberWidget width in grid columns
rowsnumberWidget height in grid rows
orderstringDisplay order

Local vs Hosted Dashboard

FeatureLocal (asd.localhost)Hosted (dashboard.asd.engineer)
Service dataReal-time from CaddyFrom fragment URL only
Auto-refreshYesNo (static snapshot)
Actions (start/stop)YesNo (read-only)
Health checksLiveSnapshot from share time
Account requiredNoNo

The local dashboard connects to the Caddy admin API for real-time service data. The hosted dashboard is a read-only viewer that decodes whatever is in the fragment URL.

Upcoming: Team Module

The Team module is an upcoming feature that adds persistent, server-side service sharing for teams. It is the counterpart to the fragment URL strategy.

Fragment URLs vs Team Module

AspectFragment URLs (current)Team Module (upcoming)
Privacy modelZero-knowledge, backend sees nothingServer stores service registry
SharingCopy URL, one-time snapshotPersistent, real-time team view
AuthenticationNone neededASD account + team membership
Service updatesManual re-shareAutomatic sync
Use caseQuick sharing, demos, privacy-firstOngoing team collaboration

What the Team Module Will Add

  • Persistent service registry: Team members see each other’s exposed services in real time
  • Team dashboard: A shared view at dashboard.asd.engineer that shows all team services
  • Access control: Only team members with the right permissions see services
  • Service discovery: Find a teammate’s service by name instead of exchanging URLs
  • Audit trail: Track who exposed what and when

The fragment URL approach remains available. It does not go away. The Team module adds an opt-in layer on top for teams that want persistent, synchronized service visibility. When you expose a service with asd expose, you choose whether it appears in your team dashboard or stays private.

Architecture Difference

Fragment URLs:

Your browser <--fragment data--> URL (never reaches server)

Team module:

Your CLI --> ASD API --> Team service registry --> Teammate's dashboard

The two approaches serve different needs. Use fragment URLs when you want privacy and zero-server-trust. Use the Team module when you want real-time team collaboration.

Iframe Embedding

The dashboard can be embedded in other applications via iframe. Configure the allowed origin in your service definitions:

network:
  services:
    dashboard:
      dial: "127.0.0.1:3000"
      iframeOrigin: "https://dashboard.asd.engineer"
      deleteResponseHeaders:
        - "Content-Security-Policy"
        - "X-Frame-Options"

The iframeOrigin property sets the X-Frame-Options: ALLOW-FROM <origin> header. Caddy strips conflicting headers from the upstream and replaces them with its own.

Related Guides