Two field-test findings drive this change: the direct-dial path needed
sudo (the profile's WireGuard key is root-owned), and a single flat
ANTHROPIC_* export set is wrong for providers that speak other API
shapes.
Relay the setup request through the daemon instead: a new
GetAgentNetworkSetup daemon RPC forwards to management over the
engine's existing peer connection, so unprivileged callers get the
caller-scoped answer the same way 'netbird status' works — no sudo,
and the key never leaves the daemon. The daemon's JSON gateway exposes
the RPC for the desktop UI for free.
Teach 'agent-network env' the per-provider environment contracts,
mirroring Claude Code's LLM-gateway configuration:
- anthropic flavor: ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN /
ANTHROPIC_MODEL
- bedrock_api: CLAUDE_CODE_USE_BEDROCK, ANTHROPIC_BEDROCK_BASE_URL,
CLAUDE_CODE_SKIP_BEDROCK_AUTH (the proxy injects AWS credentials)
- vertex_ai_api: CLAUDE_CODE_USE_VERTEX, ANTHROPIC_VERTEX_BASE_URL,
CLAUDE_CODE_SKIP_VERTEX_AUTH, plus comments for the admin-supplied
ANTHROPIC_VERTEX_PROJECT_ID and CLOUD_ML_REGION (the proxy forwards
the URL path, so those values must be the operator's real ones)
- openai flavor: OPENAI_BASE_URL / OPENAI_API_KEY
- anything else: comment lines only — no guessed variables
Selection stays explicit: --provider picks by operator label or
catalog id and is required when several providers are authorized;
--model is validated against the provider's allowed set and required
when several models are allowed. Ambiguity renders as shell comments,
never as exports.
Linear: NET-1399
The agent-network commands dial management directly with the profile's
WireGuard key, and the default profile config is root-owned — running
unprivileged fails reading it. Surface a clear "re-run with sudo"
message instead of a bare permission error.
Linear: NET-1399
An Unimplemented answer to GetAgentNetworkSetup can only come from a
server binary compiled without the regenerated management proto — the
combined and management servers share the one registration path in
boot.go. Make that failure mode self-diagnosing:
- Log "ManagementService registered on gRPC server (agent-network
setup RPC available)" at boot, so server logs prove which build is
running.
- Have the CLI name the management URL it dialed in every error, and
map Unimplemented to an actionable message including the binary
check (grep -ac GetAgentNetworkSetup <server binary>).
- Pin the wire path with a round-trip test: a real gRPC server built
from this tree routes the RPC through the NaCl envelope end to end.
Verified live: a combined server built from this branch answers an
unregistered probe with PermissionDenied "peer is not registered",
never Unimplemented.
Linear: NET-1399
Surface the caller-scoped Agent Network setup on the CLI. Both
commands dial management directly with the active profile's WireGuard
key — the same path foreground login uses — so no daemon proto or
engine wiring is needed for the proof of concept.
netbird agent-network ls prints the proxy endpoint, the authorized
providers, and the allowed models (--json for the raw response).
netbird agent-network env prints POSIX export lines for
Anthropic-compatible tools such as Claude Code, applied with
eval "$(netbird agent-network env)": ANTHROPIC_BASE_URL points at
the account's proxy endpoint and ANTHROPIC_AUTH_TOKEN carries a
placeholder (the proxy authenticates by tunnel peer and injects the
real upstream credentials). A model is never guessed: ANTHROPIC_MODEL
is exported only when exactly one model is allowed or --model pins
one; anything ambiguous is printed as comment lines instead.
"Not available for this peer" is an answer, not an error: both
commands exit 0 with a plain message (on stderr for env, keeping the
eval a harmless no-op).
Linear: NET-1399