Skip to content

feat(rbac): namespaced webhook auth and a migratable SA-UID identity - #531

Draft
therealdwright wants to merge 1 commit into
temporalio:mainfrom
therealdwright:530-namespaced-rbac
Draft

feat(rbac): namespaced webhook auth and a migratable SA-UID identity#531
therealdwright wants to merge 1 commit into
temporalio:mainfrom
therealdwright:530-namespaced-rbac

Conversation

@therealdwright

@therealdwright therealdwright commented Aug 17, 2026

Copy link
Copy Markdown

What was changed

Two changes toward reducing the cluster-scoped RBAC the controller needs in
namespace-scoped mode (rbac.restrictWatchNamespaces), without breaking existing installs on
upgrade:

  1. SubjectAccessReviewLocalSubjectAccessReview in the WorkerResourceTemplate
    webhook. It is namespaced and sufficient (the webhook rejects non-namespaced kinds and
    always checks within the object's namespace), so subjectaccessreviews create moves out
    of the cluster-scoped grant into the per-namespace Role.

  2. Identity suffix from the ServiceAccount UID instead of the Namespace UID, read via a
    small namespaced identity-reader-role. A plain suffix change would deadlock existing
    Worker Deployments (they stay managed under the old identity — thanks @jaypipes), so the
    controller also reads the namespace UID and treats the old id/<ns-uid> identity as
    reclaimable, the same pattern as the existing getDeprecatedControllerIdentity reclaim
    from Prepare to include cluster UID in CONTROLLER_IDENTITY to prevent cross-cluster conflicts #308. On helm upgrade it re-adopts existing deployments under the new id/<sa-uid>
    identity automatically.

The namespaces get grant (a minimal manager-cluster-role) is retained for this migration
window; it can be dropped in a follow-up release once deployments have been re-adopted, at
which point namespace-scoped mode no longer needs a manager ClusterRole.

Why?

Clusters whose policies forbid ClusterRole creation (common in the multi-tenant environments
namespace-scoped mode targets) currently can't install the chart. Both grants are ClusterRoles
only because their resource types are cluster-scoped, not because the controller needs
cluster-wide reach. This removes one now and sets up removing the other safely.

Checklist

  1. Closes [Feature Request] Eliminate ClusterRole requirement in namespace-scoped mode #530

  2. How was this tested:

    • New integration test (TestManagerIdentitySuffixMigration) reproduces the upgrade
      against a real Temporal server (temporaltest): it fails (deadlock) without the reclaim
      path and passes with it (re-claims and promotes the new version). The full
      TestIntegration suite passes with the change (no regression to the existing
      manager-identity tests).
    • make manifests is idempotent (CI rbac.yaml gate passes).
    • helm template (namespace-scoped): the manager is a namespaced Role; manager-cluster-role
      now holds only namespaces get; a new namespaced identity-reader-role is added; no
      subjectaccessreviews cluster grant.
    • Webhook + controller envtest suites pass.
  3. Any docs updates needed?
    Probably a short note in the namespace-scoped/RBAC docs about the reduced ClusterRole and
    the planned follow-up removal. Happy to add.

@CLAassistant

CLAassistant commented Aug 17, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a backwards-incompatible change where the temporal-worker-controller's manager identity will change and that will unfortunately result in deadlocks where existing Temporal Worker Deployments will not be able to be managed by temporal-worker-controller until a manual temporal worker deployment set-manager-identity CLI call is made.

In addition, removing namespaces entirely from the list of resources the ClusterRole needs and changing from SubjectAccessReview to LocalSubjectAccessReview for both ClusterRole and Role will likely break all existing installations, cluster-scoped or otherwise. We would certainly need a functional test that demonstrated such a migration path would be doable with helm upgrade...

Comment thread cmd/main.go
setupLog.Error(err, "unable to fetch service account UID for controller identity suffix")
os.Exit(1)
}
if err := os.Setenv(controller.IdentitySuffixEnvKey, string(sa.UID)); err != nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this break all existing installations of temporal-worker-controller in a backwards-incompatible way? The identity suffix env key will change from the namespace's UID to the service account's UID and then Worker Deployment's manager identity will change which result in all the Temporal Worker Deployments managed by the temporal-worker-controller getting into a manager-identity deadlock.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jaypipes , good pickup, I didn't consider the deadlock. First-time contributor here so apologies if I've approached this incorrectly.

I added an integration test that reproduces the behaviour you have describedr: once the suffix changes the controller won't promote a new version, since the deployment is still owned by the old identity. It fails on the current PR.

For the transition I tried to follow the existing getDeprecatedControllerIdentity reclaim path from when the ns-UID suffix landed (#308). The controller now also reads the namespace UID and treats the old id/<ns-uid> identity as reclaimable, so helm upgrade re-adopts existing deployments under the new id/<sa-uid> identity on its own, no manual set-manager-identity. Test passes with that in. I left the namespaces get grant in for the migration window, figured it can come out a release or two later once everything's re-adopted.

Does that match how you'd want the transition handled, and how it's been done before? Happy to redo it if there's a better way.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On SubjectAccessReview > LocalSubjectAccessReview: I don't think it's a permanent break, but there's an transient upgrade issue. The WRT webhook is failurePolicy: Fail, so during the rolling restart the old pod loses subjectaccessreviews create once the new RBAC is applied and WRT admissions get blocked for that window. I believe it clears once the new pod is ready. If that matters I can keep both grants for one release (same migration-window idea as the identity change) and drop the cluster one in a follow-up or I can leave it if a brief gap is fine. Do you have a preference?

@therealdwright therealdwright Aug 18, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran the helm upgrade migration on kind (released v1.8.1 then upgraded to the code/manifests in this PR):

  • Pre-upgrade: WorkerDeployment ManagerIdentity = <release>/<namespace-UID>.
  • After upgrade + a worker image bump: controller logged "claimed manager identity" under the new <release>/<SA-UID>, ManagerIdentity updated to match, and the new version promoted to current. No manual set-manager-identity, no deadlock.
  • RBAC (namespace-scoped): manager-cluster-role now only namespaces get; new namespaced identity-reader-role; localsubjectaccessreviews in the per-namespace Role; webhook accepted a live WorkerDeployment patch.

Shrinks the cluster-scoped RBAC the controller needs in namespace-scoped mode
and lays groundwork to remove the manager ClusterRole entirely in a later
release, without the manager-identity deadlock raised in review.

- The WorkerResourceTemplate webhook authorizes with LocalSubjectAccessReview
  instead of SubjectAccessReview. It is namespaced and sufficient (the webhook
  rejects non-namespaced kinds and always checks within the object's namespace),
  so the subjectaccessreviews "create" grant moves out of cluster scope into
  the per-namespace Role.

- The controller identity suffix is now the ServiceAccount UID, read via a small
  namespaced identity-reader Role, instead of the Namespace UID. To avoid
  deadlocking Worker Deployments still claimed under the previous namespace-UID
  identity, the controller also reads the namespace UID and treats that legacy
  identity as reclaimable (mirroring the existing deprecated-identity reclaim
  path), adopting such deployments under the new identity on helm upgrade. The
  namespaces "get" grant and its minimal manager-cluster-role are retained for
  this migration window and can be dropped in a later release.

Adds an integration test that reproduces the upgrade against a real Temporal
server: a deployment claimed under the pre-upgrade identity is re-claimed and
its new version promoted after the suffix changes.

Signed-off-by: Daniel Wright <danielwright@bitgo.com>
@therealdwright therealdwright changed the title feat(rbac): drop the manager ClusterRole in namespace-scoped mode feat(rbac): namespaced webhook auth and a migratable SA-UID identity Aug 18, 2026
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.

[Feature Request] Eliminate ClusterRole requirement in namespace-scoped mode

3 participants