---
name: Headscale Node Lifecycle
slug: headscale-node-lifecycle
category: Automation
description: Manage Headscale tailnet nodes across registration, approval, tagging, listing, and deletion. Use it for personal or tagged nodes, auth keys, and decommissioning.
github: "https://github.com/magnus919/agent-skills/tree/main/bundles/tailscale/skills/headscale-node-lifecycle"
language: Python
stars: 10
forks: 0
install: "git clone https://github.com/magnus919/agent-skills"
added: 2026-07-18T04:42:05.367Z
last_synced: 2026-07-18T04:42:05.367Z
canonical_url: "https://dirskills.com/skills/headscale-node-lifecycle"
---

# Headscale Node Lifecycle

Manage Headscale tailnet nodes across registration, approval, tagging, listing, and deletion. Use it for personal or tagged nodes, auth keys, and decommissioning.

**Install:** `git clone https://github.com/magnus919/agent-skills`

## README

# headscale-node-lifecycle

## Overview

Headscale manages nodes in a tailnet with two identity models:

- **Personal nodes** — registered under a specific user account (e.g. `yourname@domain`). The node key is tied to that user's identity.
- **Tagged nodes** — belong to the special `tagged-devices` user (created automatically by Headscale). These nodes are identified by one or more tags (e.g. `tag:webserver`, `tag:monitoring`) and are typically used for infrastructure service nodes.

Registration happens through:
1. **Web auth** — user visits a URL to authenticate with an OIDC/OAuth provider
2. **Pre-authenticated key (auth key)** — a one-time or reusable key generated by the admin that embeds tags, user, and expiry
3. **CLI / API** — direct node registration via `headscale` commands or REST API calls

## Pre-authenticated Keys

Auth keys streamline automated node registration. Key attributes:

| Parameter    | Description                                                      |
|-------------|------------------------------------------------------------------|
| Expiration   | Default: 1 hour. Use `0` for no expiry (not recommended).        |
| Reusable     | Single-use by default. Mark reusable for fleet provisioning.     |
| Ephemeral    | Ephemeral nodes are removed from the tailnet when they disconnect. Perfect for CI runners and ephemeral workloads. |
| Tags         | Assign tags to create a tagged node automatically.               |

## Node Registration

- **Personal nodes**: Create an auth key for a user → run `tailscale up --auth-key=<key>` on the device → approve in Headscale if registration is open.
- **Tagged nodes**: Create an auth key with `--tags` → run `tailscale up --auth-key=<key>` → the node is auto-approved and tagged.

## Node Listing

List nodes filtered by user, tag, or online status. Output includes:

- Node ID
- Name (hostname)
- Tailscale IP address(es)
- Assigned tags
- User/owner
- Online/offline status
- Last seen timestamp
- Operating system
- Tailscale client version

## Node Tagging

Tags can be added or replaced on existing nodes. Tags always carry the `tag:` prefix in Headscale. When adding tags, existing tags are preserved unless `--replace` is specified.

## Node Deletion

To decommission a node permanently:

```
headscale nodes delete -i <node-id>
```

Or via the REST API: `DELETE /api/v1/node/<node-id>`

Decommissioning is irreversible. For ephemeral nodes, disconnection alone is sufficient — the server removes them automatically.

## Environment

| Variable             | Description                   |
|---------------------|-------------------------------|
| `HEADSCALE_URL`     | Base URL of the Headscale server (e.g. `https://headscale.example.com`) |
| `HEADSCALE_API_KEY` | API key from `headscale apikeys create` |

Both env vars are required for API-based operations when the `headscale` CLI is not available on `PATH`.

## Gotchas

- **Auth key expiration**: Default is 1 hour. If you're provisioning a device and it takes longer, the key expires and registration fails. Set a longer expiry explicitly.
- **Tagged node user**: Tagged nodes always belong to the `tagged-devices` user. Do not try to assign them to a personal user.
- **Connectivity testing**: Nodes must be online (`Connected: true`) to test connectivity. Offline nodes do not respond to ping/ICMP within the tailnet.
- **CLI vs API**: When both are available, the CLI is preferred for interactive use. The REST API is preferred for automation scripts.
- **Key reuse**: Reusable keys are convenient but less secure. Use with care, especially in production environments.
- **Ephemeral nodes**: Setting `--ephemeral` means the node is fully removed on disconnection — there is no record of it in the tailnet afterward.

## Trigger Conditions

- "auth key"
- "preauthkey"
- "register node"
- "approve node"
- "tag node"
- "node list"
- "decommission node"

## Scripts

### hs-create-authkey.sh

Create pre-authenticated keys via Headscale CLI or REST API.

```
hs-create-authkey.sh --user <user> --tags <tag> --expiration <duration> --reusable --ephemeral [--json] [--dry-run]
```

### hs-list-nodes.sh

List all nodes in the tailnet with status and metadata.

```
hs-list-nodes.sh [--json] [--user <user>] [--tag <tag>] [--online-only]
```

### hs-approve-nodes.sh

Approve pending node registrations.

```
hs-approve-nodes.sh [--all] [--auth-id <id>] [--dry-run] [--json]
```

### hs-tag-node.sh

Update tags on an existing node.

```
hs-tag-node.sh --node <id/name> --tags <tag1,tag2> [--replace | --add] [--dry-run] [--json]
```
