You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2021/12/29 01:28:51 UTC

[servicecomb-service-center] branch master updated: Optimize: refactor rbac datasource interface (#1189)

This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new 7243b23  Optimize: refactor rbac datasource interface (#1189)
7243b23 is described below

commit 7243b23e6aed5ea789bb27f17faf8cd4df88a22a
Author: little-cui <su...@qq.com>
AuthorDate: Wed Dec 29 09:28:44 2021 +0800

    Optimize: refactor rbac datasource interface (#1189)
---
 datasource/account_test.go                         | 121 ---------------------
 datasource/datasource.go                           |   3 -
 datasource/etcd/account.go                         |  46 +++++---
 datasource/etcd/account_lock.go                    |  31 ++----
 datasource/etcd/etcd.go                            |  28 +----
 datasource/etcd/role.go                            |  31 +++---
 datasource/manager.go                              |  19 +---
 datasource/mongo/account.go                        |  40 ++++---
 datasource/mongo/account_lock.go                   |  33 +++---
 datasource/mongo/mongo.go                          |  28 +----
 datasource/mongo/role.go                           |  36 +++---
 datasource/{ => rbac}/account.go                   |  20 ++--
 datasource/rbac/account_test.go                    | 118 ++++++++++++++++++++
 datasource/{schema => rbac}/init.go                |  12 +-
 .../buildin/role.go => datasource/rbac/options.go  |  17 +--
 .../buildin/role.go => datasource/rbac/rbac.go     |  18 +--
 datasource/{ => rbac}/role.go                      |   2 +-
 datasource/{ => rbac}/role_test.go                 |  46 ++++----
 datasource/schema/init.go                          |   8 +-
 server/job/account/account_test.go                 |  18 +--
 server/plugin/quota/buildin/account.go             |   4 +-
 server/plugin/quota/buildin/role.go                |   4 +-
 server/resource/rbac/auth_resource.go              |  24 ++--
 server/resource/rbac/auth_resource_test.go         |   4 +-
 server/resource/rbac/role_resource_test.go         |  26 ++---
 server/service/account/account.go                  |  28 ++---
 server/service/account/account_test.go             |  42 +++----
 server/service/rbac/account_service.go             |  56 +++++-----
 server/service/rbac/blocker.go                     |   6 +-
 server/service/rbac/blocker_test.go                |  10 +-
 server/service/rbac/decision.go                    |  24 ++--
 server/service/rbac/perm_service.go                |  14 +--
 server/service/rbac/role_service.go                |  51 +++++----
 33 files changed, 447 insertions(+), 521 deletions(-)

diff --git a/datasource/account_test.go b/datasource/account_test.go
deleted file mode 100644
index a6e839b..0000000
--- a/datasource/account_test.go
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package datasource_test
-
-import (
-	"context"
-	"strconv"
-	"testing"
-	"time"
-
-	"github.com/go-chassis/cari/rbac"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-	"github.com/stretchr/testify/assert"
-)
-
-var (
-	a1 = rbac.Account{
-		ID:                  "11111-22222-33333",
-		Name:                "test-account1",
-		Password:            "tnuocca-tset",
-		Roles:               []string{"admin"},
-		TokenExpirationTime: "2020-12-30",
-		CurrentPassword:     "tnuocca-tset1",
-	}
-	a2 = rbac.Account{
-		ID:                  "11111-22222-33333-44444",
-		Name:                "test-account2",
-		Password:            "tnuocca-tset",
-		Roles:               []string{"admin"},
-		TokenExpirationTime: "2020-12-30",
-		CurrentPassword:     "tnuocca-tset2",
-	}
-)
-
-func TestAccount(t *testing.T) {
-	t.Run("add and get account", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a1)
-		assert.NoError(t, err)
-		err = datasource.GetAccountManager().CreateAccount(context.Background(), &a2)
-		assert.NoError(t, err)
-		r, err := datasource.GetAccountManager().GetAccount(context.Background(), a1.Name)
-		assert.NoError(t, err)
-		assert.Equal(t, a1, *r)
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a1.Name, a2.Name})
-		assert.NoError(t, err)
-	})
-	t.Run("account should exist", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a1)
-		assert.NoError(t, err)
-		exist, err := datasource.GetAccountManager().AccountExist(context.Background(), a1.Name)
-		assert.NoError(t, err)
-		assert.True(t, exist)
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a1.Name})
-		assert.NoError(t, err)
-	})
-	t.Run("delete account", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a2)
-		assert.NoError(t, err)
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a2.Name})
-		assert.NoError(t, err)
-	})
-	t.Run("add and update accounts then list", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a1)
-		assert.NoError(t, err)
-		err = datasource.GetAccountManager().CreateAccount(context.Background(), &a2)
-		assert.NoError(t, err)
-		a2.Password = "new-password"
-		err = datasource.GetAccountManager().UpdateAccount(context.Background(), a2.Name, &a2)
-		assert.NoError(t, err)
-		accounts, _, err := datasource.GetAccountManager().ListAccount(context.Background())
-		assert.NoError(t, err)
-		assert.GreaterOrEqual(t, len(accounts), 2)
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a1.Name})
-		assert.NoError(t, err)
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a2.Name})
-		assert.NoError(t, err)
-	})
-	t.Run("add and update accounts, should have create/update time", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a1)
-		assert.NoError(t, err)
-
-		r, err := datasource.GetAccountManager().GetAccount(context.Background(), a1.Name)
-		assert.NoError(t, err)
-		dt, _ := strconv.Atoi(r.CreateTime)
-		assert.Less(t, 0, dt)
-		assert.Equal(t, r.CreateTime, r.UpdateTime)
-
-		time.Sleep(time.Second)
-		a1.Password = "new-password"
-		err = datasource.GetAccountManager().UpdateAccount(context.Background(), a1.Name, &a1)
-		assert.NoError(t, err)
-
-		old, _ := strconv.Atoi(r.UpdateTime)
-		r, err = datasource.GetAccountManager().GetAccount(context.Background(), a1.Name)
-		assert.NoError(t, err)
-		last, _ := strconv.Atoi(r.UpdateTime)
-		assert.Less(t, old, last)
-		assert.NotEqual(t, r.CreateTime, r.UpdateTime)
-
-		_, err = datasource.GetAccountManager().DeleteAccount(context.Background(), []string{a1.Name})
-		assert.NoError(t, err)
-	})
-}
diff --git a/datasource/datasource.go b/datasource/datasource.go
index cc1efce..ae0727b 100644
--- a/datasource/datasource.go
+++ b/datasource/datasource.go
@@ -20,9 +20,6 @@ package datasource
 // DataSource is the DAO layer
 type DataSource interface {
 	SystemManager() SystemManager
-	AccountManager() AccountManager
-	AccountLockManager() AccountLockManager
-	RoleManager() RoleManager
 	DependencyManager() DependencyManager
 	MetadataManager() MetadataManager
 	SCManager() SCManager
diff --git a/datasource/etcd/account.go b/datasource/etcd/account.go
index 8159c7c..529e7e5 100644
--- a/datasource/etcd/account.go
+++ b/datasource/etcd/account.go
@@ -22,21 +22,31 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/etcdsync"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/privacy"
 	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 	"github.com/go-chassis/foundation/stringutil"
 	"github.com/little-cui/etcdadpt"
 )
 
-type AccountManager struct {
+func init() {
+	rbac.Install("etcd", NewRbacDAO)
+	rbac.Install("embeded_etcd", NewRbacDAO)
+	rbac.Install("embedded_etcd", NewRbacDAO)
 }
 
-func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) error {
+func NewRbacDAO(opts rbac.Options) (rbac.DAO, error) {
+	return &RbacDAO{}, nil
+}
+
+type RbacDAO struct {
+}
+
+func (ds *RbacDAO) CreateAccount(ctx context.Context, a *rbacmodel.Account) error {
 	lock, err := etcdsync.Lock("/account-creating/"+a.Name, -1, false)
 	if err != nil {
 		return fmt.Errorf("account %s is creating", a.Name)
@@ -53,7 +63,7 @@ func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) er
 		return err
 	}
 	if exist {
-		return datasource.ErrAccountDuplicated
+		return rbac.ErrAccountDuplicated
 	}
 	a.Password, err = privacy.ScryptPassword(a.Password)
 	if err != nil {
@@ -78,7 +88,7 @@ func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) er
 	log.Info("create new account: " + a.ID)
 	return nil
 }
