Files
57_Wolve 573785f2cc feat(headscale): add file-based ACL policy
Ship policy.hujson (mounted + installed on first deploy, edits preserved) and
wire policy.mode=file / policy.path in config.yaml. Translate the Tailscale
"grants" default into headscale's legacy "acls" format (self-access, tag:shared,
Tailscale SSH), since headscale 0.28 doesn't support grants. Embed in deploy.sh
and document `headscale policy check`.
2026-06-12 16:04:24 -05:00

98 lines
2.7 KiB
YAML

# headscale config.yaml -- 0.28.0
#
# Placeholder tokens (UPPER_SNAKE wrapped in double underscores) are
# substituted at deploy time by deploy.sh from the values in .env. Don't set
# them here directly unless you're running headscale outside the deploy script.
server_url: https://__HEADSCALE_DOMAIN__
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
# gRPC remote-control API. Disabled by default; clients use the standard
# `headscale` CLI inside the container instead. Uncomment + expose if you
# want remote admin.
# grpc_listen_addr: 0.0.0.0:50443
# grpc_allow_insecure: false
noise:
private_key_path: /var/lib/headscale/noise_private.key
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
allocation: sequential
# DERP: use Tailscale's public DERP map. Embedded DERP server stays off so
# we don't need to open UDP/3478 publicly.
derp:
server:
enabled: false
urls:
- https://controlplane.tailscale.com/derpmap/default
paths: []
auto_update_enabled: true
update_frequency: 24h
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
wal_autocheckpoint: 1000
log:
level: info
format: text
# ACL policy, loaded from a HuJSON file (see policy.hujson, mounted into the
# container). headscale uses Tailscale's legacy "acls" format, not "grants".
policy:
mode: file
path: /etc/headscale/policy.hujson
# Magic DNS for the tailnet. base_domain becomes the suffix for node
# DNS names (e.g. laptop.__TAILNET_DOMAIN__).
dns:
magic_dns: true
base_domain: __TAILNET_DOMAIN__
override_local_dns: false
nameservers:
global:
- 1.1.1.1
- 1.0.0.1
- 2606:4700:4700::1111
- 2606:4700:4700::1001
split: {}
search_domains: []
extra_records: []
# OIDC: delegate authentication to the pocket-id deployment. Register a
# new OIDC client in pocket-id with redirect URI:
# https://__HEADSCALE_DOMAIN__/oidc/callback
oidc:
only_start_if_oidc_is_available: true
issuer: https://__POCKETID_DOMAIN__
client_id: __OIDC_CLIENT_ID__
client_secret: __OIDC_CLIENT_SECRET__
scope:
- openid
- profile
- email
# PKCE protects the authorization-code exchange. Enabled with the S256
# challenge method -- make sure the pocket-id OIDC client also has PKCE on.
pkce:
enabled: true
method: S256
# Restrict who can register a node. Uncomment one or more.
# allowed_users:
# - alice@example.com
# allowed_groups:
# - tailscale-admins
# allowed_domains:
# - example.com
# How long a node stays authenticated before re-auth is required. This is a
# duration scalar (not a map). use_expiry_from_token overrides it with the
# OIDC token's own expiry when true.
expiry: 180d
use_expiry_from_token: false