Example #1
0
func (e clusterRoleEvaluator) ResolveGettableNamespaces(scope string, clusterPolicyGetter client.ClusterPolicyLister) ([]string, error) {
	_, scopeNamespace, _, err := e.parseScope(scope)
	if err != nil {
		return nil, err
	}
	rules, err := e.resolveRules(scope, clusterPolicyGetter)
	if err != nil {
		return nil, err
	}

	attributes := authorizer.DefaultAuthorizationAttributes{
		APIGroup: kapi.GroupName,
		Verb:     "get",
		Resource: "namespaces",
	}

	errors := []error{}
	for _, rule := range rules {
		matches, err := attributes.RuleMatches(rule)
		if err != nil {
			errors = append(errors, err)
			continue
		}
		if matches {
			return []string{scopeNamespace}, nil
		}
	}

	return []string{}, kutilerrors.NewAggregate(errors)
}
Example #2
0
// build LocalSubjectAccessReview struct to validate role via checkAccess
func (o *podNodeConstraints) checkPodsBindAccess(attr admission.Attributes) (bool, error) {
	ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), attr.GetNamespace()), attr.GetUserInfo())
	authzAttr := authorizer.DefaultAuthorizationAttributes{
		Verb:     "create",
		Resource: "pods/binding",
		APIGroup: kapi.GroupName,
	}
	if attr.GetResource().GroupResource() == kapi.Resource("pods") {
		authzAttr.ResourceName = attr.GetName()
	}
	allow, _, err := o.authorizer.Authorize(ctx, authzAttr)
	return allow, err
}
Example #3
0
// GetRequestAttributes populates authorizer attributes for the requests to the kubelet API.
// Default attributes are {apiVersion=v1,verb=proxy,resource=nodes,resourceName=<node name>}
// More specific verb/resource is set for the following request patterns:
//    /stats/*   => verb=<api verb from request>, resource=nodes/stats
//    /metrics/* => verb=<api verb from request>, resource=nodes/metrics
//    /logs/*    => verb=<api verb from request>, resource=nodes/log
func (n NodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *http.Request) kauthorizer.Attributes {

	namespace := ""

	apiVerb := ""
	switch r.Method {
	case "POST":
		apiVerb = "create"
	case "GET":
		apiVerb = "get"
	case "PUT":
		apiVerb = "update"
	case "PATCH":
		apiVerb = "patch"
	case "DELETE":
		apiVerb = "delete"
	}

	// Default verb/resource is <apiVerb> nodes/proxy, which allows full access to the kubelet API
	attrs := oauthorizer.DefaultAuthorizationAttributes{
		APIVersion:   "v1",
		APIGroup:     "",
		Verb:         apiVerb,
		Resource:     "nodes/proxy",
		ResourceName: n.nodeName,
		URL:          r.URL.Path,
	}

	// Override verb/resource for specific paths
	// Updates to these rules require updating NodeAdminRole and NodeReaderRole in bootstrap policy
	switch {
	case isSubpath(r, "/spec"):
		attrs.Verb = apiVerb
		attrs.Resource = authorizationapi.NodeSpecResource
	case isSubpath(r, "/stats"):
		attrs.Verb = apiVerb
		attrs.Resource = authorizationapi.NodeStatsResource
	case isSubpath(r, "/metrics"):
		attrs.Verb = apiVerb
		attrs.Resource = authorizationapi.NodeMetricsResource
	case isSubpath(r, "/logs"):
		attrs.Verb = apiVerb
		attrs.Resource = authorizationapi.NodeLogResource
	}
	// TODO: handle other things like /healthz/*? not sure if "non-resource" urls on the kubelet make sense to authorize against master non-resource URL policy

	glog.V(2).Infof("Node request attributes: namespace=%s, user=%#v, attrs=%#v", namespace, u, attrs)

	return authzadapter.KubernetesAuthorizerAttributes(namespace, u, attrs)
}
Example #4
0
// isAllowed checks to see if the current user has rights to issue a LocalSubjectAccessReview on the namespace they're attempting to access
func (r *REST) isAllowed(ctx kapi.Context, rar *authorizationapi.ResourceAccessReview) error {
	localRARAttributes := authorizer.DefaultAuthorizationAttributes{
		Verb:     "create",
		Resource: "localresourceaccessreviews",
	}
	allowed, reason, err := r.authorizer.Authorize(kapi.WithNamespace(ctx, rar.Action.Namespace), localRARAttributes)

	if err != nil {
		return kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), err)
	}
	if !allowed {
		forbiddenError := kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), errors.New("") /*discarded*/)
		forbiddenError.ErrStatus.Message = reason
		return forbiddenError
	}

	return nil
}
Example #5
0
func TestRoundTrip(t *testing.T) {
	// Start with origin attributes
	oattrs := oauthorizer.DefaultAuthorizationAttributes{
		Verb:              "get",
		APIVersion:        "av",
		APIGroup:          "ag",
		Resource:          "r",
		ResourceName:      "rn",
		RequestAttributes: "ra",
		NonResourceURL:    true,
		URL:               "/123",
	}

	// Convert to kube attributes
	kattrs := KubernetesAuthorizerAttributes("ns", &user.DefaultInfo{Name: "myuser", Groups: []string{"mygroup"}}, oattrs)
	if kattrs.GetUser().GetName() != "myuser" {
		t.Errorf("Expected %v, got %v", "myuser", kattrs.GetUser().GetName())
	}
	if !reflect.DeepEqual(kattrs.GetUser().GetGroups(), []string{"mygroup"}) {
		t.Errorf("Expected %v, got %v", []string{"mygroup"}, kattrs.GetUser().GetGroups())
	}
	if kattrs.GetVerb() != "get" {
		t.Errorf("Expected %v, got %v", "get", kattrs.GetVerb())
	}
	if kattrs.IsReadOnly() != true {
		t.Errorf("Expected %v, got %v", true, kattrs.IsReadOnly())
	}
	if kattrs.GetNamespace() != "ns" {
		t.Errorf("Expected %v, got %v", "ns", kattrs.GetNamespace())
	}
	if kattrs.GetResource() != "r" {
		t.Errorf("Expected %v, got %v", "", kattrs.GetResource())
	}
	if kattrs.IsResourceRequest() != false {
		t.Errorf("Expected %v, got %v", false, kattrs.IsResourceRequest())
	}
	if kattrs.GetPath() != "/123" {
		t.Errorf("Expected %v, got %v", "/123", kattrs.GetPath())
	}

	// Convert back to context+origin attributes
	ctx, oattrs2 := OriginAuthorizerAttributes(kattrs)

	// Ensure namespace/user info is preserved
	if user, ok := kapi.UserFrom(ctx); !ok {
		t.Errorf("No user in context")
	} else if user.GetName() != "myuser" {
		t.Errorf("Expected %v, got %v", "myuser", user.GetName())
	} else if !reflect.DeepEqual(user.GetGroups(), []string{"mygroup"}) {
		t.Errorf("Expected %v, got %v", []string{"mygroup"}, user.GetGroups())
	}

	// Ensure common attribute info is preserved
	if oattrs.GetVerb() != oattrs2.GetVerb() {
		t.Errorf("Expected %v, got %v", oattrs.GetVerb(), oattrs2.GetVerb())
	}
	if oattrs.GetResource() != oattrs2.GetResource() {
		t.Errorf("Expected %v, got %v", oattrs.GetResource(), oattrs2.GetResource())
	}

	// Ensure origin-specific info is preserved
	if oattrs.GetAPIVersion() != oattrs2.GetAPIVersion() {
		t.Errorf("Expected %v, got %v", oattrs.GetAPIVersion(), oattrs2.GetAPIVersion())
	}
	if oattrs.GetAPIGroup() != oattrs2.GetAPIGroup() {
		t.Errorf("Expected %v, got %v", oattrs.GetAPIGroup(), oattrs2.GetAPIGroup())
	}
	if oattrs.GetResourceName() != oattrs2.GetResourceName() {
		t.Errorf("Expected %v, got %v", oattrs.GetResourceName(), oattrs2.GetResourceName())
	}
	if oattrs.GetRequestAttributes() != oattrs2.GetRequestAttributes() {
		t.Errorf("Expected %v, got %v", oattrs.GetRequestAttributes(), oattrs2.GetRequestAttributes())
	}
	if oattrs.IsNonResourceURL() != oattrs2.IsNonResourceURL() {
		t.Errorf("Expected %v, got %v", oattrs.IsNonResourceURL(), oattrs2.IsNonResourceURL())
	}
	if oattrs.GetURL() != oattrs2.GetURL() {
		t.Errorf("Expected %v, got %v", oattrs.GetURL(), oattrs2.GetURL())
	}
}