-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Establish the auth context for authenticators to add data to #3552
Establish the auth context for authenticators to add data to #3552
Conversation
Signed-off-by: Juraci Paixão Kröhling <juraci@kroehling.de>
cc @alolita |
I tried finding @tigrannajaryan's PoC but couldn't. I would like to review it before getting this merged, to make sure we don't need other changes before GA. |
Here is the link to the PoC for reference:
|
I reviewed the branch and the only change that would be breaking is the change to the I think we are good to go then! |
@@ -40,7 +40,7 @@ type ServerAuthenticator interface { | |||
// When the authentication fails, an error must be returned and the caller must not retry. This function is typically called from interceptors, | |||
// on behalf of receivers, but receivers can still call this directly if the usage of interceptors isn't suitable. | |||
// The deadline and cancellation given to this function must be respected, but note that authentication data has to be part of the map, not context. | |||
Authenticate(ctx context.Context, headers map[string][]string) error | |||
Authenticate(ctx context.Context, headers map[string][]string) (context.Context, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an explanation in the comments about what the returned context is expected to be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left that part out so that we can define it when we have a first implementation making use of it, but I added the best information we have so far.
Should I define the context keys as part of this PR? It would be basically this: https://github.com/open-telemetry/opentelemetry-collector/pull/3239/files#diff-1c8371e19129e2092ab7abfce04e6558218579f1be29d90adb958d230475584f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, I updated the PR to include a few words about the resulting context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the noise, but I thought it would be better to include the auth keys as part of the API for v1, so, I included it in this PR.
Signed-off-by: Juraci Paixão Kröhling <juraci@kroehling.de>
Signed-off-by: Juraci Paixão Kröhling <juraci@kroehling.de>
@tigrannajaryan would you mind taking a look at the latest commits? |
@bogdandrutu, do you have some time to re-review this one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would strongly encourage to split this in separate PR (the 3rd commit), so I can more confident merge this PR and have more time thinking about the new API especially because it is a public API
type rawType struct{} | ||
type subjectType struct{} | ||
type groupsType struct{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to have all three of them in the same time? Can we actually have one key with an enum type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe have a "AuthContext" struct which embeds different auth types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a library that provides this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to have all three of them in the same time? Can we actually have one key with an enum type?
Yes, and quite common actually.
Maybe have a "AuthContext" struct which embeds different auth types?
Those are not auth types. The raw auth data might be a JWT, which contains the principal and group memberships. The authenticator (OIDC, for instance) will then place all the three components in the context. Another authenticator might get the subject and groups from the auth server.
I can split this if we need more time, but I think the third commit brings only a minimal API, generic enough to be extended with custom types in the future. The idea about AuthContext has been brought by @tigrannajaryan as well, though:
6b6e713#diff-208f8af800c6aa88673523930b718a5d1a5b3f2a2d2f6edbdcf97171ce3d15ca
Is there a library that provides this?
I'm not aware of any. This is really only about adding auth to a context.Context, but I'm open to using a library if it brings value.
var ( | ||
rawKey = rawType{} | ||
subjectKey = subjectType{} | ||
groupsKey = groupsType{} | ||
) | ||
|
||
type rawType struct{} | ||
type subjectType struct{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this in a generic auth/context.go at all? These appear to be specific context data for example by oidc auth extension. Why not declare there on oidc implementation?
I think we should aim for every auth extension to declare its own context data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not specific to the OIDC auth extension. Those three pieces should be common to most authenticators, as they are common parts of any authorization system. For example, we might have a basic auth authenticator, a la Apache httpd: in such case, we would have a .htpasswd
that would serve as the user data source (subject), and an optional .htgroups
, linking groups with users like Unix' /etc/group
. The raw field would be the base64 encoded username:password
received by the HTTP server from the client.
I think we should aim for every auth extension to declare its own context data.
I think every extension (not only auth) should be allowed to enhance the context data as they wish so that other components can make use of that information, but we should have a minimal set of options that are common to all authenticators, and this auth/context represents that in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I still do not understand why this needs to be in the auth
package and not in the specific extension's package which needs this. We are not expecting that we can mix auth extensions in any way, right? So why not move these declarations to the extension which plans to inject these values in the context?
I may be missing something but I think different authenticator extensions will need different values. Some authenticators will only need raw auth token others may need a subject or whatever it is called.
I don't understand what do we gain by making these concepts part of the public API of core and not just delegate it to individual auth extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not expecting that we can mix auth extensions in any way, right?
We certainly expect auth extensions to provide data that will be consumed by other components in the pipeline. For instance, the routing processor can make decisions based on the principal or group membership (tenant "acme" should go to this Jaeger, tenant "ecorp" should go to that Zipkin, ...).
All auth extensions are expected to have at least the notion of principal (like a username, or a service account name, or ...) Raw can certainly be removed from the generic package, though. I would also keep the group information, as it's also a common aspect of auth no matter the backend used.
I don't understand what do we gain by making these concepts part of the public API of core and not just delegate it to individual auth extensions.
Other components, like the routing processor I mentioned earlier, might provide tighter integration with the auth features, without requiring specific authenticators to exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jpkrohling can you please show how a routing processor could use the auth data? A sample code somewhere would be great to see and would help review this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot right now because of this missing piece, but this is how a configuration would look like for the existing routingprocessor:
receivers:
nop:
processors:
routing:
default_exporters:
- otlp
from_auth: membership
table:
- value: acme
exporters:
- jaeger/acme
- otlp/acme
- value: globex
exporters:
- otlp/globex
exporters:
otlp:
otlp/acme:
otlp/globex:
jaeger/acme:
endpoint: localhost:14250
service:
pipelines:
traces:
receivers:
- nop
processors:
- routing
exporters:
- jaeger/acme
- otlp/acme
- otlp/globex
In this example, the authentication for a hypothetical user "service-a", belonging to the tenant "acme" would cause the authenticator to place "service-a" as the subject/principal and "acme" in the group membership.
The routingprocessor would probably need to group the data by auth/membership, but minimal changes would be required to the current code, probably isolated to this function here: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/36a7da6a4c29ddf81d118ec159e0a7a1682c6f21/processor/routingprocessor/routing.go#L133-L134 . Instead of extracting the route destination from the context, it would extract from the pdata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at my notes, I think we did discuss something else though:
- the authenticators would place auth data into the context
- something at the junction point between receivers and processors would place this into pdata
- processors/exporters should rely on the data from pdata instead of the context
Other than that, the general idea remains.
Based on today's SIG Collector call, I'm renaming this PR and splitting the first two commits on its own PR (#3618). Things we discussed about this one:
One thing I did forget during the call is that this context is relevant only for the junction points: they would take data out of the context and place in the new pdata.Context object, which will be part of the pdata.Resource* structs. So, this auth here would need to be part of an internal API only. |
Please rebase :) |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
@jpkrohling now that #3618 is merged do you plan to rebase this? |
Yes, and your timing is perfect. I just cleared some things up from my queue and I'm working on this right now. |
Closing this in favor of #3745. |
This commit modifies the Authenticate method from configauth.ServerAuthenticator to return a context. At this point, there's no further change in the behavior, as a concrete solution is going to be added as part of #2733/#2734.
This should be the only breaking change required for the auth propagation to work, making the collector ready for GA from the auth perspective.
Signed-off-by: Juraci Paixão Kröhling juraci@kroehling.de