Skip to content

Commit

Permalink
oidc ignore client/audience support
Browse files Browse the repository at this point in the history
  • Loading branch information
zeck-ops committed Nov 27, 2024
1 parent ec784fb commit cf1aa2c
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 2 deletions.
27 changes: 27 additions & 0 deletions .chloggen/oidc-ignore-audience.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: oidcauthextension

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add ignore_audience config option for ignoring oidc audience

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [36568]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: go-oidc SkipClientIDCheck is set based on config ignore_audience

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
1 change: 1 addition & 0 deletions extension/oidcauthextension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extensions:
issuer_url: http://localhost:8080/auth/realms/opentelemetry
issuer_ca_path: /etc/pki/tls/cert.pem
audience: account
ignore_audience: <bool> # false if unspecified
username_claim: email

receivers:
Expand Down
8 changes: 6 additions & 2 deletions extension/oidcauthextension/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ type Config struct {

// Audience of the token, used during the verification.
// For example: "https://accounts.google.com" or "https://login.salesforce.com".
// Required.
// Required unless IgnoreAudience is true.
Audience string `mapstructure:"audience"`

// When true, this skips validating the audience field.
// Optional.
IgnoreAudience bool `mapstructure:"ignore_audience"`

// The local path for the issuer CA's TLS server cert.
// Optional.
IssuerCAPath string `mapstructure:"issuer_ca_path"`
Expand All @@ -32,7 +36,7 @@ type Config struct {
}

func (c *Config) Validate() error {
if c.Audience == "" {
if c.Audience == "" && !c.IgnoreAudience {
return errNoAudienceProvided
}
if c.IssuerURL == "" {
Expand Down
1 change: 1 addition & 0 deletions extension/oidcauthextension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (e *oidcExtension) start(ctx context.Context, _ component.Host) error {
}
e.verifier = e.provider.Verifier(&oidc.Config{
ClientID: e.cfg.Audience,
SkipClientIDCheck: e.cfg.IgnoreAudience,
})
return nil
}
Expand Down
78 changes: 78 additions & 0 deletions extension/oidcauthextension/extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,70 @@ func TestOIDCAuthenticationSucceeded(t *testing.T) {
// TODO(jpkroehling): assert that the authentication routine set the subject/membership to the resource
}

func TestOIDCAuthenticationSucceededIgnoreAudienceMismatch(t *testing.T) {
// prepare
oidcServer, err := newOIDCServer()
require.NoError(t, err)
oidcServer.Start()
defer oidcServer.Close()

config := &Config{
IssuerURL: oidcServer.URL,
Audience: "unit-test",
IgnoreAudience: true,
}
p := newExtension(config, zap.NewNop())

err = p.Start(context.Background(), componenttest.NewNopHost())
require.NoError(t, err)

payload, _ := json.Marshal(map[string]any{
"iss": oidcServer.URL,
"aud": "not-unit-test",
"exp": time.Now().Add(time.Minute).Unix(),
})
token, err := oidcServer.token(payload)
require.NoError(t, err)

// test
ctx, err := p.Authenticate(context.Background(), map[string][]string{"authorization": {fmt.Sprintf("Bearer %s", token)}})

// verify
assert.NoError(t, err)
assert.NotNil(t, ctx)
}

func TestOIDCAuthenticationFailAudienceMismatch(t *testing.T) {
// prepare
oidcServer, err := newOIDCServer()
require.NoError(t, err)
oidcServer.Start()
defer oidcServer.Close()

config := &Config{
IssuerURL: oidcServer.URL,
Audience: "unit-test",
}
p := newExtension(config, zap.NewNop())

err = p.Start(context.Background(), componenttest.NewNopHost())
require.NoError(t, err)

payload, _ := json.Marshal(map[string]any{
"iss": oidcServer.URL,
"aud": "not-unit-test",
"exp": time.Now().Add(time.Minute).Unix(),
})
token, err := oidcServer.token(payload)
require.NoError(t, err)

// test
_, err = p.Authenticate(context.Background(), map[string][]string{"authorization": {fmt.Sprintf("Bearer %s", token)}})

// verify
assert.Error(t, err)
}

func TestOIDCProviderForConfigWithTLS(t *testing.T) {
// prepare the CA cert for the TLS handler
cert := x509.Certificate{
Expand Down Expand Up @@ -423,6 +487,20 @@ func TestMissingClient(t *testing.T) {
assert.Equal(t, errNoAudienceProvided, err)
}

func TestIgnoreMissingClient(t *testing.T) {
// prepare
config := &Config{
IssuerURL: "http://example.com/",
IgnoreAudience: true,
}

// test
err := config.Validate()

// verify
assert.Nil(t, err)
}

func TestMissingIssuerURL(t *testing.T) {
// prepare
config := &Config{
Expand Down

0 comments on commit cf1aa2c

Please sign in to comment.