From e384d92d1f1353c4becec063151d02ded2b625b3 Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 14:36:12 -0400 Subject: [PATCH 01/10] docs(accessanalyzer): add external analytics store access page for 26.1 Document opening the ClickHouse native and HTTP ports with `dspmctl set-helm-param` so external tools can query the analytics store. Link it from the Integrations index and list the ports in the inbound firewall table. Generated with AI Co-Authored-By: Claude Code --- .../26.1/install/requirements.md | 1 + .../external-clickhouse-access.md | 106 ++++++++++++++++++ .../accessanalyzer/26.1/integrations/index.md | 2 + 3 files changed, 109 insertions(+) create mode 100644 docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md diff --git a/docs/accessanalyzer/26.1/install/requirements.md b/docs/accessanalyzer/26.1/install/requirements.md index 7b5413a2e9..8faf60a41e 100644 --- a/docs/accessanalyzer/26.1/install/requirements.md +++ b/docs/accessanalyzer/26.1/install/requirements.md @@ -81,6 +81,7 @@ Open these ports on the server's firewall. | 80 | TCP | Users' browsers | Redirects HTTP requests to HTTPS. | | 4504 | TCP | Netwrix Activity Monitor | Receives activity data. Open it only if you use [Netwrix Activity Monitor](../integrations/netwrix-activity-monitor.md). | | 6443 | TCP | Agent hosts | Lets [agents](../agents/index.md) connect back to the server. Open it only to the hosts you deploy agents on. | +| 9000, 8123 | TCP | External query tools | Direct access to the analytics store. Open them only if you [open the analytics store's ports](../integrations/external-clickhouse-access.md). | ### Outbound diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md new file mode 100644 index 0000000000..302d3b0a33 --- /dev/null +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -0,0 +1,106 @@ +--- +title: External analytics store access +description: Open the Access Analyzer analytics store (ClickHouse) ports so an external tool, such as a business intelligence (BI) platform, can query it directly. +sidebar_position: 2 +--- + +Access Analyzer keeps scan results in an analytics store, a ClickHouse database that backs the dashboards and reports. By default it accepts connections only from inside the Access Analyzer server. To query it from an external tool, such as a business intelligence (BI) platform, open its ports with the `dspmctl` command on the server. + +Opening access exposes two ports: + +| Port | Protocol | Purpose | +|---|---|---| +| 9000 | TCP | ClickHouse native protocol. | +| 8123 | TCP | ClickHouse HTTP interface. | + +The metrics port is never exposed. + +:::warning +These ports are unencrypted. Credentials and query results cross the network in clear text. Restrict access to a trusted network, or put a TLS-terminating proxy in front of the ports. +::: + +## Prerequisites + +- **Server access.** Shell access to the Access Analyzer server with `sudo` rights. `dspmctl` needs `sudo`, the same as the installer. +- **Network path.** The external tool must reach the server on the ports you open. Open them inbound on the server's firewall and on anything between the two hosts. + +## Choose an access type + +| Type | Use when | Access control | +|---|---|---| +| `NodePort` | The server is a single host with no load balancer. | None in Access Analyzer. Restrict access with the server's firewall. | +| `LoadBalancer` | A load balancer is available, such as one from your cloud provider. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | + +A list of allowed address ranges works only with `LoadBalancer`. Setting it with `NodePort` fails. + +## Open the ports + +`dspmctl set-helm-param` turns automated sync off for the application. The last step turns it back on. + +1. On the Access Analyzer server, set the access parameters. For `NodePort`: + + ```bash + sudo dspmctl set-helm-param netwrix \ + config.clickhouse.externalAccess.enabled=true \ + config.clickhouse.externalAccess.type=NodePort \ + config.clickhouse.externalAccess.nodePorts.native=30900 \ + config.clickhouse.externalAccess.nodePorts.http=30823 + ``` + + Choose ports from 30000 through 32767, or omit the `nodePorts` lines to have Kubernetes assign them. For `LoadBalancer`, restricted to one address range: + + ```bash + sudo dspmctl set-helm-param netwrix \ + config.clickhouse.externalAccess.enabled=true \ + config.clickhouse.externalAccess.type=LoadBalancer \ + 'config.clickhouse.externalAccess.loadBalancerSourceRanges[0]=' + ``` + + Add `[1]`, `[2]`, and so on for more ranges. + +2. Apply the change: + + ```bash + sudo dspmctl sync netwrix + ``` + +3. Turn automated sync back on: + + ```bash + sudo dspmctl enable-auto netwrix + ``` + +4. Open the chosen ports on the server's firewall. + +## Verify access + +1. On the server, list the assigned ports and address: + + ```bash + kubectl get svc clickhouse-external -n access-analyzer + ``` + +2. From the external host, check the HTTP port: + + ```bash + curl http://:/ping + ``` + + A working connection returns `Ok.`. + +## Limitations + +- With `LoadBalancer`, Kubernetes still opens a port on every node. On a cluster with routable node addresses, a client can reach the database through that port and bypass the allowed address ranges. +- Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. + +## Close access + +1. Turn the ports off: + + ```bash + sudo dspmctl set-helm-param netwrix config.clickhouse.externalAccess.enabled=false + sudo dspmctl sync netwrix + sudo dspmctl enable-auto netwrix + ``` + +2. Remove the firewall rules you added. diff --git a/docs/accessanalyzer/26.1/integrations/index.md b/docs/accessanalyzer/26.1/integrations/index.md index 1aa353969d..29c79b24c1 100644 --- a/docs/accessanalyzer/26.1/integrations/index.md +++ b/docs/accessanalyzer/26.1/integrations/index.md @@ -6,3 +6,5 @@ description: How Netwrix Activity Monitor connects to Access Analyzer and what i Access Analyzer integrates with [Netwrix Activity Monitor](netwrix-activity-monitor.md). Activity Monitor sends Access Analyzer the activity it records on file servers, SharePoint Online, and Microsoft 365 Copilot. You enroll an Activity Monitor agent with Access Analyzer using a short-lived enrollment token; after that the agent connects without it. The agent streams its events to the Access Analyzer server over TLS on port 4504. Scans tell you what data exists and who can reach it. Activity tells you who used that access, what they did, and when. With the integration in place, the **Activity** tab of the [Data security dashboard](../dashboards-reports/dashboards/data-security.md) breaks events down by type, data source, and user, and charts activity over time. The Activity Investigation report and the **Activity** tab of the Share Audit report in [Data reports](../dashboards-reports/reports/data.md) draw on the file server events from the same feed. All three stay empty until you enroll an agent and it starts sending data. + +You can also open the analytics store's ports so an external tool, such as a business intelligence (BI) platform, can query it directly. See [External analytics store access](external-clickhouse-access.md). From fc72a3cdbdf7b03d883d40ed3036bd378aa1ec92 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 18:39:44 +0000 Subject: [PATCH 02/10] fix(vale): auto-fix style issues (Vale + Dale) --- docs/accessanalyzer/26.1/install/requirements.md | 2 +- .../26.1/integrations/external-clickhouse-access.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/accessanalyzer/26.1/install/requirements.md b/docs/accessanalyzer/26.1/install/requirements.md index 8faf60a41e..889ec8c917 100644 --- a/docs/accessanalyzer/26.1/install/requirements.md +++ b/docs/accessanalyzer/26.1/install/requirements.md @@ -8,7 +8,7 @@ Gather everything on this page before you run the installer. The installer runs ## Server -Access Analyzer installs on a single Linux server, physical or virtual. +Access Analyzer installs on a single physical or virtual Linux server. | Requirement | Details | |---|---| diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 302d3b0a33..1483eee537 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -13,7 +13,7 @@ Opening access exposes two ports: | 9000 | TCP | ClickHouse native protocol. | | 8123 | TCP | ClickHouse HTTP interface. | -The metrics port is never exposed. +Access Analyzer never exposes the metrics port. :::warning These ports are unencrypted. Credentials and query results cross the network in clear text. Restrict access to a trusted network, or put a TLS-terminating proxy in front of the ports. From c45a388f53b991fe8b1470ab18348b70b400a20c Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 15:00:11 -0400 Subject: [PATCH 03/10] docs(accessanalyzer): document external analytics store credentials Add how to read the access_analyzer_external password with `dspmctl get-secret`, and note that closing access doesn't drop the user. Generated with AI Co-Authored-By: Claude Code --- .../integrations/external-clickhouse-access.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 1483eee537..044e709479 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -72,6 +72,20 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with 4. Open the chosen ports on the server's firewall. +## Get the credentials + +Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, the same as the user Access Analyzer's own reports use. + +1. On the Access Analyzer server, print the password: + + ```bash + sudo dspmctl get-secret clickhouse-external-secret password + ``` + + Omit `password` to print the username and password together. The command doesn't end the output with a newline, so copy the value from the terminal instead of piping it to another command. + +2. In the external tool, connect with the username `access_analyzer_external`, this password, and the `access_analyzer` database. + ## Verify access 1. On the server, list the assigned ports and address: @@ -95,7 +109,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with ## Close access -1. Turn the ports off: +1. Turn the ports off. This also stops `dspmctl get-secret` from reading the password, but it doesn't delete the `access_analyzer_external` user. If you shared the credentials, change the password or remove the user in the analytics store: ```bash sudo dspmctl set-helm-param netwrix config.clickhouse.externalAccess.enabled=false From 1b5ad2d842aed4cdeede5d3a7f76a594ea562f28 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:04:58 +0000 Subject: [PATCH 04/10] fix(vale): auto-fix style issues (Vale + Dale) --- docs/accessanalyzer/26.1/install/requirements.md | 2 +- .../26.1/integrations/external-clickhouse-access.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/accessanalyzer/26.1/install/requirements.md b/docs/accessanalyzer/26.1/install/requirements.md index 889ec8c917..010e84ebcc 100644 --- a/docs/accessanalyzer/26.1/install/requirements.md +++ b/docs/accessanalyzer/26.1/install/requirements.md @@ -4,7 +4,7 @@ description: Server sizing, hostname, network ports, TLS certificate, license ke sidebar_position: 1 --- -Gather everything on this page before you run the installer. The installer runs a preflight check on the server first and stops if the server doesn't meet the hard requirements, so a few minutes here saves a failed installation later. +Gather everything on this page before you run the installer. The installer runs a preflight check first and stops if the server doesn't meet the hard requirements, so a few minutes here saves a failed installation later. ## Server diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 044e709479..1e6f607ef8 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -29,7 +29,7 @@ These ports are unencrypted. Credentials and query results cross the network in | Type | Use when | Access control | |---|---|---| | `NodePort` | The server is a single host with no load balancer. | None in Access Analyzer. Restrict access with the server's firewall. | -| `LoadBalancer` | A load balancer is available, such as one from your cloud provider. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | +| `LoadBalancer` | A load balancer, such as one from your cloud provider, is available. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | A list of allowed address ranges works only with `LoadBalancer`. Setting it with `NodePort` fails. @@ -47,7 +47,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with config.clickhouse.externalAccess.nodePorts.http=30823 ``` - Choose ports from 30000 through 32767, or omit the `nodePorts` lines to have Kubernetes assign them. For `LoadBalancer`, restricted to one address range: + Choose ports from 30000 through 32767, or omit the `nodePorts` lines to have Kubernetes assign them. For `LoadBalancer`, restricting access to one address range: ```bash sudo dspmctl set-helm-param netwrix \ From 4a6cb0b2fbad963e600d987e4c7842ee37431579 Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 15:52:40 -0400 Subject: [PATCH 05/10] docs(accessanalyzer): align external access page with review feedback Recommend LoadBalancer on the bundled k3s, add the internal load balancer annotation, name the dedicated user as the only credential to hand out, document closing the node-port bypass, and fix the newline note. Generated with AI Co-Authored-By: Claude Code --- .../external-clickhouse-access.md | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 1e6f607ef8..90c46fdf70 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -13,7 +13,7 @@ Opening access exposes two ports: | 9000 | TCP | ClickHouse native protocol. | | 8123 | TCP | ClickHouse HTTP interface. | -Access Analyzer never exposes the metrics port. +Access Analyzer never exposes the metrics port. External queries run on the same analytics store that serves scan ingestion and the reports, so heavy external load competes with the product. :::warning These ports are unencrypted. Credentials and query results cross the network in clear text. Restrict access to a trusted network, or put a TLS-terminating proxy in front of the ports. @@ -28,8 +28,10 @@ These ports are unencrypted. Credentials and query results cross the network in | Type | Use when | Access control | |---|---|---| -| `NodePort` | The server is a single host with no load balancer. | None in Access Analyzer. Restrict access with the server's firewall. | -| `LoadBalancer` | A load balancer, such as one from your cloud provider, is available. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | +| `LoadBalancer` | A load balancer is available: one from your cloud provider, or the ServiceLB that the installer leaves enabled in the bundled k3s cluster. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | +| `NodePort` | No load balancer is available, for example because ServiceLB was disabled. | None in Access Analyzer. Restrict access with the server's firewall. | + +The bundled k3s cluster includes ServiceLB, so use `LoadBalancer` with an allowed address list on a standard installation. ServiceLB binds ports 9000 and 8123 on the server, so those ports must be free. A list of allowed address ranges works only with `LoadBalancer`. Setting it with `NodePort` fails. @@ -58,6 +60,15 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with Add `[1]`, `[2]`, and so on for more ranges. + On a cloud provider, request an internal load balancer so the database never gets a public address. The annotation key contains dots, so escape them and quote the argument: + + ```bash + sudo dspmctl set-helm-param netwrix \ + 'config.clickhouse.externalAccess.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-internal=true' + ``` + + The annotation name is provider-specific. Use the one your provider documents. + 2. Apply the change: ```bash @@ -74,7 +85,9 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with ## Get the credentials -Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, the same as the user Access Analyzer's own reports use. +Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. + +Give external tools only this user. Don't hand out the analytics store's administrator credentials: the exposed port reaches the administrator like any other user, so its password is the only thing protecting it. 1. On the Access Analyzer server, print the password: @@ -82,7 +95,7 @@ Opening access creates a dedicated analytics store user, `access_analyzer_extern sudo dspmctl get-secret clickhouse-external-secret password ``` - Omit `password` to print the username and password together. The command doesn't end the output with a newline, so copy the value from the terminal instead of piping it to another command. + Omit `password` to print the username and password together. Print one key at a time when you capture the value in a variable, because the two-key form adds a carriage return. 2. In the external tool, connect with the username `access_analyzer_external`, this password, and the `access_analyzer` database. @@ -104,8 +117,13 @@ Opening access creates a dedicated analytics store user, `access_analyzer_extern ## Limitations -- With `LoadBalancer`, Kubernetes still opens a port on every node. On a cluster with routable node addresses, a client can reach the database through that port and bypass the allowed address ranges. -- Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. +- With `LoadBalancer`, Kubernetes still opens a port on every node. On a cluster with routable node addresses, a client can reach the database through that port and bypass the allowed address ranges. Close it by turning off node-port allocation: + + ```bash + sudo dspmctl set-helm-param netwrix config.clickhouse.externalAccess.allocateLoadBalancerNodePorts=false + ``` + +- Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. To change how traffic is routed, set `config.clickhouse.externalAccess.externalTrafficPolicy` to `Cluster` or `Local`. ## Close access From d8ac0bf1ebcf2089b849e07c5fe0cea69036c316 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:55:53 +0000 Subject: [PATCH 06/10] fix(vale): auto-fix style issues (Vale + Dale) --- docs/accessanalyzer/26.1/install/requirements.md | 2 +- .../26.1/integrations/external-clickhouse-access.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/accessanalyzer/26.1/install/requirements.md b/docs/accessanalyzer/26.1/install/requirements.md index 010e84ebcc..7426133593 100644 --- a/docs/accessanalyzer/26.1/install/requirements.md +++ b/docs/accessanalyzer/26.1/install/requirements.md @@ -85,7 +85,7 @@ Open these ports on the server's firewall. ### Outbound -The installer downloads everything it needs during the install, and the running product keeps a small number of outbound connections afterwards. Allow TCP 443 from the server to each of these hosts. The preflight check tests every one of them: it fails if a name doesn't resolve in DNS and warns if a connection times out or is refused. +The installer downloads everything it needs during the install, and the running product keeps a small number of outbound connections afterwards. Allow TCP 443 from the server to each of these hosts. The preflight check tests every one of them: it fails if a name doesn't resolve in DNS and warns if a connection times out or the host refuses it. | Host | Purpose | |---|---| diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 90c46fdf70..590ba9c2e0 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -29,7 +29,7 @@ These ports are unencrypted. Credentials and query results cross the network in | Type | Use when | Access control | |---|---|---| | `LoadBalancer` | A load balancer is available: one from your cloud provider, or the ServiceLB that the installer leaves enabled in the bundled k3s cluster. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | -| `NodePort` | No load balancer is available, for example because ServiceLB was disabled. | None in Access Analyzer. Restrict access with the server's firewall. | +| `NodePort` | No load balancer is available, for example because you disabled ServiceLB. | None in Access Analyzer. Restrict access with the server's firewall. | The bundled k3s cluster includes ServiceLB, so use `LoadBalancer` with an allowed address list on a standard installation. ServiceLB binds ports 9000 and 8123 on the server, so those ports must be free. @@ -123,7 +123,7 @@ Give external tools only this user. Don't hand out the analytics store's adminis sudo dspmctl set-helm-param netwrix config.clickhouse.externalAccess.allocateLoadBalancerNodePorts=false ``` -- Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. To change how traffic is routed, set `config.clickhouse.externalAccess.externalTrafficPolicy` to `Cluster` or `Local`. +- Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. To change how the cluster routes traffic, set `config.clickhouse.externalAccess.externalTrafficPolicy` to `Cluster` or `Local`. ## Close access From 765743d2ef15e11ccc302b87914eecd8e2b77097 Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 15:57:16 -0400 Subject: [PATCH 07/10] docs(accessanalyzer): target the bundled k3s load balancer for external access Recommend LoadBalancer with an allowed address list on the k3s ServiceLB, keep NodePort as the fallback, and drop the cloud-provider guidance. Generated with AI Co-Authored-By: Claude Code --- .../external-clickhouse-access.md | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 590ba9c2e0..3e46e44314 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -26,12 +26,9 @@ These ports are unencrypted. Credentials and query results cross the network in ## Choose an access type -| Type | Use when | Access control | -|---|---|---| -| `LoadBalancer` | A load balancer is available: one from your cloud provider, or the ServiceLB that the installer leaves enabled in the bundled k3s cluster. | A list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. | -| `NodePort` | No load balancer is available, for example because you disabled ServiceLB. | None in Access Analyzer. Restrict access with the server's firewall. | +Access Analyzer's bundled k3s cluster includes ServiceLB, its built-in load balancer. Use `LoadBalancer` with a list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. ServiceLB binds ports 9000 and 8123 on the server, so those ports must be free. -The bundled k3s cluster includes ServiceLB, so use `LoadBalancer` with an allowed address list on a standard installation. ServiceLB binds ports 9000 and 8123 on the server, so those ports must be free. +`NodePort` has no access control in Access Analyzer, so restrict it with the server's firewall. Use it only if you disabled ServiceLB or ports 9000 and 8123 are taken. A list of allowed address ranges works only with `LoadBalancer`. Setting it with `NodePort` fails. @@ -39,17 +36,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with `dspmctl set-helm-param` turns automated sync off for the application. The last step turns it back on. -1. On the Access Analyzer server, set the access parameters. For `NodePort`: - - ```bash - sudo dspmctl set-helm-param netwrix \ - config.clickhouse.externalAccess.enabled=true \ - config.clickhouse.externalAccess.type=NodePort \ - config.clickhouse.externalAccess.nodePorts.native=30900 \ - config.clickhouse.externalAccess.nodePorts.http=30823 - ``` - - Choose ports from 30000 through 32767, or omit the `nodePorts` lines to have Kubernetes assign them. For `LoadBalancer`, restricting access to one address range: +1. On the Access Analyzer server, set the access parameters. For `LoadBalancer`, restricting access to one address range: ```bash sudo dspmctl set-helm-param netwrix \ @@ -58,16 +45,17 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with 'config.clickhouse.externalAccess.loadBalancerSourceRanges[0]=' ``` - Add `[1]`, `[2]`, and so on for more ranges. - - On a cloud provider, request an internal load balancer so the database never gets a public address. The annotation key contains dots, so escape them and quote the argument: + Add `[1]`, `[2]`, and so on for more ranges. For `NodePort`: ```bash sudo dspmctl set-helm-param netwrix \ - 'config.clickhouse.externalAccess.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-internal=true' + config.clickhouse.externalAccess.enabled=true \ + config.clickhouse.externalAccess.type=NodePort \ + config.clickhouse.externalAccess.nodePorts.native=30900 \ + config.clickhouse.externalAccess.nodePorts.http=30823 ``` - The annotation name is provider-specific. Use the one your provider documents. + Choose ports from 30000 through 32767, or omit the `nodePorts` lines to have Kubernetes assign them. 2. Apply the change: From a3ba9ecdb8dad3e973d3bf3b8bc46b97023915f3 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:00:50 +0000 Subject: [PATCH 08/10] fix(vale): auto-fix style issues (Vale + Dale) --- docs/accessanalyzer/26.1/install/requirements.md | 4 ++-- .../26.1/integrations/external-clickhouse-access.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/accessanalyzer/26.1/install/requirements.md b/docs/accessanalyzer/26.1/install/requirements.md index 7426133593..38d418333d 100644 --- a/docs/accessanalyzer/26.1/install/requirements.md +++ b/docs/accessanalyzer/26.1/install/requirements.md @@ -30,7 +30,7 @@ You pick a size when you install. The size sets the CPU and RAM the installer re | large | 24 | 96 GB | 3,000 GB | Up to about 800 million objects and 25,000 to 100,000 identities. | | enterprise | 32 | 128 GB | 8,000 GB | Up to about 3 billion objects and more than 100,000 identities. | -CPU cores and RAM are hard minimums: the installer's preflight check fails below them, and the install doesn't proceed. The check allows a 5% tolerance on RAM and disk, so a virtual machine provisioned at exactly the stated figure passes even though the guest sees slightly less. +CPU cores and RAM are hard minimums: the installer's preflight check fails below them, and the install doesn't proceed. The check allows a 5% tolerance on RAM and disk, so a virtual machine you provision at exactly the stated figure passes even though the guest sees slightly less. Disk is a recommendation. A server with less free space than the size recommends still installs and runs, but the preflight check warns that the disk is too small for the data that size is designed to hold. The 40 GB floor is different: below that, the preflight check fails. @@ -85,7 +85,7 @@ Open these ports on the server's firewall. ### Outbound -The installer downloads everything it needs during the install, and the running product keeps a small number of outbound connections afterwards. Allow TCP 443 from the server to each of these hosts. The preflight check tests every one of them: it fails if a name doesn't resolve in DNS and warns if a connection times out or the host refuses it. +The installer downloads everything it needs during the install, and the running product keeps a few outbound connections afterwards. Allow TCP 443 from the server to each of these hosts. The preflight check tests every one of them: it fails if a name doesn't resolve in DNS and warns if a connection times out or the host refuses it. | Host | Purpose | |---|---| diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 3e46e44314..299818868d 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -28,7 +28,7 @@ These ports are unencrypted. Credentials and query results cross the network in Access Analyzer's bundled k3s cluster includes ServiceLB, its built-in load balancer. Use `LoadBalancer` with a list of allowed client address ranges in Classless Inter-Domain Routing (CIDR) notation. ServiceLB binds ports 9000 and 8123 on the server, so those ports must be free. -`NodePort` has no access control in Access Analyzer, so restrict it with the server's firewall. Use it only if you disabled ServiceLB or ports 9000 and 8123 are taken. +`NodePort` has no access control in Access Analyzer, so restrict it with the server's firewall. Use it only if you disabled ServiceLB or ports 9000 and 8123 are already in use. A list of allowed address ranges works only with `LoadBalancer`. Setting it with `NodePort` fails. @@ -75,7 +75,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. -Give external tools only this user. Don't hand out the analytics store's administrator credentials: the exposed port reaches the administrator like any other user, so its password is the only thing protecting it. +Give external tools only this user. Don't share the analytics store's administrator credentials: the exposed port reaches the administrator like any other user, so its password is the only thing protecting it. 1. On the Access Analyzer server, print the password: From 32682e0573d073127f1ad0ed6e42a2d68c68820c Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 16:02:55 -0400 Subject: [PATCH 09/10] docs(accessanalyzer): note the external user's concurrent query cap Generated with AI Co-Authored-By: Claude Code --- .../26.1/integrations/external-clickhouse-access.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 299818868d..6349cd1796 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -73,7 +73,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with ## Get the credentials -Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. +Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. It can run at most four queries at once. Give external tools only this user. Don't share the analytics store's administrator credentials: the exposed port reaches the administrator like any other user, so its password is the only thing protecting it. From f52733ed0a2cdbfea05d3bc2e81c4d8d3b8246e2 Mon Sep 17 00:00:00 2001 From: Markis Taylor Date: Wed, 30 Sep 2026 16:47:50 -0400 Subject: [PATCH 10/10] docs(accessanalyzer): document rotating and removing the external credential Generated with AI Co-Authored-By: Claude Code --- .../external-clickhouse-access.md | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md index 6349cd1796..012978e857 100644 --- a/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md +++ b/docs/accessanalyzer/26.1/integrations/external-clickhouse-access.md @@ -73,7 +73,7 @@ A list of allowed address ranges works only with `LoadBalancer`. Setting it with ## Get the credentials -Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. It can run at most four queries at once. +Opening access creates a dedicated analytics store user, `access_analyzer_external`, with a generated password. The user has read-only access to the `access_analyzer` and `access_analyzer_sample` databases, with the same per-query memory limits as the user Access Analyzer's own reports use. It can run at most four queries at once, and its total memory across them is capped. Clients can't override these limits. Give external tools only this user. Don't share the analytics store's administrator credentials: the exposed port reaches the administrator like any other user, so its password is the only thing protecting it. @@ -95,7 +95,7 @@ Give external tools only this user. Don't share the analytics store's administra kubectl get svc clickhouse-external -n access-analyzer ``` -2. From the external host, check the HTTP port: +2. From the external host, check the HTTP port. With `LoadBalancer` that is `8123`. With `NodePort`, use the assigned node port from the `PORT(S)` column: ```bash curl http://:/ping @@ -113,9 +113,21 @@ Give external tools only this user. Don't share the analytics store's administra - Access Analyzer runs one analytics store. With `NodePort`, connections reach it through any node in the cluster. To change how the cluster routes traffic, set `config.clickhouse.externalAccess.externalTrafficPolicy` to `Cluster` or `Local`. +## Rotate the password + +Access Analyzer creates the password once and resets the `access_analyzer_external` user's password from it on every sync. A password changed inside the analytics store is overwritten at the next sync, so rotate through the stored secret: + +```bash +kubectl delete secret clickhouse-external-secret -n access-analyzer +sudo dspmctl sync netwrix +sudo dspmctl enable-auto netwrix +``` + +The sync generates a new password. Print it with `dspmctl get-secret`. + ## Close access -1. Turn the ports off. This also stops `dspmctl get-secret` from reading the password, but it doesn't delete the `access_analyzer_external` user. If you shared the credentials, change the password or remove the user in the analytics store: +1. Turn the ports off. This also stops `dspmctl get-secret` from reading the password, but it doesn't delete the password or the `access_analyzer_external` user, and turning access on again reuses the old password: ```bash sudo dspmctl set-helm-param netwrix config.clickhouse.externalAccess.enabled=false @@ -123,4 +135,10 @@ Give external tools only this user. Don't share the analytics store's administra sudo dspmctl enable-auto netwrix ``` -2. Remove the firewall rules you added. +2. Delete the stored password so the next time you turn access on it generates a new one: + + ```bash + kubectl delete secret clickhouse-external-secret -n access-analyzer + ``` + +3. Remove the firewall rules you added.