forked from open-telemetry/opentelemetry-collector
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for authentication processor
Includes an initial support for OIDC authenticator. Closes open-telemetry#1424 Signed-off-by: Juraci Paixão Kröhling <[email protected]>
- Loading branch information
1 parent
95389af
commit 94c5345
Showing
18 changed files
with
1,594 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Authentication Processor | ||
|
||
* Supported pipeline types: traces | ||
* Status: in development | ||
|
||
This processor authenticates the incoming traces by extracting the authentication data from the context | ||
and verifying the bearer token with the specified provider. | ||
|
||
Currently, only bearer token authentication is supported, added as part of `PerRPC` gRPC authentication. | ||
It requires the gRPC client to send a header named `authorization` in line with the equivalent HTTP/2 header. | ||
|
||
Examples: | ||
```yaml | ||
processors: | ||
authentication: | ||
oidc: | ||
issuer_url: https://auth.example.com/ | ||
issuer_ca_path: /etc/pki/tls/cert.pem | ||
client_id: my-oidc-client | ||
username_claim: email | ||
``` | ||
Refer to [config.yaml](./testdata/config.yaml) for detailed examples on using the processor. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package authenticationprocessor | ||
|
||
import ( | ||
"context" | ||
|
||
"go.opentelemetry.io/collector/component" | ||
) | ||
|
||
type authenticator interface { | ||
authenticate(context.Context) (bool, error) | ||
start(context.Context, component.Host) error | ||
shutdown(context.Context) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package authenticationprocessor | ||
|
||
import ( | ||
"go.opentelemetry.io/collector/config/configmodels" | ||
) | ||
|
||
// Config is the configuration for the processor. | ||
type Config struct { | ||
configmodels.ProcessorSettings `mapstructure:",squash"` | ||
|
||
// OIDC configures this processor to use the given OIDC provider as the backend for the authentication mechanism. | ||
// Required. | ||
OIDC *OIDC `mapstructure:"oidc"` | ||
} | ||
|
||
// OIDC defines the OpenID Connect properties for this processor | ||
type OIDC struct { | ||
// IssuerURL is the base URL for the OIDC provider. | ||
// Required. | ||
IssuerURL string `mapstructure:"issuer_url"` | ||
|
||
// Audience of the token, used during the verification. | ||
// For example: "https://accounts.google.com" or "https://login.salesforce.com". | ||
// Required. | ||
Audience string `mapstructure:"audience"` | ||
|
||
// The local path for the issuer CA's TLS server cert. | ||
// Optional. | ||
IssuerCAPath string `mapstructure:"issuer_ca_path"` | ||
|
||
// The claim to use as the username, in case the token's 'sub' isn't the suitable source. | ||
// Optional. | ||
UsernameClaim string `mapstructure:"username_claim"` | ||
|
||
// The claim that holds the subject's group membership information. | ||
// Optional. | ||
GroupsClaim string `mapstructure:"groups_claim"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package authenticationprocessor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package authenticationprocessor | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config/configerror" | ||
"go.opentelemetry.io/collector/config/configmodels" | ||
"go.opentelemetry.io/collector/consumer" | ||
) | ||
|
||
const ( | ||
// typeStr is the value of "type" for this processor in the configuration. | ||
typeStr configmodels.Type = "authentication" | ||
) | ||
|
||
var ( | ||
errNoOIDCProvided = errors.New("no OIDC information provided") | ||
errNoClientIDProvided = errors.New("no ClientID provided for the OIDC configuration") | ||
errNoIssuerURL = errors.New("no IssuerURL provided for the OIDC configuration") | ||
) | ||
|
||
// Factory is the factory for the processor. | ||
type Factory struct { | ||
} | ||
|
||
var _ component.ProcessorFactory = (*Factory)(nil) | ||
|
||
// Type gets the type of the config created by this factory. | ||
func (f *Factory) Type() configmodels.Type { | ||
return typeStr | ||
} | ||
|
||
// CreateDefaultConfig creates the default configuration for the processor. | ||
func (f *Factory) CreateDefaultConfig() configmodels.Processor { | ||
return &Config{ | ||
ProcessorSettings: configmodels.ProcessorSettings{ | ||
TypeVal: typeStr, | ||
NameVal: string(typeStr), | ||
}, | ||
} | ||
} | ||
|
||
// CreateTraceProcessor creates a trace processor based on this config. | ||
func (f *Factory) CreateTraceProcessor( | ||
_ context.Context, | ||
params component.ProcessorCreateParams, | ||
nextConsumer consumer.TraceConsumer, | ||
cfg configmodels.Processor) (component.TraceProcessor, error) { | ||
|
||
oCfg := cfg.(*Config) | ||
if oCfg.OIDC == nil { | ||
return nil, errNoOIDCProvided | ||
} | ||
if oCfg.OIDC.Audience == "" { | ||
return nil, errNoClientIDProvided | ||
} | ||
if oCfg.OIDC.IssuerURL == "" { | ||
return nil, errNoIssuerURL | ||
} | ||
|
||
return newAuthenticationProcessor(params.Logger, nextConsumer, *oCfg) | ||
} | ||
|
||
// CreateMetricsProcessor creates a metric processor based on this config. | ||
func (f *Factory) CreateMetricsProcessor( | ||
context.Context, | ||
component.ProcessorCreateParams, | ||
consumer.MetricsConsumer, | ||
configmodels.Processor) (component.MetricsProcessor, error) { | ||
return nil, configerror.ErrDataTypeIsNotSupported | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package authenticationprocessor | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap" | ||
|
||
"go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config/configerror" | ||
) | ||
|
||
func TestDefaultConfiguration(t *testing.T) { | ||
// prepare | ||
f := &Factory{} | ||
|
||
// test | ||
_ = f.CreateDefaultConfig().(*Config) | ||
} | ||
|
||
func TestCreateTestProcessor(t *testing.T) { | ||
// prepare | ||
logger, err := zap.NewDevelopment() | ||
require.NoError(t, err) | ||
|
||
f := &Factory{} | ||
c := f.CreateDefaultConfig().(*Config) | ||
|
||
c.OIDC = &OIDC{ | ||
Audience: "unit-tests", | ||
IssuerURL: "http://example.com/", | ||
} | ||
params := component.ProcessorCreateParams{Logger: logger} | ||
|
||
// test | ||
p, err := f.CreateTraceProcessor(context.Background(), params, &mockProcessor{}, c) | ||
|
||
// verify | ||
assert.NoError(t, err) | ||
assert.NotNil(t, p) | ||
} | ||
|
||
func TestMissingOIDCParameters(t *testing.T) { | ||
for _, tt := range []struct { | ||
casename string | ||
config *Config | ||
expectedErr error | ||
}{ | ||
{ | ||
"no-oidc", | ||
(&Factory{}).CreateDefaultConfig().(*Config), | ||
errNoOIDCProvided, | ||
}, | ||
{ | ||
"no-client-id", | ||
&Config{ | ||
OIDC: &OIDC{ | ||
IssuerURL: "http://example.com/", | ||
}, | ||
}, | ||
errNoClientIDProvided, | ||
}, | ||
{ | ||
"no-issuer-url", | ||
&Config{ | ||
OIDC: &OIDC{ | ||
Audience: "unit-tests", | ||
}, | ||
}, | ||
errNoIssuerURL, | ||
}, | ||
} { | ||
t.Run(tt.casename, func(t *testing.T) { | ||
// prepare | ||
f := &Factory{} | ||
params := component.ProcessorCreateParams{} | ||
|
||
// test | ||
p, err := f.CreateTraceProcessor(context.Background(), params, nil, tt.config) | ||
|
||
// verify | ||
assert.Equal(t, err, tt.expectedErr) | ||
assert.Nil(t, p) | ||
}) | ||
} | ||
} | ||
|
||
func TestType(t *testing.T) { | ||
// prepare | ||
f := &Factory{} | ||
|
||
// test | ||
typ := f.Type() | ||
|
||
// verify | ||
assert.Equal(t, typeStr, typ) | ||
} | ||
|
||
func TestNoMetricsProcessor(t *testing.T) { | ||
// prepare | ||
f := &Factory{} | ||
params := component.ProcessorCreateParams{} | ||
|
||
// test | ||
p, err := f.CreateMetricsProcessor(context.Background(), params, nil, nil) | ||
|
||
// verify | ||
assert.Equal(t, err, configerror.ErrDataTypeIsNotSupported) | ||
assert.Nil(t, p) | ||
} |
Oops, something went wrong.