allow restricting subresource access

This commit is contained in:
deads2k 2016-08-03 08:19:57 -04:00
parent 8805bbba3f
commit 1e7adaa5c0
2 changed files with 52 additions and 17 deletions

View File

@ -44,10 +44,14 @@ func (r *RBACAuthorizer) Authorize(attr authorizer.Attributes) (bool, string, er
// Frame the authorization request as a privilege escalation check.
var requestedRule rbac.PolicyRule
if attr.IsResourceRequest() {
resource := attr.GetResource()
if len(attr.GetSubresource()) > 0 {
resource = attr.GetResource() + "/" + attr.GetSubresource()
}
requestedRule = rbac.PolicyRule{
Verbs: []string{attr.GetVerb()},
APIGroups: []string{attr.GetAPIGroup()}, // TODO(ericchiang): add api version here too?
Resources: []string{attr.GetResource()},
Resources: []string{resource},
ResourceNames: []string{attr.GetName()},
}
} else {

View File

@ -86,12 +86,13 @@ func newRoleBinding(namespace, roleName string, bindType uint16, subjects ...str
}
type defaultAttributes struct {
user string
groups string
verb string
resource string
namespace string
apiGroup string
user string
groups string
verb string
resource string
subresource string
namespace string
apiGroup string
}
func (d *defaultAttributes) String() string {
@ -106,7 +107,7 @@ func (d *defaultAttributes) GetVerb() string { return d.verb }
func (d *defaultAttributes) IsReadOnly() bool { return d.verb == "get" || d.verb == "watch" }
func (d *defaultAttributes) GetNamespace() string { return d.namespace }
func (d *defaultAttributes) GetResource() string { return d.resource }
func (d *defaultAttributes) GetSubresource() string { return "" }
func (d *defaultAttributes) GetSubresource() string { return d.subresource }
func (d *defaultAttributes) GetName() string { return "" }
func (d *defaultAttributes) GetAPIGroup() string { return d.apiGroup }
func (d *defaultAttributes) GetAPIVersion() string { return "" }
@ -133,17 +134,17 @@ func TestAuthorizer(t *testing.T) {
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
&defaultAttributes{"admin", "", "get", "Pods", "ns1", ""},
&defaultAttributes{"admin", "", "watch", "Pods", "ns1", ""},
&defaultAttributes{"admin", "group1", "watch", "Foobar", "ns1", ""},
&defaultAttributes{"joe", "admins", "watch", "Foobar", "ns1", ""},
&defaultAttributes{"joe", "group1,admins", "watch", "Foobar", "ns1", ""},
&defaultAttributes{"admin", "", "get", "Pods", "", "ns1", ""},
&defaultAttributes{"admin", "", "watch", "Pods", "", "ns1", ""},
&defaultAttributes{"admin", "group1", "watch", "Foobar", "", "ns1", ""},
&defaultAttributes{"joe", "admins", "watch", "Foobar", "", "ns1", ""},
&defaultAttributes{"joe", "group1,admins", "watch", "Foobar", "", "ns1", ""},
},
shouldFail: []authorizer.Attributes{
&defaultAttributes{"admin", "", "GET", "Pods", "ns2", ""},
&defaultAttributes{"admin", "", "GET", "Nodes", "", ""},
&defaultAttributes{"admin", "admins", "GET", "Pods", "ns2", ""},
&defaultAttributes{"admin", "admins", "GET", "Nodes", "", ""},
&defaultAttributes{"admin", "", "GET", "Pods", "", "ns2", ""},
&defaultAttributes{"admin", "", "GET", "Nodes", "", "", ""},
&defaultAttributes{"admin", "admins", "GET", "Pods", "", "ns2", ""},
&defaultAttributes{"admin", "admins", "GET", "Nodes", "", "", ""},
},
},
{
@ -187,6 +188,36 @@ func TestAuthorizer(t *testing.T) {
authorizer.AttributesRecord{User: &user.DefaultInfo{Groups: []string{"prefixed"}}, Verb: "get", Path: "/api/v1"},
},
},
{
// test subresource resolution
clusterRoles: []rbac.ClusterRole{
newClusterRole("admin", newRule("*", "*", "pods", "*")),
},
roleBindings: []rbac.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
&defaultAttributes{"admin", "", "get", "pods", "", "ns1", ""},
},
shouldFail: []authorizer.Attributes{
&defaultAttributes{"admin", "", "get", "pods", "status", "ns1", ""},
},
},
{
// test subresource resolution
clusterRoles: []rbac.ClusterRole{
newClusterRole("admin", newRule("*", "*", "pods/status", "*")),
},
roleBindings: []rbac.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
&defaultAttributes{"admin", "", "get", "pods", "status", "ns1", ""},
},
shouldFail: []authorizer.Attributes{
&defaultAttributes{"admin", "", "get", "pods", "", "ns1", ""},
},
},
}
for i, tt := range tests {
ruleResolver := validation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings)