feat(network): mint WireGuard peer keys for a non-public path to OpenBao - #53
Merged
Conversation
Mints a WireGuard server keypair plus one keypair per human/CI peer, renders full wg-quick configs per peer (server pubkey, allowed IPs, persistent keepalive, split-DNS pointing scalepack.fr at the tunnel's own address). Endpoint is a stable external-dns hostname (wg.scalepack.fr:30820), not a raw node IP, so it survives node/cluster churn. Peer private keys are never bulk-written to disk: `peer_confs` is a sensitive output, and mise's vpn-generate/vpn-up/vpn-down tasks extract and manage exactly one peer's own file at a time — anyone running `terraform apply` on this root doesn't end up with every peer's plaintext key on their machine. Goal: eliminate OpenBao's public gateway route as a dependency for this repo's own `vault` provider, without a third-party control plane (no Tailscale). Human OIDC/UI login via Dex stays on the public route, untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZMCuQ5t9hdrmUctLk7hEv
Kapsule's default "default security group" allows zero inbound traffic. Adds a scaleway_instance_security_group with a default-drop stance plus one explicit allow rule for UDP/30820 (the WireGuard NodePort), attached to the node pool via security_group_id — an in-place update, not a pool recreate (verified against the provider's Go source: that field isn't ForceNew, despite an adjacent field's ForceNew warning in the docs being easy to misattribute to it). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZMCuQ5t9hdrmUctLk7hEv
…-paste The `vault` provider in 05-secrets/openbao/managed now defaults to openbao.scalepack.fr resolving through the WireGuard tunnel's split-DNS (same hostname either way — falls back to the real public route if the tunnel's down, which is fine, that route still exists for human OIDC/UI login). A commented-out direct port-forward address is kept as a documented fallback for breaking any future tunnel/OpenBao chicken-and-egg deadlock. Both the WireGuard server private key and the CI peer's private key are now read straight from 04-vpn/wireguard's state via terraform_remote_state instead of hand-copied between files, matching this repo's existing convention for cross-root secrets. Also syncs full rendered peer configs into OpenBao (apps/wireguard/confs) for self-service retrieval without needing local Terraform state. data_json_wo_version bumped 1->2 on both new WireGuard KV secrets: write- only diffing can't detect a raft snapshot restoring OpenBao from before these were first written (confirmed live 2026-08-10 after a full cluster rebuild), so the version bump is what re-triggers the write. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZMCuQ5t9hdrmUctLk7hEv
nbrieussel
force-pushed
the
feature/openbao-wireguard-tunnel
branch
from
August 11, 2026 09:04
c7a9833 to
f70d292
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Terraform's
vaultprovider (05-secrets/openbao/{bootstrap,managed}) no longer needs the public gateway route for its own sake — it authenticates through a self-hosted WireGuard tunnel instead. Human OIDC/UI login (gitops repo'sservices/platform/openbao/config) is untouched and stays public.04-vpn/wireguarddomain — explicitly temporary (see its README for why neither01-iam/nor05-secrets/quite fits a WireGuard peer identity yet). Mints one keypair per peer + the tunnel server's own keypair viaOJFord/wireguard.terraform applygenerates a ready-to-importwg-quickconfig per peer (data.wireguard_config_document+local_sensitive_file, written togenerated/*.conf, gitignored) — no manual key assembly.wg_endpointdefaults towg.scalepack.fr:30820, a hostname external-dns keeps pointed at whichever node currently hosts the tunnel server — survives this cluster's daily destroy/rebuild with zero manual intervention.05-secrets/openbao/{bootstrap,managed}/version.tf: thevaultprovider now uses the same hostname as the public route (https://openbao.scalepack.fr/) — split-DNS (gitops companion PR) resolves it through the tunnel while up, or the real public route otherwise. Same address either way.10-cluster/scaleway/main.tf: dedicatedscaleway_instance_security_groupon the node pool — Scaleway's auto-managed default group ships with zero inbound rules and blocks all direct traffic to a node's public IP, discovered live while debugging the NodePort exposure.mise run vpn-generate/vpn-up/vpn-downtasks —wg-quick's own bare-name config lookup doesn't find Terraform-generated configs, these handle that plus always forcing the correct Terraform workspace first.Companion PR in
gitops: IntegratedDynamic/gitops#22 (tunnel server, Gateway exposure, split-DNS, generic Gateway passthrough).Design notes / dead ends ruled out live
net.ipv4.ip_forward+ iptables MASQUERADE) — blocked by Kapsule's kubelet not allowlisting that sysctl, and Scaleway'skubelet_argsAPI refusing to widen it for this cluster's k8s version at all. Replaced with an application-layer proxy (gitops side).UDPRoutethere is never reachable no matter how correctly configured. Moved to a hardened NodePort instead (externalTrafficPolicy: Local+ explicitNetworkPolicy+ the dedicated security group above).proxy-openbao:8200sidecar bypassing the Gateway entirely for Terraform's API access — reasoned as avoiding Gateway/TLS dependency for a machine credential, but that didn't hold up: OpenBao'sHTTPRoutehas no path restriction, so it routes through the generic Gateway passthrough exactly like the UI does. Removed in favor of one generic mechanism.Test plan
terraform validate/planclean on all touched rootsterraform providers lockregenerated for both platforms where providers changedcurlto OpenBao through the tunnel, a realterraform planon05-secrets/openbao/managedthrough the tunnel (both the direct-port and final consolidated-hostname address), Grafana OIDC login through the tunnel (proves the split-DNS + Gateway-passthrough design generalizes beyond OpenBao)