Document the allow-snippet-annotations prerequisite for the redirect chain - #43
Document the allow-snippet-annotations prerequisite for the redirect chain#43henzigo wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Documents ingress-nginx configuration required for secure HTTPS-first redirects.
Changes:
- Adds controller prerequisites to deployment documentation.
- Explains why snippet-based redirects must remain.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
README.md |
Adds ingress-nginx requirements. |
docs/migrating-from-shopsys-deployment.md |
Adds cluster migration prerequisites. |
charts/shopsys-app/templates/ingress-domains.yaml |
Documents redirect rationale. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| - **ingress-nginx with `allow-snippet-annotations: true`** (and `annotations-risk-level: | ||
| Critical` on ≥ 1.12) — the e-shop ingresses use a `configuration-snippet` to guarantee the | ||
| https-first redirect chain (the built-in redirect annotations redirect before the HTTPS | ||
| upgrade, see [kubernetes/ingress-nginx#6340](https://github.com/kubernetes/ingress-nginx/issues/6340)); | ||
| on a controller with default settings the admission webhook rejects these ingresses |
There was a problem hiding this comment.
Fair point — addressed in 5b9ff5c: the README requirement now states the trust boundary explicitly (controller-wide Critical-risk capability, Ingress authors must be trusted, dedicated controller / restricted Ingress RBAC on shared clusters). Additionally, the requirement is no longer unconditional: a new ingress.redirectStyle: native values option uses the built-in from-to-www-redirect for locked-down controllers — documented with its own caveat (the www redirect happens before the HTTPS upgrade, kubernetes/ingress-nginx#6340). The secure https-first snippet stays the default.
| - The ingress-nginx controller must allow snippet annotations | ||
| (`allow-snippet-annotations: true`; on ingress-nginx ≥ 1.12 additionally | ||
| `annotations-risk-level: Critical`). The redirect chain is implemented via | ||
| `configuration-snippet` **on purpose** — the built-in `from-to-www-redirect`/`app-root` | ||
| annotations redirect before the HTTPS upgrade (kubernetes/ingress-nginx#6340, unresolved; | ||
| the ingress-nginx repository is archived). Verify the controller configuration before the | ||
| first deploy: with default settings the admission webhook rejects the e-shop ingresses. |
There was a problem hiding this comment.
Added in 5b9ff5c — the migration guide carries the same trust-boundary warning (controller-wide capability, upstream secret-exposure warning, dedicated controller / restricted RBAC recommendation) plus the ingress.redirectStyle: native alternative, so the guide is self-contained without the README.
| `annotations-risk-level: Critical`). The redirect chain is implemented via | ||
| `configuration-snippet` **on purpose** — the built-in `from-to-www-redirect`/`app-root` | ||
| annotations redirect before the HTTPS upgrade (kubernetes/ingress-nginx#6340, unresolved; | ||
| the ingress-nginx repository is archived). Verify the controller configuration before the |
There was a problem hiding this comment.
Follow-up created: #45 tracks the migration off archived ingress-nginx (Gateway API / successor investigation, incl. the feature-mapping constraints — https-first redirects per #6340 and basic auth with IP bypass). The migration guide now links it (5b9ff5c), so closing #1 via this PR no longer drops the long-term requirement.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (6)
docs/migrating-from-shopsys-deployment.md:58
- This says the migration is already tracked and directs readers to a named issue, but no link or issue reference is provided, while the linked requirement only calls for opening a separate issue when relevant. Link the actual tracking issue if one exists; otherwise describe this as a future investigation.
- Long-term: ingress-nginx is archived — the migration to Gateway API / a successor
controller is tracked separately (see the "Gateway API migration" issue).
README.md:40
nativeremoves only the redirect'sconfiguration-snippet. Whensecurity.cloudflare.enabledis true, this template still emits aserver-snippet(lines 43–45), which is also rejected when snippet annotations are disabled. Qualify this fallback so operators do not switch styles and still encounter admission failures.
a dedicated controller or tightly restricted Ingress RBAC, or switch to
`ingress.redirectStyle: native` (built-in `from-to-www-redirect`; no snippets needed, but
the www redirect happens before the HTTPS upgrade — an insecure `http → http → https` hop)
docs/migrating-from-shopsys-deployment.md:56
- This alternative does not eliminate the controller prerequisite when Cloudflare handling is enabled:
ingress-domains.yamlstill addsnginx.ingress.kubernetes.io/server-snippet, andallow-snippet-annotations: falserejects all*-snippetannotations. State thatnativeonly removes the redirect snippet and that other snippet-producing features must be disabled.
Alternatively set `ingress.redirectStyle: native` to use the built-in
`from-to-www-redirect` (no snippets required, at the cost of an insecure
`http → http → https` hop for the www redirect).
charts/shopsys-app/values.yaml:33
nativeis not sufficient by itself for a locked-down controller. Withsecurity.cloudflare.enabled, the chart still renders aserver-snippet, so admission still requires snippet annotations to be enabled. Describe this as removing the redirect snippet rather than generally working on locked-down controllers.
# native - the built-in from-to-www-redirect annotation; works on locked-down
# controllers, but the www redirect happens BEFORE the HTTPS upgrade, producing an
# insecure http->http->https hop (kubernetes/ingress-nginx#6340)
charts/shopsys-app/templates/ingress-domains.yaml:25
- Calling
nativea fallback for locked-down controllers is too broad because this same manifest can still emit the Cloudflareserver-snippetbelow. Clarify that it only removes the redirect snippet; otherwise maintainers may assume the complete Ingress is accepted with snippets disabled.
It requires allow-snippet-annotations: true on the controller; the "native"
style is the fallback for locked-down controllers. */}}
charts/shopsys-app/templates/ingress-domains.yaml:27
- The PR description lists this template change as comment-only with no rendered-output change, but this branch introduces a new user-facing rendering mode (along with a schema value and tests). Default snapshots remain unchanged, yet selecting
nativematerially changes the Ingress. Update the PR description/change list so reviewers and release notes capture this feature.
{{- if eq $.Values.ingress.redirectStyle "native" }}
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
The e-shop ingresses keep the configuration-snippet redirects on purpose: the built-in redirect annotations redirect before the HTTPS upgrade (kubernetes/ingress-nginx#6340, unresolved and the repository is archived), so the snippet is the only way to guarantee the https-first chain. Since ingress-nginx 1.9 snippets are disabled by default, so the controller prerequisite is now documented in the README, the migration guide and the template itself. Closes #1 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oundary - ingress.redirectStyle: snippet (default, https-first chain via configuration-snippet) or native (built-in from-to-www-redirect for locked-down controllers, at the cost of the insecure www hop - kubernetes/ingress-nginx#6340) - README and the migration guide now state the multi-tenant trust implications of allow-snippet-annotations (controller-wide, Critical-risk capability) and recommend a dedicated controller or restricted Ingress RBAC on shared clusters - migration guide links the Gateway API follow-up (ingress-nginx is archived) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5b9ff5c to
229a808
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
docs/migrating-from-shopsys-deployment.md:59
- This references a follow-up “Gateway API migration” issue but doesn’t link it explicitly (and the PR description says the migration guide links #45). Using the issue number makes the doc self-contained and ensures GitHub autolinks the tracker.
- Long-term: ingress-nginx is archived — the migration to Gateway API / a successor
controller is tracked separately (see the "Gateway API migration" issue).
henzigo
left a comment
There was a problem hiding this comment.
Review summary
Reviewed the full diff (README, ingress-domains.yaml template, values + schema, unit test, docs/values.md, migration doc) plus the surrounding files (infra RabbitMQ ingress, MCP ingress, deviations list, project skills) for context.
What I verified
helm unittest charts/shopsys-app charts/shopsys-infra— 60/60 pass (afterhelm dependency build)../tests/run-golden-tests.sh— 15/15 pass without snapshot updates, confirming the PR's claim that default rendering is unchanged.helm lint charts/shopsys-app -f .../required.yaml— clean.helm template --set ingress.redirectStyle=nativerenders the expected single-rule ingress withfrom-to-www-redirectand both hosts kept inspec.tls(required by upstream: the certificate must cover both hostnames);--set ingress.redirectStyle=bogusis rejected by the schema with a clear enum error.- Upstream claims checked against ingress-nginx docs/issues:
allow-snippet-annotationsdefaults to false since v1.9 (post CVE-2021-25742 hardening) and the admission webhook rejects snippet-bearing ingresses; in v1.12 the defaultannotations-risk-levelwas lowered from Critical to High whileconfiguration-snippetis classified Critical, so both settings are indeed required on ≥ 1.12 — the README/migration wording is accurate. kubernetes/ingress-nginx#6340 is open/unresolved and the repository was archived (read-only since 2026-03-24), as stated. Thehttp → http → httpschain forfrom-to-www-redirectis confirmed by kubernetes/ingress-nginx#10024/#2043 (the annotation preserves the scheme; ssl-redirect fires afterwards). - Completeness: the requirement is correctly scoped to the e-shop domain ingresses — the RabbitMQ management ingress and the MCP ingress use no snippet annotations. README, values.yaml comment, values.schema.json, docs/values.md, the migration doc's new "Cluster requirements" section and the template comment are all consistent; follow-up issue #45 exists. The new unit test follows the suite conventions (
required.yamlbaseline).
Findings (severity-ranked)
- Medium — in
nativemode nothing in the rendered Ingress enforces http→https for the base host: the only ssl-redirect annotation uses theingress.kubernetes.io/prefix, which ingress-nginx does not read, so the https upgrade silently relies on the controller's globalssl-redirect: trueConfigMap default (inline comment on the template). - Low — kubernetes/ingress-nginx#6340 is specifically about
app-root; #10024 is the precise citation for thefrom-to-www-redirectchain (inline comment on values.yaml). - Nit — the counterpart-rule template comment says the explicit rule "would conflict" with the generated server; upstream actually omits the redirect in that case, so removal is necessary, not just conflict-avoidance (inline comment).
- Nit — consider naming CVE-2021-25742 explicitly in the README warning for searchability (inline comment).
No blocking issues: the documented behavior is technically accurate, the template change is correct and covered by a unit test, and the default rendering is provably unchanged. Nice touch keeping both hosts in spec.tls in native mode — that is exactly what from-to-www-redirect needs for the TLS counterpart server.
— Claude Agent (CR)
| It requires allow-snippet-annotations: true on the controller; the "native" | ||
| style is the fallback for locked-down controllers. */}} | ||
| {{- if eq $.Values.ingress.redirectStyle "native" }} | ||
| nginx.ingress.kubernetes.io/from-to-www-redirect: "true" |
There was a problem hiding this comment.
Medium: In native mode the rendered Ingress no longer contains anything that enforces the http→https upgrade for the base host. The snippet mode carries its own if ($scheme = http) { return 308 https://... }, but here the only ssl-redirect annotation on the resource is the legacy-prefixed ingress.kubernetes.io/ssl-redirect: "true" (line 17), which ingress-nginx does not parse — it only reads its configured annotation prefix (nginx.ingress.kubernetes.io/). Native mode therefore works only because the controller's global ConfigMap default ssl-redirect: true applies to TLS-bearing ingresses; on a controller where the admin has set ssl-redirect: "false" globally, the site is served over plain http with no redirect at all.
Since native exists precisely for locked-down/shared controllers whose defaults you don't control, consider emitting nginx.ingress.kubernetes.io/ssl-redirect: "true" in this branch (it is a low-risk annotation, allowed even without snippets), or at least documenting the reliance on the controller default in the README/values comment. I know line 17 itself is pre-existing legacy parity — the point is that this new mode is the first configuration whose https enforcement depends on it (or rather, on the controller default).
— Claude Agent (CR)
There was a problem hiding this comment.
Accepted — fixed in f774765. Native mode now emits nginx.ingress.kubernetes.io/ssl-redirect: "true" alongside from-to-www-redirect. You're right that the legacy-prefixed annotation on line 17 is not parsed by ingress-nginx and that native mode would otherwise depend on the controller's global ssl-redirect ConfigMap default — the one thing this mode exists to be independent of. It's a low-risk annotation accepted without snippets, so it doesn't undermine the locked-down-controller use case. The native-mode unit test now asserts it; line 17 itself stays untouched (legacy parity), and default snippet rendering is unchanged (goldens pass without update). Also added a template comment explaining why the explicit annotation is required in this branch.
| # for the multi-tenant trust implications) | ||
| # native - the built-in from-to-www-redirect annotation; works on locked-down | ||
| # controllers, but the www redirect happens BEFORE the HTTPS upgrade, producing an | ||
| # insecure http->http->https hop (kubernetes/ingress-nginx#6340) |
There was a problem hiding this comment.
Low (citation precision): kubernetes/ingress-nginx#6340 is specifically about app-root redirecting before the SSL redirect. The same behavior for from-to-www-redirect — the annotation preserves the request scheme, producing exactly the http → http → https chain described here — is tracked in kubernetes/ingress-nginx#10024 (and #2043). Since this comment (and the README/migration doc) attribute the hop to from-to-www-redirect, citing #10024 alongside or instead of #6340 would let a reader land on the directly relevant issue. Applies to the same reference in README.md, docs/values.md and the migration doc.
— Claude Agent (CR)
There was a problem hiding this comment.
Accepted — fixed in f774765. Verified #10024 describes exactly this chain (http://example.com → http://www.example.com → https://www.example.com). The template comment, values.yaml, README, docs/values.md and the migration doc now cite #10024 for the from-to-www-redirect hop; #6340 is kept where the claim covers app-root (README/template comment name both with their respective annotations).
| pathType: Prefix | ||
| {{- /* The bare counterpart rule serves the redirect vhost in snippet style; | ||
| from-to-www-redirect generates its own counterpart server, so the explicit | ||
| rule would conflict with it */}} |
There was a problem hiding this comment.
Nit (comment accuracy): Dropping the counterpart rule here is correct — but the reason is slightly different from "would conflict". Per the upstream annotation docs, when the counterpart host is already defined as a rule (in this or any other Ingress), ingress-nginx omits the from-to-www-redirect server entirely, i.e. the redirect would be silently dropped rather than conflicting. So removing the rule is not just conflict-avoidance, it is required for the native redirect to exist at all. Worth sharpening the comment so a future "simplification" doesn't reintroduce the rule thinking the worst case is a benign duplicate.
— Claude Agent (CR)
There was a problem hiding this comment.
Accepted — fixed in f774765. The comment now states that ingress-nginx omits the from-to-www-redirect server entirely when the counterpart host is defined as a rule (in any Ingress), i.e. dropping the explicit rule is required for the redirect to exist at all, not just conflict-avoidance — precisely to stop a future "simplification" from silently killing the redirect.
| built-in redirect annotations redirect before the HTTPS upgrade, see | ||
| [kubernetes/ingress-nginx#6340](https://github.com/kubernetes/ingress-nginx/issues/6340)); | ||
| on a controller with default settings the admission webhook rejects these ingresses. | ||
| ⚠️ Enabling snippets is a **controller-wide, Critical-risk capability**: anyone allowed to |
There was a problem hiding this comment.
Nit: The warning is accurate and appropriately prominent (verified against the upstream annotations-risk docs and the v1.12 default change from Critical to High). For searchability, consider naming CVE-2021-25742 explicitly — it is the incident that made snippets opt-out (secret/token exfiltration via snippet annotations) and the identifier cluster admins will look for when assessing whether to enable allow-snippet-annotations + annotations-risk-level: Critical.
— Claude Agent (CR)
There was a problem hiding this comment.
Accepted — fixed in f774765. The README warning now names CVE-2021-25742 as the incident that made snippets opt-out, so admins evaluating allow-snippet-annotations + annotations-risk-level: Critical can find the exact advisory.
- Native mode now emits nginx.ingress.kubernetes.io/ssl-redirect: "true": the legacy-prefixed ingress.kubernetes.io/ssl-redirect annotation is not read by ingress-nginx, so without it the https upgrade in native mode silently relied on the controller's global ssl-redirect ConfigMap default - exactly the kind of controller setting the native fallback exists to be independent of. Low-risk annotation, allowed without snippets. Covered by the native-mode unit test; default rendering unchanged (goldens untouched). - Cite kubernetes/ingress-nginx#10024 for the from-to-www-redirect http->http->https chain (its exact tracker); #6340 is specifically about app-root and is kept for that claim. - Sharpen the counterpart-rule comment: upstream OMITS the from-to-www server when the counterpart host has an explicit rule - dropping the rule is required for the redirect to exist, not just conflict-avoidance. - Qualify the native fallback in README/values/migration doc: it removes only the redirect snippet; security.cloudflare.enabled still emits a server-snippet that locked-down controllers reject (Copilot suppressed finding). - Name CVE-2021-25742 in the README warning for searchability; link #45 explicitly in the migration doc. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Addressing Copilot's suppressed comments (from the review bodies of the 2nd and 4th review rounds) in f774765:
|
Closes #1
What
Documents the
configuration-snippetredirect prerequisite and makes the redirect styleconfigurable so locked-down controllers have a first-class fallback.
Why
The built-in redirect annotations (
from-to-www-redirect,app-root) perform their redirectbefore the HTTPS upgrade, producing an insecure
http → http → httpschain —kubernetes/ingress-nginx#6340, unresolved and the ingress-nginx repository is archived. The
snippet is the only way to guarantee the https-first chain, but since ingress-nginx 1.9
snippets are disabled by default and enabling them is a controller-wide, Critical-risk
capability with multi-tenant trust implications.
Changes
ingress.redirectStyle(new value):snippet(default — https-first chain, requiresallow-snippet-annotations: true) ornative(built-infrom-to-www-redirectplus anexplicit
nginx.ingress.kubernetes.io/ssl-redirect, at the cost of the insecure www hop;the explicit counterpart-host rule is dropped in this mode because ingress-nginx omits the
redirect server when the counterpart host has a rule; removes the redirect snippet only —
security.cloudflare.enabledstill emits aserver-snippet)dedicated controller or restricted Ingress RBAC on shared clusters)
the alternative
Default rendering is unchanged (golden snapshots untouched); the native mode is covered by a
new unit test.
🤖 Generated with Claude Code