diff --git a/.changeset/add-oidc-otlp-auth.md b/.changeset/add-oidc-otlp-auth.md new file mode 100644 index 0000000000..bc564645e3 --- /dev/null +++ b/.changeset/add-oidc-otlp-auth.md @@ -0,0 +1,5 @@ +--- +'@hyperdx/otel-collector': minor +--- + +Add OIDC-based bearer token authentication for the OTLP receiver in standalone mode, as an alternative to the existing static `OTLP_AUTH_TOKEN`. Set `OIDC_ISSUER_URL` and `OIDC_AUDIENCE` to validate incoming OTLP requests against an OIDC provider's published JWKS instead of a single long-lived shared secret. diff --git a/docker/otel-collector/Dockerfile b/docker/otel-collector/Dockerfile index f3aaf44853..e57f018422 100644 --- a/docker/otel-collector/Dockerfile +++ b/docker/otel-collector/Dockerfile @@ -75,6 +75,7 @@ LABEL org.opencontainers.image.vendor="HyperDX" \ COPY --chown=10001:10001 docker/otel-collector/config.yaml /etc/otelcol-contrib/config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml +COPY --chown=10001:10001 docker/otel-collector/config.standalone.oidc.yaml /etc/otelcol-contrib/standalone-oidc-config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.promql.yaml /etc/otelcol-contrib/standalone-promql-config.yaml COPY --chown=10001:10001 docker/otel-collector/supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl COPY --chown=10001:10001 docker/otel-collector/schema /etc/otel/schema @@ -98,6 +99,7 @@ LABEL org.opencontainers.image.vendor="HyperDX" \ COPY --chown=10001:10001 docker/otel-collector/config.yaml /etc/otelcol-contrib/config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml +COPY --chown=10001:10001 docker/otel-collector/config.standalone.oidc.yaml /etc/otelcol-contrib/standalone-oidc-config.yaml COPY --chown=10001:10001 docker/otel-collector/config.standalone.promql.yaml /etc/otelcol-contrib/standalone-promql-config.yaml COPY --chown=10001:10001 docker/otel-collector/supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl COPY --chown=10001:10001 docker/otel-collector/schema /etc/otel/schema diff --git a/docker/otel-collector/config.standalone.oidc.yaml b/docker/otel-collector/config.standalone.oidc.yaml new file mode 100644 index 0000000000..1df6484311 --- /dev/null +++ b/docker/otel-collector/config.standalone.oidc.yaml @@ -0,0 +1,27 @@ +# This configuration enables OIDC-based bearer token authentication for the +# OTLP receiver. Only included when OIDC_ISSUER_URL environment variable is set. +# +# Clients must present a JWT as a bearer token (Authorization: Bearer ). +# The collector verifies the token's signature against the issuer's published +# JWKS (fetched from {issuer_url}/.well-known/openid-configuration), and +# validates the issuer and audience claims. This is intended for deployments +# that want short-lived, centrally-issued tokens instead of (or in addition +# to) a long-lived static token -- see config.standalone.auth.yaml. + +extensions: + oidc/hyperdx: + issuer_url: ${env:OIDC_ISSUER_URL} + audience: ${env:OIDC_AUDIENCE} + +receivers: + otlp/hyperdx: + protocols: + grpc: + auth: + authenticator: oidc/hyperdx + http: + auth: + authenticator: oidc/hyperdx + +service: + extensions: [health_check, oidc/hyperdx] diff --git a/docker/otel-collector/entrypoint.sh b/docker/otel-collector/entrypoint.sh index ca05993b29..91e84e1659 100644 --- a/docker/otel-collector/entrypoint.sh +++ b/docker/otel-collector/entrypoint.sh @@ -45,8 +45,24 @@ if [ -z "$OPAMP_SERVER_URL" ]; then # Build collector arguments with multiple config files COLLECTOR_ARGS="--config /etc/otelcol-contrib/config.yaml --config /etc/otelcol-contrib/standalone-config.yaml" - # Add bearer token auth config if OTLP_AUTH_TOKEN is specified (only used in standalone mode) - if [ -n "$OTLP_AUTH_TOKEN" ]; then + # Add OIDC-based bearer token auth config if OIDC_ISSUER_URL is specified, + # otherwise fall back to static bearer token auth if OTLP_AUTH_TOKEN is + # specified (only used in standalone mode). These are mutually exclusive: + # both configure the same receiver's auth.authenticator, so enabling both + # would just make whichever config file is loaded last win. + if [ -n "$OIDC_ISSUER_URL" ]; then + # oidcauthextension requires a non-empty audience unless ignore_audience + # is set (which we don't expose here, since silently skipping the + # audience check would weaken the auth rather than just fail loudly). + # Fail fast with a clear message instead of letting the collector crash + # on the extension's own less obvious "no audience provided" error. + if [ -z "$OIDC_AUDIENCE" ]; then + echo "ERROR: OIDC_ISSUER_URL is set but OIDC_AUDIENCE is not. Both are required to enable OIDC authentication." >&2 + exit 1 + fi + echo "OIDC_ISSUER_URL is configured, enabling OIDC-based bearer token authentication" + COLLECTOR_ARGS="$COLLECTOR_ARGS --config /etc/otelcol-contrib/standalone-oidc-config.yaml" + elif [ -n "$OTLP_AUTH_TOKEN" ]; then echo "OTLP_AUTH_TOKEN is configured, enabling bearer token authentication" COLLECTOR_ARGS="$COLLECTOR_ARGS --config /etc/otelcol-contrib/standalone-auth-config.yaml" fi diff --git a/packages/otel-collector/builder-config.yaml b/packages/otel-collector/builder-config.yaml index ecd794a456..2577afaaf6 100644 --- a/packages/otel-collector/builder-config.yaml +++ b/packages/otel-collector/builder-config.yaml @@ -148,6 +148,9 @@ extensions: - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/bearertokenauthextension v__OTEL_COLLECTOR_VERSION__ + - gomod: + github.com/open-telemetry/opentelemetry-collector-contrib/extension/oidcauthextension + v__OTEL_COLLECTOR_VERSION__ - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/filestorage v__OTEL_COLLECTOR_VERSION__