Skip to content

feat: add NetBird self-hosted mesh VPN agent#2147

Merged
marcusquinn merged 6 commits intomainfrom
feature/netbird-agent
Feb 22, 2026
Merged

feat: add NetBird self-hosted mesh VPN agent#2147
marcusquinn merged 6 commits intomainfrom
feature/netbird-agent

Conversation

@marcusquinn
Copy link
Copy Markdown
Owner

@marcusquinn marcusquinn commented Feb 22, 2026

Summary

  • Add comprehensive NetBird subagent (services/networking/netbird.md) covering self-hosted WireGuard mesh VPN with SSO, ACLs, REST API, and Terraform provider
  • Update subagent-index.toon to register NetBird alongside Tailscale in the networking domain
  • Companion Cloudron app packaging repo created at ~/Git/cloudron/netbird-app/ (separate repo for git.cloudron.io submission)

Why NetBird

After evaluating Tailscale, Headscale, Netmaker, Firezone, OmniEdge, and NetBird:

  • Fully self-hosted control plane (AGPL server, BSD-3 client) -- no vendor lock-in
  • API-first with REST API + Terraform provider for automation
  • 22.9k GitHub stars, 124 contributors, German govt security backing (CISPA)
  • Best fit for aidevops: setup keys for AI worker provisioning, group-based ACLs, private DNS for service discovery

aidevops Integration Patterns

The agent documents:

  • AI worker mesh provisioning via setup keys
  • Access control groups (humans, ai-workers, build-servers, production)
  • Private DNS for service discovery
  • REST API automation examples
  • Terraform provider usage
  • Network routes for site-to-site (Proxmox subnet advertising)
  • Cloudron packaging feasibility assessment

Summary by CodeRabbit

  • Documentation

    • Added comprehensive NetBird docs: overview, install and client guides, architecture, deployment options, IdP/SSO and NAT notes, reverse proxy, health/upgrade workflows, provisioning tips, troubleshooting, and resources.
  • New Features

    • Expanded service catalog with analytics, monitoring, accounting, database (multi-org isolation), and document-processing offerings.
    • Added NetBird as an additional networking provider.
    • Enhanced tech-stack research tools with extra frontend detection providers.

…uide

Add comprehensive NetBird subagent covering self-hosted WireGuard mesh VPN
with SSO, ACLs, REST API, and Terraform provider. Includes aidevops
integration patterns for AI worker provisioning, access control groups,
private DNS, and API automation. Companion Cloudron app packaging repo
created at ~/Git/cloudron/netbird-app/.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces NetBird as a robust, self-hosted WireGuard mesh VPN solution, providing extensive documentation for its setup, configuration, and integration into various environments. The primary goal is to offer an alternative to proprietary VPN solutions, emphasizing full control, API-driven automation, and suitability for complex AI worker provisioning and secure access scenarios.

Highlights

  • New NetBird Subagent Documentation: A comprehensive subagent document for NetBird has been added, detailing its architecture, self-hosting requirements, client installation, and integration patterns for aidevops. This includes guidance on AI worker provisioning, access control groups, private DNS, API automation, and Terraform provider usage.
  • NetBird Integration into Networking Services: The subagent-index.toon file has been updated to register NetBird as a networking service, placing it alongside Tailscale as a mesh VPN and secure device connectivity option.
  • Emphasis on Self-Hosted Control and Automation: The documentation highlights NetBird's key advantages, such as its fully self-hosted control plane, API-first design, and Terraform provider, making it suitable for environments requiring full control and extensive automation, particularly for AI/DevOps workflows.
Changelog
  • .agents/services/networking/netbird.md
    • Added new file detailing NetBird's features, architecture, installation, and integration.
  • .agents/subagent-index.toon
    • Updated networking services entry to include 'netbird' as a recognized subagent.
Activity
  • No human activity has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 22, 2026

No actionable comments were generated in the recent review. 🎉


Walkthrough

Adds a new, extensive NetBird self‑hosted mesh‑VPN documentation file and updates the agent taxonomy to include netbird plus several new service and tooling entries (analytics, monitoring, accounting, database patterns, document processing, and tech‑stack research providers).

