-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Wire in WebhookTokenAutenticators support #18868
Conversation
@mrogers950 @enj PTAL |
pkg/cmd/server/apis/config/types.go
Outdated
@@ -399,6 +399,9 @@ type MasterConfig struct { | |||
EtcdConfig *EtcdConfig | |||
// OAuthConfig, if present start the /oauth endpoint in this process | |||
OAuthConfig *OAuthConfig | |||
// WebhookTokenAuthnConfig, if present configures remote token reviewers | |||
WebhookTokenAuthenticators []WebhookTokenAuthenticators |
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.
probably belongs under MasterAuthConfig
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.
do we have a use case for allowing more than one, or is that just future-proofing?
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 seem that it is more similar to OAuthConfig than RequestHeaderAuthenticationOptions as an auth type, why do we not have OAuthConfig under MasterauthConfig ?
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.
OAuth component is distinct from the master API. OAuth config is for the OAuth server. MasterAuthConfig is for the API server.
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 seem that it is more similar to OAuthConfig than RequestHeaderAuthenticationOptions as an auth type
RequestHeaderAuthenticationOptions and WebhookTokenAuthenticators both mirror upstream API authentication configuration options. We should group them under MasterAuthConfig.
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.
Ok, makes sense.
pkg/cmd/server/apis/config/types.go
Outdated
@@ -828,6 +831,15 @@ type DNSConfig struct { | |||
AllowRecursiveQueries bool | |||
} | |||
|
|||
type WebhookTokenAuthenticators 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.
type should be singular if it describes a single authenticator
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.
Ack
@@ -618,6 +618,7 @@ func defaultOpenAPIConfig(config configapi.MasterConfig) *openapicommon.Config { | |||
}, | |||
} | |||
} | |||
// TODO: handle WebhookTokenAuthenticators somehow ? |
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.
probably just as an additional condition in if len(config.ServiceAccountConfig.PublicKeyFiles) > 0 || ... token webhooks ... {
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.
yeah I wasn't sure about that I'll do as you suggest
/retest |
WebhookTokenAuthnConfigFile string `json:"webhookTokenAuthnConfigFile"` | ||
// WebhookTokenAuthnCacheTTL indicates how long an authentication result should be cached. | ||
// It takes a valid time duration string (e.g. "5m"). | ||
// If empty, you get the default timeout. If zero (e.g. "0m"), caching is disabled |
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.
Probably should state what the default timeout is (I see no code that does defaulting in 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.
There is currently no default, you are required tio state the CacheTTL
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.
Upstream defaults this to 2 minutes. @liggitt any preference?
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've added a 10s default
@@ -192,6 +192,24 @@ func ValidateMasterAuthConfig(config configapi.MasterAuthConfig, fldPath *field. | |||
validationResults.AddErrors(field.Required(fldPath.Child("requestHeader.extraHeaderPrefixes"), "must be specified for a secure connection")) | |||
} | |||
|
|||
for _, wta := range config.WebhookTokenAuthenticators { |
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.
unit test
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.
done
@@ -108,6 +109,18 @@ func newAuthenticator(config configapi.MasterConfig, accessTokenGetter oauthclie | |||
group.NewTokenGroupAdder(oauthTokenAuthenticator, []string{bootstrappolicy.AuthenticatedOAuthGroup})) | |||
} | |||
|
|||
for _, wta := range config.AuthConfig.WebhookTokenAuthenticators { |
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.
integration test (which I know you are already working on)
@liggitt I specifically asked for this from @simo5. I see no reason not to have it, and I really do not want to try to hack it in later. It is assumed that all such remote token authenticators are allowed to see all tokens - if you do not trust all of them at that level, then you should not put them in your config. |
@openshift/api-review |
t.Fatalf("unexpected error: %v", err) | ||
} | ||
|
||
// Ex |
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.
External / Example / or .. ?
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.
ignore, remnant of my copy/paste from the oidc test
pkg/cmd/server/apis/config/types.go
Outdated
@@ -399,6 +399,7 @@ type MasterConfig struct { | |||
EtcdConfig *EtcdConfig | |||
// OAuthConfig, if present start the /oauth endpoint in this process | |||
OAuthConfig *OAuthConfig | |||
|
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.
unnecessary change
@@ -247,6 +247,7 @@ type MasterConfig struct { | |||
EtcdConfig *EtcdConfig `json:"etcdConfig"` | |||
// OAuthConfig, if present start the /oauth endpoint in this process | |||
OAuthConfig *OAuthConfig `json:"oauthConfig"` | |||
|
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.
same as above
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.
yeah remamnt of a previous incarnation, will remove, thanks for catching
5330e97
to
b39e082
Compare
I think we are ready for final reviews |
api approved. |
13e3e62
to
f9af946
Compare
} | ||
errors := ValidateMasterAuthConfig(config, nil) | ||
if len(test.expectedErrors) != len(errors.Errors) { | ||
t.Errorf("%s: expected %v errors, got %v", test.testName, test.expectedErrors, errors.Errors) |
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.
continue after this line or you can panic on the next loop
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.
Ah, true, but then, the test already failed :-)
Will fix
@@ -215,6 +215,15 @@ func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runti | |||
} | |||
} | |||
|
|||
for i := range obj.AuthConfig.WebhookTokenAuthenticators { | |||
if len(obj.AuthConfig.WebhookTokenAuthenticators[i].ConfigFile) == 0 { | |||
continue |
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 don't understand this continue
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.
Does not default the TTL if there is no file to start with
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.
(config is already wrong)
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.
Sure, but then why do we not want to default? It will just make two errors show up and make the user think that both are required.
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.
ok removing both
// Set defaults Cache TTLs for external Webhook Token Reviewers | ||
for i := range obj.AuthConfig.WebhookTokenAuthenticators { | ||
if len(obj.AuthConfig.WebhookTokenAuthenticators[i].ConfigFile) == 0 { | ||
continue |
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.
Same comment
authToken := "Anything-goes!" | ||
authTestUser := "testuser" | ||
authTestUID := "42" | ||
authTestGroups := []string{"testgroup"} |
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.
TODO masters group
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.
no need
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.
OK
} | ||
|
||
// Get master config | ||
masterOptions, err := testserver.DefaultMasterOptions() |
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.
Move down
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.
?
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.
Just cosmetic for increasing readability since you do not need that variable until later.
// Try to authenticate with a token that can be validated only by our | ||
// external token reviewer | ||
userConfig := &restclient.Config{ | ||
Host: clientConfig.Host, |
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.
Anonymous helper
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.
?
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.
userConfig := AnonymousClientConfig(...)
userConfig.BearerToken = ...
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.
ok
userWhoamiOptions := cmd.WhoAmIOptions{UserInterface: userClient.Users(), Out: ioutil.Discard} | ||
retrievedUser, err := userWhoamiOptions.WhoAmI() | ||
if err != nil { | ||
t.Errorf("unexpected error: %v", err) |
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.
Fatal
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.
Not really needed, other tests do the same
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.
Just because other people write their tests incorrectly is not a valid reason to continue doing the wrong thing.
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.
ooook
masterOptions.AuthConfig.WebhookTokenAuthenticators = []configapi.WebhookTokenAuthenticator{ | ||
{ | ||
ConfigFile: authConfigFile.Name(), | ||
CacheTTL: "10s", |
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.
Remove to check defaulting
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.
defaulting is already checked in uint tests, no need to check it here
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.
Hm I guess serialization tests may be enough.
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.
DEfaulting happens before we override this part of the config anyway, so it wouldn't work :-)
t.Fatalf("unexpected error: %v", err) | ||
} | ||
err = oauthClient.Oauth().OAuthAccessTokens().Delete("XYZ", &metav1.DeleteOptions{}) | ||
if !kerrors.IsForbidden(err) { |
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.
Needs to check for scope 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.
Why ?
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.
Because we should know we got forbidden via scope and not "the token stopped working for random reason"
Signed-off-by: Monis Khan <[email protected]>
/retest |
} | ||
webhookTokenAuthenticator, err := webhooktoken.New(wta.ConfigFile, ttl) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("Failed to create webhook token authenticator for ConfigFile='%s'", wta.ConfigFile) |
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.
Include the error that caused the failure:
return nil, nil, fmt.Errorf("Failed to create webhook token authenticator for ConfigFile=%q: %v", wta.ConfigFile, err)
Also replace '%s'
with %q
on both messages.
Signed-off-by: Simo Sorce <[email protected]>
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: enj, simo5 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/refresh |
/retest |
3 similar comments
/retest |
/retest |
/retest |
/test extended_conformance_install |
/retest |
/test extended_networking_minimal |
/test extended_conformance_install |
Flake: #18982 |
/retest |
1 similar comment
/retest |
Automatic merge from submit-queue. |
This allows to use an external server for Token authentication.