| 1 | # Validate a local flow Function through direct-agent bearer auth |
| 2 | |
| 3 | ## Question |
| 4 | |
| 5 | How can an assistant prove that a local Cloud-connected Netdata Agent |
| 6 | accepts a Cloud-minted per-agent bearer and serves `flows:netflow` |
| 7 | directly, without exposing Cloud tokens, agent bearers, node ids, |
| 8 | machine GUIDs, claim ids, or raw flow rows? |
| 9 | |
| 10 | ## Inputs |
| 11 | |
| 12 | - Local agent URL, usually `http://127.0.0.1:19999`. |
| 13 | - `NETDATA_CLOUD_TOKEN` and `NETDATA_CLOUD_HOSTNAME` in `<repo>/.env`. |
| 14 | - The local agent must be connected to Cloud and expose `flows:netflow`. |
| 15 | |
| 16 | ## Steps |
| 17 | |
| 18 | 1. Capture the local identity tuple in memory and print only presence |
| 19 | checks: |
| 20 | |
| 21 | ```bash |
| 22 | INFO_JSON="$(curl -sS --max-time 10 http://127.0.0.1:19999/api/v3/info)" |
| 23 | |
| 24 | jq '{ |
| 25 | agent_count: (.agents | length), |
| 26 | node_id_present: ((.agents[0].nd // "") | length > 0), |
| 27 | machine_guid_present: ((.agents[0].mg // "") | length > 0), |
| 28 | claim_id_present: ((.agents[0].cloud.claim_id // "") | length > 0), |
| 29 | cloud_status: .agents[0].cloud.status |
| 30 | }' <<<"$INFO_JSON" |
| 31 | ``` |
| 32 | |
| 33 | 2. Load the token-safe direct-agent wrappers: |
| 34 | |
| 35 | ```bash |
| 36 | source docs/netdata-ai/skills/query-netdata-agents/scripts/_lib.sh |
| 37 | agents_load_env |
| 38 | ``` |
| 39 | |
| 40 | 3. Call the flow Function through the direct-agent path: |
| 41 | |
| 42 | ```bash |
| 43 | NODE_UUID="$(jq -r '.agents[0].nd' \ |
| 44 | <<<"$INFO_JSON")" |
| 45 | MACHINE_GUID="$(jq -r '.agents[0].mg' \ |
| 46 | <<<"$INFO_JSON")" |
| 47 | |
| 48 | mkdir -p .local/audits/query-netdata-agents |
| 49 | |
| 50 | agents_call_function \ |
| 51 | --via agent \ |
| 52 | --node "$NODE_UUID" \ |
| 53 | --host 127.0.0.1:19999 \ |
| 54 | --machine-guid "$MACHINE_GUID" \ |
| 55 | --function flows:netflow \ |
| 56 | --body '{"info":true}' \ |
| 57 | > .local/audits/query-netdata-agents/flows-netflow-info-agent.json |
| 58 | ``` |
| 59 | |
| 60 | 4. Print a sanitized result: |
| 61 | |
| 62 | ```bash |
| 63 | jq '{ |
| 64 | status, |
| 65 | type, |
| 66 | has_history, |
| 67 | response_keys: keys |
| 68 | }' .local/audits/query-netdata-agents/flows-netflow-info-agent.json |
| 69 | ``` |
| 70 | |
| 71 | ## Output |
| 72 | |
| 73 | Expected success shape: |
| 74 | |
| 75 | ```json |
| 76 | { |
| 77 | "status": 200, |
| 78 | "type": "flows", |
| 79 | "has_history": true |
| 80 | } |
| 81 | ``` |
| 82 | |
| 83 | The wrapper logs masked curl commands on stderr. The Cloud token, |
| 84 | per-agent bearer, node id, machine GUID, and claim id must not appear |
| 85 | in stdout or durable artifacts. |
| 86 | |
| 87 | ## Notes / gotchas |
| 88 | |
| 89 | - Use the exact `nd`, `mg`, and `cloud.claim_id` tuple from the same |
| 90 | local `/api/v3/info` response. A mixed tuple from a different node, |
| 91 | parent, child, room, or stale cache can produce Cloud or agent |
| 92 | rejection even when the Cloud-proxied Function path works. |
| 93 | - The direct agent uses `X-Netdata-Auth: Bearer <agent-bearer>`, not |
| 94 | `Authorization: Bearer <cloud-token>`. |
| 95 | - The helper caches the raw bearer under |
| 96 | `.local/audits/query-netdata-agents/bearers/`; that directory is |
| 97 | gitignored and should stay mode `0700`, with bearer files mode |
| 98 | `0600`. |
| 99 | - For content validation of flow rows, prefer a grouped query and print |
| 100 | only counts/statistics. Do not paste raw flow rows into durable files. |
| 101 | |
| 102 | ## Source guides |
| 103 | |
| 104 | - [Direct-agent skill](../SKILL.md) |
| 105 | - [Direct Function calls](../query-functions.md) |
| 106 | - [Network-flow Functions](../query-flows.md) |
| 107 | - [Cloud flow validation sibling how-to](../../query-netdata-cloud/how-tos/validate-local-netflow-function.md) |