main
 1{den, ...}: {
 2  den.quirks.tailscaleGrant.description = ''
 3    Tailnet access grants emitted by aspects (host)
 4
 5    The destination is implicit (the emitting host's tailscale IPv4 and IPv6
 6    addresses) unless `dst` is set explicitly. Grants are collected fleet-wide
 7    and rendered into the headscale policy file.
 8
 9    Example:
10      {
11        src = ["*"];        # Sources allowed to connect
12        ip = ["tcp:22"];    # Network capabilities
13        app = [];           # Application capabilities (optional)
14        dst = null;         # Optional explicit destination ("tag:xxx")
15      }
16  '';
17
18  den.policies.collect-tailscale-grants = _: let
19    inherit (den.lib.policy) pipe;
20  in [
21    (pipe.from "tailscaleGrant" [
22      (pipe.collectAll ({host, ...}: true))
23      pipe.withProvenance
24    ])
25  ];
26
27  den.schema.host.includes = [den.policies.collect-tailscale-grants];
28}