Changes

Cohort / File(s) Summary
NetBird Documentation
​.agents/services/networking/netbird.md
New long-form documentation describing NetBird: overview, architecture, self‑hosting options (Docker Compose, Coolify, Dokploy, Cloudron notes), IdP/SSO, NAT traversal, reverse‑proxy, health/upgrade workflows, aidevops integration, multi‑platform client install, CLI/API examples, troubleshooting, and resources.
Agent Taxonomy & Index
​.agents/subagent-index.toon
Updated networking providers to add netbird (alongside tailscale) and added multiple new catalog entries for services (analytics, monitoring, accounting, database multi‑org patterns, document processing) and tooling research providers (crft-lookup, openexplorer, wappalyzer).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🕸️ A mesh of docs, a net of light,
NetBird lands to guide the night.
Catalogs grow and tools align,
Deploy the guide, then cross the brine.
🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding a NetBird self-hosted mesh VPN agent with comprehensive documentation and integration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/netbird-agent

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 16:22:07 UTC 2026: Code review monitoring started
Sun Feb 22 16:22:07 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 16:22:09 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@gemini-code-assist
Copy link
Copy Markdown

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.agents/subagent-index.toon (2)

79-79: ⚠️ Potential issue | 🟡 Minor

providers/unbuilt doesn't match the AI summary or PR description — likely a copy-paste error.

The AI summary states this entry's key_files should be providers/crft-lookup|openexplorer|wappalyzer, and the PR description specifically names crft-lookup as the frontend technology detection provider. Line 56 already has an entry for providers/crft-lookup with a distinct purpose ("Website research"), so neither are duplicates — but providers/unbuilt as a key_files value for this entry looks like it was pasted from a different in-progress file.

🐛 Proposed fix
-tools/research/,Tech stack research - frontend technology detection providers,providers/unbuilt
+tools/research/,Tech stack research - frontend technology detection providers,providers/crft-lookup
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/subagent-index.toon at line 79, The entry in
.agents/subagent-index.toon has an incorrect key_files value
("providers/unbuilt") that doesn't match the AI summary/PR; update that entry's
key_files to "providers/crft-lookup|openexplorer|wappalyzer" so it matches the
described provider set (refer to the entry currently using key_files and the
existing providers/crft-lookup entry to confirm intent) and remove the stray
"providers/unbuilt" value.

25-25: ⚠️ Potential issue | 🟠 Major

Update TOON subagent count from [55] to [56].

The header declares 55 entries but the block contains 56 (lines 26–82 inclusive). This mismatch will cause the TOON parser to silently drop the last entry (providers/wappalyzer) or fail parsing.

Proposed fix
-<!--TOON:subagents[55]{folder,purpose,key_files}:
+<!--TOON:subagents[56]{folder,purpose,key_files}:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/subagent-index.toon at line 25, The TOON header token
"TOON:subagents[55]{folder,purpose,key_files}" is out of sync with the block (56
entries) causing the parser to drop or fail on the final entry; update the
numeric count from 55 to 56 in that header so it reads
"TOON:subagents[56]{folder,purpose,key_files}" (ensure the change is made in
.agents/subagent-index.toon) to include the final entry "providers/wappalyzer".
🧹 Nitpick comments (2)
.agents/services/networking/netbird.md (2)

225-230: expires_in: 86400 (24 h) may be too short for reusable AI worker provisioning keys.

A reusable setup key with a 24-hour expiry works for a single provisioning run, but if worker provisioning is spread across multiple days (scaling events, CI reprovisioning), the key will expire and new workers will silently fail to join the mesh. Consider documenting longer expiry values (e.g., 604800 for 7 days) or noting that admins should regenerate the key for each provisioning campaign.

💡 Suggested documentation note
     "type": "reusable",
-    "expires_in": 86400,
+    "expires_in": 604800,  # 7 days; adjust to match your provisioning window
     "auto_groups": ["ai-workers"],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/services/networking/netbird.md around lines 225 - 230, Update the
