Skip to content

Auto-instrumentation init container security context no longer inherited from app container #4848

@JulesTriomphe

Description

@JulesTriomphe

Component(s)

auto-instrumentation

What happened?

Description

Due to the changes In #4635, the security context of auto-instrumentation init containers is no longer set in pods instrumented using Operator version v0.146.0.
As a result, auto-instrumentation fails in namespaces with restricted Pod Security Standards.

The bug is in setInitContainerSecurityContext being called before the instrumentation init container is added to the pod. Here's the exact broken sequence in each injectXxx function (shown for Python, same pattern for Java, NodeJS, DotNet):

// CURRENT (BROKEN) — sdk.go, injectPython()
if len(containers) > 0 {
    for _, container := range containers {
        if err := injectPythonSDKToContainer(...); err != nil {
            ...
        } else {
            i.injectCommonEnvVar(otelinst, container)
            i.injectDefaultPythonEnvVars(container)
            pod = i.injectCommonSDKConfig(...)
            pod = i.setInitContainerSecurityContext(pod, container.SecurityContext, pythonInitContainerName)
            //   ↑ NO-OP: "opentelemetry-auto-instrumentation-python" is NOT in pod.Spec.InitContainers yet
        }
    }
    pod = injectPythonSDKToPod(...)  // ← init container added HERE, without SecurityContext
}

setInitContainerSecurityContext iterates over pod.Spec.InitContainers looking for pythonInitContainerName, finds nothing (it doesn't exist yet), and returns the pod unchanged. Then injectPythonSDKToPod appends the init container with no SecurityContext, which violates the restricted Pod Security Standard.

This was working in all pre-v0.146.0 versions because the init container was appended inside the same loop body, before setInitContainerSecurityContext was called.

Minimal Fix

Move setInitContainerSecurityContext to after injectXxxToPod in all four affected functions in internal/instrumentation/sdk.go:

// FIXED — injectPython()
if len(containers) > 0 {
    for _, container := range containers {
        if err := injectPythonSDKToContainer(...); err != nil {
            ...
        } else {
            i.injectCommonEnvVar(otelinst, container)
            i.injectDefaultPythonEnvVars(container)
            pod = i.injectCommonSDKConfig(...)
            // ← remove setInitContainerSecurityContext from here
        }
    }
    pod = injectPythonSDKToPod(otelinst.Spec.Python, pod, containers[0].Name, platform, otelinst.Spec)
    pod = i.setInitContainerSecurityContext(pod, containers[0].SecurityContext, pythonInitContainerName)
    // ↑ Now the init container exists in pod.Spec.InitContainers, so SecurityContext is actually written
}

Steps to Reproduce

Provision an auto-instrumented pod in a namespace with the restricted Pod Security Standard.

Expected Result

Instrumentation container is provisioned and runs successfully.

Actual Result

Instrumentation container can't be provisioned:

pods "foo" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "opentelemetry-auto-instrumentation-python" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "opentelemetry-auto-instrumentation-python" must set securityContext.capabilities.drop=["ALL"]), seccompProfile (pod or container "opentelemetry-auto-instrumentation-python" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")

Kubernetes Version

v1.33.7-eks-ac2d5a0

Operator version

v0.146.0

Collector version

v0.146.0

Environment information

No response

Log output

Additional context

No response

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions