Skip to content

Commit 206991f

Browse files
committed
Updated bootstrap policy to not grant builds/custom privs for system:authenticated users by default Permissions can still be granted by an administrator if needed
1 parent df195a9 commit 206991f

File tree

5 files changed

+138
-44
lines changed

5 files changed

+138
-44
lines changed

pkg/cmd/server/bootstrappolicy/policy.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -958,11 +958,6 @@ func GetBootstrapClusterRoleBindings() []authorizationapi.ClusterRoleBinding {
958958
RoleRef: kapi.ObjectReference{Name: BuildStrategyDockerRoleName},
959959
Subjects: []kapi.ObjectReference{{Kind: authorizationapi.SystemGroupKind, Name: AuthenticatedGroup}},
960960
},
961-
{
962-
ObjectMeta: kapi.ObjectMeta{Name: BuildStrategyCustomRoleBindingName},
963-
RoleRef: kapi.ObjectReference{Name: BuildStrategyCustomRoleName},
964-
Subjects: []kapi.ObjectReference{{Kind: authorizationapi.SystemGroupKind, Name: AuthenticatedGroup}},
965-
},
966961
{
967962
ObjectMeta: kapi.ObjectMeta{Name: BuildStrategySourceRoleBindingName},
968963
RoleRef: kapi.ObjectReference{Name: BuildStrategySourceRoleName},

test/cmd/policy.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,24 @@ os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/custom'
5959
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/source' 'namespaced-user'
6060
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/jenkinspipeline' 'namespaced-user'
6161
os::cmd::expect_success_and_text 'oadm policy who-can create builds/docker' 'system:authenticated'
62-
os::cmd::expect_success_and_text 'oadm policy who-can create builds/custom' 'system:authenticated'
6362
os::cmd::expect_success_and_text 'oadm policy who-can create builds/source' 'system:authenticated'
6463
os::cmd::expect_success_and_text 'oadm policy who-can create builds/jenkinspipeline' 'system:authenticated'
6564
# if this method for removing access to docker/custom/source/jenkinspipeline builds changes, docs need to be updated as well
66-
os::cmd::expect_success 'oadm policy remove-cluster-role-from-group system:build-strategy-custom system:authenticated'
6765
os::cmd::expect_success 'oadm policy remove-cluster-role-from-group system:build-strategy-docker system:authenticated'
6866
os::cmd::expect_success 'oadm policy remove-cluster-role-from-group system:build-strategy-source system:authenticated'
6967
os::cmd::expect_success 'oadm policy remove-cluster-role-from-group system:build-strategy-jenkinspipeline system:authenticated'
7068
# ensure build strategy permissions no longer exist
7169
os::cmd::try_until_failure 'oadm policy who-can create builds/source | grep system:authenticated'
7270
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/docker' 'system:authenticated'
73-
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/custom' 'system:authenticated'
7471
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/source' 'system:authenticated'
7572
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/jenkinspipeline' 'system:authenticated'
76-
os::cmd::expect_success 'oadm policy reconcile-cluster-role-bindings --confirm'
7773

74+
# ensure system:authenticated users can not create custom builds by default, but can if explicitly granted access
75+
os::cmd::expect_success_and_not_text 'oadm policy who-can create builds/custom' 'system:authenticated'
76+
os::cmd::expect_success 'oadm policy add-cluster-role-to-group system:build-strategy-custom system:authenticated'
77+
os::cmd::expect_success_and_text 'oadm policy who-can create builds/custom' 'system:authenticated'
78+
79+
os::cmd::expect_success 'oadm policy reconcile-cluster-role-bindings --confirm'
7880

7981
os::cmd::expect_success_and_text 'oc policy can-i --list' 'get update.*imagestreams/layers'
8082
os::cmd::expect_success_and_text 'oc policy can-i create pods --all-namespaces' 'yes'

test/integration/build_admission_test.go

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,44 @@ import (
1515
testserver "github.com/openshift/origin/test/util/server"
1616
)
1717

18+
// all build strategy types
19+
func buildStrategyTypes() []string {
20+
return []string{"source", "docker", "custom", "jenkinspipeline"}
21+
}
22+
23+
// build strategy types that are not granted by default to system:authenticated
24+
func buildStrategyTypesRestricted() []string {
25+
return []string{"custom"}
26+
}
27+
1828
func TestPolicyBasedRestrictionOfBuildCreateAndCloneByStrategy(t *testing.T) {
1929
defer testutil.DumpEtcdOnFailure(t)
2030
clusterAdminClient, projectAdminClient, projectEditorClient := setupBuildStrategyTest(t, false)
2131

2232
clients := map[string]*client.Client{"admin": projectAdminClient, "editor": projectEditorClient}
2333
builds := map[string]*buildapi.Build{}
2434

35+
restrictedStrategies := make(map[string]int)
36+
for key, val := range buildStrategyTypesRestricted() {
37+
restrictedStrategies[val] = key
38+
}
39+
40+
// ensure that restricted strategy types can not be created
41+
for _, strategy := range buildStrategyTypes() {
42+
for clientType, client := range clients {
43+
var err error
44+
builds[string(strategy)+clientType], err = createBuild(t, client.Builds(testutil.Namespace()), strategy)
45+
_, restricted := restrictedStrategies[strategy]
46+
if kapierror.IsForbidden(err) && !restricted {
47+
t.Errorf("unexpected error for strategy %s and client %s: %v", strategy, clientType, err)
48+
} else if !kapierror.IsForbidden(err) && restricted {
49+
t.Errorf("expected forbidden for strategy %s and client %s: Got success instead ", strategy, clientType)
50+
}
51+
}
52+
}
53+
54+
grantRestrictedBuildStrategyRoleResources(t, clusterAdminClient, projectAdminClient, projectEditorClient)
55+
2556
// Create builds to setup test
2657
for _, strategy := range buildStrategyTypes() {
2758
for clientType, client := range clients {
@@ -40,7 +71,6 @@ func TestPolicyBasedRestrictionOfBuildCreateAndCloneByStrategy(t *testing.T) {
4071
}
4172
}
4273
}
43-
4474
removeBuildStrategyRoleResources(t, clusterAdminClient, projectAdminClient, projectEditorClient)
4575

4676
// make sure builds are rejected
@@ -77,8 +107,28 @@ func TestPolicyBasedRestrictionOfBuildConfigCreateAndInstantiateByStrategy(t *te
77107

78108
clients := map[string]*client.Client{"admin": projectAdminClient, "editor": projectEditorClient}
79109
buildConfigs := map[string]*buildapi.BuildConfig{}
110+
restrictedStrategies := make(map[string]int)
111+
for key, val := range buildStrategyTypesRestricted() {
112+
restrictedStrategies[val] = key
113+
}
80114

81-
// by default admins and editors can create all type of buildconfigs
115+
// ensure that restricted strategy types can not be created
116+
for _, strategy := range buildStrategyTypes() {
117+
for clientType, client := range clients {
118+
var err error
119+
buildConfigs[string(strategy)+clientType], err = createBuildConfig(t, client.BuildConfigs(testutil.Namespace()), strategy)
120+
_, restricted := restrictedStrategies[strategy]
121+
if kapierror.IsForbidden(err) && !restricted {
122+
t.Errorf("unexpected error for strategy %s and client %s: %v", strategy, clientType, err)
123+
} else if !kapierror.IsForbidden(err) && restricted {
124+
t.Errorf("expected forbidden for strategy %s and client %s: Got success instead ", strategy, clientType)
125+
}
126+
}
127+
}
128+
129+
grantRestrictedBuildStrategyRoleResources(t, clusterAdminClient, projectAdminClient, projectEditorClient)
130+
131+
// by default admins and editors can create source, docker, and jenkinspipline buildconfigs
82132
for _, strategy := range buildStrategyTypes() {
83133
for clientType, client := range clients {
84134
var err error
@@ -127,10 +177,6 @@ func TestPolicyBasedRestrictionOfBuildConfigCreateAndInstantiateByStrategy(t *te
127177
}
128178
}
129179

130-
func buildStrategyTypes() []string {
131-
return []string{"source", "docker", "custom", "jenkinspipeline"}
132-
}
133-
134180
func setupBuildStrategyTest(t *testing.T, includeControllers bool) (clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) {
135181
testutil.RequireEtcd(t)
136182
namespace := testutil.Namespace()
@@ -202,13 +248,13 @@ func setupBuildStrategyTest(t *testing.T, includeControllers bool) (clusterAdmin
202248
func removeBuildStrategyRoleResources(t *testing.T, clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) {
203249
// remove resources from role so that certain build strategies are forbidden
204250
for _, role := range []string{bootstrappolicy.BuildStrategyCustomRoleName, bootstrappolicy.BuildStrategyDockerRoleName, bootstrappolicy.BuildStrategySourceRoleName, bootstrappolicy.BuildStrategyJenkinsPipelineRoleName} {
205-
remove := &policy.RoleModificationOptions{
251+
options := &policy.RoleModificationOptions{
206252
RoleNamespace: "",
207253
RoleName: role,
208254
RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient),
209255
Groups: []string{"system:authenticated"},
210256
}
211-
if err := remove.RemoveRole(); err != nil {
257+
if err := options.RemoveRole(); err != nil {
212258
t.Fatalf("unexpected error: %v", err)
213259
}
214260
}
@@ -227,6 +273,25 @@ func removeBuildStrategyRoleResources(t *testing.T, clusterAdminClient, projectA
227273
}
228274
}
229275

276+
func grantRestrictedBuildStrategyRoleResources(t *testing.T, clusterAdminClient, projectAdminClient, projectEditorClient *client.Client) {
277+
// grant resources to role so that restricted build strategies are available
278+
for _, role := range []string{bootstrappolicy.BuildStrategyCustomRoleName} {
279+
options := &policy.RoleModificationOptions{
280+
RoleNamespace: "",
281+
RoleName: role,
282+
RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient),
283+
Groups: []string{"system:authenticated"},
284+
}
285+
if err := options.AddRole(); err != nil {
286+
t.Fatalf("unexpected error: %v", err)
287+
}
288+
}
289+
290+
if err := testutil.WaitForPolicyUpdate(projectEditorClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.CustomBuildResource), true); err != nil {
291+
t.Fatal(err)
292+
}
293+
}
294+
230295
func strategyForType(t *testing.T, strategy string) buildapi.BuildStrategy {
231296
buildStrategy := buildapi.BuildStrategy{}
232297
switch strategy {

test/integration/imagechange_buildtrigger_test.go

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package integration
22

33
import (
4-
"testing"
5-
6-
kapi "k8s.io/kubernetes/pkg/api"
7-
watchapi "k8s.io/kubernetes/pkg/watch"
8-
4+
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
95
buildapi "github.com/openshift/origin/pkg/build/api"
106
"github.com/openshift/origin/pkg/client"
7+
"github.com/openshift/origin/pkg/cmd/admin/policy"
8+
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
119
imageapi "github.com/openshift/origin/pkg/image/api"
1210
testutil "github.com/openshift/origin/test/util"
1311
testserver "github.com/openshift/origin/test/util/server"
12+
kapi "k8s.io/kubernetes/pkg/api"
13+
watchapi "k8s.io/kubernetes/pkg/watch"
14+
"testing"
1415
)
1516

1617
const (
@@ -20,7 +21,7 @@ const (
2021

2122
func TestSimpleImageChangeBuildTriggerFromImageStreamTagSTI(t *testing.T) {
2223
defer testutil.DumpEtcdOnFailure(t)
23-
projectAdminClient := setup(t)
24+
projectAdminClient, _ := setup(t)
2425
imageStream := mockImageStream2(tag)
2526
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
2627
strategy := stiStrategy("ImageStreamTag", streamName+":"+tag)
@@ -30,7 +31,7 @@ func TestSimpleImageChangeBuildTriggerFromImageStreamTagSTI(t *testing.T) {
3031

3132
func TestSimpleImageChangeBuildTriggerFromImageStreamTagSTIWithConfigChange(t *testing.T) {
3233
defer testutil.DumpEtcdOnFailure(t)
33-
projectAdminClient := setup(t)
34+
projectAdminClient, _ := setup(t)
3435
imageStream := mockImageStream2(tag)
3536
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
3637
strategy := stiStrategy("ImageStreamTag", streamName+":"+tag)
@@ -40,7 +41,7 @@ func TestSimpleImageChangeBuildTriggerFromImageStreamTagSTIWithConfigChange(t *t
4041

4142
func TestSimpleImageChangeBuildTriggerFromImageStreamTagDocker(t *testing.T) {
4243
defer testutil.DumpEtcdOnFailure(t)
43-
projectAdminClient := setup(t)
44+
projectAdminClient, _ := setup(t)
4445
imageStream := mockImageStream2(tag)
4546
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
4647
strategy := dockerStrategy("ImageStreamTag", streamName+":"+tag)
@@ -50,7 +51,7 @@ func TestSimpleImageChangeBuildTriggerFromImageStreamTagDocker(t *testing.T) {
5051

5152
func TestSimpleImageChangeBuildTriggerFromImageStreamTagDockerWithConfigChange(t *testing.T) {
5253
defer testutil.DumpEtcdOnFailure(t)
53-
projectAdminClient := setup(t)
54+
projectAdminClient, _ := setup(t)
5455
imageStream := mockImageStream2(tag)
5556
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
5657
strategy := dockerStrategy("ImageStreamTag", streamName+":"+tag)
@@ -60,7 +61,27 @@ func TestSimpleImageChangeBuildTriggerFromImageStreamTagDockerWithConfigChange(t
6061

6162
func TestSimpleImageChangeBuildTriggerFromImageStreamTagCustom(t *testing.T) {
6263
defer testutil.DumpEtcdOnFailure(t)
63-
projectAdminClient := setup(t)
64+
projectAdminClient, clusterAdminClient := setup(t)
65+
66+
clusterRoleBindingAccessor := policy.NewClusterRoleBindingAccessor(clusterAdminClient)
67+
subjects := []kapi.ObjectReference{
68+
{
69+
Kind: authorizationapi.SystemGroupKind,
70+
Name: bootstrappolicy.AuthenticatedGroup,
71+
},
72+
}
73+
options := policy.RoleModificationOptions{
74+
RoleNamespace: testutil.Namespace(),
75+
RoleName: bootstrappolicy.BuildStrategyCustomRoleName,
76+
RoleBindingAccessor: clusterRoleBindingAccessor,
77+
Subjects: subjects,
78+
}
79+
options.AddRole()
80+
81+
if err := testutil.WaitForPolicyUpdate(projectAdminClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.CustomBuildResource), true); err != nil {
82+
t.Fatal(err)
83+
}
84+
6485
imageStream := mockImageStream2(tag)
6586
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
6687
strategy := customStrategy("ImageStreamTag", streamName+":"+tag)
@@ -70,7 +91,31 @@ func TestSimpleImageChangeBuildTriggerFromImageStreamTagCustom(t *testing.T) {
7091

7192
func TestSimpleImageChangeBuildTriggerFromImageStreamTagCustomWithConfigChange(t *testing.T) {
7293
defer testutil.DumpEtcdOnFailure(t)
73-
projectAdminClient := setup(t)
94+
projectAdminClient, _ := setup(t)
95+
96+
clusterAdminClient, err := testutil.GetClusterAdminClient(testutil.GetBaseDir() + "/openshift.local.config/master/admin.kubeconfig")
97+
if err != nil {
98+
t.Fatalf("unexpected error: %v", err)
99+
}
100+
clusterRoleBindingAccessor := policy.NewClusterRoleBindingAccessor(clusterAdminClient)
101+
subjects := []kapi.ObjectReference{
102+
{
103+
Kind: authorizationapi.SystemGroupKind,
104+
Name: bootstrappolicy.AuthenticatedGroup,
105+
},
106+
}
107+
options := policy.RoleModificationOptions{
108+
RoleNamespace: testutil.Namespace(),
109+
RoleName: bootstrappolicy.BuildStrategyCustomRoleName,
110+
RoleBindingAccessor: clusterRoleBindingAccessor,
111+
Subjects: subjects,
112+
}
113+
options.AddRole()
114+
115+
if err := testutil.WaitForPolicyUpdate(projectAdminClient, testutil.Namespace(), "create", buildapi.Resource(authorizationapi.CustomBuildResource), true); err != nil {
116+
t.Fatal(err)
117+
}
118+
74119
imageStream := mockImageStream2(tag)
75120
imageStreamMapping := mockImageStreamMapping(imageStream.Name, "someimage", tag, "registry:8080/openshift/test-image-trigger:"+tag)
76121
strategy := customStrategy("ImageStreamTag", streamName+":"+tag)
@@ -181,7 +226,7 @@ func mockImageStreamMapping(stream, image, tag, reference string) *imageapi.Imag
181226
}
182227
}
183228

184-
func setup(t *testing.T) *client.Client {
229+
func setup(t *testing.T) (*client.Client, *client.Client) {
185230
testutil.RequireEtcd(t)
186231
_, clusterAdminKubeConfigFile, err := testserver.StartTestMaster()
187232
if err != nil {
@@ -203,7 +248,7 @@ func setup(t *testing.T) *client.Client {
203248
t.Fatalf("unexpected error: %v", err)
204249
}
205250

206-
return projectAdminClient
251+
return projectAdminClient, clusterAdminClient
207252
}
208253

209254
func runTest(t *testing.T, testname string, projectAdminClient *client.Client, imageStream *imageapi.ImageStream, imageStreamMapping *imageapi.ImageStreamMapping, config *buildapi.BuildConfig, tag string) {
@@ -429,7 +474,7 @@ func TestMultipleImageChangeBuildTriggers(t *testing.T) {
429474
}
430475
return bc
431476
}
432-
projectAdminClient := setup(t)
477+
projectAdminClient, _ := setup(t)
433478
config := multipleImageChangeBuildConfig()
434479
triggersToTest := []struct {
435480
triggerIndex int

test/testdata/bootstrappolicy/bootstrap_cluster_role_bindings.yaml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -242,19 +242,6 @@ items:
242242
- kind: SystemGroup
243243
name: system:authenticated
244244
userNames: null
245-
- apiVersion: v1
246-
groupNames:
247-
- system:authenticated
248-
kind: ClusterRoleBinding
249-
metadata:
250-
creationTimestamp: null
251-
name: system:build-strategy-custom-binding
252-
roleRef:
253-
name: system:build-strategy-custom
254-
subjects:
255-
- kind: SystemGroup
256-
name: system:authenticated
257-
userNames: null
258245
- apiVersion: v1
259246
groupNames:
260247
- system:authenticated

0 commit comments

Comments
 (0)