Security & Authentication
Overview
When you expose a local service through ASD, it becomes accessible via a public HTTPS URL. ASD provides three security levels so you can choose the right balance between convenience and protection for every scenario.
All tunnel traffic is encrypted end-to-end via SSH tunnels and served over HTTPS with automatic TLS certificates β your data is always encrypted in transit regardless of the authentication level you choose.
| Level | Protection | Best For |
|---|---|---|
| No Auth | URL secrecy only | Local development, quick demos |
| Basic Password | HTTP Basic Authentication | Remote access, team sharing |
| Tunnel Tokens | Credential-based access | CI/CD pipelines, automation |
Level 1: Open Access (Default)
When you expose a service without configuring authentication, anyone who knows the tunnel URL can access it.
asd expose 3000
# Your service is now at: https://myapp-abc123.eu1.tn.asd.engineer The URL itself acts as a lightweight secret β it contains a unique client ID that is difficult to guess. This is perfectly adequate for short-lived sessions where you control who receives the link.
When open access is appropriate:
- Sharing work-in-progress with a trusted teammate
- Quick demos lasting less than an hour
- Testing webhooks from external services (Stripe, GitHub, etc.)
- Local-only access via
localhost
When you should add authentication:
- Services displaying sensitive data (databases, admin panels)
- Long-running tunnels that stay active for hours or days
- Public demos where the URL might be shared beyond your intended audience
- Any service that provides shell or code access
Level 2: Basic Password Protection
HTTP Basic Authentication adds a username/password gate in front of your services. When a visitor accesses your tunnel URL, their browser displays a login prompt before any content is served.
Project-Wide Configuration
Enable authentication for all services in your project by adding basic_auth to your asd.yaml:
# asd.yaml
network:
caddy:
basic_auth:
enabled: true
realm: "My Project" Then set your credentials in the .env file (which is automatically gitignored):
# .env
ASD_BASIC_AUTH_USERNAME=admin
ASD_BASIC_AUTH_PASSWORD=your-secure-password-here After updating, apply the configuration:
asd net apply --caddy Every service in your project is now password-protected. Passwords are automatically hashed using bcrypt before being sent to Caddy β plaintext credentials never leave your machine.
Environment Variables
Credentials are resolved from environment variables with the following priority:
| Variable | Priority | Description |
|---|---|---|
ASD_BASIC_AUTH_USERNAME | 1 (primary) | Username for authentication |
TTYD_USERNAME | 2 (fallback) | Legacy fallback for ttyd compatibility |
ASD_BASIC_AUTH_PASSWORD | 1 (primary) | Password for authentication |
ASD_BASIC_PASSWORD | 2 (alternative) | Alternative password variable |
TTYD_PASSWORD | 3 (fallback) | Legacy fallback for ttyd compatibility |
Per-Service Overrides
You can override the project-level setting for individual services. This is useful when you want most services protected but need to leave a health-check endpoint or public API open:
# asd.yaml
network:
caddy:
basic_auth:
enabled: true
services:
public-api:
dial: "127.0.0.1:3000"
basic_auth:
enabled: false # No auth for this service
admin-panel:
dial: "127.0.0.1:8080"
basic_auth:
enabled: true
realm: "Admin Only" # Custom browser prompt text You can also do the reverse β leave project-level auth disabled and enable it only for specific sensitive services.
Route Types
The routes property controls which access patterns require authentication:
| Route Type | Description | Example URL |
|---|---|---|
host | Host-based routes | https://api.localhost |
path | Path-based routes | https://asd.localhost/api |
tunnel | Tunnel routes (remote) | https://myapp-abc123.eu1.tn.asd.engineer |
When routes is not specified, authentication applies to all route types. To protect only direct host access while allowing path-based embedding (useful for dashboards):
network:
caddy:
basic_auth:
enabled: true
routes: ["host"] # Only protect direct host access Security-Sensitive Services
Some built-in services are automatically flagged as security-sensitive because they provide shell or code-editing access to your machine:
| Service | Why Itβs Sensitive | Default Behavior |
|---|---|---|
| ttyd (Web Terminal) | Full shell access | Always requires TTYD_USERNAME and TTYD_PASSWORD |
| codeserver (VS Code) | Code editing + integrated terminal | Recommends password auth via ASD_CODESERVER_AUTH=password |
When project-level authentication is enabled, these services inherit it with routes: ["host"] by default, protecting the publicly-accessible host route while allowing internal path routes to remain open for dashboard embedding.
You can also mark your own services as security-sensitive:
network:
services:
my-admin-tool:
dial: "127.0.0.1:9000"
securitySensitive: true # Auto-applies auth with routes: ["host"] Level 3: Tunnel Tokens for Automation
For CI/CD pipelines, automated testing, and programmatic access, ASD provides token-based authentication that does not require interactive login.
Ephemeral Tokens (Quick Testing)
Get instant, no-account-required credentials that last 5 minutes:
curl -X POST https://asd.engineer/functions/v1/create-ephemeral-token The response includes a tunnel_client_id and tunnel_client_secret you can use immediately. These are ideal for quick tests, one-off demos, or trying ASD for the first time.
Dashboard Tokens (CI/CD)
For longer-lived automation, create persistent tunnel tokens from your ASD dashboard:
- Sign in at asd.host
- Navigate to Account > Tunnel Tokens > Create
- Copy the generated credentials into your CI/CD secrets
# In your CI environment variables or .env file
ASD_TUNNEL_TOKEN=your-token-from-dashboard
ASD_TUNNEL_USER=your-user-id Then use them in your pipeline:
asd expose 3000
# The tunnel authenticates automatically using the token Dashboard tokens are tied to your account and subscription plan. Token management β including creation, rotation, and revocation β is available through the workspace dashboard.
Choosing the Right Level
| Scenario | Recommended Level | Why |
|---|---|---|
| Local development | No Auth | URL is only on your machine |
| Quick demo (under 1 hour) | No Auth | URL is secret enough for short sessions |
| Remote access to your machine | Basic Password | Prevents unauthorized access |
| Sharing with teammates | Basic Password | Simple credential sharing |
| Public demo or presentation | Basic Password | Audience may share the URL |
| CI/CD pipelines | Tunnel Tokens | Automated, no interactive login |
| Production workloads | Do not use ASD tunnels | Use proper deployment infrastructure |
Password Best Practices
These guidelines apply to ASD_BASIC_AUTH_PASSWORD, TTYD_PASSWORD, and ASD_CODESERVER_PASSWORD:
- Use at least 12 characters with a mix of letters, numbers, and symbols
- Never reuse passwords across different services or environments
- Never commit credentials to git β store them in
.env(already gitignored by ASD) - Rotate passwords regularly, especially after sharing them with others
Generate a strong password from your terminal:
openssl rand -base64 24 For team environments, consider using ASD Vault to store and share credentials securely rather than passing them through chat or email.
Related Guides
- Vault β Secret Management β Encrypted secret storage for passwords and API keys
- Access Patterns β How local, Caddy, and tunnel access patterns work together
- Configuration Reference (asd.yaml) β Configure basic auth and service routing in your project