diff --git a/docs/examples/with-telemetry.yaml b/docs/examples/with-telemetry.yaml index 2f81e5d1..6d3ec9f3 100644 --- a/docs/examples/with-telemetry.yaml +++ b/docs/examples/with-telemetry.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Operator-facing example: tracecore with the M2 self-telemetry # surface enabled. # diff --git a/docs/integrations/examples/clickhouse-direct.yaml b/docs/integrations/examples/clickhouse-direct.yaml index 9b6c3609..8efff7bf 100644 --- a/docs/integrations/examples/clickhouse-direct.yaml +++ b/docs/integrations/examples/clickhouse-direct.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # ClickHouse via the contrib `clickhouse` exporter. The OCB-assembled # tracecore binary bundles this exporter directly per RFC-0013 §1 + # §2 (Adoption matrix) - no intermediate `otelcol-contrib` hop. diff --git a/docs/integrations/examples/datadog.yaml b/docs/integrations/examples/datadog.yaml index 4d23c7d1..237fca4f 100644 --- a/docs/integrations/examples/datadog.yaml +++ b/docs/integrations/examples/datadog.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Datadog via the contrib `datadog` exporter. The OCB-assembled # tracecore binary bundles this exporter directly per RFC-0013 §1 + # §2 (Adoption matrix) - no intermediate `otelcol-contrib` hop. diff --git a/docs/integrations/examples/filelog-container.yaml b/docs/integrations/examples/filelog-container.yaml index 03c98be4..4bc5fb86 100644 --- a/docs/integrations/examples/filelog-container.yaml +++ b/docs/integrations/examples/filelog-container.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Container stdout/stderr tailing via the upstream `filelogreceiver` # with a container parser stanza, k8sattributes enrichment, and the # `file_storage` extension for restart-safe checkpointing. Replaces diff --git a/docs/integrations/examples/honeycomb.yaml b/docs/integrations/examples/honeycomb.yaml index 387096d3..30cefbb9 100644 --- a/docs/integrations/examples/honeycomb.yaml +++ b/docs/integrations/examples/honeycomb.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Honeycomb ingests OTLP/HTTP natively at api.honeycomb.io; the # upstream `otlphttp` exporter the OCB-assembled tracecore binary # bundles (RFC-0013 §1) is sufficient. The `x-honeycomb-team` diff --git a/docs/integrations/examples/journald-kernel.yaml b/docs/integrations/examples/journald-kernel.yaml index ae20a705..10a121b6 100644 --- a/docs/integrations/examples/journald-kernel.yaml +++ b/docs/integrations/examples/journald-kernel.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Kernel + systemd events via upstream `journaldreceiver` (journald # stream) + `filelogreceiver` (raw /dev/kmsg for kernel ring buffer), # normalized to OTel log records via OTTL `transform` so operator diff --git a/docs/integrations/examples/k8sobjects-events.yaml b/docs/integrations/examples/k8sobjects-events.yaml index ed76e248..8e5b2c04 100644 --- a/docs/integrations/examples/k8sobjects-events.yaml +++ b/docs/integrations/examples/k8sobjects-events.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Kubernetes Events API via upstream `k8sobjectsreceiver` in watch # mode, normalized through OTTL `transform` to populate the # customer-stable `k8s.event.hint` attribute (RFC-0013 §3 - the diff --git a/docs/integrations/examples/loki.yaml b/docs/integrations/examples/loki.yaml index 28f310df..0d064339 100644 --- a/docs/integrations/examples/loki.yaml +++ b/docs/integrations/examples/loki.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Grafana Loki ingests OTLP/HTTP logs natively at /otlp/v1/logs since # Loki 3.0 (2024). The upstream `otlphttp` exporter the OCB-assembled # tracecore binary bundles (RFC-0013 §1) is sufficient — no Loki- diff --git a/docs/integrations/examples/otel-backend.yaml b/docs/integrations/examples/otel-backend.yaml index 6e397735..14148308 100644 --- a/docs/integrations/examples/otel-backend.yaml +++ b/docs/integrations/examples/otel-backend.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # OTLP/HTTP to a generic OTel Collector. Uses the upstream `otlphttp` # exporter that the OCB-assembled tracecore binary bundles (RFC-0013 # §1); `tracecore validate` covers this file. diff --git a/docs/integrations/examples/prometheus-scrape.yaml b/docs/integrations/examples/prometheus-scrape.yaml index 5b9cc9fb..850a2068 100644 --- a/docs/integrations/examples/prometheus-scrape.yaml +++ b/docs/integrations/examples/prometheus-scrape.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # Generic Prometheus scrape via upstream `prometheusreceiver` - # the adoption shape for every vendor GPU exporter per RFC-0013 §2 # (NVIDIA `dcgm-exporter`, AMD `ROCm/device-metrics-exporter`, diff --git a/docs/integrations/examples/tempo.yaml b/docs/integrations/examples/tempo.yaml index e1fd9236..18fda137 100644 --- a/docs/integrations/examples/tempo.yaml +++ b/docs/integrations/examples/tempo.yaml @@ -1,3 +1,7 @@ +# Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver. +# If you expose the receiver across a trust boundary, wire the bearer-token or mTLS +# shape from docs/integrations/multi-cluster.md before deploy. +# # docs/integrations/examples/tempo.yaml # Grafana Tempo ingests OTLP natively on the same port pair as any # upstream OTel Collector (gRPC :4317, HTTP :4318); Tempo's diff --git a/scripts/doc-check.sh b/scripts/doc-check.sh index e942035a..6b2c9614 100755 --- a/scripts/doc-check.sh +++ b/scripts/doc-check.sh @@ -15,6 +15,83 @@ scan_paths=( docs/FAILURE-MODES.md ) +# M6 integration examples: trust-posture callout lint (issue #443). +# +# Drift pattern this gate closes: recipes under docs/integrations/examples/ +# default to a ClusterIP-only OTLP receiver on 0.0.0.0:4318 with no auth. +# That is correct for the single-cluster sidecar/DaemonSet ingestion shape +# the recipe documents, but operators can silently expose any of them +# through a LoadBalancer/Ingress without realising the receiver is +# unauthenticated. The trust-posture callout names this trade-off at the +# top of every recipe and cross-links to multi-cluster.md for the +# bearer-token / mTLS upgrade shape (PR #447, issue #297). +# +# Scope: every *.yaml under docs/integrations/examples/ AND +# docs/examples/with-telemetry.yaml. Exempted by basename — the auth +# recipes themselves don't need the callout because they are the upgrade +# target the callout points at, and cert-manager-mtls.yaml is not a +# tracecore receiver config. Drop a basename from $trust_posture_exempt +# to re-include it. +# +# Mutation-verify pattern: delete the callout line from any non-exempt +# example, run `bash scripts/doc-check.sh`, watch this gate fail naming +# the file. Restore. +# +# Placed early in the script so it runs unconditionally; the test-name +# parity gate below short-circuits on `referenced` empty. + +trust_posture_marker="# Trust posture:" +trust_posture_exempt=( + "multi-cluster-aggregation.yaml" + "multi-cluster-aggregation-bearer.yaml" + "multi-cluster-aggregation-mtls.yaml" + "multi-cluster-source.yaml" + "multi-cluster-source-bearer.yaml" + "multi-cluster-source-mtls.yaml" + "cert-manager-mtls.yaml" +) + +is_trust_posture_exempt() { + local base="$1" + for e in "${trust_posture_exempt[@]}"; do + [ "$base" = "$e" ] && return 0 + done + return 1 +} + +trust_posture_files=$( { + git ls-files 'docs/integrations/examples/*.yaml' 2>/dev/null + git ls-files 'docs/examples/with-telemetry.yaml' 2>/dev/null +} ) + +trust_posture_missing="" +trust_posture_count=0 +while IFS= read -r yfile; do + [ -z "$yfile" ] && continue + base=$(basename "$yfile") + if is_trust_posture_exempt "$base"; then + continue + fi + trust_posture_count=$((trust_posture_count + 1)) + if ! grep -qF "$trust_posture_marker" "$yfile"; then + trust_posture_missing="${trust_posture_missing}${yfile}\n" + fi +done <<< "$trust_posture_files" + +if [ -n "$trust_posture_missing" ]; then + echo "doc-check: integration example(s) missing trust-posture callout (issue #443):" + printf '%b' "$trust_posture_missing" | sed 's/^/ - /' + echo + echo "Add the canonical 3-line callout at the top of each file:" + echo " # Trust posture: this recipe defaults to a single-cluster ClusterIP-only receiver." + echo " # If you expose the receiver across a trust boundary, wire the bearer-token or mTLS" + echo " # shape from docs/integrations/multi-cluster.md before deploy." + exit 1 +fi +if [ "$trust_posture_count" -gt 0 ]; then + echo "doc-check: $trust_posture_count integration example(s) carry trust-posture callout" +fi + # A real Go test identifier is Test/Fuzz/Benchmark followed by an # uppercase letter or underscore (rejects "Testing", "Tests"). Trailing # bare underscore (family ref like "TestX_*" with the `*` dropped by