Skip to content

rpk: warn when role name is not RFC 1123-compliant#30325

Draft
david-yu wants to merge 2 commits intodevfrom
dyu/rpk-role-rfc1123-warning
Draft

rpk: warn when role name is not RFC 1123-compliant#30325
david-yu wants to merge 2 commits intodevfrom
dyu/rpk-role-rfc1123-warning

Conversation

@david-yu
Copy link
Copy Markdown
Contributor

@david-yu david-yu commented Apr 28, 2026

Summary

Adds a stderr warning to rpk security role create when the role name isn't a valid DNS-1123 subdomain. The warning is informational only — the role is still created, exit code stays 0, and stdout is unchanged.

$ rpk security role create MyRole
Warning: role name "MyRole" is not a valid DNS-1123 subdomain (RFC 1123):
  - a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (regex used for validation is …)
  This role cannot be adopted by a RedpandaRole CR in the Redpanda Kubernetes operator,
  since the operator binds the role name to the CR's metadata.name. Consider using a
  lowercase name (letters, digits, '-', '.') if you may migrate to operator-managed roles.
Successfully created role "MyRole"
…

Compliant names produce no warning.

What "RFC 1123 compliant" means here

The check uses the DNS-1123 subdomain rule from k8s.io/apimachinery — the same rule the Kubernetes API server applies to metadata.name on every object. In short:

  • 1 to 253 characters total
  • Only lowercase letters (az), digits (09), hyphens (-), and dots (.)
  • Must start and end with a letter or digit
  • Each dot-separated label must be 1 to 63 characters and follow the same start/end rule

Examples

Compliant (no warning) Non-compliant (warning) Why it fails
my-role MyRole uppercase letters
payments Payments uppercase letters
team.read-only App_Service underscore not allowed
app.staging.us-east my role space not allowed
role01 -foo leading hyphen
analytics-prod foo- trailing hyphen
a role! special character
kafka.connect.sink `` (empty) must be at least 1 char
b2b-events a string longer than 253 chars exceeds max length
auth.v2.read team..read empty label between dots

The general guidance is: if you'd be comfortable using the name as a hostname segment, it's compliant. If it has uppercase, underscores, spaces, or other punctuation, it isn't.

Motivation

Customers migrating from helm-only Redpanda installs to operator-managed installs have hit a wall when their existing roles have mixed-case or otherwise non-RFC-1123 names. The Redpanda Kubernetes operator binds a RedpandaRole CR's role name to its metadata.name, which the Kubernetes API server validates against RFC 1123. Roles like MyRole or App_Service cannot be adopted by an operator-managed CR — there is no way to even create such a CR, since the API server rejects the metadata.name outright.

The current workaround for migration is a per-role manual sequence: create a new lowercase role, copy members, recreate ACLs that referenced the old principal, then delete the old role. Surfacing this constraint at role-create time gives operators of pre-operator clusters a chance to pick operator-friendly names up front, even if they don't intend to migrate today, and avoids the rename dance later.

Why warning, not rejection

A hard rejection would be a breaking change for every existing Redpanda user with non-compliant role names — not just operator users. Anyone managing roles via rpk or the Admin API directly today would suddenly see role-create calls fail on upgrade.

This change is purely additive. Stdout-consuming callers (e.g. scripts using --format json) are unaffected because the warning is stderr-only. Existing CI/CD pipelines continue to work.

If a stricter mode is desired down the road, this validator is the natural spot to gate it behind a cluster property or an opt-in rpk flag.

Implementation notes

  • The validator is a thin wrapper around k8s.io/apimachinery/pkg/util/validation.IsDNS1123Subdomain — same rule the K8s API server applies, so the warning is consistent with what the operator's CR validation will actually reject.
  • apimachinery is already an rpk dependency (used by rpk debug bundle); no go.mod change.
  • Both the cloud (publicapi) and self-hosted (adminapi) create paths are covered, since the warning fires before the branch.

Test plan

  • Unit tests: go test ./src/go/rpk/pkg/cli/security/role -run TestValidateRoleNameForK8s — 11 cases covering compliant names, uppercase, leading/trailing hyphens, underscore, space, empty, and >253 chars
  • go build ./... clean across the rpk module
  • Manual smoke against a real cluster:
    • rpk security role create my-role → no warning, role created
    • rpk security role create MyRole → warning on stderr, role still created, exit 0
    • rpk security role create my-role --format json → JSON on stdout unchanged

Out of scope

  • No Admin API server-side change. Keeping the blast radius small per discussion — this is a client-side hint only.
  • No change to other rpk security role subcommands. The warning only makes sense at create time; assigns/describes/lists referencing an existing non-compliant role would be redundant noise.

Adds a stderr warning to `rpk security role create` when the role name
isn't a valid DNS-1123 subdomain. The warning is informational only --
the role is still created and the command exits 0.

The Redpanda Kubernetes operator binds a RedpandaRole CR's role name
to its metadata.name, which the Kubernetes API server validates against
RFC 1123. Roles like "MyRole" or "App_Service" cannot be adopted by an
operator-managed CR and require a manual rename (create new role, copy
members, recreate ACLs, delete old) before migration. Surfacing this
constraint at create time gives operators a chance to choose operator-
friendly names up front.

A warning rather than a hard rejection avoids breaking existing users
with non-compliant names. Stdout is unchanged so JSON/YAML formatters
and scripted callers parsing stdout aren't affected.
Comment thread src/go/rpk/pkg/cli/security/role/create.go Outdated
Comment thread src/go/rpk/pkg/cli/security/role/create.go Outdated
Per @r-vasquez review on PR #30325:

- Drop the validateRoleNameForK8s wrapper and its tests; the wrapper
  added no logic over validation.IsDNS1123Subdomain, so testing it just
  exercised the upstream function. Call IsDNS1123Subdomain directly at
  the use site.

- Collapse the multi-line warning into a single Fprintf with a raw
  string template, joining messages with strings.Join.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants