diff --git a/nix/host-modules/hive-forge/default.nix b/nix/host-modules/hive-forge/default.nix index b36cfb45..790658fa 100644 --- a/nix/host-modules/hive-forge/default.nix +++ b/nix/host-modules/hive-forge/default.nix @@ -818,7 +818,32 @@ in # `external` alone would deny (so they'd only ever be caught by # the 5-min poll fallback). Naming the single gateway host is # tighter than the broad `private` builtin. - webhook.ALLOWED_HOST_LIST = "external,${hyperhiveDomain}"; + # + # ⚠️ The SWARM domain is on this list too, and leaving it off is + # what made every swarm-controller delivery fail. Those webhooks + # target `https:///webhook/forge/*` — a different + # host from the hive's, resolving to the same private gateway IP, + # so `external` denies it and the hive entry does not cover it. + # Measured from the sender's own log, which names both the host + # and the rule: + # + # deny 'constellation.darkest.space(10.42.0.1:443)' + # webhook can only call allowed HTTP servers + # (check your webhook.ALLOWED_HOST_LIST setting) + # + # `optional` because a hive with no swarm has no such domain, and + # `unique` because an all-local deployment can legitimately set + # both to the same string — a duplicate entry is harmless to + # forgejo but reads as a mistake. + webhook.ALLOWED_HOST_LIST = lib.concatStringsSep "," ( + lib.unique ( + [ + "external" + hyperhiveDomain + ] + ++ lib.optional (swarmDomain != null) swarmDomain + ) + ); log.LEVEL = "Warn"; # Pinned explicitly rather than left to upstream's default # (currently `bleve`, a separate full-text index Forgejo