| 1 | # `.env` setup and reference |
| 2 | |
| 3 | `.env` at the repo root holds per-user secrets and pointers |
| 4 | that AI-skill scripts consume. It is **gitignored** -- values |
| 5 | never reach the committed history. |
| 6 | |
| 7 | This file is the single setup guide. Every skill that needs |
| 8 | `.env` keys lists them here with the role, where to find the |
| 9 | value, sample format, and which scripts consume it. If a |
| 10 | script tells you a key is missing, check this file. |
| 11 | |
| 12 | ## Quick start |
| 13 | |
| 14 | ```bash |
| 15 | cd <repo> |
| 16 | cp .env.template .env |
| 17 | # Open .env in your editor and fill in the keys you need. |
| 18 | chmod 0600 .env # optional but recommended |
| 19 | ``` |
| 20 | |
| 21 | You only need to fill in keys for the skills you actually |
| 22 | use. Each script checks its own required keys and exits with |
| 23 | a clear error if any are missing -- it will not corrupt |
| 24 | state if you forget a key. |
| 25 | |
| 26 | ## Key reference |
| 27 | |
| 28 | ### Netdata Cloud + agents |
| 29 | |
| 30 | | Key | Role | Where to find it | Sample format | |
| 31 | |---|---|---|---| |
| 32 | | `NETDATA_CLOUD_TOKEN` | long-lived Cloud REST token | app.netdata.cloud -> user menu -> Settings -> API Tokens -> Create. `scope:all` (full) or `scope:grafana-plugin` (read-only data). | 36-char UUID-shaped token | |
| 33 | | `NETDATA_CLOUD_HOSTNAME` | Cloud REST API host | Almost always `app.netdata.cloud` | `app.netdata.cloud` | |
| 34 | | `NETDATA_REPOS_DIR` | local Netdata-org repos mirror dir | Pick or create. Will be populated by `mirror-netdata-repos` skill's sync script. | `$HOME/src/netdata` | |
| 35 | |
| 36 | ### agent-events ingestion node |
| 37 | |
| 38 | The `agent-events` node is the Netdata-operated ingestion |
| 39 | host that receives status submissions from every Netdata |
| 40 | agent in the wild. The query-agent-events skill triages |
| 41 | crashes / panics / fatals from it. |
| 42 | |
| 43 | | Key | Role | Where to find it | Sample format | |
| 44 | |---|---|---|---| |
| 45 | | `AGENT_EVENTS_HOSTNAME` | Network address of the ingestion node. Dual-duty -- ssh host (`ssh ${AGENT_EVENTS_HOSTNAME}`) AND direct-HTTP host (`http://${AGENT_EVENTS_HOSTNAME}:19999/`). Can be a DNS name or an IP. NOTE -- this is NOT the journalctl namespace (which is hardcoded to `agent-events`) and NOT the Cloud room name (also hardcoded to `agent-events`). | Operations / your records | `10.20.1.105` or `agent-events.example` | |
| 46 | | `AGENT_EVENTS_NODE_ID` | Cloud node UUID for that node | Visit the node in app.netdata.cloud and copy the UUID from the URL; or list nodes via the Cloud API and pick the matching one. | UUID | |
| 47 | | `AGENT_EVENTS_MACHINE_GUID` | Netdata machine GUID for that node | On the host: `sudo cat /var/lib/netdata/registry/netdata.public.unique.id` | UUID | |
| 48 | |
| 49 | ### Coverity Scan (coverity-audit skill) |
| 50 | |
| 51 | | Key | Role | Where to find it | Sample format | |
| 52 | |---|---|---|---| |
| 53 | | `COVERITY_HOST` | Scan API host | Always `https://scan4.scan.coverity.com` for the new instance | URL | |
| 54 | | `COVERITY_PROJECT_ID` | integer project id | URL query param `?projectId=...` when you click the project in the dashboard | small integer | |
| 55 | | `COVERITY_COOKIE` | full browser Cookie header (with XSRF-TOKEN) | DevTools -> Network -> any request to scan4 -> Request Headers -> Cookie | long Cookie string | |
| 56 | | `COVERITY_VIEW_OUTSTANDING` | integer viewId for the "Outstanding" view | URL query param `?viewId=...` when you open that view | small integer | |
| 57 | |
| 58 | The cookie expires; refresh by re-pasting from the browser |
| 59 | (or run `coverity-audit/scripts/keepalive.sh` to extend |
| 60 | it during a triage session). |
| 61 | |
| 62 | ### SonarCloud (sonarqube-audit skill) |
| 63 | |
| 64 | | Key | Role | Where to find it | Sample format | |
| 65 | |---|---|---|---| |
| 66 | | `SONAR_HOST_URL` | SonarCloud host | Always `https://sonarcloud.io` | URL | |
| 67 | | `SONAR_ORG` | your organization key on SonarCloud | sonarcloud.io organization page | short string | |
| 68 | | `SONAR_PROJECT` | projectKey on SonarCloud | For Netdata: `netdata_netdata` | `org_repo` form | |
| 69 | | `SONAR_TOKEN` | personal access token | https://sonarcloud.io/account/security -> Generate | long opaque token | |
| 70 | |
| 71 | ### Codacy Cloud (codacy-audit skill) |
| 72 | |
| 73 | | Key | Role | Where to find it | Sample format | |
| 74 | |---|---|---|---| |
| 75 | | `CODACY_TOKEN` | Account API token (header `api-token: <value>`) | https://app.codacy.com -> top-right avatar -> Account -> API tokens -> "Create API Token" | 20-char opaque string | |
| 76 | | `CODACY_HOST` | API host. Defaults to `https://api.codacy.com`; set only if Codacy moves the API host. | n/a | URL | |
| 77 | | `CODACY_PROVIDER` | git provider. Defaults to `gh` (GitHub). | n/a | `gh` | |
| 78 | | `CODACY_ORG` | Codacy organization (matches the GitHub org). Defaults to `netdata`. | n/a | short string | |
| 79 | | `CODACY_REPO` | Codacy repository name. Defaults to `netdata`. | n/a | short string | |
| 80 | |
| 81 | `CODACY_TOKEN` is required by `pr-issues.sh` and any wrapper that |
| 82 | calls the v3 API. `analyze-local.sh` does NOT need it (the local |
| 83 | CLI runs anonymously). |
| 84 | |
| 85 | ## Per-skill checklist |
| 86 | |
| 87 | Set the keys for whichever skills you plan to use. Skills |
| 88 | not listed here either need no `.env` keys or rely on `gh |
| 89 | auth` instead. |
| 90 | |
| 91 | ### query-netdata-cloud / query-netdata-agents |
| 92 | |
| 93 | - `NETDATA_CLOUD_TOKEN` |
| 94 | - `NETDATA_CLOUD_HOSTNAME` |
| 95 | - (For agent-events examples in those skills' docs: |
| 96 | `AGENT_EVENTS_HOSTNAME`, `AGENT_EVENTS_NODE_ID`, |
| 97 | `AGENT_EVENTS_MACHINE_GUID`.) |
| 98 | |
| 99 | ### query-agent-events |
| 100 | |
| 101 | - `NETDATA_CLOUD_TOKEN` |
| 102 | - `NETDATA_CLOUD_HOSTNAME` |
| 103 | - `AGENT_EVENTS_HOSTNAME` |
| 104 | - `AGENT_EVENTS_NODE_ID` |
| 105 | - `AGENT_EVENTS_MACHINE_GUID` |
| 106 | |
| 107 | ### mirror-netdata-repos |
| 108 | |
| 109 | - `NETDATA_REPOS_DIR` |
| 110 | |
| 111 | ### integrations-lifecycle / learn-site-structure |
| 112 | |
| 113 | - `NETDATA_REPOS_DIR` (for cross-repo path references in |
| 114 | examples / recipes) |
| 115 | |
| 116 | ### coverity-audit |
| 117 | |
| 118 | - `COVERITY_HOST` |
| 119 | - `COVERITY_PROJECT_ID` |
| 120 | - `COVERITY_COOKIE` |
| 121 | - `COVERITY_VIEW_OUTSTANDING` |
| 122 | |
| 123 | ### sonarqube-audit |
| 124 | |
| 125 | - `SONAR_HOST_URL` |
| 126 | - `SONAR_ORG` |
| 127 | - `SONAR_PROJECT` |
| 128 | - `SONAR_TOKEN` |
| 129 | |
| 130 | ### codacy-audit |
| 131 | |
| 132 | - `CODACY_TOKEN` (required by `pr-issues.sh`; not by `analyze-local.sh`) |
| 133 | - `CODACY_HOST` (optional; defaults to `https://api.codacy.com`) |
| 134 | - `CODACY_PROVIDER` / `CODACY_ORG` / `CODACY_REPO` (optional; default to `gh` / `netdata` / `netdata`) |
| 135 | |
| 136 | ### pr-reviews / graphql-audit |
| 137 | |
| 138 | - No `.env` keys required. Both rely on `gh auth login` |
| 139 | having been run. |
| 140 | |
| 141 | ## Common mistakes |
| 142 | |
| 143 | - **Trailing whitespace** in a value: bash variable |
| 144 | expansion preserves the whitespace; the value comes |
| 145 | through with the trailing space and breaks API calls |
| 146 | silently. Strip whitespace inside the quotes. |
| 147 | - **Wrong quoting**: quotes around bash-expansion characters |
| 148 | (`$`, backticks, `\`) are interpreted. For tokens |
| 149 | containing those characters, use single quotes: |
| 150 | `SONAR_TOKEN='abc$def'`. |
| 151 | - **Expired Coverity cookie**: re-paste from the browser. |
| 152 | The script's error message will tell you when this |
| 153 | happens. |
| 154 | - **Wrong `gh` org**: `pr-reviews` and `graphql-audit` use |
| 155 | `gh` against the current repo's remote. Make sure your |
| 156 | remote points to the right repo (`git remote -v`). |
| 157 | - **Cloud token scope too narrow**: some endpoints require |
| 158 | `scope:all`. If you get a 403 with what looks like a valid |
| 159 | token, regenerate with broader scope. |
| 160 | - **`NETDATA_REPOS_DIR` and tilde**: bash does NOT expand |
| 161 | the home-directory shortcut character inside |
| 162 | double-quoted strings. If you write `"<TILDE>/src/netdata"`, |
| 163 | the literal tilde is kept in the value, and scripts will |
| 164 | fail with "directory does not exist" because that path |
| 165 | is not real. Use `$HOME` instead, or the full absolute |
| 166 | path: |
| 167 | ``` |
| 168 | NETDATA_REPOS_DIR="$HOME/src/netdata" |
| 169 | ``` |
| 170 | |
| 171 | ## Why these are env-keyed |
| 172 | |
| 173 | Every value above is either: |
| 174 | - a **secret** (token / cookie) that must never leak into |
| 175 | committed artifacts, or |
| 176 | - a **per-user / per-deployment** path or identifier (mirror |
| 177 | dir, ingestion node) that varies between contributors. |
| 178 | |
| 179 | The committed skills, scripts, and docs reference these |
| 180 | values exclusively via `${KEY}` placeholders, never literal |
| 181 | values. The discipline is enforced by the spec at |
| 182 | `<repo>/.agents/sow/specs/sensitive-data-discipline.md`, |
| 183 | which includes a pre-commit grep recipe to catch |
| 184 | literal-value leaks. |
| 185 | |
| 186 | ## When a skill says "X is empty in .env" |
| 187 | |
| 188 | That skill's `_lib.sh` ran the bash safety net |
| 189 | `: "${X:?...}"` because `X` was unset or empty. Open this |
| 190 | file, find the row for `X`, follow the "where to find it" |
| 191 | pointer, paste the value into `.env`, and re-run. |