Skip to content

feat(appsec): migrate injector config to spec.features.appsec.injector and add GKE Gateway support - #3337

Open
eliottness wants to merge 18 commits into
mainfrom
eliottness/appsec-ga
Open

feat(appsec): migrate injector config to spec.features.appsec.injector and add GKE Gateway support#3337
eliottness wants to merge 18 commits into
mainfrom
eliottness/appsec-ga

Conversation

@eliottness

@eliottness eliottness commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

We are about to mark appsec injector GA

Migrates AppSec proxy injector configuration from agent.datadoghq.com/appsec.* annotations to a first-class CRD surface at spec.features.appsec.injector.*, and adds GKE Gateway support.

  • New CRD surface mirroring the Helm datadog.appsec.injector.* layout 1:1, plus a net-new injector.gke.gatewayClasses.
  • Per-field precedence — annotations are parsed first, then the CRD overlays field by field: the CRD wins where set, annotations fill what is unset.
  • GKE Gateway handovergke-gateway proxy value, gatewayClassesDD_APPSEC_PROXY_GKE_GATEWAY_CLASSES, mode: external required when gke-gateway is explicitly listed in proxies, and a cluster-agent >= 7.82.0 gate.
  • RBACnetworking.gke.io/gcptrafficextensions (get/create/delete) and events gains patch, granted to both the operator's own ClusterRole and the cluster-agent's.
  • Deprecation — a V(0) log on every reconcile when any appsec.* annotation is present, plus a docs/deprecated_configs.md entry mapping all 18 annotations to their CRD paths.

Motivation

The appsec.* annotations were a stop-gap. Moving to the CRD gives users schema validation, discoverability in the generated docs, and parity with how every other feature is configured. The GKE Gateway work also needed a configuration surface that annotations could not express cleanly (gatewayClasses is a list and is CRD-only by design).

Additional Notes

  • Fully backward compatible. With no spec.features.appsec block present, behavior is unchanged. TestFromAnnotations still passes with its original cases and expectations untouched — only its call site moved from the removed FromAnnotations shim to parseAnnotations(x, nil) + Validate().
  • "Set" semantics: non-nil for pointers, len > 0 for slices. An empty CRD list therefore does not clear an annotation-set value. This asymmetry is intentional and documented on the proxies field.
  • Malformed annotations on CRD-set fields are skipped rather than errored, so the CRD wins even over an unparseable annotation. A malformed annotation on a field the CRD does not set still errors, preserving annotation-only strictness.
  • zz_generated.deepcopy.go shows ~44 deletions that are purely an import-alias reassignment (core/v1 corev1v1, meta/v1 v1metav1), triggered by the new corev1.ResourceRequirements field landing earlier in declaration order. Verified equivalent by an alias-normalized diff: exactly 2 lines removed, both old import statements, zero semantic code lost.
  • appsec: appears in the datadogagentprofiles CRD schema because DatadogFeatures is embedded by three CRDs. AppSec is not profile-overridable — that guardrail is the runtime datadogAgentProfileFeatureAllowlist, which is unchanged and still rejects it.
  • GKE behavioral caveats (create-only with no drift reconciliation, no ownerReferences, ~5-7 min teardown lag, the managed-by ownership guard, and the appsec.datadoghq.com/enabled=false opt-out) are authored as leaf Go doc-comments and flow into docs/configuration.v2alpha1.md.
  • Follow-up (pre-existing, not introduced here): a disabled or version-gated feature is dropped before ManageDependencies, so stale-dependency cleanup can remove the AppSec ClusterRole before the cluster-agent finishes its GCPTrafficExtension teardown. This affects all 7 features that use the same disabled-path convention and wants an operator-wide draining state.

Minimum Agent Versions

  • Agent: n/a — no node-agent changes
  • Cluster Agent: v7.82.0 for GKE Gateway injection (new). Existing gates unchanged: v7.76.0 for AppSec injection, v7.79.0 for ingress-nginx.

Note: the default cluster-agent image is currently 7.81.1, so GKE Gateway injection is gated off by default until the image is pinned to >= 7.82.0.

Describe your test plan

go test ./...106 ok / 0 FAIL. make lint0 issues. make generate manifests is idempotent (empty git status --porcelain afterwards).

New coverage in internal/controller/datadogagent/feature/appsec/:

  • config_test.go — 19 per-field CRD-wins rows (one per destination Config field); annotation fallback; nil injector and every nested-nil combination; empty-slice-does-not-clear; partial resources; claims dropped; deterministic first-error ordering; and each of the 4 parse-skip predicates paired with a skip-mirror case proving the skip is not over-broad.
  • feature_test.go — CRD-only enable; CRD-over-annotation precedence asserted on the emitted env var rather than just internal state; annotation-only regression; deprecation-log firing (including when disabled); and a GKE version-gate matched pair (7.81.0 → not configured, 7.82.0 → configured) built from one shared fixture so the legs differ only in the image tag. The negative leg additionally asserts isEnabled(), Validate() == nil, and requiresGKESupport() so it cannot pass for the wrong reason.
  • rbac_test.go — events verbs are exactly create + patch; the GKE rule is exactly get / create / delete.

Manual QA: there is no cluster or HTTP surface at this layer — the real user surface is a DatadogAgent goes in, and cluster-agent env vars + RequiredComponents + a ClusterRole rule set come out. Real DatadogAgents were driven through feature.BuildFeatures (the production entry point) for CRD-only, precedence, both malformed-annotation classes, the version-gate pair, and getRBACPolicyRules(), capturing observed values rather than pass/fail.

Checklist

  • PR has at least one valid label: enhancement
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed (see: signing commits) — not yet. commit.gpgsign=true is set locally but user.signingkey is unset with gpg.format=ssh, so signing silently no-op'd across all 15 commits. To be re-signed before this leaves draft.

@eliottness eliottness added the enhancement New feature or request label Aug 10, 2026
@eliottness

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 8602dbed20

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Aug 10, 2026

Copy link
Copy Markdown

Code Coverage

🎯 Code Coverage (details)
Patch Coverage: 93.41%
Overall Coverage: 50.37% (+2.54%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a0667fa | Docs | Datadog PR Page | Give us feedback!

@eliottness eliottness modified the milestones: v1.31.0, v1.30.0 Aug 10, 2026
@eliottness
eliottness marked this pull request as ready for review August 10, 2026 13:37
@eliottness
eliottness requested a review from a team August 10, 2026 13:37
@eliottness
eliottness requested review from a team as code owners August 10, 2026 13:37
@eliottness
eliottness requested a review from a team as a code owner August 10, 2026 13:37
Comment thread api/datadoghq/v2alpha1/datadogagent_types.go
Comment thread api/datadoghq/v2alpha1/datadogagent_types.go
Comment thread docs/deprecated_configs.md
Comment thread internal/controller/datadogagent/feature/appsec/rbac.go
@levan-m levan-m modified the milestones: v1.30.0, v1.31.0 Aug 21, 2026
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.

4 participants