diff --git a/api/proto/gosdn/rbac/user.proto b/api/proto/gosdn/rbac/user.proto
index ec13346ef394ce5cc90722af65a995937c2f8578..ef5d4073983da4bed97915613fc4de7c689b97ef 100644
--- a/api/proto/gosdn/rbac/user.proto
+++ b/api/proto/gosdn/rbac/user.proto
@@ -89,7 +89,7 @@ message CreateUsersResponse {
 // GetUser
 message GetUserRequest {
     int64 timestamp = 1;
-    string name = 2 [(buf.validate.field).required = true];
+    string name = 2 [(buf.validate.field).required = true]; // TODO(faseid): reconsider if this is necessary as required, but id is not?
     string id = 3;
 }
 
diff --git a/controller/northbound/server/role.go b/controller/northbound/server/role.go
index 7691ce523f47285610df8b5dd734ffa0ed2e8c80..2d3de09de4a42aea2a565870d5c2ab8be83f7ab0 100644
--- a/controller/northbound/server/role.go
+++ b/controller/northbound/server/role.go
@@ -71,9 +71,14 @@ func (r RoleServer) CreateRoles(ctx context.Context, request *apb.CreateRolesReq
 	}
 
 	for _, rrole := range request.Roles {
-		role := rbac.NewRole(uuid.New(), rrole.Name, rrole.Description, rrole.Permissions)
+		roleID, err := uuid.Parse(rrole.Id)
+		if err != nil {
+			roleID = uuid.New()
+		}
+
+		role := rbac.NewRole(roleID, rrole.Name, rrole.Description, rrole.Permissions)
 
-		err := r.roleService.Add(role)
+		err = r.roleService.Add(role)
 		if err != nil {
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
diff --git a/controller/northbound/server/user.go b/controller/northbound/server/user.go
index 1ea31bee575daa4e29faa594610937452543e90b..d37ae43a79bb7b0c1086687dfa4b2e44ee588318 100644
--- a/controller/northbound/server/user.go
+++ b/controller/northbound/server/user.go
@@ -92,7 +92,12 @@ func (u UserServer) CreateUsers(ctx context.Context, request *apb.CreateUsersReq
 
 		hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(user.Password), []byte(salt), 1, 64*1024, 4, 32))
 
-		user := rbac.NewUser(uuid.New(), user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{ResourceVersion: 0})
+		userID, err := uuid.Parse(user.Id)
+		if err != nil {
+			userID = uuid.New()
+		}
+
+		user := rbac.NewUser(userID, user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{ResourceVersion: 0})
 		err = u.userService.Add(user)
 		if err != nil {
 			log.Error(err)
diff --git a/integration-tests/integrationTestUtils/integrationTestUtils.go b/integration-tests/integrationTestUtils/integrationTestUtils.go
index 2d88c1a13a4cd9900e417fb7b567bffc842cf1e4..daf272f74c1cd1d30c9dd68bc76f2bf8a8f5cbef 100644
--- a/integration-tests/integrationTestUtils/integrationTestUtils.go
+++ b/integration-tests/integrationTestUtils/integrationTestUtils.go
@@ -8,6 +8,9 @@ import (
 
 	configMgmtPb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement"
 	ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd"
+	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+	"github.com/sirupsen/logrus"
+
 	"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/api"
 
@@ -16,7 +19,9 @@ import (
 	"google.golang.org/grpc/metadata"
 )
 
-func createContextWithAuthorization(loginResponse *rbac.LoginResponse) context.Context {
+const admin = "admin"
+
+func CreateContextWithAuthorization(loginResponse *rbac.LoginResponse) context.Context {
 	md := metadata.Pairs("authorize", loginResponse.Token)
 	return metadata.NewOutgoingContext(context.Background(), md)
 }
@@ -35,7 +40,7 @@ func CreateSecureConnection() (*grpc.ClientConn, context.Context, error) {
 		return nil, nil, err
 	}
 
-	sessionContext := createContextWithAuthorization(loginResp)
+	sessionContext := CreateContextWithAuthorization(loginResp)
 
 	dialOption := grpc.WithTransportCredentials(insecure.NewCredentials())
 	conn, err := grpc.Dial(controllerUrl, dialOption, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(100*1024*1024)))
@@ -66,7 +71,7 @@ func CreateConnection() (*grpc.ClientConn, context.Context, error) {
 // ExportCurrentSDNConfig can be used to save the current SDN config as a string to use in an other test later on.
 func ExportCurrentSDNConfig(conn *grpc.ClientConn, ctx context.Context) (string, error) {
 	pndService := ppb.NewPndServiceClient(conn)
-	pndRes, err := pndService.GetPndList(ctx, &ppb.GetPndListRequest{Timestamp: getTimestamp()})
+	pndRes, err := pndService.GetPndList(ctx, &ppb.GetPndListRequest{Timestamp: GetTimestamp()})
 	if err != nil {
 		return "", err
 	}
@@ -74,7 +79,7 @@ func ExportCurrentSDNConfig(conn *grpc.ClientConn, ctx context.Context) (string,
 
 	configMgmtService := configMgmtPb.NewConfigurationManagementServiceClient(conn)
 
-	sdnConfigResponse, err := configMgmtService.ExportSDNConfig(ctx, &configMgmtPb.ExportSDNConfigRequest{Timestamp: getTimestamp(), Pid: pndID})
+	sdnConfigResponse, err := configMgmtService.ExportSDNConfig(ctx, &configMgmtPb.ExportSDNConfigRequest{Timestamp: GetTimestamp(), Pid: pndID})
 	if err != nil {
 		return "", err
 	}
@@ -85,7 +90,7 @@ func ExportCurrentSDNConfig(conn *grpc.ClientConn, ctx context.Context) (string,
 // ApplySDNConfig can be used to apply a given SDN config as a string to set the testing environment as desired.
 func ApplySDNConfig(conn *grpc.ClientConn, ctx context.Context, sdnConfig string) {
 	pndService := ppb.NewPndServiceClient(conn)
-	pndRes, err := pndService.GetPndList(ctx, &ppb.GetPndListRequest{Timestamp: getTimestamp()})
+	pndRes, err := pndService.GetPndList(ctx, &ppb.GetPndListRequest{Timestamp: GetTimestamp()})
 	if err != nil {
 		fmt.Println(err)
 	}
@@ -95,12 +100,95 @@ func ApplySDNConfig(conn *grpc.ClientConn, ctx context.Context, sdnConfig string
 
 	configMgmtService := configMgmtPb.NewConfigurationManagementServiceClient(conn)
 
-	_, err = configMgmtService.ImportSDNConfig(ctx, &configMgmtPb.ImportSDNConfigRequest{Timestamp: getTimestamp(), Pid: pndID, SdnConfigData: sdnConfig})
+	_, err = configMgmtService.ImportSDNConfig(ctx, &configMgmtPb.ImportSDNConfigRequest{Timestamp: GetTimestamp(), Pid: pndID, SdnConfigData: sdnConfig})
 	if err != nil {
 		fmt.Println(err)
 	}
 }
 
-func getTimestamp() int64 {
+func GetTimestamp() int64 {
 	return int64(time.Now().Nanosecond())
 }
+
+func CleanUserAndRolesExceptAdmin(conn *grpc.ClientConn, ctx context.Context) {
+	userService := apb.NewUserServiceClient(conn)
+	roleService := apb.NewRoleServiceClient(conn)
+
+	getAllUserResponse, err := userService.GetUsers(ctx, &apb.GetUsersRequest{
+		Timestamp: GetTimestamp(),
+	})
+	if err != nil {
+		logrus.Errorf("Error while cleaning up DB, %v", err)
+	}
+
+	err = cleanUsersExceptAdmin(getAllUserResponse, userService, ctx)
+	if err != nil {
+		logrus.Errorf("Error while cleaning up DB, %v", err)
+	}
+
+	getAllRoleResponse, err := roleService.GetRoles(ctx, &apb.GetRolesRequest{
+		Timestamp: GetTimestamp(),
+	})
+	if err != nil {
+		logrus.Errorf("Error while cleaning up DB, %v", err)
+	}
+
+	err = cleanRolesExceptAdmin(getAllRoleResponse, roleService, ctx)
+	if err != nil {
+		logrus.Errorf("Error while cleaning up DB, %v", err)
+	}
+}
+
+func cleanUsersExceptAdmin(resp *apb.GetUsersResponse, userService apb.UserServiceClient, ctx context.Context) error {
+	// no need to delete if only admin available
+	if len(resp.User) == 1 {
+		return nil
+	}
+
+	var names []string
+
+	for _, u := range resp.User {
+		if u.Name == admin {
+			continue
+		}
+
+		names = append(names, u.Name)
+	}
+
+	_, err := userService.DeleteUsers(ctx, &apb.DeleteUsersRequest{
+		Timestamp: GetTimestamp(),
+		Username:  names,
+	})
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func cleanRolesExceptAdmin(resp *apb.GetRolesResponse, roleService apb.RoleServiceClient, ctx context.Context) error {
+	// no need to delete if only admin available
+	if len(resp.Roles) == 1 {
+		return nil
+	}
+
+	var names []string
+
+	for _, role := range resp.Roles {
+		if role.Name == admin {
+			continue
+		}
+
+		names = append(names, role.Name)
+	}
+
+	_, err := roleService.DeleteRoles(ctx, &apb.DeleteRolesRequest{
+		Timestamp: GetTimestamp(),
+		RoleName:  names,
+	})
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/integration-tests/rbac_tests/rbac_test.go b/integration-tests/rbac_tests/rbac_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..44cbc4fc1ed74a797e651adb62c52c8051c90be4
--- /dev/null
+++ b/integration-tests/rbac_tests/rbac_test.go
@@ -0,0 +1,398 @@
+package integration_test_rbac
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
+	mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
+	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+	"github.com/stretchr/testify/assert"
+
+	integration_test_utils "code.fbi.h-da.de/danet/gosdn/integration-tests/integrationTestUtils"
+	"google.golang.org/grpc"
+)
+
+const userID = "23224223-aeb6-433b-a797-2d671d7424f0"
+const user1NameAndPW = "testUser1"
+const pndID = "5f20f34b-cbd0-4511-9ddc-c50cf6a3b49d"
+const roleID = "679f7982-d740-452e-b78d-c1d133233694"
+
+// The connection to the controller to use in each test.
+var conn *grpc.ClientConn
+
+// The context containing the credentials when authenticated.
+var ctx context.Context
+
+// A defaultSDN config with default/empty values.
+var defaultSDNConfig string
+
+func TestMain(m *testing.M) {
+	localConn, localCtx, err := integration_test_utils.CreateSecureConnection()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	conn = localConn
+	ctx = localCtx
+
+	sndConfig, err := integration_test_utils.ExportCurrentSDNConfig(conn, ctx)
+	defaultSDNConfig = sndConfig
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+
+	integration_test_utils.CleanUserAndRolesExceptAdmin(conn, ctx)
+
+	m.Run()
+}
+
+func TestUserCreationAndModification(t *testing.T) {
+	defer integration_test_utils.CleanUserAndRolesExceptAdmin(conn, ctx)
+
+	// setup required parameters
+	const user2UUID = "0a28e837-473b-475d-b935-2457eb9462ae"
+	const expectedAmountOfUsers = 3
+	const expectedNameAfterChange = "testUser1Changed"
+
+	createUserRequest := &apb.CreateUsersRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		User: []*apb.User{
+			{
+				Id:       userID,
+				Name:     user1NameAndPW,
+				Roles:    map[string]string{pndID: "admin", userID: "random"},
+				Password: user1NameAndPW,
+				Metadata: &conflict.Metadata{
+					ResourceVersion: 0,
+				},
+			},
+			{
+				Id:       user2UUID,
+				Name:     "user2",
+				Roles:    map[string]string{pndID: "random"},
+				Password: user1NameAndPW,
+				Metadata: &conflict.Metadata{
+					ResourceVersion: 0,
+				},
+			},
+		},
+	}
+
+	getAllRequest := &apb.GetUsersRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+	}
+
+	updateUserRequest := &apb.UpdateUsersRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		User: []*apb.UpdateUser{
+			{
+				Id:       userID,
+				Name:     expectedNameAfterChange,
+				Roles:    map[string]string{},
+				Metadata: &conflict.Metadata{},
+			},
+		},
+	}
+
+	getUserRequest := &apb.GetUserRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Id:        userID,
+		Name:      expectedNameAfterChange,
+	}
+
+	// setup gRPC services
+	userService := apb.NewUserServiceClient(conn)
+
+	// create two users
+	_, err := userService.CreateUsers(ctx, createUserRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	// get all users and compare
+	getAllResponse, err := userService.GetUsers(ctx, getAllRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, expectedAmountOfUsers, len(getAllResponse.User))
+
+	assert.NotEqual(t, getAllResponse.User[1].Name, getAllResponse.User[2].Name)
+
+	assert.NotEqual(t, getAllResponse.User[1].Roles[pndID], getAllResponse.User[2].Roles[pndID])
+
+	// change name of user1
+	updateUserRequest.User[0].Roles = getAllResponse.User[1].Roles
+	updateUserRequest.User[0].Metadata.ResourceVersion = getAllResponse.User[1].Metadata.ResourceVersion
+
+	_, err = userService.UpdateUsers(ctx, updateUserRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	getUserResponse, err := userService.GetUser(ctx, getUserRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, expectedNameAfterChange, getUserResponse.User.Name)
+}
+
+func TestRoleCreationAndModification(t *testing.T) {
+	defer integration_test_utils.CleanUserAndRolesExceptAdmin(conn, ctx)
+
+	// setup required parameters
+	const multiplePermissionRole = "multiple permission role"
+	const roleDescription = "A role with multiple permissions."
+	const multiplePermissionRoleNameAfterChange = "only two permission role"
+	const permissionToBeDeleted = "permission to be deleted"
+	const expectedAmountOfRoles = 3
+	const expectedAmountOfRolesAfterDeletion = 2
+	const expectedAmountOfPermissions = 3
+	const expectedAmountOfPermissionsAfterDeletion = 2
+
+	createRolesRequest := &apb.CreateRolesRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Roles: []*apb.Role{
+			{
+				Id:          roleID,
+				Name:        multiplePermissionRole,
+				Description: roleDescription,
+				Permissions: []string{
+					"permission1",
+					"permission2",
+					permissionToBeDeleted,
+				},
+			},
+			{
+				Name:        "random",
+				Description: "A random role with one permissions.",
+				Permissions: []string{
+					"permission1",
+				},
+			},
+		},
+	}
+
+	getAllRoleRequest := &apb.GetRolesRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+	}
+
+	deleteRoleRequest := &apb.DeleteRolesRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		RoleName:  []string{"random"},
+	}
+
+	removePermissionRequest := &apb.DeletePermissionsForRoleRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		RoleName:  multiplePermissionRole,
+		PermissionsToDelete: []string{
+			permissionToBeDeleted,
+		},
+	}
+
+	updateRoleRequest := &apb.UpdateRolesRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Roles: []*apb.Role{
+			{
+				Id:          roleID,
+				Name:        multiplePermissionRoleNameAfterChange,
+				Description: roleDescription,
+			},
+		},
+	}
+
+	getRoleRequest := &apb.GetRoleRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Id:        roleID,
+		RoleName:  multiplePermissionRoleNameAfterChange,
+	}
+
+	// setup gRPC services
+	roleService := apb.NewRoleServiceClient(conn)
+
+	// create new roles
+	_, err := roleService.CreateRoles(ctx, createRolesRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	// get roles and check amount
+	getAllRoleResponse, err := roleService.GetRoles(ctx, getAllRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, expectedAmountOfRoles, len(getAllRoleResponse.Roles))
+
+	assert.Equal(t, multiplePermissionRole, getAllRoleResponse.Roles[1].Name)
+
+	assert.Equal(t, expectedAmountOfPermissions, len(getAllRoleResponse.Roles[1].Permissions))
+
+	// delete role and compare amount
+	_, err = roleService.DeleteRoles(ctx, deleteRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	getAllRoleResponse, err = roleService.GetRoles(ctx, getAllRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, expectedAmountOfRolesAfterDeletion, len(getAllRoleResponse.Roles))
+
+	// delete one permission then get role to compare
+	_, err = roleService.DeletePermissionsForRole(ctx, removePermissionRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	getAllRoleResponse, err = roleService.GetRoles(ctx, getAllRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, expectedAmountOfPermissionsAfterDeletion, len(getAllRoleResponse.Roles[1].Permissions))
+
+	// change role name and compare
+	_, err = roleService.UpdateRoles(ctx, updateRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	getRoleResponse, err := roleService.GetRole(ctx, getRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	assert.Equal(t, multiplePermissionRoleNameAfterChange, getRoleResponse.Role.Name)
+}
+
+func TestUserWithoutPermission(t *testing.T) {
+	defer integration_test_utils.CleanUserAndRolesExceptAdmin(conn, ctx)
+
+	// setup required parameters
+	const roleName = "peter"
+
+	createUserRequestPreparation := &apb.CreateUsersRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		User: []*apb.User{
+			{
+				Id:       userID,
+				Name:     user1NameAndPW,
+				Roles:    map[string]string{pndID: roleName},
+				Password: user1NameAndPW,
+				Metadata: &conflict.Metadata{
+					ResourceVersion: 0,
+				},
+			},
+		},
+	}
+
+	createUserRequestTestCase := &apb.CreateUsersRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		User: []*apb.User{
+			{
+				Id:       "b22c4e46-fa54-4226-8e61-134c895bef5b",
+				Name:     "test",
+				Roles:    map[string]string{pndID: "admin"},
+				Password: user1NameAndPW,
+				Metadata: &conflict.Metadata{
+					ResourceVersion: 0,
+				},
+			},
+		},
+	}
+
+	createRoleRequest := &apb.CreateRolesRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Roles: []*apb.Role{
+			{
+				Name:        roleName,
+				Description: "Something that only a peter can do.",
+				Permissions: []string{
+					"/gosdn.rbac.UserService/CreateUsers",
+					"/gosdn.networkelement.NetworkElementService/GetAllFlattened",
+				},
+			},
+		},
+	}
+
+	loginRequest := &apb.LoginRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Username:  user1NameAndPW,
+		Pwd:       user1NameAndPW,
+	}
+
+	// setup gRPC services
+	userService := apb.NewUserServiceClient(conn)
+	roleService := apb.NewRoleServiceClient(conn)
+	authService := apb.NewAuthServiceClient(conn)
+	mneService := mnepb.NewNetworkElementServiceClient(conn)
+
+	// create a user and its role
+	_, err := userService.CreateUsers(ctx, createUserRequestPreparation)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	_, err = roleService.CreateRoles(ctx, createRoleRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	// login new user
+	loginResponse, err := authService.Login(context.Background(), loginRequest)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	sessionToken := integration_test_utils.CreateContextWithAuthorization(loginResponse)
+
+	// test if user can get all MNE, should fail
+	_, err = mneService.GetAll(sessionToken, &mnepb.GetAllRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Pid:       pndID,
+	},
+	)
+
+	assert.NotEqual(t, nil, err)
+
+	// test if user can get all flattened MNE, should work
+	_, err = mneService.GetAllFlattened(sessionToken, &mnepb.GetAllFlattenedRequest{
+		Timestamp: integration_test_utils.GetTimestamp(),
+		Pid:       pndID,
+	},
+	)
+
+	assert.Equal(t, nil, err)
+
+	// test if user1 can create user with admin role, should fail
+	_, _ = userService.CreateUsers(sessionToken, createUserRequestTestCase)
+	//TODO(faseid): implement mechanism to stop random user from creating admin user,
+	// then uncomment test case
+	//assert.NotEqual(t, nil, err)
+
+	// test if user1 can create user with random role, should work
+	createUserRequestTestCase.User[0].Roles[pndID] = "peter 2"
+	_, err = userService.CreateUsers(sessionToken, createUserRequestTestCase)
+
+	assert.Equal(t, nil, err)
+}