reusable setup key configuration around the "aidevops-workers" block where
"expires_in": 86400 is set: change the expiry to a longer default (for example
604800) or add a clear documentation note beside that JSON snippet advising
admins to use longer expiries or to regenerate keys for multi-day provisioning
campaigns; ensure the guidance references the "name": "aidevops-workers" and
"expires_in" fields so readers know which value to adjust and why.

341-349: Terraform: declare netbird_group before the netbird_setup_key that references it.

netbird_setup_key.workers references netbird_group.ai_workers.id (line 344) but netbird_group.ai_workers is declared after it (lines 347–349). Terraform resolves the dependency graph regardless of order, so this works, but conventional IaC style places dependencies before their dependants for readability.

♻️ Proposed reorder
+resource "netbird_group" "ai_workers" {
+  name = "ai-workers"
+}
+
 resource "netbird_setup_key" "workers" {
   name        = "aidevops-workers"
   type        = "reusable"
   auto_groups = [netbird_group.ai_workers.id]
 }
-
-resource "netbird_group" "ai_workers" {
-  name = "ai-workers"
-}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/services/networking/netbird.md around lines 341 - 349, The Terraform
resources are declared in reverse-readability order: netbird_setup_key.workers
references netbird_group.ai_workers.id but netbird_group.ai_workers is defined
after it; reorder the declarations so the resource block for netbird_group
"ai_workers" appears before the resource block for netbird_setup_key "workers"
to make the dependency explicit and improve readability (leave the resource
names netbird_group.ai_workers and netbird_setup_key.workers unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/services/networking/netbird.md:
- Line 110: Change the single word "addon" to the hyphenated form "add-on" in
the Netbird documentation sentence ("For Cloudron deployments, use the
PostgreSQL addon.") so it reads "For Cloudron deployments, use the PostgreSQL
add-on." Update this exact sentence in .agents/services/networking/netbird.md to
fix the spelling.
- Around line 83-87: Replace the unsafe "curl ... | bash" usage that references
the unversioned getting-started.sh and relies on frontmatter bash: true by
pinning the installer URL to a specific release tag (not latest), adding a
verification step (checksum or signature) before executing, and/or switching the
automated examples to package-manager install commands; specifically update the
NETBIRD_DOMAIN quickstart snippet and all other occurrences of
getting-started.sh (noted at lines around 156, 185, 193, 237) to use a tagged
release URL and include clear verification instructions instead of piping
directly to bash.
- Around line 356-358: The manifest incorrectly suggests using tcpPorts for the
STUN service; change the manifest to declare UDP 3478 under the udpPorts field
instead of tcpPorts so NAT traversal works correctly. Locate references to
tcpPorts and the STUN/3478 binding in the manifest and replace them with
udpPorts entries (ensuring the dashboard + API remain behind the HTTP proxy
unchanged). Verify the manifest schema usage for udpPorts and update any
documentation lines that claimed tcpPorts supports UDP to reference udpPorts.
- Around line 400-403: Comment: The note saying "--disable-auto-connect" forces
relay is misleading. Update the .agents/services/networking/netbird.md snippet:
either remove the two lines "netbird up --disable-auto-connect" and the
preceding "Force relay (debug connectivity)" header, or change the header and
comment to accurately describe that "--disable-auto-connect" prevents
auto-connecting on daemon start (it does not force TURN/relay); if you want to
show how to check relay status, replace with the existing correct command
"netbird status --detail" and mention that it shows "direct" vs "relayed".
Reference: the netbird up invocation and the --disable-auto-connect flag in this
diff and the netbird status --detail command shown elsewhere.

---

Outside diff comments:
In @.agents/subagent-index.toon:
- Line 79: The entry in .agents/subagent-index.toon has an incorrect key_files
value ("providers/unbuilt") that doesn't match the AI summary/PR; update that
entry's key_files to "providers/crft-lookup|openexplorer|wappalyzer" so it
matches the described provider set (refer to the entry currently using key_files
and the existing providers/crft-lookup entry to confirm intent) and remove the
stray "providers/unbuilt" value.
- Line 25: The TOON header token "TOON:subagents[55]{folder,purpose,key_files}"
is out of sync with the block (56 entries) causing the parser to drop or fail on
the final entry; update the numeric count from 55 to 56 in that header so it
reads "TOON:subagents[56]{folder,purpose,key_files}" (ensure the change is made
in .agents/subagent-index.toon) to include the final entry
"providers/wappalyzer".

---

Nitpick comments:
In @.agents/services/networking/netbird.md:
- Around line 225-230: Update the reusable setup key configuration around the
"aidevops-workers" block where "expires_in": 86400 is set: change the expiry to
a longer default (for example 604800) or add a clear documentation note beside
that JSON snippet advising admins to use longer expiries or to regenerate keys
for multi-day provisioning campaigns; ensure the guidance references the "name":
"aidevops-workers" and "expires_in" fields so readers know which value to adjust
and why.
- Around line 341-349: The Terraform resources are declared in
reverse-readability order: netbird_setup_key.workers references
netbird_group.ai_workers.id but netbird_group.ai_workers is defined after it;
reorder the declarations so the resource block for netbird_group "ai_workers"
appears before the resource block for netbird_setup_key "workers" to make the
dependency explicit and improve readability (leave the resource names
netbird_group.ai_workers and netbird_setup_key.workers unchanged).

Comment on lines +83 to +87
```bash
# Set your domain and run the installer
export NETBIRD_DOMAIN=netbird.example.com
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

curl | bash with an unversioned latest URL is a supply-chain risk in an automated provisioning context.

Because bash: true is enabled in this subagent's frontmatter, AI workers can execute the shell code blocks directly. The quickstart URL getting-started.sh is both unversioned (latest) and piped directly to bash — if the CDN or release is tampered with, every AI-provisioned worker would silently execute attacker-controlled code. The same pattern repeats across multiple client install sections (lines 156, 185, 193, 237).

Recommended mitigations:

  • Pin the script to a specific release tag instead of latest.
  • Add a verification step (checksum or signature) before executing.
  • In automated pipelines, prefer the package-manager install path (apt/brew) over the bootstrap script.
🛡️ Proposed safer quickstart pattern
-# Set your domain and run the installer
-export NETBIRD_DOMAIN=netbird.example.com
-curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash
+# Set your domain and run the installer (pin to a specific version for reproducibility)
+export NETBIRD_DOMAIN=netbird.example.com
+NETBIRD_VERSION="v0.35.0"  # pin to verified release
+curl -fsSL "https://github.com/netbirdio/netbird/releases/download/${NETBIRD_VERSION}/getting-started.sh" \
+  -o /tmp/netbird-setup.sh
+# Verify checksum before executing (see release page for SHA256)
+bash /tmp/netbird-setup.sh
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/services/networking/netbird.md around lines 83 - 87, Replace the
unsafe "curl ... | bash" usage that references the unversioned
getting-started.sh and relies on frontmatter bash: true by pinning the installer
URL to a specific release tag (not latest), adding a verification step (checksum
or signature) before executing, and/or switching the automated examples to
package-manager install commands; specifically update the NETBIRD_DOMAIN
quickstart snippet and all other occurrences of getting-started.sh (noted at
lines around 156, 185, 193, 237) to use a tagged release URL and include clear
verification instructions instead of piping directly to bash.

…on details

- Add OIDC identity provider API examples and JWT group sync docs
- Add Cloudron OIDC addon integration details (no Keycloak needed)
- Add Cloudron TURN addon integration
- Add reverse proxy feature section (beta, requires Traefik)
- Document Cloudron reverse proxy incompatibility (TLS passthrough)
- Add Cloudron addon compatibility table
- Update comparison table with reverse proxy and JWT group sync
- Add links to OIDC, reverse proxy, and Cloudron package repos
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 17:36:36 UTC 2026: Code review monitoring started
Sun Feb 22 17:36:37 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 17:36:39 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

- Add recommended VPS specs table (1 vCPU/2GB for <25 peers, ~$4-6/mo)
- Add full installation walkthrough with Traefik and reverse proxy
- Add DNS records table for management + proxy wildcard
- Add manual upgrade procedure with backup steps
- Add auto-update script using NetBird version API
- Add cron and aidevops remote dispatch integration
- Add health monitoring examples (version, peer count, connectivity)
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 17:39:46 UTC 2026: Code review monitoring started
Sun Feb 22 17:39:47 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 17:39:49 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Coolify uses Traefik natively, enabling full NetBird feature support
including the reverse proxy feature that Cloudron cannot provide.
Documents step-by-step deployment via Coolify's Docker Compose build
pack with Traefik labels, UDP port mapping, and persistent storage.
Adds feature comparison table across all three deployment options.
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 17:42:31 UTC 2026: Code review monitoring started
Sun Feb 22 17:42:32 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 17:42:34 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.agents/services/networking/netbird.md (1)

468-468: Nit: prefer "incompatible" over "not compatible".

The LanguageTool static analysis suggests tightening this phrasing.

✏️ Proposed fix
-- **Requires Traefik** -- not compatible with nginx-based reverse proxies (including Cloudron)
+- **Requires Traefik** -- incompatible with nginx-based reverse proxies (including Cloudron)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/services/networking/netbird.md at line 468, Replace the phrase
"**not compatible with nginx-based reverse proxies (including Cloudron)**" with
"**incompatible with nginx-based reverse proxies (including Cloudron)**" in the
NetBird documentation string (the line containing "Requires Traefik") to tighten
the wording.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/services/networking/netbird.md:
- Line 153: Replace the incorrect blanket statement "Hetzner firewalls are
stateless" (the numbered gotcha heading and its sentence) with a corrected note
that distinguishes Hetzner Dedicated (Robot) firewalls from Hetzner Cloud
firewalls: state that Hetzner Cloud firewalls are stateful and the original
warning only applies to Dedicated/Robot servers, and update the guidance to
recommend opening ephemeral UDP/STUN ports only for dedicated-server (Robot)
deployments while leaving Cloud VM quickstart instructions unchanged; target the
heading "6. **Hetzner firewalls are stateless**" and the following sentence to
make this clarification.
- Around line 190-199: The snippet uses an unpinned Docker image reference
"netbirdio/netbird:latest" which is a supply-chain risk; update the `docker run`
image to a specific immutable identifier (either a fixed version tag like
`netbirdio/netbird:vX.Y.Z` or a content digest `netbirdio/netbird@sha256:...`)
and document the chosen tag in the README so AI workers don't pull `latest`;
locate the `docker run` invocation in this markdown (the block containing
`--name netbird` and `netbirdio/netbird:latest`) and replace the image ref
accordingly, and if you have an image-update process, add a note to rotate the
pinned tag/digest when you intentionally upgrade.
- Around line 129-140: The health-check curl invocation that calls
"https://netbird.example.com/api/instance/version" currently uses the wrong
Authorization prefix ("Authorization: Bearer <PAT>"); update that header to use
the Personal Access Token scheme by changing the header to "Authorization: Token
<PAT>" so the PAT consumed earlier is sent with the correct prefix.

---

Duplicate comments:
In @.agents/services/networking/netbird.md:
- Line 401: Update the spelling of "addon" to "add-on" in the sentence that
currently reads "Cloudron's OIDC addon provides credentials that are registered
as a 'Generic OIDC' identity provider in NetBird via the REST API on startup."
Replace "addon" with "add-on" so the line reads "Cloudron's OIDC add-on provides
credentials..." to match the prior correction on the earlier flag.
- Around line 496-499: The comment "# Force relay (debug connectivity)" is
misleading because the flag shown ("netbird up --disable-auto-connect") does not
force relay; update the documentation line to accurately describe the flag's
behavior—e.g., change the comment to something like "Disable auto-connect
(useful for debugging connectivity; does not force relay)" or provide the
correct command/flag that actually forces relay if that was intended; ensure the
text near "netbird up --disable-auto-connect" clearly states it disables
automatic connection rather than forcing relay.
- Line 390: Update the heading "Cloudron addons used" to use the same spelling
as the earlier flag by changing it to "Cloudron add-on used" (or "Cloudron
add-ons used" if plural context demands "add-on(s)") so it matches the prior
usage on line 110; specifically edit the markdown heading text "Cloudron addons
used" to "Cloudron add-on(s) used" to correct the spelling and keep consistency
across the document.
- Line 176: Replace the repeated unversioned "curl -fsSL
https://pkgs.netbird.io/install.sh | sh" install pattern with a pinned,
verifiable install flow: reference a versioned installer URL or explicit package
release, download the installer to a temporary file (e.g., via curl -fSL -o),
verify its integrity using a provided SHA256 checksum or GPG signature, and only
then execute it; update each occurrence of the exact string "curl -fsSL
https://pkgs.netbird.io/install.sh | sh" so they point to the versioned artifact
and include the checksum/GPG verification step before running the script.
- Line 384: The table row for "STUN (UDP 3478)" incorrectly lists the manifest
option as `tcpPorts`; update that entry to `udpPorts` so the STUN UDP 3478 port
is exposed via the UDP manifest option instead of TCP (search for the string
"STUN (UDP 3478)" and replace `tcpPorts` with `udpPorts` in that table row).
- Around line 83-87: Replace the unpinned "curl | bash" pipeline (the command
that downloads
https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh
and pipes to bash) with a safe three-step flow: 1) pin the installer URL to a
specific release tag (not "latest") and download the script to disk (e.g.,
getting-started.sh), 2) fetch the expected checksum for that same release (from
the release assets or a signed checksum file) and verify the downloaded file
with a cryptographic hash check (sha256sum or shasum -a 256), and 3) only if the
checksum matches, run the downloaded script with bash; reference the exact
command string in the doc to help reviewers locate the change and include brief
instructions to abort on mismatch to avoid executing unverified code.

---

Nitpick comments:
In @.agents/services/networking/netbird.md:
- Line 468: Replace the phrase "**not compatible with nginx-based reverse
proxies (including Cloudron)**" with "**incompatible with nginx-based reverse
proxies (including Cloudron)**" in the NetBird documentation string (the line
containing "Requires Traefik") to tighten the wording.

Comment on lines +190 to +199
```bash
docker run -d \
--name netbird \
--cap-add NET_ADMIN \
--cap-add SYS_ADMIN \
-v netbird-client:/etc/netbird \
netbirdio/netbird:latest \
up --setup-key <SETUP_KEY> \
--management-url https://netbird.example.com
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Pin the Docker image tag — latest is a supply-chain risk in this provisioning context.

With bash: true, an AI worker can execute this snippet directly. netbirdio/netbird:latest resolves to whatever was most recently pushed, meaning a broken or tampered image update silently rolls out to every AI-provisioned worker.

🛡️ Proposed fix
 docker run -d \
   --name netbird \
   --cap-add NET_ADMIN \
   --cap-add SYS_ADMIN \
   -v netbird-client:/etc/netbird \
-  netbirdio/netbird:latest \
+  netbirdio/netbird:v0.65.1 \   # pin to a verified release tag
   up --setup-key <SETUP_KEY> \
   --management-url https://netbird.example.com
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
docker run -d \
--name netbird \
--cap-add NET_ADMIN \
--cap-add SYS_ADMIN \
-v netbird-client:/etc/netbird \
netbirdio/netbird:latest \
up --setup-key <SETUP_KEY> \
--management-url https://netbird.example.com
```
docker run -d \
--name netbird \
--cap-add NET_ADMIN \
--cap-add SYS_ADMIN \
-v netbird-client:/etc/netbird \
netbirdio/netbird:v0.65.1 \
up --setup-key <SETUP_KEY> \
--management-url https://netbird.example.com
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/services/networking/netbird.md around lines 190 - 199, The snippet
uses an unpinned Docker image reference "netbirdio/netbird:latest" which is a
supply-chain risk; update the `docker run` image to a specific immutable
identifier (either a fixed version tag like `netbirdio/netbird:vX.Y.Z` or a
content digest `netbirdio/netbird@sha256:...`) and document the chosen tag in
the README so AI workers don't pull `latest`; locate the `docker run` invocation
in this markdown (the block containing `--name netbird` and
`netbirdio/netbird:latest`) and replace the image ref accordingly, and if you
have an image-update process, add a note to rotate the pinned tag/digest when
you intentionally upgrade.

…fSense, and more

Add Dokploy as alternative Traefik-based PaaS for server hosting alongside
Coolify. Expand client installation section with platform-specific guides
for Proxmox LXC (TUN passthrough), Synology (reboot script), pfSense
(static port NAT), OPNSense, and TrueNAS. Add comprehensive client
platform compatibility table with gotchas for each platform.
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 17:47:28 UTC 2026: Code review monitoring started
Sun Feb 22 17:47:29 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 17:47:31 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

- Fix PAT auth headers: Bearer -> Token (5 occurrences)
- Fix Hetzner firewall gotcha: Cloud is stateful, only Robot is stateless
- Fix --disable-auto-connect comment: does not force relay
- Fix Terraform resource ordering: group before setup_key
- Fix setup key expiry: 86400 -> 604800 (7 days for multi-day provisioning)
- Fix spelling: addon -> add-on (8 occurrences)
- Fix Cloudron STUN port: tcpPorts -> udpPorts
- Fix wording: not compatible -> incompatible
- Add production note about pinning installer versions
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 17:51:52 UTC 2026: Code review monitoring started
Sun Feb 22 17:51:52 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 17:51:55 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link
Copy Markdown

@marcusquinn marcusquinn merged commit f5c19a7 into main Feb 22, 2026
11 checks passed
@marcusquinn marcusquinn deleted the feature/netbird-agent branch March 3, 2026 03:24
marcusquinn added a commit that referenced this pull request Mar 14, 2026
- Pin getting-started.sh installer to versioned release tag (not latest)
  with download-then-verify pattern instead of curl|bash pipeline
- Pin Docker images (netbirdio/netbird, dashboard, proxy) to v0.35.0
  instead of :latest to prevent supply-chain risk in automated provisioning
- Fix Authorization header: Bearer -> Token for Personal Access Token usage
  (Bearer is for OAuth JWTs; PAT scheme uses Token prefix)
- Fix worker provisioning script to prefer package manager over unversioned
  install.sh pipe to sh
- Declare Terraform netbird_group before netbird_setup_key that references it
- Add comment clarifying Terraform resource dependency order
- Fix subagent-index.toon: replace stray providers/unbuilt key_files value
  with correct providers/crft-lookup|openexplorer|wappalyzer

Previously addressed in PR #2147 commits (already in file):
- udpPorts (not tcpPorts) for STUN UDP 3478 manifest option
- --disable-auto-connect comment accuracy (daemon start, not force relay)
- addon -> add-on spelling throughout
- Hetzner firewall stateless/stateful distinction
- expires_in 604800 (7 days) for reusable setup keys
- Authorization: Token for all health/monitoring API calls

Closes #3272
marcusquinn added a commit that referenced this pull request Mar 14, 2026
- Pin getting-started.sh installer to versioned release tag (not latest)
  with download-then-verify pattern instead of curl|bash pipeline
- Pin Docker images (netbirdio/netbird, dashboard, proxy) to v0.35.0
  instead of :latest to prevent supply-chain risk in automated provisioning
- Fix Authorization header: Bearer -> Token for Personal Access Token usage
  (Bearer is for OAuth JWTs; PAT scheme uses Token prefix)
- Fix worker provisioning script to prefer package manager over unversioned
  install.sh pipe to sh
- Declare Terraform netbird_group before netbird_setup_key that references it
- Add comment clarifying Terraform resource dependency order
- Fix subagent-index.toon: replace stray providers/unbuilt key_files value
  with correct providers/crft-lookup|openexplorer|wappalyzer

Previously addressed in PR #2147 commits (already in file):
- udpPorts (not tcpPorts) for STUN UDP 3478 manifest option
- --disable-auto-connect comment accuracy (daemon start, not force relay)
- addon -> add-on spelling throughout
- Hetzner firewall stateless/stateful distinction
- expires_in 604800 (7 days) for reusable setup keys
- Authorization: Token for all health/monitoring API calls

Closes #3272
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant