Skip to content
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

Update delegated authorization options default to eliminate unnecessary SARs #98325

Merged
merged 2 commits into from Feb 2, 2021

Conversation

deads2k
Copy link
Contributor

@deads2k deads2k commented Jan 22, 2021

healthz, readyz, and livez are canonical names for checks that the kubelet does. By default, allow access to them in the options. Callers can adjust the defaults if they have a reason to require checks.

system:masters has full power, so the authorization check is unnecessary and just uses an extra call for in-cluster access. Callers can adjust the defaults if they have a reason to require checks.

This directly impacts kube-controller-manager, kube-scheduler, and cloud-controller-manager in tree. I think these values are reasonable, but am happy to hear from @kubernetes/sig-auth-pr-reviews on the subject. And I'm willing to wire a configuration option if we think cluster-admins should be able to twiddle these knobs.

/kind cleanup
/priority important-soon
@kubernetes/sig-auth-pr-reviews @kubernetes/sig-api-machinery-pr-reviews

The default delegating authorization options now allow unauthenticated access to healthz, readyz, and livez.  A system:masters user connecting to an authz delegator will not perform an authz check.

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/auth Categorizes an issue or PR as relevant to SIG Auth. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jan 22, 2021
@deads2k
Copy link
Contributor Author

deads2k commented Jan 22, 2021

/hold

don't want to merge until there has been a good amount of time for comment.

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 22, 2021
@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver labels Jan 22, 2021
@@ -78,6 +78,14 @@ func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions {
DenyCacheTTL: 10 * time.Second,
ClientTimeout: 10 * time.Second,
WebhookRetryBackoff: DefaultAuthWebhookRetryBackoff(),
// This allows the kubelet to always get health and readiness without causing an authorization check.
// This field can be cleared by callers if they don't want this behavior.
AlwaysAllowPaths: []string{"/healthz", "readyz", "/livez"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should at least require membership in the authenticated group for something like this. Does it? How?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming you have anonymous auth enabled on your cluster, we already allow this for unauthenticated users:

{
// a role which provides just enough power read insensitive cluster information
ObjectMeta: metav1.ObjectMeta{Name: "system:public-info-viewer"},
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get").URLs(
"/livez", "/readyz", "/healthz", "/version", "/version/",
).RuleOrDie(),
},
},

rbacv1helpers.NewClusterBinding("system:public-info-viewer").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(),

This change just makes it so that the SAR checks are skipped.

@lavalamp
Copy link
Member

uh I like the specific optimization, but I'm kinda terrified in general of optimizing away authz checks. Like will this change how calls show up in the audit log?

@enj
Copy link
Member

enj commented Jan 22, 2021

LGTM and matches my personal experience. I have done the following before to make node health checks against aggregated API servers less wasteful:

authorizationOptions := genericapiserveroptions.NewDelegatingAuthorizationOptions().
    WithAlwaysAllowPaths("/healthz").
    WithAlwaysAllowGroups(user.SystemPrivilegedGroup)

@@ -78,6 +78,14 @@ func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions {
DenyCacheTTL: 10 * time.Second,
ClientTimeout: 10 * time.Second,
WebhookRetryBackoff: DefaultAuthWebhookRetryBackoff(),
// This allows the kubelet to always get health and readiness without causing an authorization check.
// This field can be cleared by callers if they don't want this behavior.
AlwaysAllowPaths: []string{"/healthz", "readyz", "/livez"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/readyz (missing leading slash)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/readyz (missing leading slash)

updated

@deads2k
Copy link
Contributor Author

deads2k commented Jan 25, 2021

uh I like the specific optimization, but I'm kinda terrified in general of optimizing away authz checks. Like will this change how calls show up in the audit log?

The audit log will show a different authorizer as allowing the connection instead of RBAC (this is built in a layered way). The authentication pieces in the audit log will match exactly.

SARs

healthz, readyz, and livez are canonical names for checks that the kubelet does.  By default, allow access to them in the options. Callers can adjust the defaults if they have a reason to require checks.

system:masters has full power, so the authorization check is unnecessary and just uses an extra call for in-cluster access.  Callers can adjust the defaults if they have a reason to require checks.
@lavalamp
Copy link
Member

The audit log will show a different authorizer as allowing the connection instead of RBAC (this is built in a layered way). The authentication pieces in the audit log will match exactly.

OK LGTM then. Will let someone from SIG auth do the official LGTM.

@enj
Copy link
Member

enj commented Jan 26, 2021

Failing test on AlwaysAllowGroups:

Executing tests from //cmd/kube-controller-manager/app/options:go_default_test
--- FAIL: TestAddFlags (0.02s)
    options_test.go:444: Got different run options than expected.
        Difference detected on:
          &options.KubeControllerManagerOptions{
          	... // 27 identical fields
          	InsecureServing: &{DeprecatedInsecureServingOptions: &{BindAddress: s"192.168.4.10", BindPort: 10000, BindNetwork: "tcp"}},
          	Authentication:  &{RemoteKubeConfigFileOptional: true, CacheTTL: s"10s", RequestHeader: {UsernameHeaders: {"x-remote-user"}, GroupHeaders: {"x-remote-group"}, ExtraHeaderPrefixes: {"x-remote-extra-"}}, WebhookRetryBackoff: &{Duration: s"500ms", Factor: 1.5, Jitter: 0.2, Steps: 5, ...}, ...},
          	Authorization: &options.DelegatingAuthorizationOptions{
          		... // 3 identical fields
          		DenyCacheTTL:        s"10s",
          		AlwaysAllowPaths:    {"/healthz"},
        - 		AlwaysAllowGroups:   nil,
        + 		AlwaysAllowGroups:   []string{"system:masters"},
          		ClientTimeout:       s"10s",
          		WebhookRetryBackoff: &{Duration: s"500ms", Factor: 1.5, Jitter: 0.2, Steps: 5, ...},
          	},
          	Metrics: &{},
          	Logs:    &{LogFormat: "text"},
          	... // 3 identical fields
          }

Do we want to update AlwaysAllowPaths for KCM to []string{"/healthz", "readyz", "/livez"}?

@deads2k
Copy link
Contributor Author

deads2k commented Jan 26, 2021

Do we want to update AlwaysAllowPaths for KCM to []string{"/healthz", "readyz", "/livez"}?

pushing update to use the defaults now.

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. area/cloudprovider sig/cloud-provider Categorizes an issue or PR as relevant to SIG Cloud Provider. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Jan 26, 2021
@k8s-ci-robot k8s-ci-robot removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 26, 2021
@leilajal
Copy link
Contributor

/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jan 26, 2021
@deads2k
Copy link
Contributor Author

deads2k commented Jan 28, 2021

/hold cancel

I think we closed on this and are ok moving forward with this one.

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 28, 2021
@enj
Copy link
Member

enj commented Feb 2, 2021

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 2, 2021
@cheftako
Copy link
Member

cheftako commented Feb 2, 2021

/lgtm

@cheftako
Copy link
Member

cheftako commented Feb 2, 2021

/approve

Copy link
Contributor

@damemi damemi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cheftako, damemi, deads2k

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 2, 2021
@k8s-ci-robot k8s-ci-robot merged commit d265910 into kubernetes:master Feb 2, 2021
@k8s-ci-robot k8s-ci-robot added this to the v1.21 milestone Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver area/cloudprovider cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/auth Categorizes an issue or PR as relevant to SIG Auth. sig/cloud-provider Categorizes an issue or PR as relevant to SIG Cloud Provider. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants