The OpenTelemetry Collector (otelcol) has an oidcauth extension. This makes for an interesting alternative to using:
First, we're going to need an OIDC identity token.
I'm going to use GCP because... that's what I have (and where my workloads are running).
gcloud
has a command to print out an identity token for a service account,
note this requires roles/iam.serviceAccountTokenCreator
on the account itself,
and maybe switching over to it for default auth?
1gcloud auth print-identity-token \
2 hwaryun@com-seankhliao.iam.gserviceaccount.com \
3 --include-email \
4 --audiences otelcol \
5 --impersonate-service-account hwaryun@com-seankhliao.iam.gserviceaccount.com
This gives you a long token like (------
parts will be actual chars):
1eyJhbGci------------J0eXAiOiJKV1QifQ.eyJhdWQi---------xODYifQ.FfpWwTlS24zl------v3pRd33tZmQgq1gLabQ
On the collector side we'll nned the oidcauth extension configured for Google's accounts endpoint, and with the right header extractor.
The verified data is stored in the context's authdata which can be extracted with the processors into proper attributes, something you'll want to do before reshaping/regrouping data with batch/groupbyX. Also, as an attribute, it's where you can implement richer filtering (eg checking project via email).
1extensions:
2 # due to header canonicaliztion weirdness
3 # http1 uses "Authorization" (leading capital)
4 # while grpc uses lowercase
5 oidc/grpc:
6 issuer_url: https://accounts.google.com
7 audience: otelcol
8 username_claim: email
9
10 oidc/http:
11 issuer_url: https://accounts.google.com
12 audience: otelcol
13 username_claim: email
14 attribute: Authorization
15
16receivers:
17 otlp:
18 protocols:
19 http:
20 auth:
21 authenticator: oidc/http
22 grpc:
23 auth:
24 authenticator: oidc/grpc
25
26processors:
27 # using th resource processor, we can pull out auth data from the auth. * context
28 # also available for the attribute processor
29 # if we want to do any stricter validation, it can be done in a processor
30 # eg, only allowing users with our @project.iam.gserviceaccount.com emails
31 resource:
32 attributes:
33 - key: oidc.subject
34 action: upsert
35 from_context: auth.subject
36 # google service accounts don't set this field
37 - key: oidc.membership
38 action: upsert
39 from_context: auth.membership
40
41exporters:
42 logging:
43 verbosity: detailed
44
45service:
46 extensions: [oidc/http, oidc/grpc]
47 pipelines:
48 traces:
49 receivers: [otlp]
50 processors: [resource]
51 exporters: [logging]
52 telemetry:
53 logs:
54 level: debug
Now we need a client to use the token
If we only care about testing if the token is accepted, curl works.
note: this uses the otlp http endpoint.
1curl -v http://localhost:4318/ -H "authorization: Bearer ${ID_TOKEN}"
tracegen is a tool that is part of the opentelemetry-collector-contrib project. It's an easy way to generate valid data.
note: the quoting rules as tracegen requires the value be quoted
1tracegen -otlp-insecure -otlp-header 'authorization="Bearer '${ID_TOKEN}'"'
For Go, this just mean pulling in GCP's idtoken
generator and hooking that in to gRPC.
It should be easy to swap out to any other token provider.
1package main
2
3import (
4 "context"
5 "crypto/tls"
6 "log"
7
8 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
9 "google.golang.org/api/idtoken"
10 "google.golang.org/grpc"
11 "google.golang.org/grpc/credentials"
12 "google.golang.org/grpc/credentials/oauth"
13)
14
15func main() {
16 ctx := context.Background()
17 gcpTS, err := idtoken.NewTokenSource(ctx, "otelcol")
18 if err != nil {
19 log.Fatal(err)
20 }
21
22 exporter, err := otlptracegrpc.New(ctx,
23 otlptracegrpc.WithDialOption(
24 // TLS required for credentials
25 grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})),
26 // id token per request in headers
27 grpc.WithPerRPCCredentials(&oauth.TokenSource{TokenSource: gcpTS}),
28 ),
29 )
30 if err != nil {
31 log.Fatalln(err)
32 }
33}
34