Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
829e6f6c
Unverified
Commit
829e6f6c
authored
Mar 01, 2017
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Include pod namespace in PSP 'use' authorization check
parent
f1575cca
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
49 deletions
+67
-49
admission.go
plugin/pkg/admission/security/podsecuritypolicy/admission.go
+11
-11
admission_test.go
...kg/admission/security/podsecuritypolicy/admission_test.go
+56
-38
No files found.
plugin/pkg/admission/security/podsecuritypolicy/admission.go
View file @
829e6f6c
...
@@ -52,7 +52,7 @@ func init() {
...
@@ -52,7 +52,7 @@ func init() {
}
}
// PSPMatchFn allows plugging in how PSPs are matched against user information.
// PSPMatchFn allows plugging in how PSPs are matched against user information.
type
PSPMatchFn
func
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
type
PSPMatchFn
func
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
,
namespace
string
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
// podSecurityPolicyPlugin holds state for and implements the admission plugin.
// podSecurityPolicyPlugin holds state for and implements the admission plugin.
type
podSecurityPolicyPlugin
struct
{
type
podSecurityPolicyPlugin
struct
{
...
@@ -130,7 +130,7 @@ func (c *podSecurityPolicyPlugin) Admit(a admission.Attributes) error {
...
@@ -130,7 +130,7 @@ func (c *podSecurityPolicyPlugin) Admit(a admission.Attributes) error {
saInfo
=
serviceaccount
.
UserInfo
(
a
.
GetNamespace
(),
pod
.
Spec
.
ServiceAccountName
,
""
)
saInfo
=
serviceaccount
.
UserInfo
(
a
.
GetNamespace
(),
pod
.
Spec
.
ServiceAccountName
,
""
)
}
}
matchedPolicies
,
err
:=
c
.
pspMatcher
(
c
.
lister
,
a
.
GetUserInfo
(),
saInfo
,
c
.
authz
)
matchedPolicies
,
err
:=
c
.
pspMatcher
(
c
.
lister
,
a
.
GetUserInfo
(),
saInfo
,
c
.
authz
,
a
.
GetNamespace
()
)
if
err
!=
nil
{
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
return
admission
.
NewForbidden
(
a
,
err
)
}
}
...
@@ -279,7 +279,7 @@ func (c *podSecurityPolicyPlugin) createProvidersFromPolicies(psps []*extensions
...
@@ -279,7 +279,7 @@ func (c *podSecurityPolicyPlugin) createProvidersFromPolicies(psps []*extensions
// TODO: this will likely need optimization since the initial implementation will
// TODO: this will likely need optimization since the initial implementation will
// always query for authorization. Needs scale testing and possibly checking against
// always query for authorization. Needs scale testing and possibly checking against
// a cache.
// a cache.
func
getMatchingPolicies
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
{
func
getMatchingPolicies
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
,
namespace
string
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
{
matchedPolicies
:=
make
([]
*
extensions
.
PodSecurityPolicy
,
0
)
matchedPolicies
:=
make
([]
*
extensions
.
PodSecurityPolicy
,
0
)
list
,
err
:=
lister
.
List
(
labels
.
Everything
())
list
,
err
:=
lister
.
List
(
labels
.
Everything
())
...
@@ -289,7 +289,7 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user
...
@@ -289,7 +289,7 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user
for
_
,
constraint
:=
range
list
{
for
_
,
constraint
:=
range
list
{
// if no user info exists then the API is being hit via the unsecured port. In this case authorize the request.
// if no user info exists then the API is being hit via the unsecured port. In this case authorize the request.
if
user
==
nil
||
authorizedForPolicy
(
user
,
constraint
,
authz
)
||
authorizedForPolicy
(
sa
,
constraint
,
authz
)
{
if
user
==
nil
||
authorizedForPolicy
(
user
,
namespace
,
constraint
,
authz
)
||
authorizedForPolicy
(
sa
,
namespace
,
constraint
,
authz
)
{
matchedPolicies
=
append
(
matchedPolicies
,
constraint
)
matchedPolicies
=
append
(
matchedPolicies
,
constraint
)
}
}
}
}
...
@@ -297,26 +297,26 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user
...
@@ -297,26 +297,26 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user
return
matchedPolicies
,
nil
return
matchedPolicies
,
nil
}
}
// authorizedForPolicy returns true if info is authorized to perform
a "get" on policy
.
// authorizedForPolicy returns true if info is authorized to perform
the "use" verb on the policy resource
.
func
authorizedForPolicy
(
info
user
.
Info
,
policy
*
extensions
.
PodSecurityPolicy
,
authz
authorizer
.
Authorizer
)
bool
{
func
authorizedForPolicy
(
info
user
.
Info
,
namespace
string
,
policy
*
extensions
.
PodSecurityPolicy
,
authz
authorizer
.
Authorizer
)
bool
{
if
info
==
nil
{
if
info
==
nil
{
return
false
return
false
}
}
attr
:=
buildAttributes
(
info
,
policy
)
attr
:=
buildAttributes
(
info
,
namespace
,
policy
)
allowed
,
reason
,
err
:=
authz
.
Authorize
(
attr
)
allowed
,
reason
,
err
:=
authz
.
Authorize
(
attr
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
5
)
.
Infof
(
"cannot authorize
d
for policy: %v,%v"
,
reason
,
err
)
glog
.
V
(
5
)
.
Infof
(
"cannot authorize for policy: %v,%v"
,
reason
,
err
)
}
}
return
allowed
return
allowed
}
}
// buildAttributes builds an attributes record for a SAR based on the user info and policy.
// buildAttributes builds an attributes record for a SAR based on the user info and policy.
func
buildAttributes
(
info
user
.
Info
,
policy
*
extensions
.
PodSecurityPolicy
)
authorizer
.
Attributes
{
func
buildAttributes
(
info
user
.
Info
,
namespace
string
,
policy
*
extensions
.
PodSecurityPolicy
)
authorizer
.
Attributes
{
// TODO consider checking against the namespace that the pod is being
// check against the namespace that the pod is being created in to allow per-namespace PSP grants.
// created in to allow per-namespace PSP definitions.
attr
:=
authorizer
.
AttributesRecord
{
attr
:=
authorizer
.
AttributesRecord
{
User
:
info
,
User
:
info
,
Verb
:
"use"
,
Verb
:
"use"
,
Namespace
:
namespace
,
Name
:
policy
.
Name
,
Name
:
policy
.
Name
,
APIGroup
:
extensions
.
GroupName
,
APIGroup
:
extensions
.
GroupName
,
Resource
:
"podsecuritypolicies"
,
Resource
:
"podsecuritypolicies"
,
...
...
plugin/pkg/admission/security/podsecuritypolicy/admission_test.go
View file @
829e6f6c
...
@@ -57,18 +57,18 @@ func NewTestAdmission(lister extensionslisters.PodSecurityPolicyLister) kadmissi
...
@@ -57,18 +57,18 @@ func NewTestAdmission(lister extensionslisters.PodSecurityPolicyLister) kadmissi
// TestAlwaysAllowedAuthorizer is a testing struct for testing that fulfills the authorizer interface.
// TestAlwaysAllowedAuthorizer is a testing struct for testing that fulfills the authorizer interface.
type
TestAuthorizer
struct
{
type
TestAuthorizer
struct
{
// disallowed contains names of disallowed policies. Map is keyed by user.Info.GetName()
// usernameToNamespaceToAllowedPSPs contains the map of allowed PSPs.
disallowed
map
[
string
][]
string
// if nil, all PSPs are allowed.
usernameToNamespaceToAllowedPSPs
map
[
string
]
map
[
string
]
map
[
string
]
bool
}
}
func
(
t
*
TestAuthorizer
)
Authorize
(
a
authorizer
.
Attributes
)
(
authorized
bool
,
reason
string
,
err
error
)
{
func
(
t
*
TestAuthorizer
)
Authorize
(
a
authorizer
.
Attributes
)
(
authorized
bool
,
reason
string
,
err
error
)
{
disallowedForUser
,
_
:=
t
.
disallowed
[
a
.
GetUser
()
.
GetName
()]
if
t
.
usernameToNamespaceToAllowedPSPs
==
nil
{
for
_
,
name
:=
range
disallowedForUser
{
return
true
,
""
,
nil
if
a
.
GetName
()
==
name
{
return
false
,
""
,
nil
}
}
}
return
true
,
""
,
nil
allowedInNamespace
:=
t
.
usernameToNamespaceToAllowedPSPs
[
a
.
GetUser
()
.
GetName
()][
a
.
GetNamespace
()][
a
.
GetName
()]
allowedClusterWide
:=
t
.
usernameToNamespaceToAllowedPSPs
[
a
.
GetUser
()
.
GetName
()][
""
][
a
.
GetName
()]
return
(
allowedInNamespace
||
allowedClusterWide
),
""
,
nil
}
}
var
_
authorizer
.
Authorizer
=
&
TestAuthorizer
{}
var
_
authorizer
.
Authorizer
=
&
TestAuthorizer
{}
...
@@ -1546,17 +1546,21 @@ func TestGetMatchingPolicies(t *testing.T) {
...
@@ -1546,17 +1546,21 @@ func TestGetMatchingPolicies(t *testing.T) {
}
}
tests
:=
map
[
string
]
struct
{
tests
:=
map
[
string
]
struct
{
user
user
.
Info
user
user
.
Info
sa
user
.
Info
sa
user
.
Info
expectedPolicies
sets
.
String
ns
string
inPolicies
[]
*
extensions
.
PodSecurityPolicy
expectedPolicies
sets
.
String
disallowedPolicies
map
[
string
][]
string
inPolicies
[]
*
extensions
.
PodSecurityPolicy
allowed
map
[
string
]
map
[
string
]
map
[
string
]
bool
}{
}{
"policy allowed by user"
:
{
"policy allowed by user"
:
{
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"sa"
:
{
"policy"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{
"user"
:
{
"test"
:
{
"policy"
:
true
},
},
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
expectedPolicies
:
sets
.
NewString
(
"policy"
),
expectedPolicies
:
sets
.
NewString
(
"policy"
),
...
@@ -1564,43 +1568,55 @@ func TestGetMatchingPolicies(t *testing.T) {
...
@@ -1564,43 +1568,55 @@ func TestGetMatchingPolicies(t *testing.T) {
"policy allowed by sa"
:
{
"policy allowed by sa"
:
{
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"user"
:
{
"policy"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{
"sa"
:
{
"test"
:
{
"policy"
:
true
},
},
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
expectedPolicies
:
sets
.
NewString
(
"policy"
),
expectedPolicies
:
sets
.
NewString
(
"policy"
),
},
},
"no policies allowed"
:
{
"no policies allowed"
:
{
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"user"
:
{
"policy"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{},
"sa"
:
{
"policy"
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy"
)},
expectedPolicies
:
sets
.
NewString
(),
expectedPolicies
:
sets
.
NewString
(),
},
},
"multiple policies allowed"
:
{
"multiple policies allowed"
:
{
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"user"
:
{
"policy1"
,
"policy3"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{
"sa"
:
{
"policy2"
,
"policy3"
},
"sa"
:
{
"test"
:
{
"policy1"
:
true
},
""
:
{
"policy4"
:
true
},
"other"
:
{
"policy6"
:
true
},
},
"user"
:
{
"test"
:
{
"policy2"
:
true
},
""
:
{
"policy5"
:
true
},
"other"
:
{
"policy7"
:
true
},
},
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy1"
),
// allowed by sa
policyWithName
(
"policy1"
),
// allowed by sa
policyWithName
(
"policy2"
),
// allowed by user
policyWithName
(
"policy2"
),
// allowed by user
policyWithName
(
"policy3"
),
// not allowed
policyWithName
(
"policy3"
),
// not allowed
policyWithName
(
"policy4"
),
// allowed by sa at cluster level
policyWithName
(
"policy5"
),
// allowed by user at cluster level
policyWithName
(
"policy6"
),
// not allowed in this namespace
policyWithName
(
"policy7"
),
// not allowed in this namespace
},
},
expectedPolicies
:
sets
.
NewString
(
"policy1"
,
"policy2"
),
expectedPolicies
:
sets
.
NewString
(
"policy1"
,
"policy2"
,
"policy4"
,
"policy5"
),
},
},
"policies are allowed for nil user info"
:
{
"policies are allowed for nil user info"
:
{
user
:
nil
,
user
:
nil
,
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
sa
:
&
user
.
DefaultInfo
{
Name
:
"sa"
},
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"user"
:
{
"policy1"
,
"policy3"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{},
// authorizer not consulted
"sa"
:
{
"policy2"
,
"policy3"
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy1"
),
policyWithName
(
"policy1"
),
policyWithName
(
"policy2"
),
policyWithName
(
"policy2"
),
...
@@ -1613,9 +1629,11 @@ func TestGetMatchingPolicies(t *testing.T) {
...
@@ -1613,9 +1629,11 @@ func TestGetMatchingPolicies(t *testing.T) {
"policies are not allowed for nil sa info"
:
{
"policies are not allowed for nil sa info"
:
{
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
user
:
&
user
.
DefaultInfo
{
Name
:
"user"
},
sa
:
nil
,
sa
:
nil
,
disallowedPolicies
:
map
[
string
][]
string
{
ns
:
"test"
,
"user"
:
{
"policy1"
,
"policy3"
},
allowed
:
map
[
string
]
map
[
string
]
map
[
string
]
bool
{
"sa"
:
{
"policy2"
,
"policy3"
},
"user"
:
{
"test"
:
{
"policy2"
:
true
},
},
},
},
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
inPolicies
:
[]
*
extensions
.
PodSecurityPolicy
{
policyWithName
(
"policy1"
),
policyWithName
(
"policy1"
),
...
@@ -1634,8 +1652,8 @@ func TestGetMatchingPolicies(t *testing.T) {
...
@@ -1634,8 +1652,8 @@ func TestGetMatchingPolicies(t *testing.T) {
store
.
Add
(
psp
)
store
.
Add
(
psp
)
}
}
authz
:=
&
TestAuthorizer
{
disallowed
:
v
.
disallowedPolicies
}
authz
:=
&
TestAuthorizer
{
usernameToNamespaceToAllowedPSPs
:
v
.
allowed
}
allowedPolicies
,
err
:=
getMatchingPolicies
(
pspInformer
.
Lister
(),
v
.
user
,
v
.
sa
,
authz
)
allowedPolicies
,
err
:=
getMatchingPolicies
(
pspInformer
.
Lister
(),
v
.
user
,
v
.
sa
,
authz
,
v
.
ns
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Errorf
(
"%s got unexpected error %#v"
,
k
,
err
)
t
.
Errorf
(
"%s got unexpected error %#v"
,
k
,
err
)
continue
continue
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment