Skip to content

Add RBAC for Gateway API, service mesh, and ingress controller CRDs#2874

Merged
eliottness merged 7 commits into
mainfrom
eliottness/ootb-crd-gateway-mesh-ingress
Jun 3, 2026
Merged

Add RBAC for Gateway API, service mesh, and ingress controller CRDs#2874
eliottness merged 7 commits into
mainfrom
eliottness/ootb-crd-gateway-mesh-ingress

Conversation

@eliottness

@eliottness eliottness commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds list/watch RBAC permissions for 14 new API groups to the cluster agent ClusterRole, enabling OOTB collection of network topology CRDs for Cloud Security internet-reachability analysis.

Gated behind the agent.datadoghq.com/network-crds-enabled: "true" annotation on the DatadogAgent resource (default: disabled, opt-in).

New API groups:

  • Gateway API: gateway.networking.k8s.io (resource-specific)
  • Service mesh: networking.istio.io (resource-specific), gateway.envoyproxy.io, traefik.containo.us, policy.linkerd.io, consul.hashicorp.com, mesh.consul.hashicorp.com, kuma.io
  • Ingress controllers: k8s.nginx.org, traefik.io (resource-specific), configuration.konghq.com, core.haproxy.org, ingress.v1.haproxy.org

Motivation

The Datadog Agent is adding OOTB collection of these CRDs for Cloud Security internet-reachability analysis. The operator needs to grant the cluster agent RBAC permissions to list/watch these resources.

RFC: https://datadoghq.atlassian.net/wiki/x/4IOyfAE

Describe how you validated your changes

  • RBAC rules follow the same pattern as existing karpenter/argoproj/fluxcd entries
  • Annotation-based gating uses featureutils.HasFeatureEnableAnnotation (same pattern as privateactionrunner, hostprofiler, flightrecorder)
  • Operator ClusterRole updated with kubebuilder RBAC markers so the operator can grant these permissions
  • Shared constants deduplicated with existing appsec RBAC via pkg/kubernetes/rbac/const.go
  • CRD manifests, OpenAPI schemas, deepcopy all regenerated
  • Unit tests cover RBAC rule generation, env var propagation, and annotation-based feature gating

QA Instructions

1. Deploy the operator on a kind cluster

kind create cluster --name qa-2874

make IMG=datadog/operator:qa-2874 docker-build
kind load docker-image datadog/operator:qa-2874 --name qa-2874

make install
make IMG=datadog/operator:qa-2874 deploy

2. Apply a DatadogAgent CR with the network CRDs annotation

kubectl apply -f - <<EOF
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
  namespace: default
  annotations:
    agent.datadoghq.com/network-crds-enabled: "true"
spec:
  global:
    clusterName: qa-2874
    credentials:
      apiKey: "0000000000000000000000000000dead"
  features:
    orchestratorExplorer:
      enabled: true
EOF

3. Verify the ClusterRole contains the new network CRD permissions

kubectl get clusterrole default-datadog-orch-exp-cluster-agent -o json \
  | jq -r '.rules[] | select(
      .apiGroups[0] == "gateway.networking.k8s.io" or
      .apiGroups[0] == "networking.istio.io" or
      .apiGroups[0] == "gateway.envoyproxy.io" or
      .apiGroups[0] == "traefik.containo.us" or
      .apiGroups[0] == "policy.linkerd.io" or
      .apiGroups[0] == "consul.hashicorp.com" or
      .apiGroups[0] == "mesh.consul.hashicorp.com" or
      .apiGroups[0] == "kuma.io" or
      .apiGroups[0] == "k8s.nginx.org" or
      .apiGroups[0] == "traefik.io" or
      .apiGroups[0] == "configuration.konghq.com" or
      .apiGroups[0] == "core.haproxy.org" or
      .apiGroups[0] == "ingress.v1.haproxy.org"
    ) | "\(.apiGroups[0]): \(.resources) \(.verbs)"'

All 13 groups should be present with ["list","watch"] verbs.

4. Verify the env vars are forwarded to the cluster-agent container

kubectl get deploy -l app.kubernetes.io/name=datadog-operator-cluster-agent -o json \
  | jq -r '.items[].spec.template.spec.containers[].env[]
    | select(.name | startswith("DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB"))'

Expected:

  • DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_GATEWAY_API=true
  • DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_SERVICE_MESH=true
  • DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_INGRESS_CONTROLLERS=true

5. Verify annotation disabled does NOT add the rules

Apply a CR without the annotation and confirm the ClusterRole does NOT contain the 13 new API groups.

6. Check operator logs for errors

kubectl logs -n system deploy/datadog-operator-manager -c manager | grep -i "forbidden\|error\|rbac"

No RBAC-related errors should appear.

Additional Notes

This PR should be merged before the corresponding agent PR. Collection is opt-in — both the operator annotation and the agent-side flags must be enabled.

Related PRs

Repo PR Purpose
DataDog/datadog-agent DataDog/datadog-agent#48966 Agent collection (merge AFTER)
DataDog/dd-go DataDog/dd-go#230589 Backend allowlist (deploy FIRST)
DataDog/helm-charts DataDog/helm-charts#2541 Helm chart RBAC

@codecov-commenter

codecov-commenter commented Apr 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 43.59%. Comparing base (b2a60a9) to head (2494f0a).
⚠️ Report is 16 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2874      +/-   ##
==========================================
+ Coverage   42.24%   43.59%   +1.34%     
==========================================
  Files         337      340       +3     
  Lines       28951    30262    +1311     
==========================================
+ Hits        12230    13192     +962     
- Misses      15916    16225     +309     
- Partials      805      845      +40     
Flag Coverage Δ
unittests 43.59% <100.00%> (+1.34%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...nal/controller/datadogagent/feature/appsec/rbac.go 100.00% <100.00%> (ø)
...atadogagent/feature/orchestratorexplorer/envvar.go 100.00% <100.00%> (ø)
...tadogagent/feature/orchestratorexplorer/feature.go 72.14% <100.00%> (+0.20%) ⬆️
.../datadogagent/feature/orchestratorexplorer/rbac.go 100.00% <100.00%> (ø)
...nal/controller/datadogagent/feature/utils/utils.go 0.00% <ø> (ø)
internal/controller/datadogagent_controller.go 62.12% <ø> (ø)

... and 28 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b2a60a9...2494f0a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@eliottness eliottness added enhancement New feature or request qa/skip-qa labels Apr 7, 2026
gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/datadog-agent that referenced this pull request Apr 9, 2026
…mesh, and ingress controllers (#48966)

### What does this PR do?

Adds 22 new builtin CRD entries to the orchestrator explorer so Cloud Security can determine internet-reachability paths for k8s workloads. Uses a hybrid collection strategy: resource-specific entries for high-volume vendors (Istio, NGINX, Traefik) and group-level entries for less common vendors.

Three new per-family config flags (all **opt-in, default: false**):
- `orchestrator_explorer.custom_resources.ootb.gateway_api`
- `orchestrator_explorer.custom_resources.ootb.service_mesh`
- `orchestrator_explorer.custom_resources.ootb.ingress_controllers`

**New families:**
- **Gateway API** (5 resource-specific): gateways, httproutes, grpcroutes, tlsroutes, listenersets
- **Service mesh — Istio** (5 resource-specific): virtualservices, gateways, destinationrules, serviceentries, sidecars (with v1beta1 fallback)
- **Service mesh — others** (6 group-level): Envoy Gateway, Traefik (legacy), Linkerd, Consul, Consul Mesh, Kuma
- **Ingress controllers — NGINX** (2 resource-specific): virtualservers, virtualserverroutes
- **Ingress controllers — Traefik** (1 resource-specific): ingressroutes
- **Ingress controllers — others** (3 group-level): Kong, HAProxy Core, HAProxy v1

### Motivation

Cloud Security needs to tell customers which container workloads are internet-reachable. Today, the agent collects standard Ingress and Service objects, covering ~16% of EKS customers. Over 36% use service meshes or non-standard ingress controllers whose exposure paths go through CRDs we don't collect.

RFC: https://datadoghq.atlassian.net/wiki/x/4IOyfAE
Technical implementation: https://datadoghq.atlassian.net/wiki/x/EgO6fAE

### Describe how you validated your changes

- All existing tests pass: `TestNewBuiltinCRDConfigs`, `TestImportBuiltinCollectors`, `TestGetDatadogCustomResourceCollectors`, `TestFilterCRCollectorsByPermission`
- New test `TestNewBuiltinCRDConfigsPerFamilyFlags` verifies each per-family flag independently disables its family, and the global OOTB flag disables everything
- Package compiles cleanly with `go build -tags "kubeapiserver orchestrator"`

### Additional Notes

**All three flags default to `false` (opt-in).** Collection is only activated when RBAC is granted (via helm/operator) and the corresponding flag is set to `true`.

**Merge order:** The backend allowlist PR (dd-go) must be deployed before this PR merges, otherwise collected CRs will be silently dropped.

- [ ] Backend allowlist deployed: DataDog/dd-go#230589
- [ ] Helm chart RBAC merged: DataDog/helm-charts#2541
- [ ] Operator RBAC merged: DataDog/datadog-operator#2874

## Related PRs

| Repo | PR | Purpose |
|------|----|---------|
| DataDog/dd-go | DataDog/dd-go#230589 | Backend allowlist (deploy FIRST) |
| DataDog/helm-charts | DataDog/helm-charts#2541 | Helm chart RBAC |
| DataDog/datadog-operator | DataDog/datadog-operator#2874 | Operator RBAC |

Co-authored-by: eliott.bouhana <[email protected]>
@eliottness
eliottness marked this pull request as ready for review April 13, 2026 13:47
@eliottness
eliottness requested a review from a team April 13, 2026 13:47
@eliottness
eliottness requested review from a team as code owners April 13, 2026 13:47

@kangyili kangyili left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They're just RBACs, I think we can remove this featureflag NetworkCRDsConfig.Enabled.

Add opt-in `networkCRDs.enabled` boolean to OrchestratorExplorerFeatureConfig
that grants list/watch RBAC for 15 API groups used by Gateway API, service
mesh (Istio, Envoy Gateway, Traefik Legacy, Linkerd, Consul, Kuma), and
ingress controllers (NGINX, Traefik, Kong, HAProxy). Uses resource-specific
rules for high-volume vendors (Gateway API, Istio, NGINX, Traefik) and
group-level wildcards for the long tail.

Also replaces inline string literals in appsec RBAC with shared constants.
The gci formatter requires a blank line between the Traefik resources
block and the general resources block, and re-aligns the equals signs
to match the new block's column width.
…agent

When networkCRDs.enabled=true, set all three per-family agent config flags
on the cluster-agent pod so collection is activated alongside the RBAC:
  DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_GATEWAY_API=true
  DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_SERVICE_MESH=true
  DD_ORCHESTRATOR_EXPLORER_CUSTOM_RESOURCES_OOTB_INGRESS_CONTROLLERS=true

These map to orchestrator_explorer.custom_resources.ootb.{gateway_api,
service_mesh,ingress_controllers} in the agent config (DataDog/datadog-agent#48966).
@eliottness
eliottness force-pushed the eliottness/ootb-crd-gateway-mesh-ingress branch from 974bcf2 to 2426537 Compare May 22, 2026 13:48
@datadog-official

datadog-official Bot commented May 22, 2026

Copy link
Copy Markdown

Code Coverage

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 43.92% (+1.33%)

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

Cover the collectKubernetesNetworkResources=true code paths in
orchestrator explorer: RBAC policy rules for Gateway API, service mesh,
and ingress controller API groups, plus the three OOTB env vars
forwarded to the cluster-agent.
@eliottness eliottness added this to the v1.28.0 milestone May 28, 2026

@tbavelier tbavelier left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks on the principle, but 2 points of attention:

  • If we can avoid a temporary CRD, we absolutely want to do it. The CRD is long-lived and is not meant to be used as a temporary flag setter
  • Operator RBACs should be updated to be able to grant them to DCA/component that runs the collection

Comment thread api/datadoghq/v2alpha1/datadogagent_types.go Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for this change!

Comment on lines +112 to +114
if orchestratorExplorer.NetworkCRDs != nil {
f.collectKubernetesNetworkResources = apiutils.BoolValue(orchestratorExplorer.NetworkCRDs.Enabled)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

see previous comment on how this could be enabled with featureutils.HasFeatureEnableAnnotation to avoid "polluting" the CRD with a flag that is "temporary"/not really meant to be toggled off once enabled (and eventually, the annotation is removed, it just becomes true by default in code)

Replace spec.features.orchestratorExplorer.networkCRDs.enabled with
agent.datadoghq.com/network-crds-enabled annotation to avoid polluting
the long-lived CRD with a temporary opt-in flag.

Add kubebuilder RBAC markers for the 13 new API groups so the operator
ClusterRole can grant those permissions to the cluster-agent.

Constraint: CRD fields are hard to deprecate once shipped
Rejected: Keep CRD field | reviewer feedback that annotation is preferred for experimental features
Confidence: high
Scope-risk: narrow
@eliottness
eliottness merged commit 9c31609 into main Jun 3, 2026
38 checks passed
@eliottness
eliottness deleted the eliottness/ootb-crd-gateway-mesh-ingress branch June 3, 2026 09:09
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.

6 participants