You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2022/12/05 09:28:31 UTC

[servicecomb-kie] branch master updated: Feature:新增rbac认证 (#264)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 69df80a  Feature:新增rbac认证 (#264)
69df80a is described below

commit 69df80ad4b8992654c6c53cfed97902e52670199
Author: little-cui <su...@qq.com>
AuthorDate: Mon Dec 5 17:28:25 2022 +0800

    Feature:新增rbac认证 (#264)
    
    * Feature:新增rbac认证 (#262)
    
    * 增加RBAC认证
    
    * 增加RBAC认证
    
    Co-authored-by: 123yangxiong <18...@163.com>
    
    * Feature:新增rbac认证 (#263)
    
    Co-authored-by: little-cui <su...@qq.com>
    
    * 增加RBAC校验 (#265)
    
    * 增加RBAC校验
    
    * Update filter_kvdoc_test.go
    
    * Update service.go
    
    * 添加license header,文件名makeScope改为scope_source (#266)
    
    * 增加RBAC校验
    
    * 增加license header,文件makeScope改名为resource_scope
    
    * rbac增加弱检查;修复无get权限时,获取配置列表报错。 (#267)
    
    * 修复只有create权限时,create配置报错;get list label匹配错误 (#268)
    
    * 修复批量删除和导入panic (#269)
    
    * 修改rbac无权限返回错误 (#271)
    
    Co-authored-by: 123yangxiong <18...@163.com>
    Co-authored-by: 123yangxiong <11...@users.noreply.github.com>
---
 .github/workflows/build.yml                        |   2 +-
 .github/workflows/etcd_storage.yml                 |   4 +-
 .github/workflows/golangci-lint.yml                |   2 +-
 .github/workflows/mongo_storage.yml                |   2 +-
 go.mod                                             |  34 ++--
 go.sum                                             | 199 ++++++++++++++++++---
 pkg/util/util.go                                   |  15 +-
 server/config/struct.go                            |   5 +-
 server/datasource/auth/decision.go                 | 155 ++++++++++++++++
 server/datasource/auth/decision_test.go            |  78 ++++++++
 .../datasource/auth/filter_kvdoc.go                |  34 ++--
 server/datasource/auth/filter_kvdoc_test.go        |  55 ++++++
 server/datasource/auth/identify.go                 |  72 ++++++++
 server/datasource/auth/perm.go                     |  60 +++++++
 .../datasource/auth/resource_scope.go              |  33 +---
 server/datasource/auth/service.go                  |  86 +++++++++
 server/datasource/dao.go                           |   3 +
 server/datasource/etcd/counter/revision.go         |   3 +-
 server/datasource/etcd/history/history_dao.go      |  14 ++
 server/datasource/etcd/init.go                     |   5 +
 server/datasource/etcd/kv/kv_dao.go                |  96 +++++++++-
 .../etcd/{counter/revision.go => rbac/rbac.go}     |  47 ++---
 server/datasource/mongo/init.go                    |   5 +
 server/datasource/mongo/kv/kv_dao.go               |  27 +++
 .../datasource/mongo/rbac/rbac.go                  |  34 ++--
 pkg/util/util.go => server/datasource/rbac/rbac.go |  30 +---
 server/rbac/rbac.go                                |  15 +-
 server/resource/v1/common.go                       |  17 +-
 server/resource/v1/history_resource.go             |   2 +-
 server/resource/v1/kv_resource.go                  |   9 +-
 server/service/kv/kv_svc.go                        |  17 +-
 server/service/kv/override_force.go                |  16 +-
 32 files changed, 986 insertions(+), 190 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c881b52..27758e4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,7 +7,7 @@ jobs:
     - name: Set up Go
       uses: actions/setup-go@v1
       with:
-        go-version: 1.16
+        go-version: 1.18
       id: go
     - name: Check out code into the Go module directory
       uses: actions/checkout@v1
diff --git a/.github/workflows/etcd_storage.yml b/.github/workflows/etcd_storage.yml
index 6426926..47202b0 100644
--- a/.github/workflows/etcd_storage.yml
+++ b/.github/workflows/etcd_storage.yml
@@ -7,7 +7,7 @@ jobs:
     - name: Set up Go
       uses: actions/setup-go@v1
       with:
-        go-version: 1.16
+        go-version: 1.18
       id: go
     - name: Check out code into the Go module directory
       uses: actions/checkout@v1
@@ -26,7 +26,7 @@ jobs:
         - name: Set up Go
           uses: actions/setup-go@v1
           with:
-            go-version: 1.16
+            go-version: 1.18
           id: go
         - name: Check out code into the Go module directory
           uses: actions/checkout@v1
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index fea97e3..cd29af6 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -25,7 +25,7 @@ jobs:
       - name: Set up Go
         uses: actions/setup-go@v1
         with:
-          go-version: 1.17
+          go-version: 1.18
         id: go
       - name: Checkout Source
         uses: actions/checkout@v2
diff --git a/.github/workflows/mongo_storage.yml b/.github/workflows/mongo_storage.yml
index 2c1ff02..b690deb 100644
--- a/.github/workflows/mongo_storage.yml
+++ b/.github/workflows/mongo_storage.yml
@@ -7,7 +7,7 @@ jobs:
     - name: Set up Go
       uses: actions/setup-go@v1
       with:
-        go-version: 1.16
+        go-version: 1.18
       id: go
     - name: Check out code into the Go module directory
       uses: actions/checkout@v1
diff --git a/go.mod b/go.mod
index df8d377..43ef4cd 100644
--- a/go.mod
+++ b/go.mod
@@ -3,18 +3,18 @@ module github.com/apache/servicecomb-kie
 require (
 	github.com/apache/servicecomb-service-center/eventbase v0.0.0-20220120070230-26997eb876ca
 	github.com/emicklei/go-restful v2.15.1-0.20220703112237-d9c71e118c95+incompatible
-	github.com/go-chassis/cari v0.5.1-0.20220216075429-46c79de3311f
+	github.com/go-chassis/cari v0.7.1-0.20220815112157-2c62cc5ae1a3
 	github.com/go-chassis/foundation v0.4.0
 	github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b
-	github.com/go-chassis/go-chassis/v2 v2.5.2
+	github.com/go-chassis/go-chassis/v2 v2.7.1
 	github.com/go-chassis/openlog v1.1.3
 	github.com/go-chassis/seclog v1.3.1-0.20210917082355-52c40864f240
 	github.com/gofrs/uuid v4.0.0+incompatible
 	github.com/hashicorp/serf v0.9.5
 	github.com/little-cui/etcdadpt v0.3.2
-	github.com/stretchr/testify v1.7.0
+	github.com/stretchr/testify v1.7.1
 	github.com/urfave/cli v1.22.4
-	go.mongodb.org/mongo-driver v1.4.6
+	go.mongodb.org/mongo-driver v1.5.1
 	gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -27,7 +27,7 @@ require (
 	github.com/bgentry/speakeasy v0.1.0 // indirect
 	github.com/cenkalti/backoff v2.2.1+incompatible // indirect
 	github.com/cenkalti/backoff/v4 v4.1.1 // indirect
-	github.com/cespare/xxhash/v2 v2.1.1 // indirect
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 	github.com/coreos/go-semver v0.3.0 // indirect
 	github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
 	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
@@ -41,7 +41,7 @@ require (
 	github.com/fsnotify/fsnotify v1.4.9 // indirect
 	github.com/go-chassis/go-restful-swagger20 v1.0.4-0.20220704025524-9243cbee26b7 // indirect
 	github.com/go-chassis/kie-client v0.1.1-0.20210926011742-97eed4281056 // indirect
-	github.com/go-chassis/sc-client v0.6.1-0.20210918130508-2b9daad232da // indirect
+	github.com/go-chassis/sc-client v0.6.1-0.20220728072125-dacdd0c834bf // indirect
 	github.com/go-playground/locales v0.13.0 // indirect
 	github.com/go-playground/universal-translator v0.17.0 // indirect
 	github.com/go-playground/validator v9.31.0+incompatible // indirect
@@ -68,7 +68,7 @@ require (
 	github.com/hashicorp/memberlist v0.2.2 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/jonboulle/clockwork v0.2.2 // indirect
-	github.com/json-iterator/go v1.1.11 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/karlseguin/ccache/v2 v2.0.8 // indirect
 	github.com/klauspost/compress v1.9.5 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
@@ -79,16 +79,16 @@ require (
 	github.com/mitchellh/cli v1.1.0 // indirect
 	github.com/mitchellh/mapstructure v1.1.2 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
-	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/opentracing/opentracing-go v1.1.0 // indirect
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/posener/complete v1.2.3 // indirect
-	github.com/prometheus/client_golang v1.11.0 // indirect
+	github.com/prometheus/client_golang v1.12.2 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
-	github.com/prometheus/common v0.26.0 // indirect
-	github.com/prometheus/procfs v0.6.0 // indirect
+	github.com/prometheus/common v0.32.1 // indirect
+	github.com/prometheus/procfs v0.7.3 // indirect
 	github.com/russross/blackfriday/v2 v2.0.1 // indirect
 	github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
@@ -97,9 +97,11 @@ require (
 	github.com/spf13/cast v1.3.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
-	github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
-	github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc // indirect
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+	github.com/xdg-go/scram v1.0.2 // indirect
+	github.com/xdg-go/stringprep v1.0.2 // indirect
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 	go.etcd.io/bbolt v1.3.6 // indirect
 	go.etcd.io/etcd/api/v3 v3.5.0 // indirect
 	go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect
@@ -122,9 +124,9 @@ require (
 	go.uber.org/multierr v1.6.0 // indirect
 	go.uber.org/zap v1.17.0 // indirect
 	golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
-	golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
+	golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-	golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect
+	golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
 	google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
@@ -138,4 +140,4 @@ require (
 	sigs.k8s.io/yaml v1.2.0 // indirect
 )
 
-go 1.17
+go 1.18
diff --git a/go.sum b/go.sum
index a24292e..aa74546 100644
--- a/go.sum
+++ b/go.sum
@@ -5,13 +5,34 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A
 cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
 cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
 cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
 cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
 github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
@@ -71,8 +92,9 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5P
 github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
 github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
-github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -117,7 +139,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
 github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.12.0+incompatible h1:SIvoTSbsMEwuM3dzFirLwKc4BH6VXP5CNf+G1FfJVr4=
 github.com/emicklei/go-restful v2.12.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful v2.15.1-0.20220703112237-d9c71e118c95+incompatible h1:o87Jf90Yb9ZvrdJKy2jYAdzosa7MtC2H214tJxJx7As=
 github.com/emicklei/go-restful v2.15.1-0.20220703112237-d9c71e118c95+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
@@ -149,8 +170,8 @@ github.com/go-chassis/cari v0.4.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SK
 github.com/go-chassis/cari v0.5.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
 github.com/go-chassis/cari v0.5.1-0.20210823023004-74041d1363c4/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
 github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
-github.com/go-chassis/cari v0.5.1-0.20220216075429-46c79de3311f h1:NQqJFcsvoCMuRmgj5A6LsJ1nNkg6DkMQpEZy+eZjkOk=
-github.com/go-chassis/cari v0.5.1-0.20220216075429-46c79de3311f/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
+github.com/go-chassis/cari v0.7.1-0.20220815112157-2c62cc5ae1a3 h1:pSOHycBsSS8yO73zzNn0ARtX+DpuuEnt/GVnXA5VOeE=
+github.com/go-chassis/cari v0.7.1-0.20220815112157-2c62cc5ae1a3/go.mod h1:vM13BN0TT505ZKqeJ+hUfzZvfn4nN0vgE6IpBOTWcTc=
 github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
 github.com/go-chassis/foundation v0.2.2/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
 github.com/go-chassis/foundation v0.3.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
@@ -160,11 +181,8 @@ github.com/go-chassis/go-archaius v1.5.1/go.mod h1:QPwvvtBxvwiC48rmydoAqxopqOr93
 github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b h1:0u2kNkdw+J8OublV27I1Xn6berg3MiUm5GSl/T3qXSg=
 github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b/go.mod h1:qjfG7opNF/QTzj7SyVIn/eIawaPhl7xeGgg8kxzFsDw=
 github.com/go-chassis/go-chassis/v2 v2.3.0/go.mod h1:iyJ2DWSkqfnCmad/0Il9nXWHaob7RcwPGlIDRNxccH0=
-github.com/go-chassis/go-chassis/v2 v2.3.1-0.20211217084436-360a6a6a0ef3 h1:Ctxgyo/gc5sogcCJLoIvIKj9kEUzJOlbENpYO/nSPWA=
-github.com/go-chassis/go-chassis/v2 v2.3.1-0.20211217084436-360a6a6a0ef3/go.mod h1:oMnRaz2P+OPTtEfh2HEuiF9YzdYHQrNVPXdnbKzKO9w=
-github.com/go-chassis/go-chassis/v2 v2.5.2 h1:Au+rNk3ZYoYHp73HHWMVrI5FIIOBVlt12SyXZjDnC2Q=
-github.com/go-chassis/go-chassis/v2 v2.5.2/go.mod h1:Ru3kB+ndcxxFZl3clnuihKVv+gOi7lOVR9Ghhtw8jaQ=
-github.com/go-chassis/go-restful-swagger20 v1.0.3 h1:kWfeLwMwJZVkXP1zNyFpkmR41UZ55UTcOptTteXhvEs=
+github.com/go-chassis/go-chassis/v2 v2.7.1 h1:bkYntNY0l5UVRJVQePCD+l+fR/QNqVHxnEjpJxzUBGQ=
+github.com/go-chassis/go-chassis/v2 v2.7.1/go.mod h1:uzFDzYKzpQrCff8xgPMUEi4ku0VAF6DbXdz57iXYqQM=
 github.com/go-chassis/go-restful-swagger20 v1.0.3/go.mod h1:eW62fYuzlNFDvIacB6AV8bhUDCTy4myfTCv0bT9Gbb0=
 github.com/go-chassis/go-restful-swagger20 v1.0.4-0.20220704025524-9243cbee26b7 h1:EOIGW+inOz52zh6vgr9EQHvvgL2w/VghAeCQIFOVUSE=
 github.com/go-chassis/go-restful-swagger20 v1.0.4-0.20220704025524-9243cbee26b7/go.mod h1:pSGkT+ksxlMgytyJb4IAz8aZih6OLE1++d9CE6aO9Hg=
@@ -176,13 +194,14 @@ github.com/go-chassis/openlog v1.1.2/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCx
 github.com/go-chassis/openlog v1.1.3 h1:XqIOvZ8YPJ9o9lLtLBskQNNWolK5kC6a4Sv7r4s9sZ4=
 github.com/go-chassis/openlog v1.1.3/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA=
 github.com/go-chassis/sc-client v0.6.1-0.20210615014358-a45e9090c751/go.mod h1:TBS9g7OaIeu1OR/9tVPJEl6BgHFcYEdbuJlgVDQczbc=
-github.com/go-chassis/sc-client v0.6.1-0.20210918130508-2b9daad232da h1:NwRzmqX1UImlw9RRFReEjtVBXl+zw0NqMCA7Ikyu+v8=
-github.com/go-chassis/sc-client v0.6.1-0.20210918130508-2b9daad232da/go.mod h1:njEnGErgKB1aem5slUPzntnS74IduZWLMZFFakzdBnU=
+github.com/go-chassis/sc-client v0.6.1-0.20220728072125-dacdd0c834bf h1:xBaBVl/4iU8mtCatN1uC4/7iVAa0kiGZSBdC0HyO0Q8=
+github.com/go-chassis/sc-client v0.6.1-0.20220728072125-dacdd0c834bf/go.mod h1:DmclCLMhyNpYN42ae0f5AgiF4lTrpG6NyJJgmyAgC+E=
 github.com/go-chassis/seclog v1.3.0/go.mod h1:a/zGvX5BRiwtq/O0fRqS6VWjrBaXYtqFJBx3EX9xzSE=
 github.com/go-chassis/seclog v1.3.1-0.20210917082355-52c40864f240 h1:sa4aHe3Rsc7DNzkKhsgCNjQi+iYC9gw6ASV+ieLZI54=
 github.com/go-chassis/seclog v1.3.1-0.20210917082355-52c40864f240/go.mod h1:BsV4SB+CpbJnr4QazhUyV4H4gVHbcZiTWxP5XOd4GuA=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -244,15 +263,22 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -275,7 +301,9 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
@@ -284,9 +312,14 @@ github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSN
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -368,8 +401,9 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -439,8 +473,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -476,8 +511,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
+github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -488,14 +524,16 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
+github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
+github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -547,8 +585,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -560,13 +599,21 @@ github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
 github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
 github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
+github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
+github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
 github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -587,11 +634,13 @@ go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD0
 go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
 go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
 go.mongodb.org/mongo-driver v1.4.2/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
-go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
-go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
+go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
+go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
 go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE=
@@ -639,6 +688,7 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
@@ -648,7 +698,11 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -659,6 +713,8 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
@@ -666,6 +722,7 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
 golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -686,27 +743,39 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -714,6 +783,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
@@ -739,19 +810,32 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -759,17 +843,20 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -804,11 +891,32 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
 golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -822,13 +930,24 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
 google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
 google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -838,10 +957,28 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
 google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -851,7 +988,11 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
@@ -906,6 +1047,8 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
 k8s.io/api v0.19.5/go.mod h1:yGZReuNa0vj56op6eT+NLrXJne0R0u9ktexZ8jdJzpc=
 k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
@@ -927,6 +1070,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
 k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
 k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
 sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
diff --git a/pkg/util/util.go b/pkg/util/util.go
index fba4f51..8d243c3 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -17,7 +17,12 @@
 
 package util
 
-import "reflect"
+import (
+	"reflect"
+
+	"github.com/go-chassis/cari/config"
+	"github.com/go-chassis/cari/pkg/errsvc"
+)
 
 // IsEquivalentLabel compares whether two labels are equal.
 // In particular, if one is nil and another is an empty map, it return true
@@ -41,3 +46,11 @@ func IsContainLabel(x, y map[string]string) bool {
 	}
 	return true
 }
+
+func SvcErr(err error) *errsvc.Error {
+	svcErr, ok := err.(*errsvc.Error)
+	if ok {
+		return svcErr
+	}
+	return config.NewError(config.ErrInternal, err.Error())
+}
diff --git a/server/config/struct.go b/server/config/struct.go
index 8526030..83e91f0 100644
--- a/server/config/struct.go
+++ b/server/config/struct.go
@@ -50,8 +50,9 @@ type DB struct {
 
 // RBAC is rbac config
 type RBAC struct {
-	Enabled    bool   `yaml:"enabled"`
-	PubKeyFile string `yaml:"rsaPublicKeyFile"`
+	Enabled        bool   `yaml:"enabled"`
+	AllowMissToken bool   `yaml:"allowMissToken"`
+	PubKeyFile     string `yaml:"rsaPublicKeyFile"`
 }
 
 // Sync is sync config
diff --git a/server/datasource/auth/decision.go b/server/datasource/auth/decision.go
new file mode 100644
index 0000000..f17fc88
--- /dev/null
+++ b/server/datasource/auth/decision.go
@@ -0,0 +1,155 @@
+/*
+ * 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 auth
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/servicecomb-kie/server/datasource"
+	rbacmodel "github.com/go-chassis/cari/rbac"
+	"github.com/go-chassis/openlog"
+)
+
+// Allow return: matched labels(empty if no label defined), error
+func Allow(ctx context.Context, roleList []string, targetResource *ResourceScope) ([]map[string]string, error) {
+	//TODO check project
+	allPerms, err := getPermsByRoles(ctx, roleList)
+	if err != nil {
+		openlog.Error("get role list errors", openlog.WithErr(err))
+		return nil, err
+	}
+	if len(allPerms) == 0 {
+		openlog.Warn("role list 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, 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
+	if len(labelList) == 0 {
+		return nil, nil
+	}
+	// target resource needs no label, return without filter
+	if len(targetResource.Labels) == 0 {
+		return labelList, nil
+	}
+	// allow, and labels found, filter the labels
+	filteredLabelList := FilterLabel(targetResource.Labels, labelList)
+	// target resource label matches no label in permission, means not allow
+	if len(filteredLabelList) == 0 {
+		return nil, rbacmodel.NewError(rbacmodel.ErrNoPermission,
+			fmt.Sprintf("role has no permissions[%s:%s] for labels %v",
+				targetResource.Type, targetResource.Verb, targetResource.Labels))
+	}
+	return filteredLabelList, nil
+}
+
+func FilterLabel(targetResourceLabel []map[string]string, permLabelList []map[string]string) []map[string]string {
+	l := make([]map[string]string, 0)
+	for _, resourceLabel := range targetResourceLabel {
+		for _, label := range permLabelList {
+			if LabelMatched(resourceLabel, label) {
+				l = append(l, label)
+			}
+		}
+	}
+	return l
+}
+
+func LabelMatched(targetResourceLabel map[string]string, permLabel map[string]string) bool {
+	for k, v := range permLabel {
+		if vv := targetResourceLabel[k]; vv != v {
+			return false
+		}
+	}
+	return true
+}
+
+func getPermsByRoles(ctx context.Context, roleList []string) ([]*rbacmodel.Permission, error) {
+	var allPerms = make([]*rbacmodel.Permission, 0)
+	for _, name := range roleList {
+		r, err := datasource.GetBroker().GetRbacDao().GetRole(ctx, name)
+		if err == nil {
+			allPerms = append(allPerms, r.Perms...)
+			continue
+		}
+		if err.Error() == "role not exist" {
+			openlog.Warn(fmt.Sprintf("role [%s] not exist", name))
+			continue
+		}
+		openlog.Error(fmt.Sprintf("get role [%s] failed", name), openlog.WithErr(err))
+		return nil, err
+	}
+	return allPerms, nil
+}
+
+// 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 []*rbacmodel.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
+	for _, perm := range perms {
+		a, l := GetLabelFromSinglePerm(perm, targetResource, verb)
+		if !a {
+			continue
+		}
+		allow = true
+		// allow and has no label, return fast
+		if len(l) == 0 {
+			return true, nil
+		}
+		labelList = append(labelList, l...)
+	}
+	return
+}
+
+// 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 *rbacmodel.Permission, targetResource, verb string) (allow bool, labelList []map[string]string) {
+	if !allowVerb(perm.Verbs, verb) {
+		return false, nil
+	}
+
+	return getResourceLabel(perm.Resources, targetResource)
+}
+
+func allowVerb(haystack []string, needle string) bool {
+	for _, e := range haystack {
+		if e == "*" || e == needle {
+			return true
+		}
+	}
+	return false
+}
+
+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 {
+			continue
+		}
+		// has no label, return fast
+		if len(resource.Labels) == 0 {
+			return true, nil
+		}
+		labelList = append(labelList, resource.Labels)
+		allow = true
+	}
+	return
+}
diff --git a/server/datasource/auth/decision_test.go b/server/datasource/auth/decision_test.go
new file mode 100644
index 0000000..ff86352
--- /dev/null
+++ b/server/datasource/auth/decision_test.go
@@ -0,0 +1,78 @@
+/*
+ * 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 auth
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestLabelMatched(t *testing.T) {
+	targetResourceLabel := map[string]string{
+		"environment": "production",
+		"appId":       "default",
+	}
+	t.Run("value not match, should not match", func(t *testing.T) {
+		permResourceLabel := map[string]string{
+			"environment": "testing",
+		}
+		assert.False(t, LabelMatched(targetResourceLabel, permResourceLabel))
+	})
+	t.Run("key not match, should not match", func(t *testing.T) {
+		permResourceLabel := map[string]string{
+			"serviceName": "default",
+		}
+		assert.False(t, LabelMatched(targetResourceLabel, permResourceLabel))
+	})
+	t.Run("target resource label matches no permission resource label, should not match", func(t *testing.T) {
+		permResourceLabel := map[string]string{
+			"version": "1.0.0",
+		}
+		assert.False(t, LabelMatched(targetResourceLabel, permResourceLabel))
+	})
+	t.Run("target resource label matches part permission resource label, should not match", func(t *testing.T) {
+		permResourceLabel := map[string]string{
+			"version":     "1.0.0",
+			"environment": "production",
+		}
+		assert.False(t, LabelMatched(targetResourceLabel, permResourceLabel))
+	})
+	t.Run("target resource label matches  permission resource label, should not match", func(t *testing.T) {
+		permResourceLabel := map[string]string{
+			"environment": "production",
+		}
+		assert.True(t, LabelMatched(targetResourceLabel, permResourceLabel))
+	})
+}
+func TestFilterLabel(t *testing.T) {
+	targetResourceLabel := []map[string]string{
+		{"environment": "production", "appId": "default"},
+		{"serviceName": "service-center"},
+	}
+	permResourceLabel := []map[string]string{
+		{"environment": "production", "appId": "default"},
+		{"appId": "default"},
+		{"environment": "production", "serviceName": "service-center"},
+		{"serviceName": "service-center", "version": "1.0.0"},
+		{"serviceName": "service-center"},
+		{"environment": "testing"},
+	}
+	l := FilterLabel(targetResourceLabel, permResourceLabel)
+	assert.Equal(t, 3, len(l))
+}
diff --git a/pkg/util/util.go b/server/datasource/auth/filter_kvdoc.go
similarity index 61%
copy from pkg/util/util.go
copy to server/datasource/auth/filter_kvdoc.go
index fba4f51..87a410c 100644
--- a/pkg/util/util.go
+++ b/server/datasource/auth/filter_kvdoc.go
@@ -15,29 +15,29 @@
  * limitations under the License.
  */
 
-package util
+package auth
 
-import "reflect"
+import "github.com/apache/servicecomb-kie/pkg/model"
 
-// IsEquivalentLabel compares whether two labels are equal.
-// In particular, if one is nil and another is an empty map, it return true
-func IsEquivalentLabel(x, y map[string]string) bool {
-	if len(x) == 0 && len(y) == 0 {
-		return true
+func FilterKVs(kvs []*model.KVDoc, labelsList []map[string]string) []*model.KVDoc {
+	var permKVs []*model.KVDoc
+	for _, kv := range kvs {
+		for _, labels := range labelsList {
+			if !matchOne(kv, labels) {
+				continue
+			}
+			permKVs = append(permKVs, kv)
+			break
+		}
 	}
-	return reflect.DeepEqual(x, y)
+	return permKVs
 }
 
-// IsContainLabel compares whether x contain y
-func IsContainLabel(x, y map[string]string) bool {
-	if len(x) < len(y) {
-		return false
-	}
-	for yK, yV := range y {
-		if xV, ok := x[yK]; ok && xV == yV {
-			continue
+func matchOne(kv *model.KVDoc, labels map[string]string) bool {
+	for lk, lv := range labels {
+		if v := kv.Labels[lk]; v != lv {
+			return false
 		}
-		return false
 	}
 	return true
 }
diff --git a/server/datasource/auth/filter_kvdoc_test.go b/server/datasource/auth/filter_kvdoc_test.go
new file mode 100644
index 0000000..1dcdaf2
--- /dev/null
+++ b/server/datasource/auth/filter_kvdoc_test.go
@@ -0,0 +1,55 @@
+/*
+ * 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 auth
+
+import (
+	"testing"
+
+	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestFilterKVs(t *testing.T) {
+	permResourceLabel := []map[string]string{
+		{"environment": "production", "appId": "default", "service": "s1"},
+		{"environment": "testing"},
+	}
+
+	var kvs []*model.KVDoc
+
+	kv1 := new(model.KVDoc)
+	kv1.Key = "k1"
+	kv1.Value = "v1"
+	kv1.Labels = map[string]string{"environment": "production", "appId": "default", "service": "s1"}
+	kvs = append(kvs, kv1)
+
+	kv2 := new(model.KVDoc)
+	kv2.Key = "k2"
+	kv2.Value = "v2"
+	kv2.Labels = map[string]string{"environment": "production", "appId": "default"}
+	kvs = append(kvs, kv2)
+
+	kv3 := new(model.KVDoc)
+	kv3.Key = "k3"
+	kv3.Value = "v3"
+	kv3.Labels = map[string]string{"environment": "xxx", "appId": "xxx", "serviceName": "xxx", "version": "xxx"}
+	kvs = append(kvs, kv3)
+
+	r := FilterKVs(kvs, permResourceLabel)
+	assert.Equal(t, 1, len(r))
+}
diff --git a/server/datasource/auth/identify.go b/server/datasource/auth/identify.go
new file mode 100644
index 0000000..3055430
--- /dev/null
+++ b/server/datasource/auth/identify.go
@@ -0,0 +1,72 @@
+/*
+ * 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 auth
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"github.com/apache/servicecomb-kie/server/datasource"
+	rbacmodel "github.com/go-chassis/cari/rbac"
+	"github.com/go-chassis/openlog"
+)
+
+const (
+	RootName = "root"
+)
+
+var ErrNoRoles = errors.New("no role found in token")
+
+func Identify(ctx context.Context) (*rbacmodel.Account, error) {
+	claims, err := rbacmodel.FromContext(ctx)
+	if err != nil {
+		openlog.Error("get account from token failed", openlog.WithErr(err))
+		return nil, err
+	}
+	account, err := rbacmodel.GetAccount(claims)
+	if err != nil {
+		openlog.Error("get account from claims failed", openlog.WithErr(err))
+		return nil, err
+	}
+	if len(account.Roles) == 0 {
+		openlog.Error("no role found in token")
+		return nil, rbacmodel.NewError(rbacmodel.ErrNoPermission, "no role found in token")
+	}
+	err = accountExist(ctx, account.Name)
+	if err != nil {
+		return nil, err
+	}
+	return account, nil
+}
+
+func accountExist(ctx context.Context, user string) error {
+	// if root should pass, cause of root initialization
+	if user == RootName {
+		return nil
+	}
+	exist, err := datasource.GetBroker().GetRbacDao().AccountExist(ctx, user)
+	if err != nil {
+		return err
+	}
+	if !exist {
+		msg := fmt.Sprintf("account [%s] is deleted", user)
+		return rbacmodel.NewError(rbacmodel.ErrTokenOwnedAccountDeleted, msg)
+	}
+	return nil
+}
diff --git a/server/datasource/auth/perm.go b/server/datasource/auth/perm.go
new file mode 100644
index 0000000..a6781be
--- /dev/null
+++ b/server/datasource/auth/perm.go
@@ -0,0 +1,60 @@
+/*
+ * 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 auth
+
+import (
+	"context"
+
+	"github.com/apache/servicecomb-kie/server/config"
+	rbacmodel "github.com/go-chassis/cari/rbac"
+)
+
+// CheckPerm return the resource scope ...
+func CheckPerm(ctx context.Context, targetResource *ResourceScope) ([]map[string]string, error) {
+	account, err := Identify(ctx)
+	if err != nil {
+		return nil, err
+	}
+	hasAdmin, normalRoles := filterRoles(account.Roles)
+	if hasAdmin {
+		return nil, nil
+	}
+	return Allow(ctx, normalRoles, targetResource)
+}
+
+func filterRoles(roleList []string) (hasAdmin bool, normalRoles []string) {
+	for _, r := range roleList {
+		if r == rbacmodel.RoleAdmin {
+			hasAdmin = true
+			return
+		}
+		normalRoles = append(normalRoles, r)
+	}
+	return
+}
+
+func CheckEnable(ctx context.Context) bool {
+	if !config.GetRBAC().Enabled {
+		return false
+	}
+	if !config.GetRBAC().AllowMissToken {
+		return true
+	}
+	claims, _ := rbacmodel.FromContext(ctx)
+	return claims != nil
+}
diff --git a/pkg/util/util.go b/server/datasource/auth/resource_scope.go
similarity index 59%
copy from pkg/util/util.go
copy to server/datasource/auth/resource_scope.go
index fba4f51..0dbba46 100644
--- a/pkg/util/util.go
+++ b/server/datasource/auth/resource_scope.go
@@ -15,29 +15,14 @@
  * limitations under the License.
  */
 
-package util
+package auth
 
-import "reflect"
-
-// IsEquivalentLabel compares whether two labels are equal.
-// In particular, if one is nil and another is an empty map, it return true
-func IsEquivalentLabel(x, y map[string]string) bool {
-	if len(x) == 0 && len(y) == 0 {
-		return true
-	}
-	return reflect.DeepEqual(x, y)
-}
-
-// IsContainLabel compares whether x contain y
-func IsContainLabel(x, y map[string]string) bool {
-	if len(x) < len(y) {
-		return false
-	}
-	for yK, yV := range y {
-		if xV, ok := x[yK]; ok && xV == yV {
-			continue
-		}
-		return false
-	}
-	return true
+// ResourceScope is the resource scope parsed from request
+type ResourceScope struct {
+	Type string
+	// Labels is a map used to filter resource permissions during pre verification.
+	// If a key of permission set is missing in the Labels, pre verification will pass this key
+	Labels []map[string]string
+	// Verb is the apply resource action, e.g. "get", "create"
+	Verb string
 }
diff --git a/server/datasource/auth/service.go b/server/datasource/auth/service.go
new file mode 100644
index 0000000..f5fd1f0
--- /dev/null
+++ b/server/datasource/auth/service.go
@@ -0,0 +1,86 @@
+/*
+ * 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 auth
+
+import (
+	"context"
+
+	"github.com/apache/servicecomb-kie/pkg/model"
+)
+
+const verbGet, verbCreate, verbUpdate, verbDelete = "get", "create", "update", "delete"
+
+func configPerms(verb string, labels map[string]string) *ResourceScope {
+	var labelsList []map[string]string
+	if labels != nil {
+		labelsList = append(labelsList, labels)
+	}
+	return &ResourceScope{
+		Type:   "config",
+		Verb:   verb,
+		Labels: labelsList,
+	}
+}
+
+func FilterKVList(ctx context.Context, kvs []*model.KVDoc) ([]*model.KVDoc, error) {
+	if !CheckEnable(ctx) {
+		return kvs, nil
+	}
+	// TODO error
+	labels, err := CheckPerm(ctx, configPerms(verbGet, nil))
+	if err != nil {
+		return []*model.KVDoc{}, nil
+	}
+	if len(labels) == 0 {
+		// allow all
+		return kvs, nil
+	}
+	return FilterKVs(kvs, labels), nil
+}
+
+func CheckGetKV(ctx context.Context, kv *model.KVDoc) error {
+	if !CheckEnable(ctx) {
+		return nil
+	}
+	_, err := CheckPerm(ctx, configPerms(verbGet, kv.Labels))
+	return err
+}
+
+func CheckCreateKV(ctx context.Context, kv *model.KVDoc) error {
+	if !CheckEnable(ctx) {
+		return nil
+	}
+	_, err := CheckPerm(ctx, configPerms(verbCreate, kv.Labels))
+	return err
+}
+
+func CheckDeleteKV(ctx context.Context, kv *model.KVDoc) error {
+	if !CheckEnable(ctx) {
+		return nil
+	}
+	_, err := CheckPerm(ctx, configPerms(verbDelete, kv.Labels))
+	return err
+}
+
+func CheckUpdateKV(ctx context.Context, kv *model.KVDoc) error {
+	if !CheckEnable(ctx) {
+		return nil
+	}
+	_, err := CheckPerm(ctx, configPerms(verbUpdate, kv.Labels))
+	return err
+}
diff --git a/server/datasource/dao.go b/server/datasource/dao.go
index 7a4870e..bce146b 100644
--- a/server/datasource/dao.go
+++ b/server/datasource/dao.go
@@ -23,6 +23,7 @@ import (
 	"errors"
 	"fmt"
 
+	"github.com/apache/servicecomb-kie/server/datasource/rbac"
 	"github.com/go-chassis/openlog"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
@@ -61,6 +62,7 @@ type Broker interface {
 	GetHistoryDao() HistoryDao
 	GetTrackDao() TrackDao
 	GetKVDao() KVDao
+	GetRbacDao() rbac.Dao
 }
 
 func GetBroker() Broker {
@@ -80,6 +82,7 @@ type KVDao interface {
 
 	//Get return kv by id
 	Get(ctx context.Context, req *model.GetKVRequest) (*model.KVDoc, error)
+	GetByKey(ctx context.Context, key, project, domain string, options ...FindOption) ([]*model.KVDoc, error)
 	Exist(ctx context.Context, key, project, domain string, options ...FindOption) (bool, error)
 	// Total should return kv resource number by domain id and project id
 	Total(ctx context.Context, project, domain string) (int64, error)
diff --git a/server/datasource/etcd/counter/revision.go b/server/datasource/etcd/counter/revision.go
index 6788da4..07d1448 100644
--- a/server/datasource/etcd/counter/revision.go
+++ b/server/datasource/etcd/counter/revision.go
@@ -22,6 +22,7 @@ import (
 
 	"github.com/apache/servicecomb-kie/server/datasource"
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/key"
+	"github.com/go-chassis/cari/config"
 	"github.com/go-chassis/openlog"
 	"github.com/little-cui/etcdadpt"
 )
@@ -50,7 +51,7 @@ func (s *Dao) ApplyRevision(ctx context.Context, domain string) (int64, error) {
 	resp, err := etcdadpt.PutBytesAndGet(ctx, key.Counter(revision, domain), nil)
 	if err != nil {
 		openlog.Error("put bytes error: " + err.Error())
-		return 0, err
+		return 0, config.NewError(config.ErrInternal, "apply revision failed")
 	}
 	if resp.Count == 0 {
 		return 0, datasource.ErrRevisionNotExist
diff --git a/server/datasource/etcd/history/history_dao.go b/server/datasource/etcd/history/history_dao.go
index 4139684..bebc4ea 100644
--- a/server/datasource/etcd/history/history_dao.go
+++ b/server/datasource/etcd/history/history_dao.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"encoding/json"
 
+	"github.com/apache/servicecomb-kie/server/datasource/auth"
 	"github.com/go-chassis/openlog"
 	"github.com/little-cui/etcdadpt"
 
@@ -35,6 +36,19 @@ type Dao struct {
 
 // GetHistory get all history by label id
 func (s *Dao) GetHistory(ctx context.Context, kvID, project, domain string, options ...datasource.FindOption) (*model.KVResponse, error) {
+	kvreq := &model.GetKVRequest{
+		Domain:  domain,
+		Project: project,
+		ID:      kvID,
+	}
+	kvdoc, err := datasource.GetBroker().GetKVDao().Get(ctx, kvreq)
+	if err != nil {
+		return nil, err
+	}
+	if err := auth.CheckGetKV(ctx, kvdoc); err != nil {
+		return nil, err
+	}
+
 	opts := datasource.FindOptions{}
 	for _, o := range options {
 		o(&opts)
diff --git a/server/datasource/etcd/init.go b/server/datasource/etcd/init.go
index 6be7c12..b2f68b2 100644
--- a/server/datasource/etcd/init.go
+++ b/server/datasource/etcd/init.go
@@ -22,7 +22,9 @@ import (
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/counter"
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/history"
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/kv"
+	"github.com/apache/servicecomb-kie/server/datasource/etcd/rbac"
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/track"
+	rbacdao "github.com/apache/servicecomb-kie/server/datasource/rbac"
 )
 
 type Broker struct {
@@ -43,6 +45,9 @@ func (*Broker) GetHistoryDao() datasource.HistoryDao {
 func (*Broker) GetTrackDao() datasource.TrackDao {
 	return &track.Dao{}
 }
+func (*Broker) GetRbacDao() rbacdao.Dao {
+	return &rbac.Dao{}
+}
 
 func init() {
 	datasource.RegisterPlugin("etcd", NewFrom)
diff --git a/server/datasource/etcd/kv/kv_dao.go b/server/datasource/etcd/kv/kv_dao.go
index 6296e08..8fb15c3 100644
--- a/server/datasource/etcd/kv/kv_dao.go
+++ b/server/datasource/etcd/kv/kv_dao.go
@@ -30,6 +30,7 @@ import (
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/pkg/util"
 	"github.com/apache/servicecomb-kie/server/datasource"
+	"github.com/apache/servicecomb-kie/server/datasource/auth"
 	"github.com/apache/servicecomb-kie/server/datasource/etcd/key"
 )
 
@@ -38,6 +39,10 @@ type Dao struct {
 }
 
 func (s *Dao) Create(ctx context.Context, kv *model.KVDoc, options ...datasource.WriteOption) (*model.KVDoc, error) {
+	if err := auth.CheckCreateKV(ctx, kv); err != nil {
+		return nil, err
+	}
+
 	opts := datasource.NewWriteOptions(options...)
 	var exist bool
 	var err error
@@ -116,6 +121,11 @@ func (s *Dao) Update(ctx context.Context, kv *model.KVDoc, options ...datasource
 		openlog.Error(err.Error())
 		return err
 	}
+
+	if err := auth.CheckUpdateKV(ctx, &oldKV); err != nil {
+		return err
+	}
+
 	oldKV.LabelFormat = kv.LabelFormat
 	oldKV.Value = kv.Value
 	oldKV.Status = kv.Status
@@ -182,7 +192,7 @@ func (s *Dao) Exist(ctx context.Context, key, project, domain string, options ..
 	for _, o := range options {
 		o(&opts)
 	}
-	kvs, err := s.List(ctx, project, domain,
+	kvs, err := s.listNoAuth(ctx, project, domain,
 		datasource.WithExactLabels(),
 		datasource.WithLabels(opts.Labels),
 		datasource.WithLabelFormat(opts.LabelFormat),
@@ -201,6 +211,30 @@ func (s *Dao) Exist(ctx context.Context, key, project, domain string, options ..
 	return true, nil
 }
 
+func (s *Dao) GetByKey(ctx context.Context, key, project, domain string, options ...datasource.FindOption) ([]*model.KVDoc, error) {
+	opts := datasource.FindOptions{Key: key}
+	for _, o := range options {
+		o(&opts)
+	}
+	kvs, err := s.listNoAuth(ctx, project, domain,
+		datasource.WithExactLabels(),
+		datasource.WithLabels(opts.Labels),
+		datasource.WithLabelFormat(opts.LabelFormat),
+		datasource.WithKey(key),
+		datasource.WithCaseSensitive())
+	if err != nil {
+		openlog.Error("check kv exist: " + err.Error())
+		return nil, err
+	}
+	if IsUniqueFind(opts) && len(kvs.Data) == 0 {
+		return nil, datasource.ErrKeyNotExists
+	}
+	if len(kvs.Data) != 1 {
+		return nil, datasource.ErrTooMany
+	}
+	return kvs.Data, nil
+}
+
 // FindOneAndDelete deletes one kv by id and return the deleted kv as these appeared before deletion
 // domain=tenant
 func (s *Dao) FindOneAndDelete(ctx context.Context, kvID, project, domain string, options ...datasource.WriteOption) (*model.KVDoc, error) {
@@ -215,6 +249,11 @@ func (s *Dao) FindOneAndDelete(ctx context.Context, kvID, project, domain string
 func findOneAndDelete(ctx context.Context, kvID, project, domain string) (*model.KVDoc, error) {
 	kvKey := key.KV(domain, project, kvID)
 	kvDoc := model.KVDoc{}
+
+	if _, err := getKVDoc(ctx, domain, project, kvID); err != nil {
+		return nil, err
+	}
+
 	resp, err := etcdadpt.ListAndDelete(ctx, kvKey)
 	if err != nil {
 		openlog.Error("delete Key error: " + err.Error())
@@ -269,7 +308,7 @@ func txnFindOneAndDelete(ctx context.Context, kvID, project, domain string) (*mo
 	return kvDoc, nil
 }
 
-// getKVDoc is to get kv
+// getKVDoc is to get kv for delete
 func getKVDoc(ctx context.Context, domain, project, kvID string) (*model.KVDoc, error) {
 	resp, err := etcdadpt.Get(ctx, key.KV(domain, project, kvID))
 	if err != nil {
@@ -285,6 +324,11 @@ func getKVDoc(ctx context.Context, domain, project, kvID string) (*model.KVDoc,
 		openlog.Error("decode error: " + err.Error())
 		return nil, err
 	}
+
+	if err := auth.CheckDeleteKV(ctx, curKV); err != nil {
+		return nil, err
+	}
+
 	return curKV, nil
 }
 
@@ -301,9 +345,18 @@ func (s *Dao) FindManyAndDelete(ctx context.Context, kvIDs []string, project, do
 func findManyAndDelete(ctx context.Context, kvIDs []string, project, domain string) ([]*model.KVDoc, int64, error) {
 	var docs []*model.KVDoc
 	var opOptions []etcdadpt.OpOptions
+	var err error
 	for _, id := range kvIDs {
+		if _, err = getKVDoc(ctx, domain, project, id); err != nil {
+			continue
+		}
 		opOptions = append(opOptions, etcdadpt.OpDel(etcdadpt.WithStrKey(key.KV(domain, project, id))))
 	}
+
+	if len(opOptions) == 0 {
+		return make([]*model.KVDoc, 0), 0, err
+	}
+
 	resp, err := etcdadpt.ListAndDeleteMany(ctx, opOptions...)
 	if err != nil {
 		openlog.Error("find Keys error: " + err.Error())
@@ -412,6 +465,11 @@ func (s *Dao) Get(ctx context.Context, req *model.GetKVRequest) (*model.KVDoc, e
 		openlog.Error("decode error: " + err.Error())
 		return nil, err
 	}
+
+	if err := auth.CheckGetKV(ctx, curKV); err != nil {
+		return nil, err
+	}
+
 	return curKV, nil
 }
 
@@ -426,6 +484,33 @@ func (s *Dao) Total(ctx context.Context, project, domain string) (int64, error)
 
 // List get kv list by key and criteria
 func (s *Dao) List(ctx context.Context, project, domain string, options ...datasource.FindOption) (*model.KVResponse, error) {
+	result, opts, err := s.listData(ctx, project, domain, options...)
+	if err != nil {
+		return nil, err
+	}
+
+	filterKVs, err := auth.FilterKVList(ctx, result.Data)
+	if err != nil {
+		return nil, err
+	}
+
+	result.Data = filterKVs
+	result.Total = len(filterKVs)
+
+	return pagingResult(result, opts), nil
+}
+
+func (s *Dao) listNoAuth(ctx context.Context, project, domain string, options ...datasource.FindOption) (*model.KVResponse, error) {
+	result, opts, err := s.listData(ctx, project, domain, options...)
+	if err != nil {
+		return nil, err
+	}
+
+	return pagingResult(result, opts), nil
+}
+
+// List get kv list by key and criteria
+func (s *Dao) listData(ctx context.Context, project, domain string, options ...datasource.FindOption) (*model.KVResponse, datasource.FindOptions, error) {
 	opts := datasource.NewDefaultFindOpts()
 	for _, o := range options {
 		o(&opts)
@@ -435,13 +520,13 @@ func (s *Dao) List(ctx context.Context, project, domain string, options ...datas
 
 	regex, err := toRegex(opts)
 	if err != nil {
-		return nil, err
+		return nil, opts, err
 	}
 	// TODO may be OOM
 	kvs, _, err := etcdadpt.List(ctx, key.KVList(domain, project))
 	if err != nil {
 		openlog.Error("list kv failed: " + err.Error())
-		return nil, err
+		return nil, opts, err
 	}
 	result := &model.KVResponse{
 		Data: []*model.KVDoc{},
@@ -465,7 +550,8 @@ func (s *Dao) List(ctx context.Context, project, domain string, options ...datas
 			break
 		}
 	}
-	return pagingResult(result, opts), nil
+
+	return result, opts, nil
 }
 
 func IsUniqueFind(opts datasource.FindOptions) bool {
diff --git a/server/datasource/etcd/counter/revision.go b/server/datasource/etcd/rbac/rbac.go
similarity index 52%
copy from server/datasource/etcd/counter/revision.go
copy to server/datasource/etcd/rbac/rbac.go
index 6788da4..8c1249a 100644
--- a/server/datasource/etcd/counter/revision.go
+++ b/server/datasource/etcd/rbac/rbac.go
@@ -15,45 +15,46 @@
  * limitations under the License.
  */
 
-package counter
+package rbac
 
 import (
 	"context"
+	"encoding/json"
+	"errors"
 
-	"github.com/apache/servicecomb-kie/server/datasource"
-	"github.com/apache/servicecomb-kie/server/datasource/etcd/key"
+	crbac "github.com/go-chassis/cari/rbac"
 	"github.com/go-chassis/openlog"
 	"github.com/little-cui/etcdadpt"
 )
 
-const revision = "revision_counter"
+func generateRBACRoleKey(name string) string {
+	return "/cse-sr/roles/" + name
+}
+
+func generateRBACAccountKey(name string) string {
+	return "/cse-sr/accounts/" + name
+}
 
-// Dao is the implementation
 type Dao struct {
 }
 
-// GetRevision return current revision number
-func (s *Dao) GetRevision(ctx context.Context, domain string) (int64, error) {
-	kv, err := etcdadpt.Get(ctx, key.Counter(revision, domain))
+func (re *Dao) GetRole(ctx context.Context, name string) (*crbac.Role, error) {
+	kv, err := etcdadpt.Get(ctx, generateRBACRoleKey(name))
 	if err != nil {
-		openlog.Error("get error: " + err.Error())
-		return 0, err
+		return nil, err
 	}
 	if kv == nil {
-		return 0, nil
+		return nil, errors.New("role not exist")
 	}
-	return kv.Version, nil
-}
-
-// ApplyRevision increase revision number and return modified value
-func (s *Dao) ApplyRevision(ctx context.Context, domain string) (int64, error) {
-	resp, err := etcdadpt.PutBytesAndGet(ctx, key.Counter(revision, domain), nil)
+	role := &crbac.Role{}
+	err = json.Unmarshal(kv.Value, role)
 	if err != nil {
-		openlog.Error("put bytes error: " + err.Error())
-		return 0, err
-	}
-	if resp.Count == 0 {
-		return 0, datasource.ErrRevisionNotExist
+		openlog.Error("role info format invalid", openlog.WithErr(err))
+		return nil, err
 	}
-	return resp.Kvs[0].Version, nil
+	return role, nil
+}
+
+func (re *Dao) AccountExist(ctx context.Context, name string) (bool, error) {
+	return etcdadpt.Exist(ctx, generateRBACAccountKey(name))
 }
diff --git a/server/datasource/mongo/init.go b/server/datasource/mongo/init.go
index ab555e9..002db5c 100644
--- a/server/datasource/mongo/init.go
+++ b/server/datasource/mongo/init.go
@@ -20,6 +20,8 @@ package mongo
 import (
 	"context"
 
+	"github.com/apache/servicecomb-kie/server/datasource/mongo/rbac"
+	rbacdao "github.com/apache/servicecomb-kie/server/datasource/rbac"
 	dmongo "github.com/go-chassis/cari/db/mongo"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
@@ -57,6 +59,9 @@ func (*Broker) GetHistoryDao() datasource.HistoryDao {
 func (*Broker) GetTrackDao() datasource.TrackDao {
 	return &track.Dao{}
 }
+func (*Broker) GetRbacDao() rbacdao.Dao {
+	return &rbac.Dao{}
+}
 
 func ensureDB() error {
 	err := ensureRevisionCounter()
diff --git a/server/datasource/mongo/kv/kv_dao.go b/server/datasource/mongo/kv/kv_dao.go
index 5f70e51..79eb6ff 100644
--- a/server/datasource/mongo/kv/kv_dao.go
+++ b/server/datasource/mongo/kv/kv_dao.go
@@ -666,6 +666,33 @@ func (s *Dao) Get(ctx context.Context, req *model.GetKVRequest) (*model.KVDoc, e
 	return kvs[0], nil
 }
 
+func (s *Dao) GetByKey(ctx context.Context, key, project, domain string, options ...datasource.FindOption) ([]*model.KVDoc, error) {
+	opts := datasource.FindOptions{}
+	for _, o := range options {
+		o(&opts)
+	}
+	if opts.LabelFormat != "" {
+		kvs, err := findKVByLabel(ctx, domain, opts.LabelFormat, key, project)
+		if err != nil {
+			return nil, err
+		}
+		return kvs, nil
+	}
+	kvs, err := s.List(ctx, domain, project,
+		datasource.WithExactLabels(),
+		datasource.WithLabels(opts.Labels),
+		datasource.WithKey(key))
+	if err != nil {
+		openlog.Error("check kv exist: " + err.Error())
+		return nil, err
+	}
+	if len(kvs.Data) != 1 {
+		return nil, datasource.ErrTooMany
+	}
+
+	return kvs.Data, nil
+}
+
 func (s *Dao) Total(ctx context.Context, project, domain string) (int64, error) {
 	collection := dmongo.GetClient().GetDB().Collection(mmodel.CollectionKV)
 	filter := bson.M{"domain": domain, "project": project}
diff --git a/pkg/util/util.go b/server/datasource/mongo/rbac/rbac.go
similarity index 59%
copy from pkg/util/util.go
copy to server/datasource/mongo/rbac/rbac.go
index fba4f51..987a519 100644
--- a/pkg/util/util.go
+++ b/server/datasource/mongo/rbac/rbac.go
@@ -15,29 +15,21 @@
  * limitations under the License.
  */
 
-package util
+package rbac
 
-import "reflect"
+import (
+	"context"
 
-// IsEquivalentLabel compares whether two labels are equal.
-// In particular, if one is nil and another is an empty map, it return true
-func IsEquivalentLabel(x, y map[string]string) bool {
-	if len(x) == 0 && len(y) == 0 {
-		return true
-	}
-	return reflect.DeepEqual(x, y)
+	crbac "github.com/go-chassis/cari/rbac"
+)
+
+type Dao struct {
+}
+
+func (rm *Dao) GetRole(ctx context.Context, name string) (*crbac.Role, error) {
+	panic("implement me")
 }
 
-// IsContainLabel compares whether x contain y
-func IsContainLabel(x, y map[string]string) bool {
-	if len(x) < len(y) {
-		return false
-	}
-	for yK, yV := range y {
-		if xV, ok := x[yK]; ok && xV == yV {
-			continue
-		}
-		return false
-	}
-	return true
+func (rm *Dao) AccountExist(ctx context.Context, name string) (bool, error) {
+	panic("implement me")
 }
diff --git a/pkg/util/util.go b/server/datasource/rbac/rbac.go
similarity index 59%
copy from pkg/util/util.go
copy to server/datasource/rbac/rbac.go
index fba4f51..4484dae 100644
--- a/pkg/util/util.go
+++ b/server/datasource/rbac/rbac.go
@@ -15,29 +15,15 @@
  * limitations under the License.
  */
 
-package util
+package rbac
 
-import "reflect"
+import (
+	"context"
 
-// IsEquivalentLabel compares whether two labels are equal.
-// In particular, if one is nil and another is an empty map, it return true
-func IsEquivalentLabel(x, y map[string]string) bool {
-	if len(x) == 0 && len(y) == 0 {
-		return true
-	}
-	return reflect.DeepEqual(x, y)
-}
+	crbac "github.com/go-chassis/cari/rbac"
+)
 
-// IsContainLabel compares whether x contain y
-func IsContainLabel(x, y map[string]string) bool {
-	if len(x) < len(y) {
-		return false
-	}
-	for yK, yV := range y {
-		if xV, ok := x[yK]; ok && xV == yV {
-			continue
-		}
-		return false
-	}
-	return true
+type Dao interface {
+	GetRole(ctx context.Context, name string) (*crbac.Role, error)
+	AccountExist(ctx context.Context, name string) (bool, error)
 }
diff --git a/server/rbac/rbac.go b/server/rbac/rbac.go
index b7614fa..9f08111 100644
--- a/server/rbac/rbac.go
+++ b/server/rbac/rbac.go
@@ -24,7 +24,6 @@ import (
 	"strings"
 
 	"github.com/apache/servicecomb-kie/server/config"
-	"github.com/go-chassis/cari/rbac"
 	"github.com/go-chassis/go-archaius"
 	"github.com/go-chassis/go-chassis/v2/middleware/jwt"
 	"github.com/go-chassis/go-chassis/v2/security/secret"
@@ -34,6 +33,7 @@ import (
 
 const (
 	pubContentKey = "rbac.publicKey"
+	HeaderAuth    = "Authorization"
 )
 
 // Init initialize the rbac module
@@ -48,6 +48,12 @@ func Init() {
 			if !config.GetRBAC().Enabled {
 				return false
 			}
+
+			v := req.Header.Get(HeaderAuth)
+			if config.GetRBAC().AllowMissToken && v == "" {
+				return false
+			}
+
 			if strings.Contains(req.URL.Path, "/v1/health") {
 				return false
 			}
@@ -62,13 +68,6 @@ func Init() {
 			}
 			return p, nil
 		},
-		Authorize: func(payload map[string]interface{}, req *http.Request) error {
-			payload["domain"] = "default" //TODO eliminate dead code
-			newReq := req.WithContext(rbac.NewContext(req.Context(), payload))
-			*req = *newReq
-			//TODO role perm check
-			return nil
-		},
 	})
 	loadPublicKey()
 	openlog.Info("rbac is enabled")
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 2f19140..f71f145 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -26,6 +26,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/go-chassis/cari/pkg/errsvc"
+
 	"github.com/apache/servicecomb-kie/server/cache"
 	"github.com/gofrs/uuid"
 
@@ -86,8 +88,11 @@ func ReadClaims(ctx context.Context) map[string]interface{} {
 // ReadDomain get domain info
 func ReadDomain(ctx context.Context) string {
 	c := ReadClaims(ctx)
-	if c != nil {
-		return c["domain"].(string)
+	if c == nil {
+		return "default"
+	}
+	if d, ok := c["domain"].(string); ok {
+		return d
 	}
 	return "default"
 }
@@ -135,6 +140,14 @@ func WriteErrResponse(context *restful.Context, code int32, msg string) {
 	}
 }
 
+func WriteError(context *restful.Context, err error) {
+	svcErr, ok := err.(*errsvc.Error)
+	if !ok {
+		svcErr = config.NewError(config.ErrInternal, err.Error())
+	}
+	WriteErrResponse(context, svcErr.Code, svcErr.Message)
+}
+
 func readRequest(ctx *restful.Context, v interface{}) error {
 	if ctx.ReadHeader(common.HeaderContentType) == common.ContentTypeYaml {
 		return yaml.NewDecoder(ctx.ReadRequest().Body).Decode(v)
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 09cd019..de5092e 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -60,7 +60,7 @@ func (r *HistoryResource) GetRevisions(context *restful.Context) {
 			WriteErrResponse(context, config.ErrRecordNotExists, err.Error())
 			return
 		}
-		WriteErrResponse(context, config.ErrInternal, err.Error())
+		WriteError(context, err)
 		return
 	}
 	err = writeResponse(context, revisions)
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 1fc087a..8a9c6e1 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -91,6 +91,7 @@ func (r *KVResource) Post(rctx *restful.Context) {
 // Put update a kv
 func (r *KVResource) Put(rctx *restful.Context) {
 	var err error
+
 	kvID := rctx.ReadPathParameter(common.PathParamKVID)
 	project := rctx.ReadPathParameter(common.PathParameterProject)
 	kvReq := new(model.UpdateKVRequest)
@@ -114,7 +115,7 @@ func (r *KVResource) Put(rctx *restful.Context) {
 			WriteErrResponse(rctx, config.ErrRecordNotExists, err.Error())
 			return
 		}
-		WriteErrResponse(rctx, config.ErrInternal, "update kv failed")
+		WriteError(rctx, err)
 		return
 	}
 	err = pubsub.Publish(&pubsub.KVChangeEvent{
@@ -155,7 +156,7 @@ func (r *KVResource) Get(rctx *restful.Context) {
 			WriteErrResponse(rctx, config.ErrRecordNotExists, err.Error())
 			return
 		}
-		WriteErrResponse(rctx, config.ErrInternal, "get kv failed")
+		WriteError(rctx, err)
 		return
 	}
 	kv.Domain = ""
@@ -297,7 +298,7 @@ func (r *KVResource) Delete(rctx *restful.Context) {
 			WriteErrResponse(rctx, config.ErrRecordNotExists, err.Error())
 			return
 		}
-		WriteErrResponse(rctx, config.ErrInternal, common.MsgDeleteKVFailed)
+		WriteError(rctx, err)
 		return
 	}
 	err = pubsub.Publish(&pubsub.KVChangeEvent{
@@ -337,7 +338,7 @@ func (r *KVResource) DeleteList(rctx *restful.Context) {
 			"kvIDs": b.IDs,
 			"error": err.Error(),
 		}))
-		WriteErrResponse(rctx, config.ErrInternal, common.MsgDeleteKVFailed)
+		WriteError(rctx, err)
 		return
 	}
 	for _, kv := range kvs {
diff --git a/server/service/kv/kv_svc.go b/server/service/kv/kv_svc.go
index 1b539c2..b98030d 100644
--- a/server/service/kv/kv_svc.go
+++ b/server/service/kv/kv_svc.go
@@ -24,6 +24,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/apache/servicecomb-kie/pkg/util"
+
 	"github.com/apache/servicecomb-kie/pkg/common"
 	"github.com/apache/servicecomb-kie/pkg/concurrency"
 	"github.com/apache/servicecomb-kie/pkg/model"
@@ -117,7 +119,7 @@ func Create(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, *errsvc.Error)
 	kv, err = datasource.GetBroker().GetKVDao().Create(ctx, kv, datasource.WithSync(sync.FromContext(ctx)))
 	if err != nil {
 		openlog.Error(fmt.Sprintf("post err:%s", err.Error()))
-		return nil, config.NewError(config.ErrInternal, "create kv failed")
+		return nil, util.SvcErr(err)
 	}
 	err = datasource.GetBroker().GetHistoryDao().AddHistory(ctx, kv)
 	if err != nil {
@@ -316,3 +318,16 @@ func Exist(ctx context.Context, key, project, domain string, labels map[string]s
 	}
 	return exist, nil
 }
+
+func GetByKey(ctx context.Context, key, project, domain string, labels map[string]string) ([]*model.KVDoc, error) {
+	if labels == nil {
+		labels = map[string]string{}
+	}
+	labelFormat := stringutil.FormatMap(labels)
+	kvs, err := datasource.GetBroker().GetKVDao().GetByKey(ctx, key, project, domain, datasource.WithLabelFormat(labelFormat))
+	if err != nil {
+		openlog.Error(err.Error())
+		return nil, err
+	}
+	return kvs, nil
+}
diff --git a/server/service/kv/override_force.go b/server/service/kv/override_force.go
index 41a51eb..27317d1 100644
--- a/server/service/kv/override_force.go
+++ b/server/service/kv/override_force.go
@@ -21,6 +21,8 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/apache/servicecomb-kie/pkg/util"
+
 	"github.com/go-chassis/cari/config"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/openlog"
@@ -45,19 +47,13 @@ func (f *Force) Execute(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, *er
 		return input, err
 	}
 
-	request := &model.ListKVRequest{
-		Project: input.Project,
-		Domain:  input.Domain,
-		Key:     input.Key,
-		Labels:  input.Labels,
-	}
-	_, getKvsByOpts, getKvErr := ListKV(ctx, request)
+	getKvsByOpts, getKvErr := GetByKey(ctx, input.Key, input.Project, input.Domain, input.Labels)
 	if getKvErr != nil {
 		openlog.Info(fmt.Sprintf("get record [key: %s, labels: %s] failed", input.Key, input.Labels))
-		return input, getKvErr
+		return input, util.SvcErr(getKvErr)
 	}
 	kvReq := &model.UpdateKVRequest{
-		ID:      getKvsByOpts.Data[0].ID,
+		ID:      getKvsByOpts[0].ID,
 		Value:   input.Value,
 		Status:  input.Status,
 		Project: input.Project,
@@ -66,7 +62,7 @@ func (f *Force) Execute(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, *er
 	kv, updateErr := Update(ctx, kvReq)
 	if updateErr != nil {
 		openlog.Error(fmt.Sprintf("update record [key: %s, labels: %s] failed", input.Key, input.Labels))
-		return input, config.NewError(config.ErrInternal, updateErr.Error())
+		return input, util.SvcErr(updateErr)
 	}
 	return kv, nil
 }