Skip to content

docs: cover namespace-restricted installs on the 1.x installation page (#629) - #641

Merged
Rachael-Graham merged 2 commits into
kagent-dev:mainfrom
boxcee-interview:fix/issue-629
Oct 23, 2026
Merged

Rachael-Graham merged 2 commits into
kagent-dev:mainfrom
boxcee-interview:fix/issue-629

Conversation

@boxcee-interview

Copy link
Copy Markdown
Contributor

Closes #629

The 1.x installation page had no guidance on restricting kagent to specific namespaces; the only documentation of the alternative was the global.watchNamespaces row in 1.x/reference/helm.md.

Adds the optional section "Restrict kagent to specific namespaces" after "Verify the installation" and before "Next steps", per the issue's scope:

  • Shows a global.watchNamespaces values example.
  • Recommends global.watchNamespaces over the per-surface keys, and explains that the chart derives both surfaces (RBAC and the controller watch) from it, and appends the install namespace automatically.
  • States the precedence and validation rules: rbac.namespaces wins when the key is present, an explicit rbac.namespaces: [] restores cluster-scoped RBAC and must include the install namespace when set, and config.kubernetes.watchNamespaces outside the RBAC scope fails the render (Forbidden loop).
  • Links the allowedNamespaces coverage for the chart-created RemoteMCPServer to the existing tools-ecosystem section rather than repeating it.

Verified against the chart at v1.0.0-alpha16 (the latest release as of 2026-10-19): the precedence, install-namespace append, and render-failure behavior described are what helm/kagent/templates/_helpers.tpl and the RBAC templates implement.

How to Test

Build the docs and check the new section and its link:

make build   # Hugo build, passes on hugo 0.160.1 extended

The section renders on /kagent/1.x/setup/installation/ and the anchor link resolves to the existing "Reach kagent-tool-server from another namespace" section of the tools-ecosystem reference.

kagent-dev#629)

Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>

@Rachael-Graham Rachael-Graham left a comment

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.

Thanks! I tested this locally and had a fw suggestions based on that

- `config.kubernetes.watchNamespaces` narrows the watch below the RBAC scope. A watch entry that names a namespace outside the RBAC scope fails the render, because the controller would loop on `Forbidden` errors at runtime.
- The `kagent-tool-server` RemoteMCPServer that the chart creates admits references from its own namespace only. An Agent in another watched namespace that binds it does not become ready until you set `allowedNamespaces` on that server. See [Reach kagent-tool-server from another namespace]({{< link path="reference/tools-ecosystem#reach-kagent-tool-server-from-another-namespace" >}}).

Verify a namespaced install the same way as the default one, plus the negative case: create an Agent in each watched namespace and in one unwatched namespace, and confirm that the controller reconciles only the watched two while the Agent in the unwatched namespace stays unmanaged.

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.

can you change this to numbered steps w/ commands and expected output to match the rest of the guide? or link to a diff verification steps section

watchNamespaces: [prod-agents, staging-agents]
```

Prefer `global.watchNamespaces` over the per-surface keys. The chart derives both surfaces from this one value, so they cannot disagree: it replaces the cluster-scoped getter and writer ClusterRoles with a Role and RoleBinding in each listed namespace, and it limits the controller's watch to the same list. The chart appends the install namespace to the list automatically, so the release's own objects remain managed.

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.

getter and writer ClusterRoles

this names only two of the three ClusterRoles the chart namespaces, bc kagent-tools-cluster-admin-role also becomes a role - maybe "replaces every kagent ClusterRole with a Role and RoleBinding in each listed namespace"

The per-surface keys still exist for installs that scope the surfaces independently, and the validation rules bind them:

- `rbac.namespaces` takes precedence over `global.watchNamespaces` whenever the key is present. An explicit `rbac.namespaces: []` restores cluster-scoped RBAC. When `rbac.namespaces` is set, it must include the install namespace or the render fails.
- `config.kubernetes.watchNamespaces` narrows the watch below the RBAC scope. A watch entry that names a namespace outside the RBAC scope fails the render, because the controller would loop on `Forbidden` errors at runtime.

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.

Under global.watchNamespaces, the chart adds config.kubernetes.watchNamespaces entries to the RBAC scope instead of failing (_helpers.tpl:93-96,109). The render fails only when rbac.namespaces is set explicitly, so please make the bullet conditional on that.

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.

also on this line - I tested this in a cluster, abd setting config.kubernetes.watchNamespaces alongside global.watchNamespaces replaces the watch list & the install namespace isnt added back. On alpha16, global.watchNamespaces: [prod-agents, staging-agents] with config.kubernetes.watchNamespaces: [prod-agents] left new Agents in kagent with no status. So I think state that the install namespace must be listed explicitly.

@boxcee-interview

Copy link
Copy Markdown
Contributor Author

The deploy check fails on this PR because it comes from a fork: fork PRs don't receive repo secrets, so the CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID the wrangler step needs are empty, and wrangler versions upload dies in the non-interactive environment before uploading anything. This is the documented behaviour — .github/workflows/preview.yaml (the "Comment preview URLs on the PR" step) notes that fork PRs "cannot reach the Cloudflare secrets, so the upload step above fails".

The content-gating checks all pass: Static + content checks, linkChecker, DCO. So the deploy red is an environment limitation of fork PRs, not a content problem — no preview URL will be available for this PR until it is merged (or the branch is mirrored into an org account that can see the secrets).

…-dev#629)

Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>
@boxcee-interview

Copy link
Copy Markdown
Contributor Author

All four points addressed in 0b4bb74:

  1. The verification steps are now numbered, with commands and example output for the positive and negative cases.
  2. "replaces the cluster-scoped getter and writer ClusterRoles" now reads "replaces every kagent ClusterRole with a Role and RoleBinding in each listed namespace".
  3. The bullet is conditional on rbac.namespaces being set: the render fails only then. Under global.watchNamespaces the chart folds config.kubernetes.watchNamespaces entries into the scope instead of failing (helm/kagent/templates/_helpers.tpl kagent.rbac.validate / kagent.rbacNamespaces).
  4. Added that the watch list replaces the default once config.kubernetes.watchNamespaces is set, so the install namespace is not added back — it must be listed explicitly. That matches kagent.watchNamespaces: the explicit list wins and the RBAC-scope fallback (which is where the install namespace is appended) is skipped.

@Rachael-Graham Rachael-Graham left a comment

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.

nice, thank you very much for covering this. Merging

@Rachael-Graham
Rachael-Graham merged commit a774b6e into kagent-dev:main Oct 23, 2026
3 of 4 checks passed
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.

Document namespace-scoped installs on the 1.x installation page

2 participants