-func GenAccountOpts(a *rbac.Account, action etcdadpt.Action) ([]etcdadpt.OpOptions, error) {
+func GenAccountOpts(a *rbacmodel.Account, action etcdadpt.Action) ([]etcdadpt.OpOptions, error) {
 	opts := make([]etcdadpt.OpOptions, 0)
 	value, err := json.Marshal(a)
 	if err != nil {
@@ -100,18 +110,18 @@ func GenAccountOpts(a *rbac.Account, action etcdadpt.Action) ([]etcdadpt.OpOptio
 
 	return opts, nil
 }
-func (ds *AccountManager) AccountExist(ctx context.Context, name string) (bool, error) {
+func (ds *RbacDAO) AccountExist(ctx context.Context, name string) (bool, error) {
 	return etcdadpt.Exist(ctx, path.GenerateRBACAccountKey(name))
 }
-func (ds *AccountManager) GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
+func (ds *RbacDAO) GetAccount(ctx context.Context, name string) (*rbacmodel.Account, error) {
 	kv, err := etcdadpt.Get(ctx, path.GenerateRBACAccountKey(name))
 	if err != nil {
 		return nil, err
 	}
 	if kv == nil {
-		return nil, datasource.ErrAccountNotExist
+		return nil, rbac.ErrAccountNotExist
 	}
-	account := &rbac.Account{}
+	account := &rbacmodel.Account{}
 	err = json.Unmarshal(kv.Value, account)
 	if err != nil {
 		log.Error("account info format invalid", err)
@@ -121,7 +131,7 @@ func (ds *AccountManager) GetAccount(ctx context.Context, name string) (*rbac.Ac
 	return account, nil
 }
 
-func (ds *AccountManager) compatibleOldVersionAccount(a *rbac.Account) {
+func (ds *RbacDAO) compatibleOldVersionAccount(a *rbacmodel.Account) {
 	// old version use Role, now use Roles
 	// Role/Roles will not exist at the same time
 	if len(a.Role) == 0 {
@@ -131,14 +141,14 @@ func (ds *AccountManager) compatibleOldVersionAccount(a *rbac.Account) {
 	a.Role = ""
 }
 
-func (ds *AccountManager) ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
+func (ds *RbacDAO) ListAccount(ctx context.Context) ([]*rbacmodel.Account, int64, error) {
 	kvs, n, err := etcdadpt.List(ctx, path.GenerateRBACAccountKey(""))
 	if err != nil {
 		return nil, 0, err
 	}
-	accounts := make([]*rbac.Account, 0, n)
+	accounts := make([]*rbacmodel.Account, 0, n)
 	for _, v := range kvs {
-		a := &rbac.Account{}
+		a := &rbacmodel.Account{}
 		err = json.Unmarshal(v.Value, a)
 		if err != nil {
 			log.Error("account info format invalid:", err)
@@ -150,7 +160,7 @@ func (ds *AccountManager) ListAccount(ctx context.Context) ([]*rbac.Account, int
 	}
 	return accounts, n, nil
 }
-func (ds *AccountManager) DeleteAccount(ctx context.Context, names []string) (bool, error) {
+func (ds *RbacDAO) DeleteAccount(ctx context.Context, names []string) (bool, error) {
 	if len(names) == 0 {
 		return false, nil
 	}
@@ -172,13 +182,13 @@ func (ds *AccountManager) DeleteAccount(ctx context.Context, names []string) (bo
 		}
 		err = etcdadpt.Txn(ctx, opts)
 		if err != nil {
-			log.Error(datasource.ErrDeleteAccountFailed.Error(), err)
+			log.Error(rbac.ErrDeleteAccountFailed.Error(), err)
 			return false, err
 		}
 	}
 	return true, nil
 }
-func (ds *AccountManager) UpdateAccount(ctx context.Context, name string, account *rbac.Account) error {
+func (ds *RbacDAO) UpdateAccount(ctx context.Context, name string, account *rbacmodel.Account) error {
 	var (
 		opts []etcdadpt.OpOptions
 		err  error
@@ -216,7 +226,7 @@ func (ds *AccountManager) UpdateAccount(ctx context.Context, name string, accoun
 	return err
 }
 
-func hasRole(account *rbac.Account, r string) bool {
+func hasRole(account *rbacmodel.Account, r string) bool {
 	for _, n := range account.Roles {
 		if r == n {
 			return true
diff --git a/datasource/etcd/account_lock.go b/datasource/etcd/account_lock.go
index d1c9ee6..76ed58d 100644
--- a/datasource/etcd/account_lock.go
+++ b/datasource/etcd/account_lock.go
@@ -20,16 +20,13 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/little-cui/etcdadpt"
 )
 
-type AccountLockManager struct {
-}
-
-func (al AccountLockManager) UpsertLock(ctx context.Context, lock *datasource.AccountLock) error {
+func (al *RbacDAO) UpsertLock(ctx context.Context, lock *rbac.Lock) error {
 	value, err := json.Marshal(lock)
 	if err != nil {
 		log.Error("account lock is invalid", err)
@@ -46,15 +43,15 @@ func (al AccountLockManager) UpsertLock(ctx context.Context, lock *datasource.Ac
 	return nil
 }
 
-func (al AccountLockManager) GetLock(ctx context.Context, key string) (*datasource.AccountLock, error) {
+func (al *RbacDAO) GetLock(ctx context.Context, key string) (*rbac.Lock, error) {
 	kv, err := etcdadpt.Get(ctx, path.GenerateAccountLockKey(key))
 	if err != nil {
 		return nil, err
 	}
 	if kv == nil {
-		return nil, datasource.ErrAccountLockNotExist
+		return nil, rbac.ErrAccountLockNotExist
 	}
-	lock := &datasource.AccountLock{}
+	lock := &rbac.Lock{}
 	err = json.Unmarshal(kv.Value, lock)
 	if err != nil {
 		log.Error(fmt.Sprintf("key %s format invalid", key), err)
@@ -63,14 +60,14 @@ func (al AccountLockManager) GetLock(ctx context.Context, key string) (*datasour
 	return lock, nil
 }
 
-func (al AccountLockManager) ListLock(ctx context.Context) ([]*datasource.AccountLock, int64, error) {
+func (al *RbacDAO) ListLock(ctx context.Context) ([]*rbac.Lock, int64, error) {
 	kvs, n, err := etcdadpt.List(ctx, path.GenerateAccountLockKey(""))
 	if err != nil {
 		return nil, 0, err
 	}
-	locks := make([]*datasource.AccountLock, 0, n)
+	locks := make([]*rbac.Lock, 0, n)
 	for _, v := range kvs {
-		lock := &datasource.AccountLock{}
+		lock := &rbac.Lock{}
 		err = json.Unmarshal(v.Value, lock)
 		if err != nil {
 			log.Error("account lock info format invalid:", err)
@@ -81,17 +78,17 @@ func (al AccountLockManager) ListLock(ctx context.Context) ([]*datasource.Accoun
 	return locks, n, nil
 }
 
-func (al AccountLockManager) DeleteLock(ctx context.Context, key string) error {
+func (al *RbacDAO) DeleteLock(ctx context.Context, key string) error {
 	_, err := etcdadpt.Delete(ctx, path.GenerateAccountLockKey(key))
 	if err != nil {
 		log.Error(fmt.Sprintf("remove lock %s failed", key), err)
-		return datasource.ErrCannotReleaseLock
+		return rbac.ErrCannotReleaseLock
 	}
 	log.Info(fmt.Sprintf("%s is released", key))
 	return nil
 }
 
-func (al AccountLockManager) DeleteLockList(ctx context.Context, keys []string) error {
+func (al *RbacDAO) DeleteLockList(ctx context.Context, keys []string) error {
 	var opts []etcdadpt.OpOptions
 	for _, key := range keys {
 		opts = append(opts, etcdadpt.OpDel(etcdadpt.WithStrKey(path.GenerateAccountLockKey(key))))
@@ -102,12 +99,8 @@ func (al AccountLockManager) DeleteLockList(ctx context.Context, keys []string)
 	err := etcdadpt.Txn(ctx, opts)
 	if err != nil {
 		log.Error(fmt.Sprintf("remove locks %v failed", keys), err)
-		return datasource.ErrCannotReleaseLock
+		return rbac.ErrCannotReleaseLock
 	}
 	log.Info(fmt.Sprintf("%v are released", keys))
 	return nil
 }
-
-func NewAccountLockManager() datasource.AccountLockManager {
-	return &AccountLockManager{}
-}
diff --git a/datasource/etcd/etcd.go b/datasource/etcd/etcd.go
index 42e5e5a..75ebf72 100644
--- a/datasource/etcd/etcd.go
+++ b/datasource/etcd/etcd.go
@@ -48,32 +48,17 @@ func init() {
 type DataSource struct {
 	Options *datasource.Options
 
-	accountLockManager datasource.AccountLockManager
-	accountManager     datasource.AccountManager
-	metadataManager    datasource.MetadataManager
-	roleManager        datasource.RoleManager
-	sysManager         datasource.SystemManager
-	depManager         datasource.DependencyManager
-	scManager          datasource.SCManager
-	metricsManager     datasource.MetricsManager
-}
-
-func (ds *DataSource) AccountLockManager() datasource.AccountLockManager {
-	return ds.accountLockManager
+	metadataManager datasource.MetadataManager
+	sysManager      datasource.SystemManager
+	depManager      datasource.DependencyManager
+	scManager       datasource.SCManager
+	metricsManager  datasource.MetricsManager
 }
 
 func (ds *DataSource) SystemManager() datasource.SystemManager {
 	return ds.sysManager
 }
 
-func (ds *DataSource) AccountManager() datasource.AccountManager {
-	return ds.accountManager
-}
-
-func (ds *DataSource) RoleManager() datasource.RoleManager {
-	return ds.roleManager
-}
-
 func (ds *DataSource) DependencyManager() datasource.DependencyManager {
 	return ds.depManager
 }
@@ -109,9 +94,6 @@ func NewDataSource(opts datasource.Options) (datasource.DataSource, error) {
 	if err := inst.initialize(); err != nil {
 		return nil, err
 	}
-	inst.accountManager = &AccountManager{}
-	inst.accountLockManager = NewAccountLockManager()
-	inst.roleManager = &RoleManager{}
 	inst.metadataManager = newMetadataManager(opts.SchemaNotEditable, opts.InstanceTTL)
 	inst.sysManager = newSysManager()
 	inst.depManager = &DepManager{}
diff --git a/datasource/etcd/role.go b/datasource/etcd/role.go
index 467d640..f1a1092 100644
--- a/datasource/etcd/role.go
+++ b/datasource/etcd/role.go
@@ -24,19 +24,16 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/etcdsync"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 	"github.com/little-cui/etcdadpt"
 )
 
-type RoleManager struct {
-}
-
-func (rm *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
+func (rm *RbacDAO) CreateRole(ctx context.Context, r *rbacmodel.Role) error {
 	lock, err := etcdsync.Lock("/role-creating/"+r.Name, -1, false)
 	if err != nil {
 		return fmt.Errorf("role %s is creating", r.Name)
@@ -54,7 +51,7 @@ func (rm *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
 		return err
 	}
 	if exist {
-		return datasource.ErrRoleDuplicated
+		return rbac.ErrRoleDuplicated
 	}
 	r.ID = util.GenerateUUID()
 	r.CreateTime = strconv.FormatInt(time.Now().Unix(), 10)
@@ -73,19 +70,19 @@ func (rm *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
 	return nil
 }
 
-func (rm *RoleManager) RoleExist(ctx context.Context, name string) (bool, error) {
+func (rm *RbacDAO) RoleExist(ctx context.Context, name string) (bool, error) {
 	return etcdadpt.Exist(ctx, path.GenerateRBACRoleKey(name))
 }
 
-func (rm *RoleManager) GetRole(ctx context.Context, name string) (*rbac.Role, error) {
+func (rm *RbacDAO) GetRole(ctx context.Context, name string) (*rbacmodel.Role, error) {
 	kv, err := etcdadpt.Get(ctx, path.GenerateRBACRoleKey(name))
 	if err != nil {
 		return nil, err
 	}
 	if kv == nil {
-		return nil, datasource.ErrRoleNotExist
+		return nil, rbac.ErrRoleNotExist
 	}
-	role := &rbac.Role{}
+	role := &rbacmodel.Role{}
 	err = json.Unmarshal(kv.Value, role)
 	if err != nil {
 		log.Error("role info format invalid", err)
@@ -93,14 +90,14 @@ func (rm *RoleManager) GetRole(ctx context.Context, name string) (*rbac.Role, er
 	}
 	return role, nil
 }
-func (rm *RoleManager) ListRole(ctx context.Context) ([]*rbac.Role, int64, error) {
+func (rm *RbacDAO) ListRole(ctx context.Context) ([]*rbacmodel.Role, int64, error) {
 	kvs, n, err := etcdadpt.List(ctx, path.GenerateRBACRoleKey(""))
 	if err != nil {
 		return nil, 0, err
 	}
-	roles := make([]*rbac.Role, 0, n)
+	roles := make([]*rbacmodel.Role, 0, n)
 	for _, v := range kvs {
-		r := &rbac.Role{}
+		r := &rbacmodel.Role{}
 		err = json.Unmarshal(v.Value, r)
 		if err != nil {
 			log.Error("role info format invalid:", err)
@@ -111,14 +108,14 @@ func (rm *RoleManager) ListRole(ctx context.Context) ([]*rbac.Role, int64, error
 	}
 	return roles, n, nil
 }
-func (rm *RoleManager) DeleteRole(ctx context.Context, name string) (bool, error) {
+func (rm *RbacDAO) DeleteRole(ctx context.Context, name string) (bool, error) {
 	exists, err := RoleBindingExists(ctx, name)
 	if err != nil {
 		log.Error("", err)
 		return false, err
 	}
 	if exists {
-		return false, datasource.ErrRoleBindingExist
+		return false, rbac.ErrRoleBindingExist
 	}
 	del, err := etcdadpt.Delete(ctx, path.GenerateRBACRoleKey(name))
 	if err != nil {
@@ -134,7 +131,7 @@ func RoleBindingExists(ctx context.Context, role string) (bool, error) {
 	}
 	return total > 0, nil
 }
-func (rm *RoleManager) UpdateRole(ctx context.Context, name string, role *rbac.Role) error {
+func (rm *RbacDAO) UpdateRole(ctx context.Context, name string, role *rbacmodel.Role) error {
 	role.UpdateTime = strconv.FormatInt(time.Now().Unix(), 10)
 	value, err := json.Marshal(role)
 	if err != nil {
diff --git a/datasource/manager.go b/datasource/manager.go
index 9ac3e5d..5cb56dc 100644
--- a/datasource/manager.go
+++ b/datasource/manager.go
@@ -20,6 +20,7 @@ package datasource
 import (
 	"fmt"
 
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/datasource/schema"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 )
@@ -47,10 +48,11 @@ func Init(opts Options) error {
 	if err != nil {
 		return err
 	}
-
-	err = schema.Init(schema.Options{
-		Kind: opts.Kind,
-	})
+	err = schema.Init(schema.Options{Kind: opts.Kind})
+	if err != nil {
+		return err
+	}
+	err = rbac.Init(rbac.Options{Kind: opts.Kind})
 	if err != nil {
 		return err
 	}
@@ -80,15 +82,6 @@ func GetMetadataManager() MetadataManager {
 func GetSystemManager() SystemManager {
 	return dataSourceInst.SystemManager()
 }
-func GetRoleManager() RoleManager {
-	return dataSourceInst.RoleManager()
-}
-func GetAccountManager() AccountManager {
-	return dataSourceInst.AccountManager()
-}
-func GetAccountLockManager() AccountLockManager {
-	return dataSourceInst.AccountLockManager()
-}
 func GetDependencyManager() DependencyManager {
 	return dataSourceInst.DependencyManager()
 }
diff --git a/datasource/mongo/account.go b/datasource/mongo/account.go
index ecc2c3d..06dd65e 100644
--- a/datasource/mongo/account.go
+++ b/datasource/mongo/account.go
@@ -23,10 +23,10 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/go-chassis/cari/rbac"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 	"go.mongodb.org/mongo-driver/mongo"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
 	mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
@@ -35,10 +35,18 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/util"
 )
 
-type AccountManager struct {
+func init() {
+	rbac.Install("mongo", NewRbacDAO)
 }
 
-func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) error {
+func NewRbacDAO(opts rbac.Options) (rbac.DAO, error) {
+	return &RbacDAO{}, nil
+}
+
+type RbacDAO struct {
+}
+
+func (ds *RbacDAO) CreateAccount(ctx context.Context, a *rbacmodel.Account) error {
 	exist, err := ds.AccountExist(ctx, a.Name)
 	if err != nil {
 		msg := fmt.Sprintf("failed to query account, account name %s", a.Name)
@@ -46,7 +54,7 @@ func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) er
 		return err
 	}
 	if exist {
-		return datasource.ErrAccountDuplicated
+		return rbac.ErrAccountDuplicated
 	}
 	a.Password, err = privacy.ScryptPassword(a.Password)
 	if err != nil {
@@ -62,7 +70,7 @@ func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) er
 	_, err = client.GetMongoClient().Insert(ctx, model.CollectionAccount, a)
 	if err != nil {
 		if client.IsDuplicateKey(err) {
-			return datasource.ErrAccountDuplicated
+			return rbac.ErrAccountDuplicated
 		}
 		return err
 	}
@@ -70,7 +78,7 @@ func (ds *AccountManager) CreateAccount(ctx context.Context, a *rbac.Account) er
 	return nil
 }
 
-func (ds *AccountManager) AccountExist(ctx context.Context, name string) (bool, error) {
+func (ds *RbacDAO) AccountExist(ctx context.Context, name string) (bool, error) {
 	filter := mutil.NewFilter(mutil.AccountName(name))
 	count, err := client.GetMongoClient().Count(ctx, model.CollectionAccount, filter)
 	if err != nil {
@@ -82,7 +90,7 @@ func (ds *AccountManager) AccountExist(ctx context.Context, name string) (bool,
 	return true, nil
 }
 
-func (ds *AccountManager) GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
+func (ds *RbacDAO) GetAccount(ctx context.Context, name string) (*rbacmodel.Account, error) {
 	filter := mutil.NewFilter(mutil.AccountName(name))
 	result, err := client.GetMongoClient().FindOne(ctx, model.CollectionAccount, filter)
 	if err != nil {
@@ -92,13 +100,13 @@ func (ds *AccountManager) GetAccount(ctx context.Context, name string) (*rbac.Ac
 	}
 	if err = result.Err(); err != nil {
 		if err == mongo.ErrNoDocuments {
-			return nil, datasource.ErrAccountNotExist
+			return nil, rbac.ErrAccountNotExist
 		}
 		msg := fmt.Sprintf("failed to query account, account name %s", name)
 		log.Error(msg, result.Err())
-		return nil, datasource.ErrQueryAccountFailed
+		return nil, rbac.ErrQueryAccountFailed
 	}
-	var account rbac.Account
+	var account rbacmodel.Account
 	err = result.Decode(&account)
 	if err != nil {
 		log.Error("failed to decode account", err)
@@ -107,16 +115,16 @@ func (ds *AccountManager) GetAccount(ctx context.Context, name string) (*rbac.Ac
 	return &account, nil
 }
 
-func (ds *AccountManager) ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
+func (ds *RbacDAO) ListAccount(ctx context.Context) ([]*rbacmodel.Account, int64, error) {
 	filter := mutil.NewFilter()
 	cursor, err := client.GetMongoClient().Find(ctx, model.CollectionAccount, filter)
 	if err != nil {
 		return nil, 0, err
 	}
-	var accounts []*rbac.Account
+	var accounts []*rbacmodel.Account
 	defer cursor.Close(ctx)
 	for cursor.Next(ctx) {
-		var account rbac.Account
+		var account rbacmodel.Account
 		err = cursor.Decode(&account)
 		if err != nil {
 			log.Error("failed to decode account", err)
@@ -128,7 +136,7 @@ func (ds *AccountManager) ListAccount(ctx context.Context) ([]*rbac.Account, int
 	return accounts, int64(len(accounts)), nil
 }
 
-func (ds *AccountManager) DeleteAccount(ctx context.Context, names []string) (bool, error) {
+func (ds *RbacDAO) DeleteAccount(ctx context.Context, names []string) (bool, error) {
 	if len(names) == 0 {
 		return false, nil
 	}
@@ -144,7 +152,7 @@ func (ds *AccountManager) DeleteAccount(ctx context.Context, names []string) (bo
 	return true, nil
 }
 
-func (ds *AccountManager) UpdateAccount(ctx context.Context, name string, account *rbac.Account) error {
+func (ds *RbacDAO) UpdateAccount(ctx context.Context, name string, account *rbacmodel.Account) error {
 	filter := mutil.NewFilter(mutil.AccountName(name))
 	setFilter := mutil.NewFilter(
 		mutil.ID(account.ID),
diff --git a/datasource/mongo/account_lock.go b/datasource/mongo/account_lock.go
index e3c0022..484e89e 100644
--- a/datasource/mongo/account_lock.go
+++ b/datasource/mongo/account_lock.go
@@ -19,19 +19,16 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
 	mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
-type AccountLockManager struct {
-}
-
-func (al *AccountLockManager) UpsertLock(ctx context.Context, lock *datasource.AccountLock) error {
+func (al *RbacDAO) UpsertLock(ctx context.Context, lock *rbac.Lock) error {
 	key := lock.Key
 	releaseAt := lock.ReleaseAt
 	filter := mutil.NewFilter(mutil.AccountLockKey(key))
@@ -54,7 +51,7 @@ func (al *AccountLockManager) UpsertLock(ctx context.Context, lock *datasource.A
 	return nil
 }
 
-func (al *AccountLockManager) GetLock(ctx context.Context, key string) (*datasource.AccountLock, error) {
+func (al *RbacDAO) GetLock(ctx context.Context, key string) (*rbac.Lock, error) {
 	filter := mutil.NewFilter(mutil.AccountLockKey(key))
 	result, err := client.GetMongoClient().FindOne(ctx, model.CollectionAccountLock, filter)
 	if err != nil {
@@ -62,13 +59,13 @@ func (al *AccountLockManager) GetLock(ctx context.Context, key string) (*datasou
 	}
 	if err = result.Err(); err != nil {
 		if err == mongo.ErrNoDocuments {
-			return nil, datasource.ErrAccountLockNotExist
+			return nil, rbac.ErrAccountLockNotExist
 		}
 		msg := fmt.Sprintf("failed to query account lock, key %s", key)
 		log.Error(msg, result.Err())
-		return nil, datasource.ErrQueryAccountLockFailed
+		return nil, rbac.ErrQueryAccountLockFailed
 	}
-	var lock datasource.AccountLock
+	var lock rbac.Lock
 	err = result.Decode(&lock)
 	if err != nil {
 		log.Error(fmt.Sprintf("failed to decode account lock %s", key), err)
@@ -77,16 +74,16 @@ func (al *AccountLockManager) GetLock(ctx context.Context, key string) (*datasou
 	return &lock, nil
 }
 
-func (al *AccountLockManager) ListLock(ctx context.Context) ([]*datasource.AccountLock, int64, error) {
+func (al *RbacDAO) ListLock(ctx context.Context) ([]*rbac.Lock, int64, error) {
 	filter := mutil.NewFilter()
 	cursor, err := client.GetMongoClient().Find(ctx, model.CollectionAccountLock, filter)
 	if err != nil {
 		return nil, 0, err
 	}
-	var locks []*datasource.AccountLock
+	var locks []*rbac.Lock
 	defer cursor.Close(ctx)
 	for cursor.Next(ctx) {
-		var lock datasource.AccountLock
+		var lock rbac.Lock
 		err = cursor.Decode(&lock)
 		if err != nil {
 			log.Error("failed to decode account lock", err)
@@ -97,18 +94,18 @@ func (al *AccountLockManager) ListLock(ctx context.Context) ([]*datasource.Accou
 	return locks, int64(len(locks)), nil
 }
 
-func (al *AccountLockManager) DeleteLock(ctx context.Context, key string) error {
+func (al *RbacDAO) DeleteLock(ctx context.Context, key string) error {
 	filter := mutil.NewFilter(mutil.AccountLockKey(key))
 	_, err := client.GetMongoClient().Delete(ctx, model.CollectionAccountLock, filter)
 	if err != nil {
 		log.Error(fmt.Sprintf("remove lock %s failed", key), err)
-		return datasource.ErrCannotReleaseLock
+		return rbac.ErrCannotReleaseLock
 	}
 	log.Info(fmt.Sprintf("%s is released", key))
 	return nil
 }
 
-func (al *AccountLockManager) DeleteLockList(ctx context.Context, keys []string) error {
+func (al *RbacDAO) DeleteLockList(ctx context.Context, keys []string) error {
 	var delKeys []mongo.WriteModel
 	for _, key := range keys {
 		delKeys = append(delKeys, mongo.NewDeleteOneModel().SetFilter(mutil.NewFilter(mutil.AccountLockKey(key))))
@@ -119,12 +116,8 @@ func (al *AccountLockManager) DeleteLockList(ctx context.Context, keys []string)
 	_, err := client.GetMongoClient().BatchDelete(ctx, model.CollectionAccountLock, delKeys)
 	if err != nil {
 		log.Error(fmt.Sprintf("remove locks %v failed", keys), err)
-		return datasource.ErrCannotReleaseLock
+		return rbac.ErrCannotReleaseLock
 	}
 	log.Info(fmt.Sprintf("%v are released", keys))
 	return nil
 }
-
-func NewAccountLockManager() datasource.AccountLockManager {
-	return &AccountLockManager{}
-}
diff --git a/datasource/mongo/mongo.go b/datasource/mongo/mongo.go
index 1460102..8bac3c4 100644
--- a/datasource/mongo/mongo.go
+++ b/datasource/mongo/mongo.go
@@ -37,32 +37,17 @@ func init() {
 }
 
 type DataSource struct {
-	accountLockManager datasource.AccountLockManager
-	accountManager     datasource.AccountManager
-	metadataManager    datasource.MetadataManager
-	roleManager        datasource.RoleManager
-	sysManager         datasource.SystemManager
-	depManager         datasource.DependencyManager
-	scManager          datasource.SCManager
-	metricsManager     datasource.MetricsManager
-}
-
-func (ds *DataSource) AccountLockManager() datasource.AccountLockManager {
-	return ds.accountLockManager
+	metadataManager datasource.MetadataManager
+	sysManager      datasource.SystemManager
+	depManager      datasource.DependencyManager
+	scManager       datasource.SCManager
+	metricsManager  datasource.MetricsManager
 }
 
 func (ds *DataSource) SystemManager() datasource.SystemManager {
 	return ds.sysManager
 }
 
-func (ds *DataSource) AccountManager() datasource.AccountManager {
-	return ds.accountManager
-}
-
-func (ds *DataSource) RoleManager() datasource.RoleManager {
-	return ds.roleManager
-}
-
 func (ds *DataSource) DependencyManager() datasource.DependencyManager {
 	return ds.depManager
 }
@@ -89,10 +74,7 @@ func NewDataSource(opts datasource.Options) (datasource.DataSource, error) {
 	inst.scManager = &SCManager{}
 	inst.depManager = &DepManager{}
 	inst.sysManager = &SysManager{}
-	inst.roleManager = &RoleManager{}
 	inst.metadataManager = &MetadataManager{SchemaNotEditable: opts.SchemaNotEditable, InstanceTTL: opts.InstanceTTL}
-	inst.accountManager = &AccountManager{}
-	inst.accountLockManager = NewAccountLockManager()
 	inst.metricsManager = &MetricsManager{}
 	return inst, nil
 }
diff --git a/datasource/mongo/role.go b/datasource/mongo/role.go
index fbbb4ef..a6b2022 100644
--- a/datasource/mongo/role.go
+++ b/datasource/mongo/role.go
@@ -22,28 +22,24 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/go-chassis/cari/rbac"
-	"go.mongodb.org/mongo-driver/bson"
-
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
 	mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	rbacmodel "github.com/go-chassis/cari/rbac"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
-type RoleManager struct {
-}
-
-func (ds *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
+func (ds *RbacDAO) CreateRole(ctx context.Context, r *rbacmodel.Role) error {
 	exist, err := ds.RoleExist(ctx, r.Name)
 	if err != nil {
 		log.Error("failed to query role", err)
 		return err
 	}
 	if exist {
-		return datasource.ErrRoleDuplicated
+		return rbac.ErrRoleDuplicated
 	}
 	r.ID = util.GenerateUUID()
 	r.CreateTime = strconv.FormatInt(time.Now().Unix(), 10)
@@ -51,7 +47,7 @@ func (ds *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
 	_, err = client.GetMongoClient().Insert(ctx, model.CollectionRole, r)
 	if err != nil {
 		if client.IsDuplicateKey(err) {
-			return datasource.ErrRoleDuplicated
+			return rbac.ErrRoleDuplicated
 		}
 		return err
 	}
@@ -59,7 +55,7 @@ func (ds *RoleManager) CreateRole(ctx context.Context, r *rbac.Role) error {
 	return nil
 }
 
-func (ds *RoleManager) RoleExist(ctx context.Context, name string) (bool, error) {
+func (ds *RbacDAO) RoleExist(ctx context.Context, name string) (bool, error) {
 	filter := mutil.NewFilter(mutil.RoleName(name))
 	count, err := client.GetMongoClient().Count(ctx, model.CollectionRole, filter)
 	if err != nil {
@@ -71,16 +67,16 @@ func (ds *RoleManager) RoleExist(ctx context.Context, name string) (bool, error)
 	return true, nil
 }
 
-func (ds *RoleManager) GetRole(ctx context.Context, name string) (*rbac.Role, error) {
+func (ds *RbacDAO) GetRole(ctx context.Context, name string) (*rbacmodel.Role, error) {
 	filter := mutil.NewFilter(mutil.RoleName(name))
 	result, err := client.GetMongoClient().FindOne(ctx, model.CollectionRole, filter)
 	if err != nil {
 		return nil, err
 	}
 	if result.Err() != nil {
-		return nil, datasource.ErrRoleNotExist
+		return nil, rbac.ErrRoleNotExist
 	}
-	var role rbac.Role
+	var role rbacmodel.Role
 	err = result.Decode(&role)
 	if err != nil {
 		log.Error("failed to decode role", err)
@@ -89,16 +85,16 @@ func (ds *RoleManager) GetRole(ctx context.Context, name string) (*rbac.Role, er
 	return &role, nil
 }
 
-func (ds *RoleManager) ListRole(ctx context.Context) ([]*rbac.Role, int64, error) {
+func (ds *RbacDAO) ListRole(ctx context.Context) ([]*rbacmodel.Role, int64, error) {
 	filter := mutil.NewFilter()
 	cursor, err := client.GetMongoClient().Find(ctx, model.CollectionRole, filter)
 	if err != nil {
 		return nil, 0, err
 	}
-	var roles []*rbac.Role
+	var roles []*rbacmodel.Role
 	defer cursor.Close(ctx)
 	for cursor.Next(ctx) {
-		var role rbac.Role
+		var role rbacmodel.Role
 		err = cursor.Decode(&role)
 		if err != nil {
 			log.Error("failed to decode role", err)
@@ -109,13 +105,13 @@ func (ds *RoleManager) ListRole(ctx context.Context) ([]*rbac.Role, int64, error
 	return roles, int64(len(roles)), nil
 }
 
-func (ds *RoleManager) DeleteRole(ctx context.Context, name string) (bool, error) {
+func (ds *RbacDAO) DeleteRole(ctx context.Context, name string) (bool, error) {
 	n, err := client.Count(ctx, model.CollectionAccount, bson.M{"roles": bson.M{"$in": []string{name}}})
 	if err != nil {
 		return false, err
 	}
 	if n > 0 {
-		return false, datasource.ErrRoleBindingExist
+		return false, rbac.ErrRoleBindingExist
 	}
 	filter := mutil.NewFilter(mutil.RoleName(name))
 	result, err := client.DeleteDoc(ctx, model.CollectionRole, filter)
@@ -128,7 +124,7 @@ func (ds *RoleManager) DeleteRole(ctx context.Context, name string) (bool, error
 	return true, nil
 }
 
-func (ds *RoleManager) UpdateRole(ctx context.Context, name string, role *rbac.Role) error {
+func (ds *RbacDAO) UpdateRole(ctx context.Context, name string, role *rbacmodel.Role) error {
 	filter := mutil.NewFilter(mutil.RoleName(name))
 	setFilter := mutil.NewFilter(
 		mutil.ID(role.ID),
diff --git a/datasource/account.go b/datasource/rbac/account.go
similarity index 84%
rename from datasource/account.go
rename to datasource/rbac/account.go
index d0235a0..d46f19e 100644
--- a/datasource/account.go
+++ b/datasource/rbac/account.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package datasource
+package rbac
 
 import (
 	"context"
@@ -52,20 +52,20 @@ type AccountManager interface {
 	UpdateAccount(ctx context.Context, name string, account *rbac.Account) error
 }
 
-// AccountLockManager saves login failure status
-type AccountLockManager interface {
-	UpsertLock(ctx context.Context, lock *AccountLock) error
-	GetLock(ctx context.Context, key string) (*AccountLock, error)
-	ListLock(ctx context.Context) ([]*AccountLock, int64, error)
+// LockManager saves login failure status
+type LockManager interface {
+	UpsertLock(ctx context.Context, lock *Lock) error
+	GetLock(ctx context.Context, key string) (*Lock, error)
+	ListLock(ctx context.Context) ([]*Lock, int64, error)
 	DeleteLock(ctx context.Context, key string) error
 	DeleteLockList(ctx context.Context, keys []string) error
 }
-type AccountLock struct {
+type Lock struct {
 	Key       string `json:"key,omitempty"`
 	Status    string `json:"status,omitempty"`
 	ReleaseAt int64  `json:"releaseAt,omitempty" bson:"release_at"`
 }
-type AccountLockResponse struct {
-	Total       int64          `json:"total"`
-	AccountLock []*AccountLock `json:"data"`
+type LockResponse struct {
+	Total int64   `json:"total"`
+	Locks []*Lock `json:"data"`
 }
diff --git a/datasource/rbac/account_test.go b/datasource/rbac/account_test.go
new file mode 100644
index 0000000..a15a5b3
--- /dev/null
+++ b/datasource/rbac/account_test.go
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package rbac_test
+
+import (
+	"context"
+	"strconv"
+	"testing"
+	"time"
+
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
+	"github.com/stretchr/testify/assert"
+)
+
+var (
+	a1 = rbacmodel.Account{
+		ID:                  "11111-22222-33333",
+		Name:                "test-account1",
+		Password:            "tnuocca-tset",
+		Roles:               []string{"admin"},
+		TokenExpirationTime: "2020-12-30",
+		CurrentPassword:     "tnuocca-tset1",
+	}
+	a2 = rbacmodel.Account{
+		ID:                  "11111-22222-33333-44444",
+		Name:                "test-account2",
+		Password:            "tnuocca-tset",
+		Roles:               []string{"admin"},
+		TokenExpirationTime: "2020-12-30",
+		CurrentPassword:     "tnuocca-tset2",
+	}
+)
+
+func TestAccount(t *testing.T) {
+	t.Run("add and get account", func(t *testing.T) {
+		err := rbac.Instance().CreateAccount(context.Background(), &a1)
+		assert.NoError(t, err)
+		err = rbac.Instance().CreateAccount(context.Background(), &a2)
+		assert.NoError(t, err)
+		r, err := rbac.Instance().GetAccount(context.Background(), a1.Name)
+		assert.NoError(t, err)
+		assert.Equal(t, a1, *r)
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a1.Name, a2.Name})
+		assert.NoError(t, err)
+	})
+	t.Run("account should exist", func(t *testing.T) {
+		err := rbac.Instance().CreateAccount(context.Background(), &a1)
+		assert.NoError(t, err)
+		exist, err := rbac.Instance().AccountExist(context.Background(), a1.Name)
+		assert.NoError(t, err)
+		assert.True(t, exist)
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a1.Name})
+		assert.NoError(t, err)
+	})
+	t.Run("delete account", func(t *testing.T) {
+		err := rbac.Instance().CreateAccount(context.Background(), &a2)
+		assert.NoError(t, err)
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a2.Name})
+		assert.NoError(t, err)
+	})
+	t.Run("add and update accounts then list", func(t *testing.T) {
+		err := rbac.Instance().CreateAccount(context.Background(), &a1)
+		assert.NoError(t, err)
+		err = rbac.Instance().CreateAccount(context.Background(), &a2)
+		assert.NoError(t, err)
+		a2.Password = "new-password"
+		err = rbac.Instance().UpdateAccount(context.Background(), a2.Name, &a2)
+		assert.NoError(t, err)
+		accounts, _, err := rbac.Instance().ListAccount(context.Background())
+		assert.NoError(t, err)
+		assert.GreaterOrEqual(t, len(accounts), 2)
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a1.Name})
+		assert.NoError(t, err)
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a2.Name})
+		assert.NoError(t, err)
+	})
+	t.Run("add and update accounts, should have create/update time", func(t *testing.T) {
+		err := rbac.Instance().CreateAccount(context.Background(), &a1)
+		assert.NoError(t, err)
+
+		r, err := rbac.Instance().GetAccount(context.Background(), a1.Name)
+		assert.NoError(t, err)
+		dt, _ := strconv.Atoi(r.CreateTime)
+		assert.Less(t, 0, dt)
+		assert.Equal(t, r.CreateTime, r.UpdateTime)
+
+		time.Sleep(time.Second)
+		a1.Password = "new-password"
+		err = rbac.Instance().UpdateAccount(context.Background(), a1.Name, &a1)
+		assert.NoError(t, err)
+
+		old, _ := strconv.Atoi(r.UpdateTime)
+		r, err = rbac.Instance().GetAccount(context.Background(), a1.Name)
+		assert.NoError(t, err)
+		last, _ := strconv.Atoi(r.UpdateTime)
+		assert.Less(t, old, last)
+		assert.NotEqual(t, r.CreateTime, r.UpdateTime)
+
+		_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a1.Name})
+		assert.NoError(t, err)
+	})
+}
diff --git a/datasource/schema/init.go b/datasource/rbac/init.go
similarity index 84%
copy from datasource/schema/init.go
copy to datasource/rbac/init.go
index 2a6e6d1..be5652e 100644
--- a/datasource/schema/init.go
+++ b/datasource/rbac/init.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package schema
+package rbac
 
 import (
 	"fmt"
@@ -23,16 +23,16 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 )
 
-type engine func(opts Options) (DAO, error)
+type initFunc func(opts Options) (DAO, error)
 
 var (
-	plugins  = make(map[string]engine)
+	plugins  = make(map[string]initFunc)
 	instance DAO
 )
 
 // Install load plugins configuration into plugins
-func Install(pluginImplName string, engineFunc engine) {
-	plugins[pluginImplName] = engineFunc
+func Install(pluginImplName string, f initFunc) {
+	plugins[pluginImplName] = f
 }
 
 // Init construct storage plugin instance
@@ -52,7 +52,7 @@ func Init(opts Options) error {
 	if err != nil {
 		return err
 	}
-	log.Info(fmt.Sprintf("schema plugin [%s] enabled", opts.Kind))
+	log.Info(fmt.Sprintf("rbac plugin [%s] enabled", opts.Kind))
 
 	return nil
 }
diff --git a/server/plugin/quota/buildin/role.go b/datasource/rbac/options.go
similarity index 75%
copy from server/plugin/quota/buildin/role.go
copy to datasource/rbac/options.go
index f771d14..69573c3 100644
--- a/server/plugin/quota/buildin/role.go
+++ b/datasource/rbac/options.go
@@ -15,18 +15,9 @@
  * limitations under the License.
  */
 
-package buildin
+package rbac
 
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-)
-
-func RoleUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetRoleManager().ListRole(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
+//Options contains configuration for plugins
+type Options struct {
+	Kind string
 }
diff --git a/server/plugin/quota/buildin/role.go b/datasource/rbac/rbac.go
similarity index 75%
copy from server/plugin/quota/buildin/role.go
copy to datasource/rbac/rbac.go
index f771d14..b9d5c32 100644
--- a/server/plugin/quota/buildin/role.go
+++ b/datasource/rbac/rbac.go
@@ -15,18 +15,10 @@
  * limitations under the License.
  */
 
-package buildin
+package rbac
 
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-)
-
-func RoleUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetRoleManager().ListRole(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
+type DAO interface {
+	AccountManager
+	RoleManager
+	LockManager
 }
diff --git a/datasource/role.go b/datasource/rbac/role.go
similarity index 98%
rename from datasource/role.go
rename to datasource/rbac/role.go
index 076f6d6..c06dd09 100644
--- a/datasource/role.go
+++ b/datasource/rbac/role.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package datasource
+package rbac
 
 import (
 	"context"
diff --git a/datasource/role_test.go b/datasource/rbac/role_test.go
similarity index 63%
rename from datasource/role_test.go
rename to datasource/rbac/role_test.go
index 5ed6259..13fc691 100644
--- a/datasource/role_test.go
+++ b/datasource/rbac/role_test.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package datasource_test
+package rbac_test
 
 import (
 	"context"
@@ -23,27 +23,25 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-chassis/cari/rbac"
-
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 	"github.com/stretchr/testify/assert"
-
-	"github.com/apache/servicecomb-service-center/datasource"
 )
 
 var (
-	r1 = rbac.Role{
+	r1 = rbacmodel.Role{
 		ID:    "11111-22222-33333",
 		Name:  "test-role",
 		Perms: nil,
 	}
 
-	r2 = rbac.Role{
+	r2 = rbacmodel.Role{
 		ID:    "11111-22222-33333-44444",
 		Name:  "test-role-ex",
 		Perms: nil,
 	}
 
-	a = rbac.Account{
+	a = rbacmodel.Account{
 		Name:     "account-role-test",
 		Password: "abc",
 		Roles:    []string{"test-role"},
@@ -52,9 +50,9 @@ var (
 
 func TestRole(t *testing.T) {
 	t.Run("create role should success", func(t *testing.T) {
-		err := datasource.GetRoleManager().CreateRole(context.Background(), &r1)
+		err := rbac.Instance().CreateRole(context.Background(), &r1)
 		assert.NoError(t, err)
-		r, err := datasource.GetRoleManager().GetRole(context.Background(), "test-role")
+		r, err := rbac.Instance().GetRole(context.Background(), "test-role")
 		assert.NoError(t, err)
 		assert.Equal(t, r1, *r)
 		dt, _ := strconv.Atoi(r.CreateTime)
@@ -62,27 +60,27 @@ func TestRole(t *testing.T) {
 		assert.Equal(t, r.CreateTime, r.UpdateTime)
 	})
 	t.Run("role should exist", func(t *testing.T) {
-		exist, err := datasource.GetRoleManager().RoleExist(context.Background(), "test-role")
+		exist, err := rbac.Instance().RoleExist(context.Background(), "test-role")
 		assert.NoError(t, err)
 		assert.True(t, exist)
 	})
 
 	t.Run("repeated create role should failed", func(t *testing.T) {
-		err := datasource.GetRoleManager().CreateRole(context.Background(), &r1)
+		err := rbac.Instance().CreateRole(context.Background(), &r1)
 		assert.Error(t, err)
 	})
 
 	t.Run("update role should success", func(t *testing.T) {
-		r, err := datasource.GetRoleManager().GetRole(context.Background(), "test-role")
+		r, err := rbac.Instance().GetRole(context.Background(), "test-role")
 		assert.NoError(t, err)
 		old, _ := strconv.Atoi(r.UpdateTime)
 
 		time.Sleep(time.Second)
 		r1.ID = "11111-22222-33333-4"
-		err = datasource.GetRoleManager().UpdateRole(context.Background(), "test-role", &r1)
+		err = rbac.Instance().UpdateRole(context.Background(), "test-role", &r1)
 		assert.NoError(t, err)
 
-		r, err = datasource.GetRoleManager().GetRole(context.Background(), "test-role")
+		r, err = rbac.Instance().GetRole(context.Background(), "test-role")
 		assert.NoError(t, err)
 		last, _ := strconv.Atoi(r.UpdateTime)
 		assert.Less(t, old, last)
@@ -90,39 +88,39 @@ func TestRole(t *testing.T) {
 	})
 
 	t.Run("add new role should success", func(t *testing.T) {
-		err := datasource.GetRoleManager().CreateRole(context.Background(), &r2)
+		err := rbac.Instance().CreateRole(context.Background(), &r2)
 		assert.NoError(t, err)
-		_, n, err := datasource.GetRoleManager().ListRole(context.Background())
+		_, n, err := rbac.Instance().ListRole(context.Background())
 		assert.NoError(t, err)
 		assert.Equal(t, int64(2), n)
 	})
 
 	t.Run("delete role bind to user should failed", func(t *testing.T) {
-		err := datasource.GetAccountManager().CreateAccount(context.Background(), &a)
+		err := rbac.Instance().CreateAccount(context.Background(), &a)
 		assert.NoError(t, err)
 
-		_, err = datasource.GetRoleManager().DeleteRole(context.Background(), "test-role")
+		_, err = rbac.Instance().DeleteRole(context.Background(), "test-role")
 		assert.Error(t, err)
 	})
 
 	t.Run("update account role and delete old role should success", func(t *testing.T) {
 		a.Roles = []string{"test-role-ex"}
-		err := datasource.GetAccountManager().UpdateAccount(context.Background(), "account-role-test", &a)
+		err := rbac.Instance().UpdateAccount(context.Background(), "account-role-test", &a)
 		assert.NoError(t, err)
 
-		_, err = datasource.GetRoleManager().DeleteRole(context.Background(), "test-role")
+		_, err = rbac.Instance().DeleteRole(context.Background(), "test-role")
 		assert.NoError(t, err)
 	})
 
 	t.Run("delete role should success", func(t *testing.T) {
-		b, err := datasource.GetAccountManager().DeleteAccount(context.Background(), []string{"account-role-test"})
+		b, err := rbac.Instance().DeleteAccount(context.Background(), []string{"account-role-test"})
 		assert.True(t, b)
 		assert.NoError(t, err)
 
-		_, err = datasource.GetRoleManager().DeleteRole(context.Background(), "test-role-ex")
+		_, err = rbac.Instance().DeleteRole(context.Background(), "test-role-ex")
 		assert.NoError(t, err)
 
-		_, n, err := datasource.GetRoleManager().ListRole(context.Background())
+		_, n, err := rbac.Instance().ListRole(context.Background())
 		assert.NoError(t, err)
 		assert.Equal(t, int64(0), n)
 	})
diff --git a/datasource/schema/init.go b/datasource/schema/init.go
index 2a6e6d1..1c24df5 100644
--- a/datasource/schema/init.go
+++ b/datasource/schema/init.go
@@ -23,16 +23,16 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 )
 
-type engine func(opts Options) (DAO, error)
+type initFunc func(opts Options) (DAO, error)
 
 var (
-	plugins  = make(map[string]engine)
+	plugins  = make(map[string]initFunc)
 	instance DAO
 )
 
 // Install load plugins configuration into plugins
-func Install(pluginImplName string, engineFunc engine) {
-	plugins[pluginImplName] = engineFunc
+func Install(pluginImplName string, f initFunc) {
+	plugins[pluginImplName] = f
 }
 
 // Init construct storage plugin instance
diff --git a/server/job/account/account_test.go b/server/job/account/account_test.go
index 1c6c322..bc76ddf 100644
--- a/server/job/account/account_test.go
+++ b/server/job/account/account_test.go
@@ -24,7 +24,7 @@ import (
 
 	_ "github.com/apache/servicecomb-service-center/test"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	dao "github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/server/job/account"
 	"github.com/stretchr/testify/assert"
 )
@@ -32,9 +32,9 @@ import (
 func TestCleanupReleasedLockHistory(t *testing.T) {
 	t.Run("have a released lock, should be cleanup", func(t *testing.T) {
 		const key = "TestCleanupReleasedLockHistory1"
-		err := datasource.GetAccountLockManager().UpsertLock(context.Background(), &datasource.AccountLock{
+		err := dao.Instance().UpsertLock(context.Background(), &dao.Lock{
 			Key:       key,
-			Status:    datasource.StatusBanned,
+			Status:    dao.StatusBanned,
 			ReleaseAt: time.Now().Add(-time.Second).Unix(),
 		})
 		assert.NoError(t, err)
@@ -42,14 +42,14 @@ func TestCleanupReleasedLockHistory(t *testing.T) {
 		err = account.CleanupReleasedLockHistory(context.Background())
 		assert.NoError(t, err)
 
-		_, err = datasource.GetAccountLockManager().GetLock(context.Background(), key)
-		assert.Equal(t, datasource.ErrAccountLockNotExist, err)
+		_, err = dao.Instance().GetLock(context.Background(), key)
+		assert.Equal(t, dao.ErrAccountLockNotExist, err)
 	})
 	t.Run("have an unreleased lock, should NOT be cleanup", func(t *testing.T) {
 		const key = "TestCleanupReleasedLockHistory2"
-		err := datasource.GetAccountLockManager().UpsertLock(context.Background(), &datasource.AccountLock{
+		err := dao.Instance().UpsertLock(context.Background(), &dao.Lock{
 			Key:       key,
-			Status:    datasource.StatusBanned,
+			Status:    dao.StatusBanned,
 			ReleaseAt: time.Now().Add(time.Minute).Unix(),
 		})
 		assert.NoError(t, err)
@@ -57,11 +57,11 @@ func TestCleanupReleasedLockHistory(t *testing.T) {
 		err = account.CleanupReleasedLockHistory(context.Background())
 		assert.NoError(t, err)
 
-		lock, err := datasource.GetAccountLockManager().GetLock(context.Background(), key)
+		lock, err := dao.Instance().GetLock(context.Background(), key)
 		assert.NoError(t, err)
 		assert.NotNil(t, lock)
 
-		err = datasource.GetAccountLockManager().DeleteLock(context.Background(), key)
+		err = dao.Instance().DeleteLock(context.Background(), key)
 		assert.NoError(t, err)
 	})
 }
diff --git a/server/plugin/quota/buildin/account.go b/server/plugin/quota/buildin/account.go
index 3fa5f42..a5ec0af 100644
--- a/server/plugin/quota/buildin/account.go
+++ b/server/plugin/quota/buildin/account.go
@@ -20,11 +20,11 @@ package buildin
 import (
 	"context"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 )
 
 func AccountUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetAccountManager().ListAccount(ctx)
+	_, used, err := rbac.Instance().ListAccount(ctx)
 	if err != nil {
 		return 0, err
 	}
diff --git a/server/plugin/quota/buildin/role.go b/server/plugin/quota/buildin/role.go
index f771d14..c7cb44f 100644
--- a/server/plugin/quota/buildin/role.go
+++ b/server/plugin/quota/buildin/role.go
@@ -20,11 +20,11 @@ package buildin
 import (
 	"context"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 )
 
 func RoleUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetRoleManager().ListRole(ctx)
+	_, used, err := rbac.Instance().ListRole(ctx)
 	if err != nil {
 		return 0, err
 	}
diff --git a/server/resource/rbac/auth_resource.go b/server/resource/rbac/auth_resource.go
index ab30469..89249a1 100644
--- a/server/resource/rbac/auth_resource.go
+++ b/server/resource/rbac/auth_resource.go
@@ -22,7 +22,7 @@ import (
 	"io/ioutil"
 	"net/http"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/rest"
@@ -30,7 +30,7 @@ import (
 	rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	"github.com/go-chassis/cari/discovery"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 	"github.com/go-chassis/go-chassis/v2/security/authr"
 )
 
@@ -61,7 +61,7 @@ func (ar *AuthResource) CreateAccount(w http.ResponseWriter, req *http.Request)
 		rest.WriteError(w, discovery.ErrInternal, err.Error())
 		return
 	}
-	a := &rbac.Account{}
+	a := &rbacmodel.Account{}
 	if err = json.Unmarshal(body, a); err != nil {
 		log.Error("json err", err)
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
@@ -95,7 +95,7 @@ func (ar *AuthResource) UpdateAccount(w http.ResponseWriter, req *http.Request)
 		rest.WriteError(w, discovery.ErrInternal, err.Error())
 		return
 	}
-	a := &rbac.Account{}
+	a := &rbacmodel.Account{}
 	if err = json.Unmarshal(body, a); err != nil {
 		log.Error("json err", err)
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
@@ -118,7 +118,7 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
 		rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
 		return
 	}
-	resp := &rbac.AccountResponse{
+	resp := &rbacmodel.AccountResponse{
 		Total:    n,
 		Accounts: as,
 	}
@@ -143,7 +143,7 @@ func (ar *AuthResource) ChangePassword(w http.ResponseWriter, req *http.Request)
 		rest.WriteError(w, discovery.ErrInternal, err.Error())
 		return
 	}
-	a := &rbac.Account{}
+	a := &rbacmodel.Account{}
 	if err = json.Unmarshal(body, a); err != nil {
 		log.Error("json err", err)
 		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgJSON)
@@ -166,7 +166,7 @@ func (ar *AuthResource) Login(w http.ResponseWriter, r *http.Request) {
 		rest.WriteError(w, discovery.ErrInternal, err.Error())
 		return
 	}
-	a := &rbac.Account{}
+	a := &rbacmodel.Account{}
 	if err = json.Unmarshal(body, a); err != nil {
 		log.Error("json err", err)
 		rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
@@ -187,7 +187,7 @@ func (ar *AuthResource) Login(w http.ResponseWriter, r *http.Request) {
 		rest.WriteServiceError(w, err)
 		return
 	}
-	rest.WriteResponse(w, r, nil, &rbac.Token{TokenStr: t})
+	rest.WriteResponse(w, r, nil, &rbacmodel.Token{TokenStr: t})
 }
 
 func (ar *AuthResource) ListSelfPerms(w http.ResponseWriter, r *http.Request) {
@@ -197,7 +197,7 @@ func (ar *AuthResource) ListSelfPerms(w http.ResponseWriter, r *http.Request) {
 		rest.WriteServiceError(w, err)
 		return
 	}
-	resp := &rbac.SelfPermissionResponse{
+	resp := &rbacmodel.SelfPermissionResponse{
 		Perms: perms,
 	}
 	rest.WriteResponse(w, r, nil, resp)
@@ -211,9 +211,9 @@ func (ar *AuthResource) ListLock(w http.ResponseWriter, r *http.Request) {
 		rest.WriteServiceError(w, err)
 		return
 	}
-	resp := &datasource.AccountLockResponse{
-		Total:       n,
-		AccountLock: al,
+	resp := &rbac.LockResponse{
+		Total: n,
+		Locks: al,
 	}
 	rest.WriteResponse(w, r, nil, resp)
 }
diff --git a/server/resource/rbac/auth_resource_test.go b/server/resource/rbac/auth_resource_test.go
index ac8a5bd..977885c 100644
--- a/server/resource/rbac/auth_resource_test.go
+++ b/server/resource/rbac/auth_resource_test.go
@@ -29,7 +29,7 @@ import (
 
 	_ "github.com/apache/servicecomb-service-center/test"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/rest"
 	"github.com/apache/servicecomb-service-center/server/config"
 	v4 "github.com/apache/servicecomb-service-center/server/resource/rbac"
@@ -442,7 +442,7 @@ func TestAuthResource_ListLock(t *testing.T) {
 		w3 := httptest.NewRecorder()
 		rest.GetRouter().ServeHTTP(w3, r3)
 		assert.Equal(t, http.StatusOK, w3.Code)
-		resp := &datasource.AccountLockResponse{}
+		resp := &rbac.LockResponse{}
 		err := json.Unmarshal(w.Body.Bytes(), resp)
 		assert.NoError(t, err)
 	})
diff --git a/server/resource/rbac/role_resource_test.go b/server/resource/rbac/role_resource_test.go
index ad2d2f6..7148a53 100644
--- a/server/resource/rbac/role_resource_test.go
+++ b/server/resource/rbac/role_resource_test.go
@@ -20,31 +20,29 @@
 package rbac_test
 
 import (
-	"strings"
-
-	rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
-	_ "github.com/apache/servicecomb-service-center/test"
-	"github.com/go-chassis/cari/rbac"
-
 	"bytes"
 	"context"
 	"encoding/json"
 	"net/http"
 	"net/http/httptest"
+	"strings"
 	"testing"
 
+	_ "github.com/apache/servicecomb-service-center/test"
+
 	"github.com/apache/servicecomb-service-center/pkg/rest"
+	rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
 	rbacmodel "github.com/go-chassis/cari/rbac"
 	"github.com/go-chassis/go-chassis/v2/server/restful"
 	"github.com/stretchr/testify/assert"
 )
 
-func newRole(name string) *rbac.Role {
-	return &rbac.Role{
+func newRole(name string) *rbacmodel.Role {
+	return &rbacmodel.Role{
 		Name: name,
-		Perms: []*rbac.Permission{
+		Perms: []*rbacmodel.Permission{
 			{
-				Resources: []*rbac.Resource{
+				Resources: []*rbacmodel.Resource{
 					{
 						Type: rbacsvc.ResourceService,
 					},
@@ -60,11 +58,11 @@ const (
 	testPwd1 = "Ab@11111"
 )
 
-func newAccount(name string) *rbac.Account {
-	return &rbac.Account{
+func newAccount(name string) *rbacmodel.Account {
+	return &rbacmodel.Account{
 		Name:     name,
 		Password: testPwd0,
-		Roles:    []string{rbac.RoleAdmin},
+		Roles:    []string{rbacmodel.RoleAdmin},
 		Status:   "active",
 	}
 }
@@ -115,7 +113,7 @@ func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
 		assert.Equal(t, http.StatusOK, w3.Code)
 
 		newTestRole := newRole(testRole.Name)
-		newTestRole.Perms = []*rbac.Permission{
+		newTestRole.Perms = []*rbacmodel.Permission{
 			{
 				Resources: []*rbacmodel.Resource{{Type: rbacsvc.ResourceAccount}},
 				Verbs:     []string{"*"},
diff --git a/server/service/account/account.go b/server/service/account/account.go
index 36a6336..40ecdef 100644
--- a/server/service/account/account.go
+++ b/server/service/account/account.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/config"
 )
@@ -18,7 +18,7 @@ const (
 func IsBanned(ctx context.Context, key string) (bool, error) {
 	lock, err := GetLock(ctx, key)
 	if err != nil {
-		if err == datasource.ErrAccountLockNotExist {
+		if err == rbac.ErrAccountLockNotExist {
 			return false, nil
 		}
 		return false, err
@@ -27,46 +27,46 @@ func IsBanned(ctx context.Context, key string) (bool, error) {
 		err = DeleteLock(ctx, key)
 		if err != nil {
 			log.Error("remove lock failed", err)
-			return false, datasource.ErrCannotReleaseLock
+			return false, rbac.ErrCannotReleaseLock
 		}
 		log.Info(fmt.Sprintf("release lock for %s", key))
 		return false, nil
 	}
-	if lock.Status == datasource.StatusBanned {
+	if lock.Status == rbac.StatusBanned {
 		return true, nil
 	}
 	return false, nil
 }
 
 func Ban(ctx context.Context, key string) error {
-	return Lock(ctx, key, datasource.StatusBanned)
+	return Lock(ctx, key, rbac.StatusBanned)
 }
 
 func Lock(ctx context.Context, key, status string) error {
 	duration := config.GetDuration("rbac.retainLockHistoryFor", defaultRetainLockHistoryFor)
-	if status == datasource.StatusBanned {
+	if status == rbac.StatusBanned {
 		duration = config.GetDuration("rbac.releaseLockAfter", defaultReleaseLockAfter)
 	}
-	lock := &datasource.AccountLock{
+	lock := &rbac.Lock{
 		Key:       key,
 		Status:    status,
 		ReleaseAt: time.Now().Add(duration).Unix(),
 	}
-	return datasource.GetAccountLockManager().UpsertLock(ctx, lock)
+	return rbac.Instance().UpsertLock(ctx, lock)
 }
 
-func GetLock(ctx context.Context, key string) (*datasource.AccountLock, error) {
-	return datasource.GetAccountLockManager().GetLock(ctx, key)
+func GetLock(ctx context.Context, key string) (*rbac.Lock, error) {
+	return rbac.Instance().GetLock(ctx, key)
 }
 
-func ListLock(ctx context.Context) ([]*datasource.AccountLock, int64, error) {
-	return datasource.GetAccountLockManager().ListLock(ctx)
+func ListLock(ctx context.Context) ([]*rbac.Lock, int64, error) {
+	return rbac.Instance().ListLock(ctx)
 }
 
 func DeleteLock(ctx context.Context, key string) error {
-	return datasource.GetAccountLockManager().DeleteLock(ctx, key)
+	return rbac.Instance().DeleteLock(ctx, key)
 }
 
 func DeleteLockList(ctx context.Context, keys []string) error {
-	return datasource.GetAccountLockManager().DeleteLockList(ctx, keys)
+	return rbac.Instance().DeleteLockList(ctx, keys)
 }
diff --git a/server/service/account/account_test.go b/server/service/account/account_test.go
index 2c18e9d..6b33e4b 100644
--- a/server/service/account/account_test.go
+++ b/server/service/account/account_test.go
@@ -7,27 +7,27 @@ import (
 
 	_ "github.com/apache/servicecomb-service-center/test"
 
-	"github.com/apache/servicecomb-service-center/datasource"
-	"github.com/apache/servicecomb-service-center/server/service/account"
+	dao "github.com/apache/servicecomb-service-center/datasource/rbac"
+	accountsvc "github.com/apache/servicecomb-service-center/server/service/account"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestIsBanned(t *testing.T) {
 	t.Run("ban a key and check status, it should be banned, check other key should not be banned",
 		func(t *testing.T) {
-			err := account.Ban(context.TODO(), "dev_guy::127.0.0.1")
+			err := accountsvc.Ban(context.TODO(), "dev_guy::127.0.0.1")
 			assert.NoError(t, err)
 
-			ok, err := account.IsBanned(context.TODO(), "dev_guy::127.0.0.1")
+			ok, err := accountsvc.IsBanned(context.TODO(), "dev_guy::127.0.0.1")
 			assert.NoError(t, err)
 			assert.True(t, ok)
 
-			ok, err = account.IsBanned(context.TODO(), "test_guy::127.0.0.1")
+			ok, err = accountsvc.IsBanned(context.TODO(), "test_guy::127.0.0.1")
 			assert.NoError(t, err)
 			assert.False(t, ok)
 
 			time.Sleep(4 * time.Second)
-			ok, err = account.IsBanned(context.TODO(), "dev_guy::127.0.0.1")
+			ok, err = accountsvc.IsBanned(context.TODO(), "dev_guy::127.0.0.1")
 			assert.NoError(t, err)
 			assert.False(t, ok)
 		})
@@ -35,10 +35,10 @@ func TestIsBanned(t *testing.T) {
 
 func TestListLock(t *testing.T) {
 	t.Run("list 1 account lock, should return 1 item", func(t *testing.T) {
-		err := account.Ban(context.TODO(), "dev_lock::127.0.0.1")
+		err := accountsvc.Ban(context.TODO(), "dev_lock::127.0.0.1")
 		assert.NoError(t, err)
 
-		locks, n, err := account.ListLock(context.Background())
+		locks, n, err := accountsvc.ListLock(context.Background())
 		assert.NoError(t, err)
 		assert.NotEqual(t, 0, n)
 		for _, lock := range locks {
@@ -54,12 +54,12 @@ func TestBan(t *testing.T) {
 	var banTime int64
 
 	t.Run("ban account TestAccountLock, should return no error", func(t *testing.T) {
-		err := account.Ban(context.Background(), "TestAccountLock")
+		err := accountsvc.Ban(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
 
-		lock, err := datasource.GetAccountLockManager().GetLock(context.Background(), "TestAccountLock")
+		lock, err := dao.Instance().GetLock(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
-		assert.Equal(t, datasource.StatusBanned, lock.Status)
+		assert.Equal(t, dao.StatusBanned, lock.Status)
 		assert.Less(t, time.Now().Unix(), lock.ReleaseAt)
 
 		banTime = lock.ReleaseAt
@@ -68,35 +68,35 @@ func TestBan(t *testing.T) {
 	t.Run("ban account TestAccountLock again, should return a new release time", func(t *testing.T) {
 		time.Sleep(time.Second)
 
-		err := account.Ban(context.Background(), "TestAccountLock")
+		err := accountsvc.Ban(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
 
-		lock, err := datasource.GetAccountLockManager().GetLock(context.Background(), "TestAccountLock")
+		lock, err := dao.Instance().GetLock(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
-		assert.Equal(t, datasource.StatusBanned, lock.Status)
+		assert.Equal(t, dao.StatusBanned, lock.Status)
 		assert.Less(t, banTime, lock.ReleaseAt)
 	})
 
 	t.Run("ban account TestAccountLock again, should refresh releaseAt", func(t *testing.T) {
-		lock1, err := datasource.GetAccountLockManager().GetLock(context.Background(), "TestAccountLock")
+		lock1, err := dao.Instance().GetLock(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
-		assert.Equal(t, datasource.StatusBanned, lock1.Status)
+		assert.Equal(t, dao.StatusBanned, lock1.Status)
 
 		time.Sleep(time.Second)
-		err = account.Ban(context.Background(), "TestAccountLock")
+		err = accountsvc.Ban(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
 
-		lock2, err := datasource.GetAccountLockManager().GetLock(context.Background(), "TestAccountLock")
+		lock2, err := dao.Instance().GetLock(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
 		assert.Less(t, lock1.ReleaseAt, lock2.ReleaseAt)
 	})
 
 	t.Run("delete account lock, should return no error", func(t *testing.T) {
-		err := datasource.GetAccountLockManager().DeleteLock(context.Background(), "TestAccountLock")
+		err := dao.Instance().DeleteLock(context.Background(), "TestAccountLock")
 		assert.NoError(t, err)
 
-		lock, err := datasource.GetAccountLockManager().GetLock(context.Background(), "TestAccountLock")
-		assert.Equal(t, datasource.ErrAccountLockNotExist, err)
+		lock, err := dao.Instance().GetLock(context.Background(), "TestAccountLock")
+		assert.Equal(t, dao.ErrAccountLockNotExist, err)
 		assert.Nil(t, lock)
 	})
 }
diff --git a/server/service/rbac/account_service.go b/server/service/rbac/account_service.go
index f893f37..04d0fa4 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -22,20 +22,20 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	"github.com/go-chassis/cari/discovery"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 )
 
 //CreateAccount save account info
-func CreateAccount(ctx context.Context, a *rbac.Account) error {
+func CreateAccount(ctx context.Context, a *rbacmodel.Account) error {
 	quotaErr := quotasvc.ApplyAccount(ctx, 1)
 	if quotaErr != nil {
-		return rbac.NewError(rbac.ErrAccountNoQuota, quotaErr.Error())
+		return rbacmodel.NewError(rbacmodel.ErrAccountNoQuota, quotaErr.Error())
 	}
 	err := validator.ValidateCreateAccount(a)
 	if err != nil {
@@ -51,23 +51,23 @@ func CreateAccount(ctx context.Context, a *rbac.Account) error {
 		return discovery.NewError(discovery.ErrInvalidParams, err.Error())
 	}
 	if err = checkRoleNames(ctx, a.Roles); err != nil {
-		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+		return rbacmodel.NewError(rbacmodel.ErrAccountHasInvalidRole, err.Error())
 	}
 
-	err = datasource.GetAccountManager().CreateAccount(ctx, a)
+	err = rbac.Instance().CreateAccount(ctx, a)
 	if err == nil {
 		log.Info(fmt.Sprintf("create account [%s] success", a.Name))
 		return nil
 	}
 	log.Error(fmt.Sprintf("create account [%s] failed", a.Name), err)
-	if err == datasource.ErrAccountDuplicated {
-		return rbac.NewError(rbac.ErrAccountConflict, err.Error())
+	if err == rbac.ErrAccountDuplicated {
+		return rbacmodel.NewError(rbacmodel.ErrAccountConflict, err.Error())
 	}
 	return err
 }
 
 // UpdateAccount updates an account's info, except the password
-func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
+func UpdateAccount(ctx context.Context, name string, a *rbacmodel.Account) error {
 	// todo params validation
 	err := validator.ValidateUpdateAccount(a)
 	if err != nil {
@@ -92,9 +92,9 @@ func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
 		oldAccount.Roles = a.Roles
 	}
 	if err = checkRoleNames(ctx, oldAccount.Roles); err != nil {
-		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+		return rbacmodel.NewError(rbacmodel.ErrAccountHasInvalidRole, err.Error())
 	}
-	err = datasource.GetAccountManager().UpdateAccount(ctx, name, oldAccount)
+	err = rbac.Instance().UpdateAccount(ctx, name, oldAccount)
 	if err != nil {
 		log.Error("can not edit account info", err)
 		return err
@@ -103,52 +103,52 @@ func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
 	return nil
 }
 
-func GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
-	r, err := datasource.GetAccountManager().GetAccount(ctx, name)
+func GetAccount(ctx context.Context, name string) (*rbacmodel.Account, error) {
+	r, err := rbac.Instance().GetAccount(ctx, name)
 	if err != nil {
-		if err == datasource.ErrAccountNotExist {
+		if err == rbac.ErrAccountNotExist {
 			msg := fmt.Sprintf("account [%s] not exist", name)
-			return nil, rbac.NewError(rbac.ErrAccountNotExist, msg)
+			return nil, rbacmodel.NewError(rbacmodel.ErrAccountNotExist, msg)
 		}
 		return nil, err
 	}
 	return r, nil
 }
-func ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
-	return datasource.GetAccountManager().ListAccount(ctx)
+func ListAccount(ctx context.Context) ([]*rbacmodel.Account, int64, error) {
+	return rbac.Instance().ListAccount(ctx)
 }
 func AccountExist(ctx context.Context, name string) (bool, error) {
-	return datasource.GetAccountManager().AccountExist(ctx, name)
+	return rbac.Instance().AccountExist(ctx, name)
 }
 func DeleteAccount(ctx context.Context, name string) error {
 	if err := illegalAccountCheck(ctx, name); err != nil {
 		return err
 	}
-	exist, err := datasource.GetAccountManager().AccountExist(ctx, name)
+	exist, err := rbac.Instance().AccountExist(ctx, name)
 	if err != nil {
 		log.Error(fmt.Sprintf("check account [%s] exit failed", name), err)
 		return err
 	}
 	if !exist {
 		msg := fmt.Sprintf("account [%s] not exist", name)
-		return rbac.NewError(rbac.ErrAccountNotExist, msg)
+		return rbacmodel.NewError(rbacmodel.ErrAccountNotExist, msg)
 	}
-	_, err = datasource.GetAccountManager().DeleteAccount(ctx, []string{name})
+	_, err = rbac.Instance().DeleteAccount(ctx, []string{name})
 	return err
 }
 
 //EditAccount save account info
-func EditAccount(ctx context.Context, a *rbac.Account) error {
-	exist, err := datasource.GetAccountManager().AccountExist(ctx, a.Name)
+func EditAccount(ctx context.Context, a *rbacmodel.Account) error {
+	exist, err := rbac.Instance().AccountExist(ctx, a.Name)
 	if err != nil {
 		log.Error("can not edit account info", err)
 		return err
 	}
 	if !exist {
-		return rbac.NewError(rbac.ErrAccountNotExist, "")
+		return rbacmodel.NewError(rbacmodel.ErrAccountNotExist, "")
 	}
 
-	err = datasource.GetAccountManager().UpdateAccount(ctx, a.Name, a)
+	err = rbac.Instance().UpdateAccount(ctx, a.Name, a)
 	if err != nil {
 		log.Error("can not edit account info", err)
 		return err
@@ -165,7 +165,7 @@ func checkRoleNames(ctx context.Context, roles []string) error {
 			return err
 		}
 		if !exist {
-			return datasource.ErrRoleNotExist
+			return rbac.ErrRoleNotExist
 		}
 	}
 	return nil
@@ -173,11 +173,11 @@ func checkRoleNames(ctx context.Context, roles []string) error {
 
 func illegalAccountCheck(ctx context.Context, target string) error {
 	if target == RootName {
-		return rbac.NewError(rbac.ErrForbidOperateBuildInAccount, errorsEx.MsgCantOperateRoot)
+		return rbacmodel.NewError(rbacmodel.ErrForbidOperateBuildInAccount, errorsEx.MsgCantOperateRoot)
 	}
 	changer := UserFromContext(ctx)
 	if target == changer {
-		return rbac.NewError(rbac.ErrForbidOperateSelfAccount, errorsEx.MsgCantOperateYour)
+		return rbacmodel.NewError(rbacmodel.ErrForbidOperateSelfAccount, errorsEx.MsgCantOperateYour)
 	}
 	return nil
 }
diff --git a/server/service/rbac/blocker.go b/server/service/rbac/blocker.go
index 6f6d943..365abe5 100644
--- a/server/service/rbac/blocker.go
+++ b/server/service/rbac/blocker.go
@@ -23,7 +23,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	accountsvc "github.com/apache/servicecomb-service-center/server/service/account"
 	"golang.org/x/time/rate"
@@ -59,9 +59,9 @@ func TryLockAccount(key string) {
 	}
 
 	allow := l.limiter.AllowN(time.Now(), 1)
-	status := datasource.StatusAttempted
+	status := rbac.StatusAttempted
 	if !allow {
-		status = datasource.StatusBanned
+		status = rbac.StatusBanned
 	}
 	err := accountsvc.Lock(context.Background(), key, status)
 	if err != nil {
diff --git a/server/service/rbac/blocker_test.go b/server/service/rbac/blocker_test.go
index eb9e801..b4d9b3e 100644
--- a/server/service/rbac/blocker_test.go
+++ b/server/service/rbac/blocker_test.go
@@ -22,7 +22,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	dao "github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/server/resource/rbac"
 	accountsvc "github.com/apache/servicecomb-service-center/server/service/account"
 	rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
@@ -61,9 +61,9 @@ func TestCountFailure(t *testing.T) {
 		assert.False(t, rbacsvc.IsBanned(key2))
 
 		_, err := accountsvc.GetLock(context.Background(), key1)
-		assert.ErrorIs(t, datasource.ErrAccountLockNotExist, err)
+		assert.ErrorIs(t, dao.ErrAccountLockNotExist, err)
 		_, err = accountsvc.GetLock(context.Background(), key2)
-		assert.ErrorIs(t, datasource.ErrAccountLockNotExist, err)
+		assert.ErrorIs(t, dao.ErrAccountLockNotExist, err)
 	})
 }
 
@@ -75,7 +75,7 @@ func TestTryLockAccount(t *testing.T) {
 
 		lock, err := accountsvc.GetLock(context.Background(), key1)
 		assert.NoError(t, err)
-		assert.Equal(t, datasource.StatusAttempted, lock.Status)
+		assert.Equal(t, dao.StatusAttempted, lock.Status)
 
 		assert.False(t, rbacsvc.IsBanned(key1))
 
@@ -89,7 +89,7 @@ func TestTryLockAccount(t *testing.T) {
 
 		lock, err := accountsvc.GetLock(context.Background(), key1)
 		assert.NoError(t, err)
-		assert.Equal(t, datasource.StatusAttempted, lock.Status)
+		assert.Equal(t, dao.StatusAttempted, lock.Status)
 		assert.Less(t, oldReleaseAt, lock.ReleaseAt)
 
 		assert.False(t, rbacsvc.IsBanned(key1))
diff --git a/server/service/rbac/decision.go b/server/service/rbac/decision.go
index 96b1649..4a82577 100644
--- a/server/service/rbac/decision.go
+++ b/server/service/rbac/decision.go
@@ -21,10 +21,10 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/plugin/auth"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 )
 
 // Allow return: matched labels(empty if no label defined), error
@@ -38,11 +38,11 @@ func Allow(ctx context.Context, project string, roleList []string,
 	}
 	if len(allPerms) == 0 {
 		log.Warn("role list has no any permissions")
-		return nil, rbac.NewError(rbac.ErrNoPermission, "role has no any permissions")
+		return nil, rbacmodel.NewError(rbacmodel.ErrNoPermission, "role has no any permissions")
 	}
 	allow, labelList := GetLabel(allPerms, targetResource.Type, targetResource.Verb)
 	if !allow {
-		return nil, rbac.NewError(rbac.ErrNoPermission,
+		return nil, rbacmodel.NewError(rbacmodel.ErrNoPermission,
 			fmt.Sprintf("role has no permissions[%s:%s]", targetResource.Type, targetResource.Verb))
 	}
 	// allow, but no label found, means we can ignore the labels
@@ -57,7 +57,7 @@ func Allow(ctx context.Context, project string, roleList []string,
 	filteredLabelList := FilterLabel(targetResource.Labels, labelList)
 	// target resource label matches no label in permission, means not allow
 	if len(filteredLabelList) == 0 {
-		return nil, rbac.NewError(rbac.ErrNoPermission,
+		return nil, rbacmodel.NewError(rbacmodel.ErrNoPermission,
 			fmt.Sprintf("role has no permissions[%s:%s] for labels %v",
 				targetResource.Type, targetResource.Verb, targetResource.Labels))
 	}
@@ -85,15 +85,15 @@ func LabelMatched(targetResourceLabel map[string]string, permLabel map[string]st
 	return true
 }
 
-func getPermsByRoles(ctx context.Context, roleList []string) ([]*rbac.Permission, error) {
-	var allPerms = make([]*rbac.Permission, 0)
+func getPermsByRoles(ctx context.Context, roleList []string) ([]*rbacmodel.Permission, error) {
+	var allPerms = make([]*rbacmodel.Permission, 0)
 	for _, name := range roleList {
-		r, err := datasource.GetRoleManager().GetRole(ctx, name)
+		r, err := rbac.Instance().GetRole(ctx, name)
 		if err == nil {
 			allPerms = append(allPerms, r.Perms...)
 			continue
 		}
-		if err == datasource.ErrRoleNotExist {
+		if err == rbac.ErrRoleNotExist {
 			log.Warn(fmt.Sprintf("role [%s] not exist", name))
 			continue
 		}
@@ -105,7 +105,7 @@ func getPermsByRoles(ctx context.Context, roleList []string) ([]*rbac.Permission
 
 // GetLabel checks if the perms have permission to operate the resource(ignore label),
 // if one perm have the permission, add it's label to the result.
-func GetLabel(perms []*rbac.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
+func GetLabel(perms []*rbacmodel.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
 	for _, perm := range perms {
 		a, l := GetLabelFromSinglePerm(perm, targetResource, verb)
 		if !a {
@@ -123,7 +123,7 @@ func GetLabel(perms []*rbac.Permission, targetResource, verb string) (allow bool
 
 // GetLabel checks if the perm have permission to operate the resource(ignore label),
 // if the perm have the permission, return it's label.
-func GetLabelFromSinglePerm(perm *rbac.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
+func GetLabelFromSinglePerm(perm *rbacmodel.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
 	if !allowVerb(perm.Verbs, verb) {
 		return false, nil
 	}
@@ -140,7 +140,7 @@ func allowVerb(haystack []string, needle string) bool {
 	return false
 }
 
-func getResourceLabel(resources []*rbac.Resource, needle string) (allow bool, labelList []map[string]string) {
+func getResourceLabel(resources []*rbacmodel.Resource, needle string) (allow bool, labelList []map[string]string) {
 	for _, resource := range resources {
 		// filter the same resource
 		if resource.Type != needle {
diff --git a/server/service/rbac/perm_service.go b/server/service/rbac/perm_service.go
index 961e430..351b8eb 100644
--- a/server/service/rbac/perm_service.go
+++ b/server/service/rbac/perm_service.go
@@ -20,24 +20,24 @@ package rbac
 import (
 	"context"
 
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
-	"github.com/go-chassis/cari/rbac"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 )
 
 // ListSelfPerms list the user permission from ctx
-func ListSelfPerms(ctx context.Context) ([]*rbac.Permission, error) {
+func ListSelfPerms(ctx context.Context) ([]*rbacmodel.Permission, error) {
 	user := UserFromContext(ctx)
 	if len(user) == 0 {
-		return nil, rbac.NewError(rbac.ErrUnauthorized, errorsEx.MsgListSelfPermsFailed)
+		return nil, rbacmodel.NewError(rbacmodel.ErrUnauthorized, errorsEx.MsgListSelfPermsFailed)
 	}
-	account, err := datasource.GetAccountManager().GetAccount(ctx, user)
+	account, err := rbac.Instance().GetAccount(ctx, user)
 	if err != nil {
 		return nil, err
 	}
-	var perms []*rbac.Permission
+	var perms []*rbacmodel.Permission
 	for _, roleName := range account.Roles {
-		role, err := datasource.GetRoleManager().GetRole(ctx, roleName)
+		role, err := rbac.Instance().GetRole(ctx, roleName)
 		if err != nil {
 			return nil, err
 		}
diff --git a/server/service/rbac/role_service.go b/server/service/rbac/role_service.go
index a317596..9bb24ee 100644
--- a/server/service/rbac/role_service.go
+++ b/server/service/rbac/role_service.go
@@ -22,17 +22,16 @@ import (
 	"errors"
 	"fmt"
 
-	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
-	"github.com/go-chassis/cari/discovery"
-	"github.com/go-chassis/cari/rbac"
-
-	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/rbac"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
 	"github.com/apache/servicecomb-service-center/pkg/log"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
+	"github.com/go-chassis/cari/discovery"
+	rbacmodel "github.com/go-chassis/cari/rbac"
 )
 
-func CreateRole(ctx context.Context, r *rbac.Role) error {
+func CreateRole(ctx context.Context, r *rbacmodel.Role) error {
 	err := validator.ValidateCreateRole(r)
 	if err != nil {
 		log.Error(fmt.Sprintf("create role [%s] failed", r.Name), err)
@@ -40,39 +39,39 @@ func CreateRole(ctx context.Context, r *rbac.Role) error {
 	}
 	quotaErr := quotasvc.ApplyRole(ctx, 1)
 	if quotaErr != nil {
-		return rbac.NewError(rbac.ErrRoleNoQuota, quotaErr.Error())
+		return rbacmodel.NewError(rbacmodel.ErrRoleNoQuota, quotaErr.Error())
 	}
-	err = datasource.GetRoleManager().CreateRole(ctx, r)
+	err = rbac.Instance().CreateRole(ctx, r)
 	if err == nil {
 		log.Info(fmt.Sprintf("create role [%s] success", r.Name))
 		return nil
 	}
 
 	log.Error(fmt.Sprintf("create role [%s] failed", r.Name), err)
-	if err == datasource.ErrRoleDuplicated {
-		return rbac.NewError(rbac.ErrRoleConflict, err.Error())
+	if err == rbac.ErrRoleDuplicated {
+		return rbacmodel.NewError(rbacmodel.ErrRoleConflict, err.Error())
 	}
 
 	return err
 }
 
-func GetRole(ctx context.Context, name string) (*rbac.Role, error) {
-	resp, err := datasource.GetRoleManager().GetRole(ctx, name)
+func GetRole(ctx context.Context, name string) (*rbacmodel.Role, error) {
+	resp, err := rbac.Instance().GetRole(ctx, name)
 	if err == nil {
 		return resp, nil
 	}
-	if err == datasource.ErrRoleNotExist {
-		return nil, rbac.NewError(rbac.ErrRoleNotExist, "")
+	if err == rbac.ErrRoleNotExist {
+		return nil, rbacmodel.NewError(rbacmodel.ErrRoleNotExist, "")
 	}
 	return nil, err
 }
 
-func ListRole(ctx context.Context) ([]*rbac.Role, int64, error) {
-	return datasource.GetRoleManager().ListRole(ctx)
+func ListRole(ctx context.Context) ([]*rbacmodel.Role, int64, error) {
+	return rbac.Instance().ListRole(ctx)
 }
 
 func RoleExist(ctx context.Context, name string) (bool, error) {
-	return datasource.GetRoleManager().RoleExist(ctx, name)
+	return rbac.Instance().RoleExist(ctx, name)
 }
 
 func DeleteRole(ctx context.Context, name string) error {
@@ -86,12 +85,12 @@ func DeleteRole(ctx context.Context, name string) error {
 	}
 	if !exist {
 		log.Error(fmt.Sprintf("role [%s] not exist", name), err)
-		return rbac.NewError(rbac.ErrRoleNotExist, "")
+		return rbacmodel.NewError(rbacmodel.ErrRoleNotExist, "")
 	}
-	succeed, err := datasource.GetRoleManager().DeleteRole(ctx, name)
+	succeed, err := rbac.Instance().DeleteRole(ctx, name)
 	if err != nil {
-		if errors.Is(err, datasource.ErrRoleBindingExist) {
-			return rbac.NewError(rbac.ErrRoleIsBound, "")
+		if errors.Is(err, rbac.ErrRoleBindingExist) {
+			return rbacmodel.NewError(rbacmodel.ErrRoleIsBound, "")
 		}
 		return err
 	}
@@ -101,7 +100,7 @@ func DeleteRole(ctx context.Context, name string) error {
 	return nil
 }
 
-func EditRole(ctx context.Context, name string, a *rbac.Role) error {
+func EditRole(ctx context.Context, name string, a *rbacmodel.Role) error {
 	if err := illegalRoleCheck(name); err != nil {
 		return err
 	}
@@ -112,7 +111,7 @@ func EditRole(ctx context.Context, name string, a *rbac.Role) error {
 	}
 	if !exist {
 		log.Error(fmt.Sprintf("role [%s] not exist", name), err)
-		return rbac.NewError(rbac.ErrRoleNotExist, "")
+		return rbacmodel.NewError(rbacmodel.ErrRoleNotExist, "")
 	}
 	oldRole, err := GetRole(ctx, name)
 	if err != nil {
@@ -122,7 +121,7 @@ func EditRole(ctx context.Context, name string, a *rbac.Role) error {
 
 	oldRole.Perms = a.Perms
 
-	err = datasource.GetRoleManager().UpdateRole(ctx, name, oldRole)
+	err = rbac.Instance().UpdateRole(ctx, name, oldRole)
 	if err != nil {
 		log.Error("can not edit role info", err)
 		return err
@@ -132,8 +131,8 @@ func EditRole(ctx context.Context, name string, a *rbac.Role) error {
 }
 
 func illegalRoleCheck(role string) error {
-	if role == rbac.RoleAdmin || role == rbac.RoleDeveloper {
-		return rbac.NewError(rbac.ErrForbidOperateBuildInRole, errorsEx.MsgCantOperateBuildInRole)
+	if role == rbacmodel.RoleAdmin || role == rbacmodel.RoleDeveloper {
+		return rbacmodel.NewError(rbacmodel.ErrForbidOperateBuildInRole, errorsEx.MsgCantOperateBuildInRole)
 	}
 	return nil
 }