Skip to content

fix: white-label the access-request CRD from a brand name, not a DNS domain - #477

Open
ab-alien-dev wants to merge 3 commits into
mainfrom
alan/alien-563-fix-accessrequest-branding
Open

fix: white-label the access-request CRD from a brand name, not a DNS domain#477
ab-alien-dev wants to merge 3 commits into
mainfrom
alan/alien-563-fix-accessrequest-branding

Conversation

@ab-alien-dev

Copy link
Copy Markdown
Contributor

Summary

  • The access-request CRD's group/kind/plural were derived from a literal DNS domain (label_domain, e.g. acme.dev) and used verbatim in the group (accessrequests.acme.dev).
  • Kubernetes only requires the group to be shaped like a DNS subdomain — it never resolves it. Any non-domain-shaped brand value (a plain project name like test2, or a placeholder like test2.local) produced a group the operator's own ServiceAccount was never granted RBAC for, causing 403 Forbidden on every access-request CR creation.
  • access_request_crd_names now takes a brand name and slugs it consistently regardless of shape (acme.devacme, test2test2, My Cool Appmycoolapp) — the CRD, RBAC, and the operator's own runtime CR-creation call all derive from the identical slug, so they can't drift.

Test plan

  • cargo test -p alien-core access_request_crd — 6/6 pass
  • cargo test -p alien-helm access_request_crd_is_white_labeled — pass
  • cargo test -p alien-helm --test generator — 21/21 pass (full integration suite)
  • Root-caused live: reproduced the exact 403 Forbidden on a real kind cluster against a whitelabeled test2 operator, confirmed the new brand_slug logic correctly slugs test2.localtest2 in isolation

🤖 Generated with Claude Code

…domain

Kubernetes requires the CRD's API group to be *shaped* like a DNS
subdomain, but never resolves it — the group isn't a domain the
vendor owns, just a stable customer-facing identity slugified into
that shape. The previous design took a literal DNS domain
(label_domain, e.g. "acme.dev") and used it in the group verbatim
(accessrequests.acme.dev), which meant any non-domain-shaped brand
value (e.g. a plain project name like "test2", or a placeholder like
"test2.local") produced a group the operator's own ServiceAccount
was never granted RBAC for — the CRD/RBAC (rendered from the same
slugified brand) and a differently-shaped runtime group request
diverge.

access_request_crd_names now takes a brand name and slugs it the same
way regardless of whether the input already looks like a domain
(acme.dev), a plain name (test2), or free text (My Cool App) — the
group, RBAC, and the operator's own runtime CR-creation call all
derive from the identical slug, so they can't drift.
@greptile-apps

greptile-apps Bot commented Aug 23, 2026

Copy link
Copy Markdown

Greptile Summary

The PR consistently derives access-request CRD identifiers from a normalized brand slug rather than using the branding domain verbatim.

  • Updates shared CRD group, kind, plural, short-name, API-version, and metadata-name derivation.
  • Aligns generated Helm CRD and RBAC expectations with the new default and branded groups.
  • Makes the operator prefer the embedded brand identity while retaining compatibility with older embedded configurations.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/alien-core/src/access_request_crd.rs Centralizes slug-based access-request CRD naming and adds coverage for default, domain-shaped, and plain-text brands.
crates/alien-helm/src/generator.rs Updates generated CRD and RBAC expectations to use the normalized brand-derived API group.
crates/alien-operator/src/cli.rs Prefers the embedded brand for operator configuration while retaining the legacy label-domain fallback.

Reviews (4): Last reviewed commit: "fix: update stale accessrequests.alien.d..." | Re-trigger Greptile

Comment thread crates/alien-core/src/access_request_crd.rs
@ab-alien-dev

Copy link
Copy Markdown
Contributor Author

@greptile-apps review

…perator's own CRD names

The operator's own access-request-CRD naming re-derived label_domain
from the embedded binary config's raw label_domain field, redundant
with (and disagreeing with) the already-slugged brand field the same
config carries — packages-builder computes and embeds both. When the
raw value isn't already brand-shaped (e.g. a placeholder domain like
"acme.local" instead of a real owned domain), the operator's runtime
CR-creation call requested a group the deployed CRD/RBAC — generated
from the same brand slug — was never granted, causing every
access-request creation to fail with 403 Forbidden.

Verified live: rebuilt+redeployed a whitelabeled operator, confirmed
access-request CRs now materialize successfully and the customer
approval patch (PENDING_APPROVAL -> APPROVED) round-trips correctly.
The default (unbranded) CRD group collapsed from accessrequests.alien.dev
to accessrequests.alien, but this test still matched on the old string —
falling through to the generic read-only assertion and failing on the
access-request rule's legitimate create/update/patch verbs.
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.

1 participant