diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index adac357ef..a1eb120ec 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -63,9 +63,9 @@ jobs: if: env.IS_RELEASE_BRANCH == 'true' working-directory: ${{ matrix.directory }} - name: golangci-lint - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 + uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 with: - version: v1.61 + version: v1.64 working-directory: ${{ matrix.directory }} skip-cache: true args: --out-format=colored-line-number diff --git a/.github/workflows/nightly-build.yaml b/.github/workflows/nightly-build.yaml index 1f25666c1..8203134b9 100644 --- a/.github/workflows/nightly-build.yaml +++ b/.github/workflows/nightly-build.yaml @@ -39,7 +39,7 @@ jobs: password: ${{ steps.gcp-auth.outputs.access_token }} - id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 with: images: ${{ secrets.DOCKER_REPO }} tags: | diff --git a/.github/workflows/release-build.yaml b/.github/workflows/release-build.yaml index 4463498a4..3b937198f 100644 --- a/.github/workflows/release-build.yaml +++ b/.github/workflows/release-build.yaml @@ -45,7 +45,7 @@ jobs: password: ${{ steps.gcp-auth.outputs.access_token }} - id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 with: images: ${{ secrets.DOCKER_REPO }} tags: | diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b4d1bd25a..c4b3cf7ee 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,7 +17,7 @@ jobs: steps: - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" @@ -30,7 +30,7 @@ jobs: - id: todo if: fromJson(steps.release-please.outputs.releases_created) run: | - for x in ${{join(fromJson(steps.release-please.outputs.paths_released), ' ')}}; do + <<<"$RELEASED_PATHS" jq -r '.[]'| while IFS= read -r x; do case "$x" in lib/ocrypto) echo "TO_UPDATE=['examples','sdk','service']">>"$GITHUB_OUTPUT" @@ -60,7 +60,8 @@ jobs: ;; esac done - + env: + RELEASED_PATHS: ${{ steps.release-please.outputs.paths_released }} update-go-mods: runs-on: ubuntu-latest needs: @@ -78,15 +79,15 @@ jobs: - run: | git checkout -b update-go-mods-for-${{matrix.path}} git push -f -u origin update-go-mods-for-${{matrix.path}} - cd ${{matrix.path}} - for x in ${{join(fromJson(needs.release-please.outputs.paths_released), ' ')}}; do - export pkg=github.com/opentdf/platform/${x} + cd ${{matrix.path}} || exit 1 + <<<"$RELEASED_PATHS" jq -r '.[]'| while IFS= read -r x; do + export pkg="github.com/opentdf/platform/${x}" if go mod edit --json | jq -e '.Replace[] | select(.Old.Path == env.pkg)'; then - go mod edit --dropreplace=$pkg + go mod edit --dropreplace="$pkg" fi echo "Should we update [${pkg}] in [${{ matrix.path }}]?" if go mod edit --json | jq -e '.Require[] | select(.Path == env.pkg)'; then - ver=$(jq -r .\[\"${x}\"\] < "${GITHUB_WORKSPACE}/.release-please-manifest.json") + ver="$(jq -r --arg x "$x" '.[$x]' <"${GITHUB_WORKSPACE}"/.release-please-manifest.json)" echo "go get ${pkg}@v${ver}" go get "${pkg}@v${ver}" fi @@ -99,6 +100,7 @@ jobs: git diff env: GONOSUMDB: github.com/opentdf/platform/${{join(fromJson(needs.release-please.outputs.paths_released), ',github.com/opentdf/platform/')}} + RELEASED_PATHS: ${{ needs.release-please.outputs.paths_released }} - uses: planetscale/ghcommit-action@d4176bfacef926cc2db351eab20398dfc2f593b5 with: commit_message: "fix(core): Autobump ${{ matrix.path }}" @@ -108,7 +110,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 9fe2a94a5..a29690528 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -10,7 +10,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 with: days-before-stale: 120 # negative number means they will never be closed automatically [https://github.com/actions/stale#days-before-close] diff --git a/.github/workflows/traffic.yaml b/.github/workflows/traffic.yaml index be8d858e2..b666f5c75 100644 --- a/.github/workflows/traffic.yaml +++ b/.github/workflows/traffic.yaml @@ -13,18 +13,17 @@ jobs: matrix: repo-values: - {repo: platform, event: ""} - - {repo: otdfctl, event: backend-} - - {repo: spec, event: frontend-} + - {repo: otdfctl, event: otdfctl-} + - {repo: spec, event: spec-} - {repo: tests, event: tests-} - - {repo: client-web, event: clientweb-} - - {repo: client-cpp, event: cpp-sdk-} + - {repo: web-sdk, event: web-sdk-} - {repo: java-sdk, event: java-sdk-} - {repo: charts, event: charts-} - {repo: nifi, event: nifi-} steps: - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" diff --git a/.golangci.yaml b/.golangci.yaml index dac566eb3..33586547b 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -9,8 +9,6 @@ linters-settings: # Such cases aren't reported by default. # Default: false check-type-assertions: true - # https://github.com/golangci/golangci-lint/issues/4743 - ignore: '' exhaustive: # Program elements to check for exhaustiveness. @@ -138,7 +136,7 @@ linters: - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 - exhaustive # checks exhaustiveness of enum switch statements - # - exportloopref # checks for pointers to enclosing loop variables Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar." + - exptostd # Added in 1.63. Checks for usages of the deprecated experimental packages # - fatcontext - forbidigo # forbids identifiers - forcetypeassert # finds forced type assertions @@ -173,7 +171,6 @@ linters: # - spancheck # checks for incorrect usage of opentracing.Span # Added in golangci-lint 1.56 - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed - stylecheck # is a replacement for golint - - tenv # detects using os.Setenv instead of t.Setenv since Go1.17 - testableexamples # checks if examples are testable (have an expected output) - testifylint #- testpackage # makes you use a separate _test package @@ -181,6 +178,7 @@ linters: - unconvert # removes unnecessary type conversions - unparam # reports unused function parameters - usestdlibvars # detects the possibility to use variables/constants from the Go standard library + - usetesting # Replaced tenv in golangci-lint 1.63 - wastedassign # finds wasted assignment statements - whitespace # detects leading and trailing whitespace diff --git a/.release-please-manifest.json b/.release-please-manifest.json index af353cb6c..67170cd6d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,8 +1,8 @@ { "lib/fixtures": "0.2.10", - "lib/ocrypto": "0.1.7", + "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", - "protocol/go": "0.2.25", - "sdk": "0.3.26", - "service": "0.4.38" + "protocol/go": "0.2.28", + "sdk": "0.3.28", + "service": "0.4.39" } diff --git a/Makefile b/Makefile index d4bc7b530..29f494b82 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,9 @@ all: toolcheck clean build lint license test toolcheck: @echo "Checking for required tools..." @which buf > /dev/null || (echo "buf not found, please install it from https://docs.buf.build/installation" && exit 1) - @which golangci-lint > /dev/null || (echo "golangci-lint not found, run 'go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0'" && exit 1) + @which golangci-lint > /dev/null || (echo "golangci-lint not found, run 'go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5'" && exit 1) @which protoc-gen-doc > /dev/null || (echo "protoc-gen-doc not found, run 'go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.5.1'" && exit 1) - @golangci-lint --version | grep "version v\?1.6[123]" > /dev/null || (echo "golangci-lint version must be v1.61 or later [$$(golangci-lint --version)]" && exit 1) + @golangci-lint --version | grep "version v\?1.6[456]" > /dev/null || (echo "golangci-lint version must be v1.64 or later [$$(golangci-lint --version)]" && exit 1) @which goimports >/dev/null || (echo "goimports not found, run 'go install golang.org/x/tools/cmd/goimports@latest'") fix: tidy fmt @@ -45,8 +45,12 @@ proto-lint: fi) go-lint: - for m in $(HAND_MODS); do (cd $$m && golangci-lint run $(LINT_OPTIONS) --path-prefix=$$m) || exit 1; done - + status=0; \ + for m in $(HAND_MODS); do \ + echo "Linting module: $$m"; \ + (cd "$$m" && golangci-lint run $(LINT_OPTIONS) --path-prefix="$$m" ) || status=1; \ + done; \ + exit $$status proto-generate: rm -rf protocol/go/[a-fh-z]* docs/grpc docs/openapi buf generate service diff --git a/README.md b/README.md index b7fc62bc6..f158243d8 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,19 @@ - [Podman Compose](https://github.com/containers/podman-compose) - [Buf](https://buf.build/docs/ecosystem/cli-overview) is used for managing protobuf files. Required for developing services. +- [golangci-lint](https://golangci-lint.run/) is used for ensuring good coding practices. + Use `make go-lint` to run it before submitting a PR On macOS, these can be installed with [brew](https://docs.brew.sh/Installation) ```sh -brew install buf go +brew install buf go golangci-lint ``` #### Optional tools - _Optional_ [Air](https://github.com/cosmtrek/air) is used for hot-reload development - install with `go install github.com/cosmtrek/air@latest` -- _Optional_ [golangci-lint](https://golangci-lint.run/) is used for ensuring good coding practices - - install with `brew install golangci-lint` - _Optional_ [grpcurl](https://github.com/fullstorydev/grpcurl) is used for testing gRPC services - install with `brew install grpcurl` - _Optional_ [openssl](https://www.openssl.org/) is used for generating certificates diff --git a/buf.lock b/buf.lock index c8ac0410d..10d51eb79 100644 --- a/buf.lock +++ b/buf.lock @@ -2,11 +2,11 @@ version: v2 deps: - name: buf.build/bufbuild/protovalidate - commit: e097f827e65240ac9fd4b1158849a8fc - digest: b5:beda657a164abf9d1bac222e352f14d9a4a8c913ccdb7e5c3dfeda097690f60e8edb27b518c2d8e73b70aecb6ac47fdc3654a1f62b9e09c3566cd4e620628cfd + commit: 63bb56e204954558946a641ef0d68910 + digest: b5:ec5661b2855484eca2043fe61d27eb22673ab926ccd0e849531752eb17b08402fae1382705cee7f7b42d4d9ec56aff72bba7ec6835902cf6f86323c9ac682d16 - name: buf.build/googleapis/googleapis - commit: a86849a25cc04f4dbe9b15ddddfbc488 - digest: b5:a77a2082c596ee6800a23d8cecd021d316eb10565d6cb94532f2d7c567fe6c9a177b5bb123b51a3acb4f1f18d4f54a6da883afcb682919a137a8a37c020509a2 + commit: 83c0f6c19b2f4ea0b0fd84a80e753659 + digest: b5:e9d077ad9d2eaa08a056108a15292a69548880d3a935781c498f2e591e60e531e49e1f5fc1d7356e5f989d3a8540e9885a02df18cb0cecc4ffa439fa4438a09e - name: buf.build/grpc-ecosystem/grpc-gateway - commit: 3f42134f4c564983838425bc43c7a65f - digest: b5:291b947d8ac09492517557e4e72e294788cb8201afc7d0df7bda80fa10931adb60d4d669208a7696bf24f1ecb2a33a16d4c1e766e6f31809248b00343119569b + commit: 4c5ba75caaf84e928b7137ae5c18c26a + digest: b5:c113e62fb3b29289af785866cae062b55ec8ae19ab3f08f3004098928fbca657730a06810b2012951294326b95669547194fa84476b9e9b688d4f8bf77a0691d diff --git a/docs/Contributing.md b/docs/Contributing.md index ca5bf24fa..9afb89971 100644 --- a/docs/Contributing.md +++ b/docs/Contributing.md @@ -51,4 +51,5 @@ Note: When `exportToJaeger` is false, traces will be written to local files inst ## Advice for Code Contributors +* Make sure to run our linters with `make lint` * Follow our [Error Guidelines](./Contributing-errors.md) diff --git a/docs/grpc/index.html b/docs/grpc/index.html index 309ca58dd..bffbf1f5d 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -3557,6 +3557,14 @@

KeyAccess

header is only used for NanoTDFs

+ + ephemeral_public_key + string + +

For wrapping with an ECDH derived key, when type=ec-wrapped. +Should be a PEM-encoded PKCS#8 (asn.1) value.

+ + @@ -3964,10 +3972,62 @@

UnsignedRewrapRequest

+ + key_access + KeyAccess + +

Deprecated. Used for legacy non-bulk requests

+ + + + policy + string + +

Deprecated. Used for legacy non-bulk requests

+ + + + algorithm + string + +

Deprecated. Used for legacy non-bulk requests

+ + + + +

Fields with deprecated option

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameOption
key_access

true

policy

true

algorithm

true

+ + @@ -5043,13 +5103,48 @@

GetAttributeRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + attribute_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -5091,13 +5186,48 @@

GetAttributeValueRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + value_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -6422,13 +6552,55 @@

GetKeyAccessServerRequest< id string -

Required

+

Deprecated. Deprecated

+ + + + kas_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + name + string + +

+ + + + uri + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -6755,13 +6927,21 @@

ListPublicKeyMappingRequ kas_id string -

Optional - -Future filter by fields -// Optional -string kas_name = 2; -// Optional -string kas_uri = 3;

+

Optional

+ + + + kas_name + string + +

Optional

+ + + + kas_uri + string + +

Optional

@@ -6951,13 +7131,21 @@

ListPublicKeysRequest

kas_id string -

Optional - -Future filter by fields -// Optional -string kas_name = 2; -// Optional -string kas_uri = 3;

+

Optional

+ + + + kas_name + string + +

Optional

+ + + + kas_uri + string + +

Optional

@@ -7574,13 +7762,48 @@

GetNamespaceRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + namespace_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + diff --git a/docs/openapi/policy/attributes/attributes.swagger.json b/docs/openapi/policy/attributes/attributes.swagger.json index 0027fda4e..d9c4593a2 100644 --- a/docs/openapi/policy/attributes/attributes.swagger.json +++ b/docs/openapi/policy/attributes/attributes.swagger.json @@ -249,10 +249,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "valueId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -543,10 +556,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "attributeId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json b/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json index 9cff708cf..a3606167c 100644 --- a/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json +++ b/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json @@ -168,10 +168,29 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "kasId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "uri", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/docs/openapi/policy/namespaces/namespaces.swagger.json b/docs/openapi/policy/namespaces/namespaces.swagger.json index 7f435905c..3aa587d3f 100644 --- a/docs/openapi/policy/namespaces/namespaces.swagger.json +++ b/docs/openapi/policy/namespaces/namespaces.swagger.json @@ -189,10 +189,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "namespaceId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/examples/cmd/decrypt.go b/examples/cmd/decrypt.go index 430465e1d..f8040cc5a 100644 --- a/examples/cmd/decrypt.go +++ b/examples/cmd/decrypt.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" + "github.com/opentdf/platform/sdk" + "github.com/spf13/cobra" ) @@ -18,6 +20,7 @@ func init() { RunE: decrypt, Args: cobra.MinimumNArgs(1), } + decryptCmd.Flags().StringVarP(&alg, "rewrap-encapsulation-algorithm", "A", "rsa:2048", "Key wrap response algorithm algorithm:parameters") ExamplesCmd.AddCommand(decryptCmd) } @@ -81,7 +84,15 @@ func decrypt(cmd *cobra.Command, args []string) error { } if !isNano { - tdfreader, err := client.LoadTDF(file) + opts := []sdk.TDFReaderOption{} + if alg != "" { + kt, err := keyTypeForKeyType(alg) + if err != nil { + return err + } + opts = append(opts, sdk.WithSessionKeyType(kt)) + } + tdfreader, err := client.LoadTDF(file, opts...) if err != nil { return err } diff --git a/examples/cmd/encrypt.go b/examples/cmd/encrypt.go index fdf242792..7287facd5 100644 --- a/examples/cmd/encrypt.go +++ b/examples/cmd/encrypt.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/opentdf/platform/lib/ocrypto" - "github.com/opentdf/platform/sdk" "github.com/spf13/cobra" ) @@ -23,6 +22,7 @@ var ( outputName string dataAttributes []string collection int + alg string ) func init() { @@ -38,6 +38,7 @@ func init() { encryptCmd.Flags().BoolVar(&noKIDInKAO, "no-kid-in-kao", false, "[deprecated] Disable storing key identifiers in TDF KAOs") encryptCmd.Flags().BoolVar(&noKIDInNano, "no-kid-in-nano", true, "Disable storing key identifiers in nanoTDF KAS ResourceLocator") encryptCmd.Flags().StringVarP(&outputName, "output", "o", "sensitive.txt.tdf", "name or path of output file; - for stdout") + encryptCmd.Flags().StringVarP(&alg, "key-encapsulation-algorithm", "A", "rsa:2048", "Key wrap algorithm algorithm:parameters") encryptCmd.Flags().IntVarP(&collection, "collection", "c", 0, "number of nano's to create for collection. If collection >0 (default) then output will be _") ExamplesCmd.AddCommand(&encryptCmd) @@ -102,6 +103,7 @@ func encrypt(cmd *cobra.Command, args []string) error { opts := []sdk.TDFOption{sdk.WithDataAttributes(dataAttributes...)} if !autoconfigure { opts = append(opts, sdk.WithAutoconfigure(autoconfigure)) + opts = append(opts, sdk.WithWrappingKeyAlg(ocrypto.EC256Key)) opts = append(opts, sdk.WithKasInformation( sdk.KASInfo{ // examples assume insecure http @@ -109,6 +111,13 @@ func encrypt(cmd *cobra.Command, args []string) error { PublicKey: "", })) } + if alg != "" { + kt, err := keyTypeForKeyType(alg) + if err != nil { + return err + } + opts = append(opts, sdk.WithWrappingKeyAlg(kt)) + } tdf, err := client.CreateTDF(out, in, opts...) if err != nil { return err @@ -156,6 +165,18 @@ func encrypt(cmd *cobra.Command, args []string) error { return nil } +func keyTypeForKeyType(alg string) (ocrypto.KeyType, error) { + switch alg { + case string(ocrypto.RSA2048Key): + return ocrypto.RSA2048Key, nil + case string(ocrypto.EC256Key): + return ocrypto.EC256Key, nil + default: + // do not submit add ocrypto.UnknownKey + return ocrypto.RSA2048Key, fmt.Errorf("unsupported key type [%s]", alg) + } +} + func cat(cmd *cobra.Command, nTdfFile string) error { f, err := os.Open(nTdfFile) if err != nil { diff --git a/examples/go.mod b/examples/go.mod index 40049e454..bff25077c 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,9 +3,9 @@ module github.com/opentdf/platform/examples go 1.21 require ( - github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 - github.com/opentdf/platform/sdk v0.3.23 + github.com/opentdf/platform/lib/ocrypto v0.1.8 + github.com/opentdf/platform/protocol/go v0.2.27 + github.com/opentdf/platform/sdk v0.3.27 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.66.0 diff --git a/examples/go.sum b/examples/go.sum index a0e575291..ce825598a 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -105,14 +105,14 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opentdf/platform/lib/fixtures v0.2.8 h1:lGYrMnbORtU62lxsJi8qPsxjFuNIkc4Dop8rVkH6pD0= -github.com/opentdf/platform/lib/fixtures v0.2.8/go.mod h1:8yCSe+oUzW9jbM573r9qgE68rjwDMNzktObiGVsO/W8= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= -github.com/opentdf/platform/sdk v0.3.23 h1:lTjWiqCGcA1fvMNOMUPIiOl8FNNQTaEK/+xyGvpbMZs= -github.com/opentdf/platform/sdk v0.3.23/go.mod h1:KpT/m5zXQ19WqhGePKfIC39Ly8LOipKdKGbJ1B/59a8= +github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXvCTb+nJCuiU2WsWs= +github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= +github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= +github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/sdk v0.3.27 h1:O9jCdpnxz3FEaTXj/hAOixR5mk/APsalcWCexGxfwkM= +github.com/opentdf/platform/sdk v0.3.27/go.mod h1:ZJyz6hy0CMiD3MFfG4PrByTnSJnEtArTGA6ZoR1Xg6E= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/lib/ocrypto/CHANGELOG.md b/lib/ocrypto/CHANGELOG.md index d9dfca584..ae8a91d5e 100644 --- a/lib/ocrypto/CHANGELOG.md +++ b/lib/ocrypto/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.1.8](https://github.com/opentdf/platform/compare/lib/ocrypto/v0.1.7...lib/ocrypto/v0.1.8) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **kas:** collect metrics ([#1702](https://github.com/opentdf/platform/issues/1702)) ([def28d1](https://github.com/opentdf/platform/commit/def28d1984b0b111a07330a3eb59c1285206062d)) + ## [0.1.7](https://github.com/opentdf/platform/compare/lib/ocrypto/v0.1.6...lib/ocrypto/v0.1.7) (2024-11-15) diff --git a/lib/ocrypto/asym_decryption.go b/lib/ocrypto/asym_decryption.go index 1cf2eba9d..1982b58dc 100644 --- a/lib/ocrypto/asym_decryption.go +++ b/lib/ocrypto/asym_decryption.go @@ -2,20 +2,34 @@ package ocrypto import ( "crypto" + "crypto/aes" + "crypto/cipher" + "crypto/ecdh" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rsa" + "crypto/sha256" "crypto/x509" "encoding/pem" "errors" "fmt" + "io" "strings" + + "golang.org/x/crypto/hkdf" ) type AsymDecryption struct { PrivateKey *rsa.PrivateKey } -// NewAsymDecryption creates and returns a new AsymDecryption. -func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { +type PrivateKeyDecryptor interface { + // Decrypt decrypts ciphertext with private key. + Decrypt(data []byte) ([]byte, error) +} + +// FromPrivatePEM creates and returns a new AsymDecryption. +func FromPrivatePEM(privateKeyInPem string) (PrivateKeyDecryptor, error) { block, _ := pem.Decode([]byte(privateKeyInPem)) if block == nil { return AsymDecryption{}, errors.New("failed to parse PEM formatted private key") @@ -40,13 +54,34 @@ func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { } switch privateKey := priv.(type) { + case *ecdsa.PrivateKey: + sk, err := privateKey.ECDH() + if err != nil { + return nil, fmt.Errorf("unable to create ECDH key: %w", err) + } + return NewECDecryptor(sk) + case *ecdh.PrivateKey: + return NewECDecryptor(privateKey) case *rsa.PrivateKey: return AsymDecryption{privateKey}, nil default: break } - return AsymDecryption{}, errors.New("not an rsa PEM formatted private key") + return nil, errors.New("not a supported PEM formatted private key") +} + +func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { + d, err := FromPrivatePEM(privateKeyInPem) + if err != nil { + return AsymDecryption{}, err + } + switch d := d.(type) { + case AsymDecryption: + return d, nil + default: + return AsymDecryption{}, errors.New("not an RSA private key") + } } // Decrypt decrypts ciphertext with private key. @@ -64,3 +99,96 @@ func (asymDecryption AsymDecryption) Decrypt(data []byte) ([]byte, error) { return bytes, nil } + +type ECDecryptor struct { + sk *ecdh.PrivateKey + salt []byte + info []byte +} + +func NewECDecryptor(sk *ecdh.PrivateKey) (ECDecryptor, error) { + // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? + salt := []byte("salt") + return ECDecryptor{sk, salt, nil}, nil +} + +func (e ECDecryptor) Decrypt(_ []byte) ([]byte, error) { + // TK How to get the ephmeral key into here? + return nil, errors.New("ecdh standard decrypt unimplemented") +} + +func (e ECDecryptor) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) { + var ek *ecdh.PublicKey + + if pubFromDSN, err := x509.ParsePKIXPublicKey(ephemeral); err == nil { + switch pubFromDSN := pubFromDSN.(type) { + case *ecdsa.PublicKey: + ek, err = ConvertToECDHPublicKey(pubFromDSN) + if err != nil { + return nil, fmt.Errorf("ecdh conversion failure: %w", err) + } + case *ecdh.PublicKey: + ek = pubFromDSN + default: + return nil, errors.New("not an supported type of public key") + } + } else { + ekDSA, err := UncompressECPubKey(convCurve(e.sk.Curve()), ephemeral) + if err != nil { + return nil, err + } + ek, err = ekDSA.ECDH() + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + } + + ikm, err := e.sk.ECDH(ek) + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + + hkdfObj := hkdf.New(sha256.New, ikm, e.salt, e.info) + + derivedKey := make([]byte, len(ikm)) + if _, err := io.ReadFull(hkdfObj, derivedKey); err != nil { + return nil, fmt.Errorf("hkdf failure: %w", err) + } + + // Encrypt data with derived key using aes-gcm + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, fmt.Errorf("aes.NewCipher failure: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("cipher.NewGCM failure: %w", err) + } + + nonceSize := gcm.NonceSize() + if len(data) < nonceSize { + return nil, errors.New("ciphertext too short") + } + + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, fmt.Errorf("gcm.Open failure: %w", err) + } + + return plaintext, nil +} + +func convCurve(c ecdh.Curve) elliptic.Curve { + switch c { + case ecdh.P256(): + return elliptic.P256() + case ecdh.P384(): + return elliptic.P384() + case ecdh.P521(): + return elliptic.P521() + default: + return nil + } +} diff --git a/lib/ocrypto/asym_encrypt_decrypt_test.go b/lib/ocrypto/asym_encrypt_decrypt_test.go index a40e93834..29a9d33de 100644 --- a/lib/ocrypto/asym_encrypt_decrypt_test.go +++ b/lib/ocrypto/asym_encrypt_decrypt_test.go @@ -5,7 +5,7 @@ import ( ) func TestAsymEncryptionAndDecryption(t *testing.T) { - var rsaKeys = []struct { + var keypairs = []struct { privateKey string publicKey string }{ @@ -215,10 +215,25 @@ I099IoRfC5djHUYYLMU/VkOIHuPC3sb7J65pSN26eR8bTMVNagk187V/xNwUuvkf wVyElqp317Ksz+GtTIc+DE6oryxK3tZd4hrj9fXT4KiJvQ4pcRjpePgH7B8= -----END CERTIFICATE-----`, }, + {`-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwQlQvwfqC0sEaPVi +l1CdHNqAndukGsrqMsfiIefXHQChRANCAAQSZSoVakwpWhKBZIR9dmmTkKv7GK6n +6d0yFeGzOyqB7l9LOzOwlCDdm9k0jBQBw597Dyy7KQzW73zi+pSpgfYr +-----END PRIVATE KEY----- +`, `-----BEGIN CERTIFICATE----- +MIIBcTCCARegAwIBAgIUQBzVxCvhpTzXU+i7qyiTNniBL4owCgYIKoZIzj0EAwIw +DjEMMAoGA1UEAwwDa2FzMB4XDTI1MDExMDE2MzQ1NVoXDTI2MDExMDE2MzQ1NVow +DjEMMAoGA1UEAwwDa2FzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEmUqFWpM +KVoSgWSEfXZpk5Cr+xiup+ndMhXhszsqge5fSzszsJQg3ZvZNIwUAcOfew8suykM +1u984vqUqYH2K6NTMFEwHQYDVR0OBBYEFCAo/c694aHwmw/0kUTKuFvAQ4OcMB8G +A1UdIwQYMBaAFCAo/c694aHwmw/0kUTKuFvAQ4OcMA8GA1UdEwEB/wQFMAMBAf8w +CgYIKoZIzj0EAwIDSAAwRQIgUzKsJS6Pcu2aZ6BFfuqob552Ebdel4uFGZMqWrwW +bW0CIQDT5QED+8mHFot9JXSx2q1c5mnRvl4yElK0fiHeatBdqw== +-----END CERTIFICATE-----`}, } - for _, test := range rsaKeys { - asymEncryptor, err := NewAsymEncryption(test.publicKey) + for _, test := range keypairs { + asymEncryptor, err := FromPublicPEM(test.publicKey) if err != nil { t.Fatalf("NewAsymEncryption - failed: %v", err) } @@ -229,14 +244,25 @@ wVyElqp317Ksz+GtTIc+DE6oryxK3tZd4hrj9fXT4KiJvQ4pcRjpePgH7B8= t.Fatalf("AsymEncryption encrypt failed: %v", err) } - asymDecryptor, err := NewAsymDecryption(test.privateKey) + asymDecryptor, err := FromPrivatePEM(test.privateKey) if err != nil { t.Fatalf("NewAsymDecryption - failed: %v", err) } - decryptedText, err := asymDecryptor.Decrypt(cipherText) - if err != nil { - t.Fatalf("AsymDecryption decrypt failed: %v", err) + var decryptedText []byte + ek := asymEncryptor.EphemeralKey() + if ek == nil { + decryptedText, err = asymDecryptor.Decrypt(cipherText) + if err != nil { + t.Fatalf("AsymDecryption decrypt failed: %v", err) + } + } else if ecd, ok := asymDecryptor.(ECDecryptor); ok { + decryptedText, err = ecd.DecryptWithEphemeralKey(cipherText, ek) + if err != nil { + t.Fatalf("AsymDecryption decrypt failed: %v", err) + } + } else { + t.Fatalf("AsymDecryption wrong type: %T", asymDecryptor) } if string(decryptedText) != plainText { diff --git a/lib/ocrypto/asym_encryption.go b/lib/ocrypto/asym_encryption.go index 65ef5a115..f8cfd68b9 100644 --- a/lib/ocrypto/asym_encryption.go +++ b/lib/ocrypto/asym_encryption.go @@ -1,63 +1,169 @@ package ocrypto import ( + "crypto/aes" + "crypto/cipher" + "crypto/ecdh" + "crypto/ecdsa" "crypto/rand" "crypto/rsa" "crypto/sha1" //nolint:gosec // used for padding which is safe + "crypto/sha256" "crypto/x509" "encoding/pem" "errors" "fmt" + "io" "strings" + + "golang.org/x/crypto/hkdf" ) +type SchemeType string + +const ( + RSA SchemeType = "wrapped" + EC SchemeType = "ec-wrapped" +) + +type PublicKeyEncryptor interface { + // Encrypt encrypts data with public key. + Encrypt(data []byte) ([]byte, error) + + // PublicKeyInPemFormat Returns public key in pem format, or the empty string if not present + PublicKeyInPemFormat() (string, error) + + // Type required to use the scheme for encryption - notably, if it procduces extra metadata. + Type() SchemeType + + // For EC schemes, this method returns the public part of the ephemeral key. + // Otherwise, it returns nil. + EphemeralKey() []byte + + // Any extra metadata, e.g. the ephemeral public key for EC scheme keys. + Metadata() (map[string]string, error) +} + type AsymEncryption struct { PublicKey *rsa.PublicKey } +type ECEncryptor struct { + pub *ecdh.PublicKey + ek *ecdh.PrivateKey + salt []byte + info []byte +} + +func FromPublicPEM(publicKeyInPem string) (PublicKeyEncryptor, error) { + pub, err := getPublicPart(publicKeyInPem) + if err != nil { + return nil, err + } + + switch pub := pub.(type) { + case *rsa.PublicKey: + return &AsymEncryption{pub}, nil + case *ecdsa.PublicKey: + e, err := pub.ECDH() + if err != nil { + return nil, err + } + return newECIES(e) + case *ecdh.PublicKey: + return newECIES(pub) + default: + break + } + + return nil, errors.New("not an supported type of public key") +} + +func newECIES(pub *ecdh.PublicKey) (ECEncryptor, error) { + ek, err := pub.Curve().GenerateKey(rand.Reader) + // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? + salt := []byte("salt") + return ECEncryptor{pub, ek, salt, nil}, err +} + // NewAsymEncryption creates and returns a new AsymEncryption. +// Deprecated: Use FromPublicPEM instead. func NewAsymEncryption(publicKeyInPem string) (AsymEncryption, error) { + pub, err := getPublicPart(publicKeyInPem) + if err != nil { + return AsymEncryption{}, err + } + + switch pub := pub.(type) { + case *rsa.PublicKey: + return AsymEncryption{pub}, nil + default: + break + } + + return AsymEncryption{}, errors.New("not an supported type of public key") +} + +func getPublicPart(publicKeyInPem string) (any, error) { block, _ := pem.Decode([]byte(publicKeyInPem)) if block == nil { - return AsymEncryption{}, errors.New("failed to parse PEM formatted public key") + return nil, errors.New("failed to parse PEM formatted public key") } var pub any if strings.Contains(publicKeyInPem, "BEGIN CERTIFICATE") { cert, err := x509.ParseCertificate(block.Bytes) if err != nil { - return AsymEncryption{}, fmt.Errorf("x509.ParseCertificate failed: %w", err) + return nil, fmt.Errorf("x509.ParseCertificate failed: %w", err) } - var ok bool - if pub, ok = cert.PublicKey.(*rsa.PublicKey); !ok { - return AsymEncryption{}, errors.New("failed to parse PEM formatted public key") - } + pub = cert.PublicKey } else { var err error pub, err = x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return AsymEncryption{}, fmt.Errorf("x509.ParsePKIXPublicKey failed: %w", err) + return nil, fmt.Errorf("x509.ParsePKIXPublicKey failed: %w", err) } } + return pub, nil +} - switch pub := pub.(type) { - case *rsa.PublicKey: - return AsymEncryption{pub}, nil - default: - break +func (e AsymEncryption) Type() SchemeType { + return RSA +} + +func (e ECEncryptor) Type() SchemeType { + return EC +} + +func (e AsymEncryption) EphemeralKey() []byte { + return nil +} + +func (e ECEncryptor) EphemeralKey() []byte { + publicKeyBytes, err := x509.MarshalPKIXPublicKey(e.ek.PublicKey()) + if err != nil { + return nil } + return publicKeyBytes +} - return AsymEncryption{}, errors.New("not an rsa PEM formatted public key") +func (e AsymEncryption) Metadata() (map[string]string, error) { + return make(map[string]string), nil } -// Encrypt encrypts data with public key. -func (asymEncryption AsymEncryption) Encrypt(data []byte) ([]byte, error) { - if asymEncryption.PublicKey == nil { +func (e ECEncryptor) Metadata() (map[string]string, error) { + m := make(map[string]string) + m["ephemeralPublicKey"] = string(e.EphemeralKey()) + return m, nil +} + +func (e AsymEncryption) Encrypt(data []byte) ([]byte, error) { + if e.PublicKey == nil { return nil, errors.New("failed to encrypt, public key is empty") } - bytes, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, asymEncryption.PublicKey, data, nil) //nolint:gosec // used for padding which is safe + bytes, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, e.PublicKey, data, nil) //nolint:gosec // used for padding which is safe if err != nil { return nil, fmt.Errorf("rsa.EncryptOAEP failed: %w", err) } @@ -65,13 +171,12 @@ func (asymEncryption AsymEncryption) Encrypt(data []byte) ([]byte, error) { return bytes, nil } -// PublicKeyInPemFormat Returns public key in pem format. -func (asymEncryption AsymEncryption) PublicKeyInPemFormat() (string, error) { - if asymEncryption.PublicKey == nil { +func publicKeyInPemFormat(pk any) (string, error) { + if pk == nil { return "", errors.New("failed to generate PEM formatted public key") } - publicKeyBytes, err := x509.MarshalPKIXPublicKey(asymEncryption.PublicKey) + publicKeyBytes, err := x509.MarshalPKIXPublicKey(pk) if err != nil { return "", fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err) } @@ -85,3 +190,46 @@ func (asymEncryption AsymEncryption) PublicKeyInPemFormat() (string, error) { return string(publicKeyPem), nil } + +func (e AsymEncryption) PublicKeyInPemFormat() (string, error) { + return publicKeyInPemFormat(e.PublicKey) +} + +// Encrypts the data with the EC public key. +func (e ECEncryptor) Encrypt(data []byte) ([]byte, error) { + ikm, err := e.ek.ECDH(e.pub) + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + + hkdfObj := hkdf.New(sha256.New, ikm, e.salt, e.info) + + derivedKey := make([]byte, len(ikm)) + if _, err := io.ReadFull(hkdfObj, derivedKey); err != nil { + return nil, fmt.Errorf("hkdf failure: %w", err) + } + + // Encrypt data with derived key using aes-gcm + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, fmt.Errorf("aes.NewCipher failed: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("cipher.NewGCM failed: %w", err) + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, fmt.Errorf("nonce generation failed: %w", err) + } + + ciphertext := gcm.Seal(nonce, nonce, data, nil) + return ciphertext, nil +} + +// PublicKeyInPemFormat Returns public key in pem format. +func (e ECEncryptor) PublicKeyInPemFormat() (string, error) { + return publicKeyInPemFormat(e.ek.Public()) +} diff --git a/lib/ocrypto/ec_key_pair.go b/lib/ocrypto/ec_key_pair.go index 6b9d0a960..504c13408 100644 --- a/lib/ocrypto/ec_key_pair.go +++ b/lib/ocrypto/ec_key_pair.go @@ -19,6 +19,15 @@ import ( type ECCMode uint8 +type KeyType string + +const ( + RSA2048Key KeyType = "rsa:2048" + EC256Key KeyType = "ec:secp256r1" + EC384Key KeyType = "ec:secp384r1" + EC521Key KeyType = "ec:secp521r1" +) + const ( ECCModeSecp256r1 ECCMode = 0 ECCModeSecp384r1 ECCMode = 1 @@ -26,10 +35,60 @@ const ( ECCModeSecp256k1 ECCMode = 3 ) +const ( + ECCurveP256Size = 256 + ECCurveP384Size = 384 + ECCurveP521Size = 521 + RSA2048Size = 2048 +) + +type KeyPair interface { + PublicKeyInPemFormat() (string, error) + PrivateKeyInPemFormat() (string, error) + GetKeyType() KeyType +} + +func NewKeyPair(kt KeyType) (KeyPair, error) { + switch kt { + case RSA2048Key: + bits, err := RSAKeyTypeToBits(kt) + if err != nil { + return nil, err + } + return NewRSAKeyPair(bits) + case EC256Key, EC384Key, EC521Key: + mode, err := ECKeyTypeToMode(kt) + if err != nil { + return nil, err + } + return NewECKeyPair(mode) + default: + return nil, fmt.Errorf("unsupported key type: %v", kt) + } +} + type ECKeyPair struct { PrivateKey *ecdsa.PrivateKey } +func IsECKeyType(kt KeyType) bool { + switch kt { //nolint:exhaustive // only handle ec types + case EC256Key, EC384Key, EC521Key: + return true + default: + return false + } +} + +func IsRSAKeyType(kt KeyType) bool { + switch kt { //nolint:exhaustive // only handle rsa types + case RSA2048Key: + return true + default: + return false + } +} + // GetECCurveFromECCMode return elliptic curve from ecc mode func GetECCurveFromECCMode(mode ECCMode) (elliptic.Curve, error) { var c elliptic.Curve @@ -65,6 +124,42 @@ func (mode ECCMode) String() string { return "unspecified" } +// ECSizeToMode converts a curve size to an ECCMode +func ECSizeToMode(size int) (ECCMode, error) { + switch size { + case ECCurveP256Size: + return ECCModeSecp256r1, nil + case ECCurveP384Size: + return ECCModeSecp384r1, nil + case ECCurveP521Size: + return ECCModeSecp521r1, nil + default: + return 0, fmt.Errorf("unsupported EC curve size: %d", size) + } +} + +func ECKeyTypeToMode(kt KeyType) (ECCMode, error) { + switch kt { //nolint:exhaustive // only handle ec types + case EC256Key: + return ECCModeSecp256r1, nil + case EC384Key: + return ECCModeSecp384r1, nil + case EC521Key: + return ECCModeSecp521r1, nil + default: + return 0, fmt.Errorf("unsupported type: %v", kt) + } +} + +func RSAKeyTypeToBits(kt KeyType) (int, error) { + switch kt { //nolint:exhaustive // only handle rsa types + case RSA2048Key: + return RSA2048Size, nil + default: + return 0, fmt.Errorf("unsupported type: %v", kt) + } +} + // NewECKeyPair Generates an EC key pair of the given bit size. func NewECKeyPair(mode ECCMode) (ECKeyPair, error) { var c elliptic.Curve @@ -361,3 +456,37 @@ func ECPublicKeyInPemFormat(publicKey ecdsa.PublicKey) (string, error) { return string(publicKeyPem), nil } + +// GetECKeySize returns the curve size from a PEM-encoded EC public key +func GetECKeySize(pemData []byte) (int, error) { + block, _ := pem.Decode(pemData) + if block == nil { + return 0, fmt.Errorf("failed to parse PEM block") + } + + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return 0, fmt.Errorf("failed to parse public key: %w", err) + } + + ecKey, ok := pub.(*ecdsa.PublicKey) + if !ok { + return 0, fmt.Errorf("not an EC key") + } + + switch ecKey.Curve { + case elliptic.P256(): + return ECCurveP256Size, nil + case elliptic.P384(): + return ECCurveP384Size, nil + case elliptic.P521(): + return ECCurveP521Size, nil + default: + return 0, fmt.Errorf("unknown curve") + } +} + +// GetKeyType returns the key type (ECKey) +func (keyPair ECKeyPair) GetKeyType() KeyType { + return EC256Key +} diff --git a/lib/ocrypto/rsa_key_pair.go b/lib/ocrypto/rsa_key_pair.go index e52a5428a..914eb8f80 100644 --- a/lib/ocrypto/rsa_key_pair.go +++ b/lib/ocrypto/rsa_key_pair.go @@ -76,3 +76,8 @@ func (keyPair RsaKeyPair) KeySize() (int, error) { } return keyPair.privateKey.N.BitLen(), nil } + +// GetKeyType returns the key type (RSAKey) +func (keyPair RsaKeyPair) GetKeyType() KeyType { + return RSA2048Key +} diff --git a/protocol/go/CHANGELOG.md b/protocol/go/CHANGELOG.md index 43469e82d..547202595 100644 --- a/protocol/go/CHANGELOG.md +++ b/protocol/go/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## [0.2.28](https://github.com/opentdf/platform/compare/protocol/go/v0.2.27...protocol/go/v0.2.28) (2025-02-26) + + +### Bug Fixes + +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) + +## [0.2.27](https://github.com/opentdf/platform/compare/protocol/go/v0.2.26...protocol/go/v0.2.27) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) + + +### Bug Fixes + +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) + +## [0.2.26](https://github.com/opentdf/platform/compare/protocol/go/v0.2.25...protocol/go/v0.2.26) (2025-02-14) + + +### Features + +* add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) + ## [0.2.25](https://github.com/opentdf/platform/compare/protocol/go/v0.2.24...protocol/go/v0.2.25) (2025-01-31) diff --git a/protocol/go/kas/kas.pb.go b/protocol/go/kas/kas.pb.go index 7451da9c9..cd41a7c29 100644 --- a/protocol/go/kas/kas.pb.go +++ b/protocol/go/kas/kas.pb.go @@ -227,6 +227,9 @@ type KeyAccess struct { WrappedKey []byte `protobuf:"bytes,8,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` // header is only used for NanoTDFs Header []byte `protobuf:"bytes,9,opt,name=header,proto3" json:"header,omitempty"` + // For wrapping with an ECDH derived key, when type=ec-wrapped. + // Should be a PEM-encoded PKCS#8 (asn.1) value. + EphemeralPublicKey string `protobuf:"bytes,10,opt,name=ephemeral_public_key,json=ephemeralPublicKey,proto3" json:"ephemeral_public_key,omitempty"` } func (x *KeyAccess) Reset() { @@ -324,6 +327,13 @@ func (x *KeyAccess) GetHeader() []byte { return nil } +func (x *KeyAccess) GetEphemeralPublicKey() string { + if x != nil { + return x.EphemeralPublicKey + } + return "" +} + type UnsignedRewrapRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -331,6 +341,18 @@ type UnsignedRewrapRequest struct { ClientPublicKey string `protobuf:"bytes,1,opt,name=client_public_key,json=clientPublicKey,proto3" json:"client_public_key,omitempty"` Requests []*UnsignedRewrapRequest_WithPolicyRequest `protobuf:"bytes,2,rep,name=requests,proto3" json:"requests,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + KeyAccess *KeyAccess `protobuf:"bytes,3,opt,name=key_access,json=keyAccess,proto3" json:"key_access,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + Policy string `protobuf:"bytes,4,opt,name=policy,proto3" json:"policy,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + Algorithm string `protobuf:"bytes,5,opt,name=algorithm,proto3" json:"algorithm,omitempty"` } func (x *UnsignedRewrapRequest) Reset() { @@ -379,6 +401,30 @@ func (x *UnsignedRewrapRequest) GetRequests() []*UnsignedRewrapRequest_WithPolic return nil } +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetKeyAccess() *KeyAccess { + if x != nil { + return x.KeyAccess + } + return nil +} + +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetPolicy() string { + if x != nil { + return x.Policy + } + return "" +} + +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + type PublicKeyRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -986,7 +1032,7 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x6d, 0x22, 0x3b, 0x0a, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x6c, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xa1, + 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xd3, 0x02, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, @@ -1005,147 +1051,157 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x22, 0x95, 0x04, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, - 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6b, 0x61, 0x73, - 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2f, 0x0a, 0x14, - 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x3a, 0x0a, - 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, 0x11, 0x57, 0x69, - 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6b, 0x61, - 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, 0x6b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x3d, 0x0a, - 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, - 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, - 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, 0x6b, 0x65, 0x79, - 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, 0x63, 0x75, 0x72, - 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, 0x01, 0x76, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, 0x76, 0x22, 0x44, - 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, 0x62, - 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, - 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, - 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, 0x73, 0x57, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x77, - 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x65, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x22, 0x86, 0x05, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, + 0x0a, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x08, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6b, + 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, + 0x12, 0x3a, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, + 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, + 0x11, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, + 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, + 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x12, 0x3d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, + 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, + 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, + 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, + 0x6b, 0x65, 0x79, 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, + 0x63, 0x75, 0x72, 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, + 0x01, 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, + 0x76, 0x22, 0x44, 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x52, 0x06, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, + 0x73, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x22, 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, + 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, + 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x30, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x12, 0x29, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, + 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, + 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, + 0x2f, 0x76, 0x32, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, + 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, + 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, + 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, + 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, + 0x58, 0x0a, 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, + 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, - 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x10, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, - 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x29, - 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, - 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, - 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6b, 0x61, - 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, - 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, - 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, - 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, 0x67, 0x61, - 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x58, 0x0a, 0x06, - 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, - 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, 0x61, 0x73, - 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, 0x2f, - 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, 0x0a, 0x1a, - 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, 0x42, 0x53, - 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, 0x61, 0x72, - 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, 0x30, 0x0a, - 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x61, - 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, 0x02, 0x03, - 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, + 0x76, 0x32, 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, + 0x71, 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, + 0x12, 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, + 0x65, 0x61, 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, + 0x2e, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, + 0x2f, 0x6b, 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, + 0xca, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1185,26 +1241,27 @@ var file_kas_kas_proto_goTypes = []interface{}{ var file_kas_kas_proto_depIdxs = []int32{ 3, // 0: kas.KeyAccess.policy_binding:type_name -> kas.PolicyBinding 14, // 1: kas.UnsignedRewrapRequest.requests:type_name -> kas.UnsignedRewrapRequest.WithPolicyRequest - 15, // 2: kas.KeyAccessRewrapResult.metadata:type_name -> kas.KeyAccessRewrapResult.MetadataEntry - 9, // 3: kas.PolicyRewrapResult.results:type_name -> kas.KeyAccessRewrapResult - 16, // 4: kas.RewrapResponse.metadata:type_name -> kas.RewrapResponse.MetadataEntry - 10, // 5: kas.RewrapResponse.responses:type_name -> kas.PolicyRewrapResult - 4, // 6: kas.UnsignedRewrapRequest.WithKeyAccessObject.key_access_object:type_name -> kas.KeyAccess - 13, // 7: kas.UnsignedRewrapRequest.WithPolicyRequest.key_access_objects:type_name -> kas.UnsignedRewrapRequest.WithKeyAccessObject - 12, // 8: kas.UnsignedRewrapRequest.WithPolicyRequest.policy:type_name -> kas.UnsignedRewrapRequest.WithPolicy - 17, // 9: kas.KeyAccessRewrapResult.MetadataEntry.value:type_name -> google.protobuf.Value - 17, // 10: kas.RewrapResponse.MetadataEntry.value:type_name -> google.protobuf.Value - 6, // 11: kas.AccessService.PublicKey:input_type -> kas.PublicKeyRequest - 2, // 12: kas.AccessService.LegacyPublicKey:input_type -> kas.LegacyPublicKeyRequest - 8, // 13: kas.AccessService.Rewrap:input_type -> kas.RewrapRequest - 7, // 14: kas.AccessService.PublicKey:output_type -> kas.PublicKeyResponse - 18, // 15: kas.AccessService.LegacyPublicKey:output_type -> google.protobuf.StringValue - 11, // 16: kas.AccessService.Rewrap:output_type -> kas.RewrapResponse - 14, // [14:17] is the sub-list for method output_type - 11, // [11:14] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 4, // 2: kas.UnsignedRewrapRequest.key_access:type_name -> kas.KeyAccess + 15, // 3: kas.KeyAccessRewrapResult.metadata:type_name -> kas.KeyAccessRewrapResult.MetadataEntry + 9, // 4: kas.PolicyRewrapResult.results:type_name -> kas.KeyAccessRewrapResult + 16, // 5: kas.RewrapResponse.metadata:type_name -> kas.RewrapResponse.MetadataEntry + 10, // 6: kas.RewrapResponse.responses:type_name -> kas.PolicyRewrapResult + 4, // 7: kas.UnsignedRewrapRequest.WithKeyAccessObject.key_access_object:type_name -> kas.KeyAccess + 13, // 8: kas.UnsignedRewrapRequest.WithPolicyRequest.key_access_objects:type_name -> kas.UnsignedRewrapRequest.WithKeyAccessObject + 12, // 9: kas.UnsignedRewrapRequest.WithPolicyRequest.policy:type_name -> kas.UnsignedRewrapRequest.WithPolicy + 17, // 10: kas.KeyAccessRewrapResult.MetadataEntry.value:type_name -> google.protobuf.Value + 17, // 11: kas.RewrapResponse.MetadataEntry.value:type_name -> google.protobuf.Value + 6, // 12: kas.AccessService.PublicKey:input_type -> kas.PublicKeyRequest + 2, // 13: kas.AccessService.LegacyPublicKey:input_type -> kas.LegacyPublicKeyRequest + 8, // 14: kas.AccessService.Rewrap:input_type -> kas.RewrapRequest + 7, // 15: kas.AccessService.PublicKey:output_type -> kas.PublicKeyResponse + 18, // 16: kas.AccessService.LegacyPublicKey:output_type -> google.protobuf.StringValue + 11, // 17: kas.AccessService.Rewrap:output_type -> kas.RewrapResponse + 15, // [15:18] is the sub-list for method output_type + 12, // [12:15] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_kas_kas_proto_init() } diff --git a/protocol/go/policy/attributes/attributes.pb.go b/protocol/go/policy/attributes/attributes.pb.go index 30d3b09da..988dcdf05 100644 --- a/protocol/go/policy/attributes/attributes.pb.go +++ b/protocol/go/policy/attributes/attributes.pb.go @@ -380,8 +380,15 @@ type GetAttributeRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/attributes/attributes.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetAttributeRequest_AttributeId + // *GetAttributeRequest_Fqn + Identifier isGetAttributeRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetAttributeRequest) Reset() { @@ -416,6 +423,7 @@ func (*GetAttributeRequest) Descriptor() ([]byte, []int) { return file_policy_attributes_attributes_proto_rawDescGZIP(), []int{6} } +// Deprecated: Marked as deprecated in policy/attributes/attributes.proto. func (x *GetAttributeRequest) GetId() string { if x != nil { return x.Id @@ -423,6 +431,44 @@ func (x *GetAttributeRequest) GetId() string { return "" } +func (m *GetAttributeRequest) GetIdentifier() isGetAttributeRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetAttributeRequest) GetAttributeId() string { + if x, ok := x.GetIdentifier().(*GetAttributeRequest_AttributeId); ok { + return x.AttributeId + } + return "" +} + +func (x *GetAttributeRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetAttributeRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetAttributeRequest_Identifier interface { + isGetAttributeRequest_Identifier() +} + +type GetAttributeRequest_AttributeId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + AttributeId string `protobuf:"bytes,2,opt,name=attribute_id,json=attributeId,proto3,oneof"` +} + +type GetAttributeRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetAttributeRequest_AttributeId) isGetAttributeRequest_Identifier() {} + +func (*GetAttributeRequest_Fqn) isGetAttributeRequest_Identifier() {} + type GetAttributeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -818,8 +864,15 @@ type GetAttributeValueRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/attributes/attributes.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetAttributeValueRequest_ValueId + // *GetAttributeValueRequest_Fqn + Identifier isGetAttributeValueRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetAttributeValueRequest) Reset() { @@ -854,6 +907,7 @@ func (*GetAttributeValueRequest) Descriptor() ([]byte, []int) { return file_policy_attributes_attributes_proto_rawDescGZIP(), []int{14} } +// Deprecated: Marked as deprecated in policy/attributes/attributes.proto. func (x *GetAttributeValueRequest) GetId() string { if x != nil { return x.Id @@ -861,6 +915,44 @@ func (x *GetAttributeValueRequest) GetId() string { return "" } +func (m *GetAttributeValueRequest) GetIdentifier() isGetAttributeValueRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetAttributeValueRequest) GetValueId() string { + if x, ok := x.GetIdentifier().(*GetAttributeValueRequest_ValueId); ok { + return x.ValueId + } + return "" +} + +func (x *GetAttributeValueRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetAttributeValueRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetAttributeValueRequest_Identifier interface { + isGetAttributeValueRequest_Identifier() +} + +type GetAttributeValueRequest_ValueId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + ValueId string `protobuf:"bytes,2,opt,name=value_id,json=valueId,proto3,oneof"` +} + +type GetAttributeValueRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetAttributeValueRequest_ValueId) isGetAttributeValueRequest_Identifier() {} + +func (*GetAttributeValueRequest_Fqn) isGetAttributeValueRequest_Identifier() {} + type GetAttributeValueResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2337,10 +2429,35 @@ var file_policy_attributes_attributes_proto_rawDesc = []byte{ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbe, + 0x03, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, + 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, + 0x03, 0x66, 0x71, 0x6e, 0x3a, 0xaa, 0x02, 0xba, 0x48, 0xa6, 0x02, 0x1a, 0xa2, 0x01, 0x0a, 0x10, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x50, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, + 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, + 0x74, 0x68, 0x1a, 0x3c, 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, + 0x1a, 0x7f, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x33, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x37, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x29, + 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, + 0x29, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, @@ -2412,447 +2529,471 @@ var file_policy_attributes_attributes_proto_rawDesc = []byte{ 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, - 0x34, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, - 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x40, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7a, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xc5, 0x03, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, - 0x12, 0xb4, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x9d, 0x02, 0xba, 0x48, 0x99, 0x02, 0xba, 0x01, 0x8d, 0x02, 0x0a, 0x16, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, - 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, - 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, - 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, - 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, - 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, - 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd, 0x01, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, - 0x10, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0xd1, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, - 0x61, 0x76, 0x69, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3b, 0x0a, 0x1f, 0x44, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, - 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, 0x20, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0xab, 0x03, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x07, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x03, 0x66, + 0x71, 0x6e, 0x3a, 0x9a, 0x02, 0xba, 0x48, 0x96, 0x02, 0x1a, 0x9a, 0x01, 0x0a, 0x10, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x4c, + 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x1a, 0x38, 0x21, 0x28, + 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, 0x1a, 0x77, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2f, 0x45, 0x69, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x33, 0x68, 0x61, 0x73, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, + 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x42, + 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x40, 0x0a, + 0x19, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x81, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x92, 0x01, 0x05, 0x08, 0x01, 0x10, 0xfa, 0x01, 0x52, 0x04, - 0x66, 0x71, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x69, 0x74, 0x68, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x9b, 0x03, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x14, 0x66, 0x71, 0x6e, 0x5f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, - 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x71, 0x6e, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x12, 0x66, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x09, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x23, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x8c, 0x01, 0x0a, 0x17, 0x46, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x5b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x45, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, - 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x95, 0x01, 0x0a, 0x27, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, - 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x28, 0x41, 0x73, + 0xad, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, + 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x75, 0x6d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x7a, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, + 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc5, 0x03, 0x0a, 0x1b, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, 0x12, 0xb4, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x9d, 0x02, 0xba, 0x48, 0x99, 0x02, 0xba, + 0x01, 0x8d, 0x02, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, + 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, + 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, + 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x4a, 0x04, 0x08, + 0x04, 0x10, 0x05, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3b, 0x0a, 0x1f, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, + 0x0a, 0x20, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, + 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x66, + 0x71, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x92, 0x01, + 0x05, 0x08, 0x01, 0x10, 0xfa, 0x01, 0x52, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x0a, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x09, 0x77, 0x69, 0x74, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9b, 0x03, 0x0a, 0x20, + 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x7d, 0x0a, 0x14, 0x66, 0x71, 0x6e, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x66, 0x71, 0x6e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, + 0x69, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x8c, 0x01, 0x0a, 0x17, 0x46, + 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x5b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, + 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x27, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x29, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, - 0x2a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x85, 0x01, 0x0a, 0x23, 0x41, 0x73, 0x73, 0x69, - 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, - 0x86, 0x01, 0x0a, 0x24, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x87, 0x01, 0x0a, 0x25, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x22, 0x96, 0x01, 0x0a, 0x28, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, + 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x26, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, - 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x6b, 0x0a, - 0x1b, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x64, 0x0a, 0x1c, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x22, 0x6d, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, - 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, - 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, - 0x66, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x29, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x2a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, + 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x5b, 0x0a, 0x17, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, - 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x18, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, - 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, - 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x55, 0x0a, 0x19, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, - 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, - 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, + 0x85, 0x01, 0x0a, 0x23, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x86, 0x01, 0x0a, 0x24, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x22, 0x87, 0x01, 0x0a, 0x25, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x26, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x6b, 0x0a, 0x1b, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, + 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x22, 0x64, 0x0a, 0x1c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, + 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x6d, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x66, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, + 0x5b, 0x0a, 0x17, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x18, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, + 0x65, 0x79, 0x22, 0x55, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, + 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, - 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x32, 0xad, 0x17, 0x0a, 0x11, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x7d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x95, - 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x7c, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, + 0x79, 0x32, 0xad, 0x17, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x7c, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, - 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x90, 0x02, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, - 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, - 0x2a, 0x2f, 0x66, 0x71, 0x6e, 0x90, 0x02, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, - 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, - 0x2a, 0x32, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0xa1, 0x01, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x66, 0x71, 0x6e, 0x90, 0x02, 0x01, + 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x32, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, - 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xa6, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, + 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xcd, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, + 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, + 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xdb, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, - 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0xcd, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, - 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0xdb, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x29, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, + 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, + 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x12, 0x79, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x22, 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, - 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x79, 0x0a, 0x14, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, - 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, - 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x30, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, - 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, - 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x16, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, - 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x42, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0xa2, 0x02, 0x03, 0x50, 0x41, 0x58, 0xaa, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, - 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, + 0x10, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, + 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, + 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, + 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x0f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, + 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x41, 0x58, 0xaa, + 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3536,6 +3677,14 @@ func file_policy_attributes_attributes_proto_init() { } } } + file_policy_attributes_attributes_proto_msgTypes[6].OneofWrappers = []interface{}{ + (*GetAttributeRequest_AttributeId)(nil), + (*GetAttributeRequest_Fqn)(nil), + } + file_policy_attributes_attributes_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*GetAttributeValueRequest_ValueId)(nil), + (*GetAttributeValueRequest_Fqn)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/attributes/attributes.pb.gw.go b/protocol/go/policy/attributes/attributes.pb.gw.go index 2e8af7a7e..ed631b9f4 100644 --- a/protocol/go/policy/attributes/attributes.pb.gw.go +++ b/protocol/go/policy/attributes/attributes.pb.gw.go @@ -103,6 +103,10 @@ func local_request_AttributesService_ListAttributeValues_0(ctx context.Context, } +var ( + filter_AttributesService_GetAttribute_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_AttributesService_GetAttribute_0(ctx context.Context, marshaler runtime.Marshaler, client AttributesServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetAttributeRequest var metadata runtime.ServerMetadata @@ -124,6 +128,13 @@ func request_AttributesService_GetAttribute_0(ctx context.Context, marshaler run return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttribute_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetAttribute(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -150,6 +161,13 @@ func local_request_AttributesService_GetAttribute_0(ctx context.Context, marshal return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttribute_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetAttribute(ctx, &protoReq) return msg, metadata, err @@ -329,6 +347,10 @@ func local_request_AttributesService_DeactivateAttribute_0(ctx context.Context, } +var ( + filter_AttributesService_GetAttributeValue_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_AttributesService_GetAttributeValue_0(ctx context.Context, marshaler runtime.Marshaler, client AttributesServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetAttributeValueRequest var metadata runtime.ServerMetadata @@ -350,6 +372,13 @@ func request_AttributesService_GetAttributeValue_0(ctx context.Context, marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttributeValue_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetAttributeValue(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -376,6 +405,13 @@ func local_request_AttributesService_GetAttributeValue_0(ctx context.Context, ma return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttributeValue_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetAttributeValue(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go index 14aeeb8cd..fd54fee6a 100644 --- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go +++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go @@ -29,8 +29,16 @@ type GetKeyAccessServerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/kasregistry/key_access_server_registry.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetKeyAccessServerRequest_KasId + // *GetKeyAccessServerRequest_Name + // *GetKeyAccessServerRequest_Uri + Identifier isGetKeyAccessServerRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetKeyAccessServerRequest) Reset() { @@ -65,6 +73,7 @@ func (*GetKeyAccessServerRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{0} } +// Deprecated: Marked as deprecated in policy/kasregistry/key_access_server_registry.proto. func (x *GetKeyAccessServerRequest) GetId() string { if x != nil { return x.Id @@ -72,6 +81,57 @@ func (x *GetKeyAccessServerRequest) GetId() string { return "" } +func (m *GetKeyAccessServerRequest) GetIdentifier() isGetKeyAccessServerRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetKeyAccessServerRequest) GetKasId() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_KasId); ok { + return x.KasId + } + return "" +} + +func (x *GetKeyAccessServerRequest) GetName() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_Name); ok { + return x.Name + } + return "" +} + +func (x *GetKeyAccessServerRequest) GetUri() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_Uri); ok { + return x.Uri + } + return "" +} + +type isGetKeyAccessServerRequest_Identifier interface { + isGetKeyAccessServerRequest_Identifier() +} + +type GetKeyAccessServerRequest_KasId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + KasId string `protobuf:"bytes,2,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type GetKeyAccessServerRequest_Name struct { + Name string `protobuf:"bytes,3,opt,name=name,proto3,oneof"` +} + +type GetKeyAccessServerRequest_Uri struct { + Uri string `protobuf:"bytes,4,opt,name=uri,proto3,oneof"` +} + +func (*GetKeyAccessServerRequest_KasId) isGetKeyAccessServerRequest_Identifier() {} + +func (*GetKeyAccessServerRequest_Name) isGetKeyAccessServerRequest_Identifier() {} + +func (*GetKeyAccessServerRequest_Uri) isGetKeyAccessServerRequest_Identifier() {} + type GetKeyAccessServerResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -825,7 +885,10 @@ type GetPublicKeyRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetPublicKeyRequest_Id + Identifier isGetPublicKeyRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetPublicKeyRequest) Reset() { @@ -860,13 +923,30 @@ func (*GetPublicKeyRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{14} } +func (m *GetPublicKeyRequest) GetIdentifier() isGetPublicKeyRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + func (x *GetPublicKeyRequest) GetId() string { - if x != nil { + if x, ok := x.GetIdentifier().(*GetPublicKeyRequest_Id); ok { return x.Id } return "" } +type isGetPublicKeyRequest_Identifier interface { + isGetPublicKeyRequest_Identifier() +} + +type GetPublicKeyRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` +} + +func (*GetPublicKeyRequest_Id) isGetPublicKeyRequest_Identifier() {} + type GetPublicKeyResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -919,8 +999,12 @@ type ListPublicKeysRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Optional - KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3" json:"kas_id,omitempty"` + // Types that are assignable to KasFilter: + // + // *ListPublicKeysRequest_KasId + // *ListPublicKeysRequest_KasName + // *ListPublicKeysRequest_KasUri + KasFilter isListPublicKeysRequest_KasFilter `protobuf_oneof:"kas_filter"` // Optional Pagination *policy.PageRequest `protobuf:"bytes,10,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -957,13 +1041,34 @@ func (*ListPublicKeysRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{16} } +func (m *ListPublicKeysRequest) GetKasFilter() isListPublicKeysRequest_KasFilter { + if m != nil { + return m.KasFilter + } + return nil +} + func (x *ListPublicKeysRequest) GetKasId() string { - if x != nil { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasId); ok { return x.KasId } return "" } +func (x *ListPublicKeysRequest) GetKasName() string { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasName); ok { + return x.KasName + } + return "" +} + +func (x *ListPublicKeysRequest) GetKasUri() string { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasUri); ok { + return x.KasUri + } + return "" +} + func (x *ListPublicKeysRequest) GetPagination() *policy.PageRequest { if x != nil { return x.Pagination @@ -971,6 +1076,31 @@ func (x *ListPublicKeysRequest) GetPagination() *policy.PageRequest { return nil } +type isListPublicKeysRequest_KasFilter interface { + isListPublicKeysRequest_KasFilter() +} + +type ListPublicKeysRequest_KasId struct { + // Optional + KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type ListPublicKeysRequest_KasName struct { + // Optional + KasName string `protobuf:"bytes,2,opt,name=kas_name,json=kasName,proto3,oneof"` +} + +type ListPublicKeysRequest_KasUri struct { + // Optional + KasUri string `protobuf:"bytes,3,opt,name=kas_uri,json=kasUri,proto3,oneof"` +} + +func (*ListPublicKeysRequest_KasId) isListPublicKeysRequest_KasFilter() {} + +func (*ListPublicKeysRequest_KasName) isListPublicKeysRequest_KasFilter() {} + +func (*ListPublicKeysRequest_KasUri) isListPublicKeysRequest_KasFilter() {} + type ListPublicKeysResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1031,8 +1161,12 @@ type ListPublicKeyMappingRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Optional - KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3" json:"kas_id,omitempty"` + // Types that are assignable to KasFilter: + // + // *ListPublicKeyMappingRequest_KasId + // *ListPublicKeyMappingRequest_KasName + // *ListPublicKeyMappingRequest_KasUri + KasFilter isListPublicKeyMappingRequest_KasFilter `protobuf_oneof:"kas_filter"` // Optional Public Key ID PublicKeyId string `protobuf:"bytes,4,opt,name=public_key_id,json=publicKeyId,proto3" json:"public_key_id,omitempty"` // Optional @@ -1071,13 +1205,34 @@ func (*ListPublicKeyMappingRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{18} } +func (m *ListPublicKeyMappingRequest) GetKasFilter() isListPublicKeyMappingRequest_KasFilter { + if m != nil { + return m.KasFilter + } + return nil +} + func (x *ListPublicKeyMappingRequest) GetKasId() string { - if x != nil { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasId); ok { return x.KasId } return "" } +func (x *ListPublicKeyMappingRequest) GetKasName() string { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasName); ok { + return x.KasName + } + return "" +} + +func (x *ListPublicKeyMappingRequest) GetKasUri() string { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasUri); ok { + return x.KasUri + } + return "" +} + func (x *ListPublicKeyMappingRequest) GetPublicKeyId() string { if x != nil { return x.PublicKeyId @@ -1092,6 +1247,31 @@ func (x *ListPublicKeyMappingRequest) GetPagination() *policy.PageRequest { return nil } +type isListPublicKeyMappingRequest_KasFilter interface { + isListPublicKeyMappingRequest_KasFilter() +} + +type ListPublicKeyMappingRequest_KasId struct { + // Optional + KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type ListPublicKeyMappingRequest_KasName struct { + // Optional + KasName string `protobuf:"bytes,2,opt,name=kas_name,json=kasName,proto3,oneof"` +} + +type ListPublicKeyMappingRequest_KasUri struct { + // Optional + KasUri string `protobuf:"bytes,3,opt,name=kas_uri,json=kasUri,proto3,oneof"` +} + +func (*ListPublicKeyMappingRequest_KasId) isListPublicKeyMappingRequest_KasFilter() {} + +func (*ListPublicKeyMappingRequest_KasName) isListPublicKeyMappingRequest_KasFilter() {} + +func (*ListPublicKeyMappingRequest_KasUri) isListPublicKeyMappingRequest_KasFilter() {} + type ListPublicKeyMappingResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1806,10 +1986,37 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x61, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe4, 0x03, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, 0x01, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, + 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, + 0x00, 0x52, 0x03, 0x75, 0x72, 0x69, 0x3a, 0xb7, 0x02, 0xba, 0x48, 0xb3, 0x02, 0x1a, 0xa8, 0x01, + 0x0a, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x4a, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, + 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x75, 0x72, 0x69, 0x27, + 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x1a, 0x48, + 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x26, + 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x61, 0x73, 0x5f, + 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x75, 0x72, 0x69, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x29, 0x29, 0x1a, 0x85, 0x01, 0x0a, 0x0f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2d, 0x45, 0x69, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x72, 0x69, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x43, 0x68, 0x61, 0x73, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x75, 0x72, 0x69, 0x29, 0x20, 0x7c, + 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, + 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, @@ -1831,7 +2038,7 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xd8, 0x05, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x69, 0x6f, 0x6e, 0x22, 0xdb, 0x05, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x87, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xf4, 0x01, 0xba, 0x48, 0xf0, 0x01, 0xba, 0x01, 0xec, 0x01, 0x0a, 0x0a, 0x75, @@ -1853,8 +2060,8 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x09, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0xbe, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa9, 0x02, 0xba, 0x48, 0xa5, 0x02, 0xba, 0x01, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0xc1, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0xac, 0x02, 0xba, 0x48, 0xa8, 0x02, 0xba, 0x01, 0x9c, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, @@ -1872,138 +2079,147 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, - 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x72, 0x03, - 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x64, - 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x22, 0xe0, 0x06, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, - 0xac, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, - 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, - 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, - 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, - 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, - 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, - 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, - 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x30, - 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0xb9, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, - 0xa4, 0x02, 0xba, 0x48, 0xa0, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, - 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, - 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, - 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, - 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, - 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, - 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, + 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xc8, 0x01, + 0x00, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, - 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, - 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x64, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x38, 0x0a, - 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x37, 0x0a, - 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xd0, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x10, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x52, 0x0a, 0x10, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, - 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0b, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x16, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, - 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x22, 0x38, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x25, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x61, 0x22, 0x64, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xe3, 0x06, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0xac, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x99, 0x02, 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0xd8, 0x01, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, + 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, + 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, + 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, + 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x03, 0x75, 0x72, + 0x69, 0x12, 0x30, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0xbc, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x09, 0x42, 0xa7, 0x02, 0xba, 0x48, 0xa3, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, + 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, + 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, + 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, + 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, + 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, + 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x00, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x64, 0x0a, + 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, + 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x38, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, 0x0a, + 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, + 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xd0, 0x02, 0x0a, + 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x10, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, + 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, + 0x52, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, + 0x9e, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x6b, 0x61, + 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x06, + 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, + 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x38, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x63, 0x0a, 0x15, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, - 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3f, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x42, 0x0c, 0x0a, + 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x22, 0xca, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x06, + 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, + 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, + 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x61, + 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, + 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x33, 0x0a, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, @@ -2011,288 +2227,296 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x8d, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x22, 0x81, 0x02, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0xf6, 0x05, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x71, 0x0a, 0x13, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x52, 0x11, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xba, 0x01, 0x0a, 0x10, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, - 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x5b, 0x0a, 0x0b, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0xbe, 0x02, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0b, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x0a, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x2f, 0x0a, 0x0b, 0x41, 0x73, 0x73, 0x6f, - 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xb3, 0x01, 0x0a, 0x16, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, - 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, - 0x38, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x39, 0x0a, 0x1a, 0x44, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x1b, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0x37, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, - 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3a, 0x0a, 0x19, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, + 0x73, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, + 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x6b, 0x61, 0x73, + 0x5f, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, + 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, + 0x12, 0x2f, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, + 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, + 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x22, 0xf6, 0x05, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x13, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xba, + 0x01, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x61, + 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x61, + 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x5b, + 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0xbe, 0x02, 0x0a, 0x09, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x5e, + 0x0a, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5c, + 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x2f, 0x0a, 0x0b, + 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, + 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xbd, 0x01, + 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x38, 0x0a, + 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, - 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x9e, 0x07, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xcb, 0x01, 0x0a, - 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xb3, 0x01, - 0xba, 0x48, 0xaf, 0x01, 0xba, 0x01, 0xab, 0x01, 0x0a, 0x14, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x23, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6d, - 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, - 0x55, 0x49, 0x44, 0x1a, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, - 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, - 0x5d, 0x7b, 0x38, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, - 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, - 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, - 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x31, 0x32, - 0x7d, 0x27, 0x29, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0xb3, 0x02, 0x0a, 0x07, 0x6b, - 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, 0xba, - 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, - 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, - 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, - 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, - 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, - 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, - 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, - 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, - 0x12, 0xc0, 0x02, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x42, 0xa4, 0x02, 0xba, 0x48, 0xa0, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, - 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, - 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, - 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, - 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, - 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, - 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, - 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, - 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, - 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x29, 0x3f, 0x24, 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, - 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, - 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x0e, 0x0a, 0x1e, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, - 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x90, 0x02, 0x01, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, - 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0x9c, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, - 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, - 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, - 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, - 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x19, 0x4c, 0x69, + 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x36, 0x0a, 0x1a, 0x44, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x3c, 0x0a, 0x1b, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x34, 0x0a, + 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x3a, 0x0a, 0x19, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, + 0xa1, 0x07, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0xcb, 0x01, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xb3, 0x01, 0xba, 0x48, 0xaf, 0x01, 0xba, 0x01, 0xab, 0x01, + 0x0a, 0x14, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x23, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x55, 0x49, 0x44, 0x1a, 0x6e, 0x73, 0x69, 0x7a, + 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5b, 0x30, + 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x38, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, + 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, + 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, + 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, + 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x31, 0x32, 0x7d, 0x27, 0x29, 0x52, 0x05, 0x6b, 0x61, 0x73, + 0x49, 0x64, 0x12, 0xb3, 0x02, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, + 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, + 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, + 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, + 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, + 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, + 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0xc3, 0x02, 0x0a, 0x08, 0x6b, 0x61, 0x73, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa7, 0x02, 0xba, 0x48, + 0xa3, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, + 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, + 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, + 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x00, + 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, + 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x0e, 0x0a, 0x1e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, - 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x90, 0x02, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, + 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, + 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x90, 0x02, 0x01, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, + 0x12, 0x9c, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, - 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x6b, 0x65, 0x79, + 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, + 0xa1, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x6b, 0x65, 0x79, + 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x90, 0x02, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, - 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x0e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, - 0x0a, 0x11, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xdb, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, - 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, - 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0xca, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x78, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x11, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2c, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xdb, 0x01, + 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, + 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, 0x02, 0x12, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xca, + 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, + 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -2801,6 +3025,24 @@ func file_policy_kasregistry_key_access_server_registry_proto_init() { } } } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*GetKeyAccessServerRequest_KasId)(nil), + (*GetKeyAccessServerRequest_Name)(nil), + (*GetKeyAccessServerRequest_Uri)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*GetPublicKeyRequest_Id)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[16].OneofWrappers = []interface{}{ + (*ListPublicKeysRequest_KasId)(nil), + (*ListPublicKeysRequest_KasName)(nil), + (*ListPublicKeysRequest_KasUri)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[18].OneofWrappers = []interface{}{ + (*ListPublicKeyMappingRequest_KasId)(nil), + (*ListPublicKeyMappingRequest_KasName)(nil), + (*ListPublicKeyMappingRequest_KasUri)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go index 4d4c921c6..66ab08b0e 100644 --- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go +++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go @@ -67,6 +67,10 @@ func local_request_KeyAccessServerRegistryService_ListKeyAccessServers_0(ctx con } +var ( + filter_KeyAccessServerRegistryService_GetKeyAccessServer_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx context.Context, marshaler runtime.Marshaler, client KeyAccessServerRegistryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetKeyAccessServerRequest var metadata runtime.ServerMetadata @@ -88,6 +92,13 @@ func request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx context.Con return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_KeyAccessServerRegistryService_GetKeyAccessServer_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetKeyAccessServer(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -114,6 +125,13 @@ func local_request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx conte return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_KeyAccessServerRegistryService_GetKeyAccessServer_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetKeyAccessServer(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/namespaces/namespaces.pb.go b/protocol/go/policy/namespaces/namespaces.pb.go index b51e683dd..adbe06cd0 100644 --- a/protocol/go/policy/namespaces/namespaces.pb.go +++ b/protocol/go/policy/namespaces/namespaces.pb.go @@ -143,8 +143,15 @@ type GetNamespaceRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/namespaces/namespaces.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetNamespaceRequest_NamespaceId + // *GetNamespaceRequest_Fqn + Identifier isGetNamespaceRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetNamespaceRequest) Reset() { @@ -179,6 +186,7 @@ func (*GetNamespaceRequest) Descriptor() ([]byte, []int) { return file_policy_namespaces_namespaces_proto_rawDescGZIP(), []int{2} } +// Deprecated: Marked as deprecated in policy/namespaces/namespaces.proto. func (x *GetNamespaceRequest) GetId() string { if x != nil { return x.Id @@ -186,6 +194,44 @@ func (x *GetNamespaceRequest) GetId() string { return "" } +func (m *GetNamespaceRequest) GetIdentifier() isGetNamespaceRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetNamespaceRequest) GetNamespaceId() string { + if x, ok := x.GetIdentifier().(*GetNamespaceRequest_NamespaceId); ok { + return x.NamespaceId + } + return "" +} + +func (x *GetNamespaceRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetNamespaceRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetNamespaceRequest_Identifier interface { + isGetNamespaceRequest_Identifier() +} + +type GetNamespaceRequest_NamespaceId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + NamespaceId string `protobuf:"bytes,2,opt,name=namespace_id,json=namespaceId,proto3,oneof"` +} + +type GetNamespaceRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetNamespaceRequest_NamespaceId) isGetNamespaceRequest_Identifier() {} + +func (*GetNamespaceRequest_Fqn) isGetNamespaceRequest_Identifier() {} + type GetNamespaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1053,10 +1099,35 @@ var file_policy_namespaces_namespaces_proto_rawDesc = []byte{ 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, - 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x2f, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0xbe, + 0x03, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, + 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, + 0x03, 0x66, 0x71, 0x6e, 0x3a, 0xaa, 0x02, 0xba, 0x48, 0xa6, 0x02, 0x1a, 0xa2, 0x01, 0x0a, 0x10, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x50, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, + 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, + 0x74, 0x68, 0x1a, 0x3c, 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, + 0x1a, 0x7f, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x33, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x37, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x29, + 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, + 0x29, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, @@ -1648,6 +1719,10 @@ func file_policy_namespaces_namespaces_proto_init() { } } } + file_policy_namespaces_namespaces_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*GetNamespaceRequest_NamespaceId)(nil), + (*GetNamespaceRequest_Fqn)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/namespaces/namespaces.pb.gw.go b/protocol/go/policy/namespaces/namespaces.pb.gw.go index e8b49e8be..85a45c78f 100644 --- a/protocol/go/policy/namespaces/namespaces.pb.gw.go +++ b/protocol/go/policy/namespaces/namespaces.pb.gw.go @@ -31,6 +31,10 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +var ( + filter_NamespaceService_GetNamespace_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_NamespaceService_GetNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client NamespaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetNamespaceRequest var metadata runtime.ServerMetadata @@ -52,6 +56,13 @@ func request_NamespaceService_GetNamespace_0(ctx context.Context, marshaler runt return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_NamespaceService_GetNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -78,6 +89,13 @@ func local_request_NamespaceService_GetNamespace_0(ctx context.Context, marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_NamespaceService_GetNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetNamespace(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/objects.pb.go b/protocol/go/policy/objects.pb.go index 37db1d2a4..b2d806fbb 100644 --- a/protocol/go/policy/objects.pb.go +++ b/protocol/go/policy/objects.pb.go @@ -1876,106 +1876,108 @@ var file_policy_objects_proto_rawDesc = []byte{ 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x03, 0x6b, 0x61, 0x73, 0x12, 0x2c, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x61, 0x0a, 0x0c, 0x4b, 0x61, - 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x65, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x12, 0x2d, - 0x0a, 0x03, 0x61, 0x6c, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x03, 0x61, 0x6c, 0x67, 0x22, 0x3b, 0x0a, - 0x0f, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, - 0x12, 0x28, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0xe0, 0x03, 0x0a, 0x09, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x84, 0x03, 0x0a, 0x06, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xe9, 0x02, 0xba, 0x48, 0xe5, 0x02, - 0xba, 0x01, 0xe1, 0x02, 0x0a, 0x0a, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x12, 0xcf, 0x01, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, - 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, - 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, - 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, - 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, - 0x73, 0x2e, 0x1a, 0x80, 0x01, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x28, 0x27, 0x5e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x28, 0x5c, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, 0x5b, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x29, 0x2a, 0x28, 0x2f, 0x2e, 0x2a, - 0x29, 0x3f, 0x24, 0x27, 0x29, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, - 0x31, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2a, 0xb3, 0x01, - 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x54, 0x54, 0x52, 0x49, - 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, - 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, - 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4c, - 0x4c, 0x5f, 0x4f, 0x46, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x4f, 0x46, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x41, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x4b, + 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x03, 0x70, + 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, + 0x01, 0x18, 0x80, 0x40, 0x52, 0x03, 0x70, 0x65, 0x6d, 0x12, 0x1b, 0x0a, 0x03, 0x6b, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xba, 0x48, 0x06, 0x72, 0x04, 0x10, 0x01, 0x18, + 0x20, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x03, 0x61, 0x6c, 0x67, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, + 0x42, 0x0a, 0xba, 0x48, 0x07, 0x82, 0x01, 0x04, 0x10, 0x01, 0x20, 0x00, 0x52, 0x03, 0x61, 0x6c, + 0x67, 0x22, 0x3b, 0x0a, 0x0f, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x53, 0x65, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0xe0, + 0x03, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x84, 0x03, 0x0a, + 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xe9, 0x02, + 0xba, 0x48, 0xe5, 0x02, 0xba, 0x01, 0xe1, 0x02, 0x0a, 0x0a, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x12, 0xcf, 0x01, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, + 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, + 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, + 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x80, 0x01, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x28, 0x5c, 0x5c, + 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, + 0x7d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x29, 0x2a, + 0x28, 0x2f, 0x2e, 0x2a, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x2a, 0xb3, 0x01, 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x48, 0x49, 0x45, 0x52, 0x41, 0x52, 0x43, 0x48, - 0x59, 0x10, 0x03, 0x2a, 0xca, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, - 0x75, 0x6d, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, - 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x53, 0x55, 0x42, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x10, - 0x02, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x53, 0x10, 0x03, - 0x2a, 0x90, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, - 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x2b, 0x0a, - 0x27, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, - 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, - 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x44, 0x10, 0x01, 0x12, - 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, - 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4f, - 0x52, 0x10, 0x02, 0x2a, 0x88, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x27, 0x0a, 0x23, 0x4b, - 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, - 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, + 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, + 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, + 0x4d, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x4f, 0x46, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, + 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x4f, 0x46, 0x10, 0x02, 0x12, + 0x26, 0x0a, 0x22, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x48, 0x49, 0x45, 0x52, + 0x41, 0x52, 0x43, 0x48, 0x59, 0x10, 0x03, 0x2a, 0xca, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, + 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, + 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x53, + 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, + 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, + 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, + 0x4e, 0x53, 0x10, 0x03, 0x2a, 0x90, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, + 0x6d, 0x12, 0x2b, 0x0a, 0x27, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, + 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, + 0x0a, 0x1f, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, + 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, + 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, + 0x55, 0x4d, 0x5f, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x88, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x12, + 0x27, 0x0a, 0x23, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, + 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, + 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x24, + 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x34, 0x30, + 0x39, 0x36, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, - 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, - 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, - 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x02, - 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, - 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, - 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, - 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, - 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x33, 0x38, 0x34, - 0x52, 0x31, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, - 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, - 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x10, 0x07, 0x42, 0x82, - 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x0c, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, - 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xa2, 0x02, 0x03, - 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xca, 0x02, 0x06, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x10, 0x05, 0x12, 0x28, + 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, + 0x50, 0x33, 0x38, 0x34, 0x52, 0x31, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, + 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, + 0x10, 0x07, 0x42, 0x82, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x42, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, + 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0xca, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/unsafe/unsafe.pb.go b/protocol/go/policy/unsafe/unsafe.pb.go index 08aa3c1fb..858516b55 100644 --- a/protocol/go/policy/unsafe/unsafe.pb.go +++ b/protocol/go/policy/unsafe/unsafe.pb.go @@ -1160,12 +1160,12 @@ var file_policy_unsafe_unsafe_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xdf, 0x03, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xe2, 0x03, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, - 0x64, 0x12, 0xc4, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0xaf, 0x02, 0xba, 0x48, 0xab, 0x02, 0xba, 0x01, 0xa2, 0x02, 0x0a, 0x15, 0x61, 0x74, 0x74, + 0x64, 0x12, 0xc7, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0xb2, 0x02, 0xba, 0x48, 0xae, 0x02, 0xba, 0x01, 0xa2, 0x02, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, @@ -1183,206 +1183,206 @@ var file_policy_unsafe_unsafe_proto_rawDesc = []byte{ 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x72, 0x03, 0x18, - 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, - 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, + 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xc8, 0x01, 0x00, + 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x72, + 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x1d, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3c, 0x0a, + 0x20, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x54, 0x0a, 0x21, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x22, 0x52, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, + 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0xe7, 0x02, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3c, 0x0a, 0x20, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, - 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x54, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, - 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x52, - 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, - 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x03, 0x66, - 0x71, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x22, 0xe7, 0x02, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x12, 0xa7, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x90, 0x02, 0xba, 0x48, 0x8c, 0x02, 0xba, 0x01, 0x83, 0x02, 0x0a, - 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x20, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, - 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, - 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, - 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, - 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x49, - 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x41, 0x0a, 0x25, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, - 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x26, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, + 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0xa7, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x90, 0x02, 0xba, 0x48, 0x8c, 0x02, 0xba, 0x01, + 0x83, 0x02, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0xb5, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, + 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, + 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, + 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, + 0x29, 0x3f, 0x24, 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x41, 0x0a, 0x25, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, 0x21, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, 0x71, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x03, 0x66, 0x71, 0x6e, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x38, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, - 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x1d, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x32, 0xd2, 0x0c, 0x0a, 0x0d, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, - 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, - 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, - 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x4d, 0x0a, 0x26, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, + 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, + 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x38, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x1d, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x32, 0xd2, 0x0c, 0x0a, + 0x0d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x93, + 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, + 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, + 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, + 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, + 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, - 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa9, 0x01, - 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x32, 0x1e, 0x2f, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc0, 0x01, 0x0a, 0x1e, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x2e, 0x70, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, + 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2b, 0x22, 0x29, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0xa9, 0x01, 0x0a, - 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, + 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0xa9, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x32, 0x1e, 0x2f, 0x75, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc0, 0x01, 0x0a, + 0x1e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x29, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, + 0xa9, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xac, - 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x42, 0x0b, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0xa2, 0x02, 0x03, 0x50, 0x55, 0x58, - 0xaa, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0xca, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0xe2, 0x02, 0x19, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0xac, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x42, 0x0b, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0xa2, 0x02, 0x03, + 0x50, 0x55, 0x58, 0xaa, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0xca, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0xe2, 0x02, 0x19, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/sample.tdf b/sample.tdf new file mode 100644 index 000000000..556f6c0ad Binary files /dev/null and b/sample.tdf differ diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 40e6175c6..0d5f56421 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -1,5 +1,37 @@ # Changelog +## [0.3.28](https://github.com/opentdf/platform/compare/sdk/v0.3.27...sdk/v0.3.28) (2025-02-26) + + +### Bug Fixes + +* **core:** Autobump sdk ([#1948](https://github.com/opentdf/platform/issues/1948)) ([4dfb457](https://github.com/opentdf/platform/commit/4dfb45780ef5a42d95405a8ad09421a21c9cd149)) +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) + +## [0.3.27](https://github.com/opentdf/platform/compare/sdk/v0.3.26...sdk/v0.3.27) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) +* **sdk:** Allow schema validation during TDF decrypt ([#1870](https://github.com/opentdf/platform/issues/1870)) ([b7e6fb2](https://github.com/opentdf/platform/commit/b7e6fb24631b4898561b1a64c24c85b32c452a1c)) +* **sdk:** MIC-1436: User can decrypt TDF files created with FileWatcher2.0.8 and older. ([#1833](https://github.com/opentdf/platform/issues/1833)) ([f77d110](https://github.com/opentdf/platform/commit/f77d110fcc7f332ceec5a3294b144973eced37c1)) +* **sdk:** remove hex encoding for segment hash ([#1805](https://github.com/opentdf/platform/issues/1805)) ([d7179c2](https://github.com/opentdf/platform/commit/d7179c2a91b508c26fbe6499fe5c1ac8334e5505)) +* **sdk:** sdk.New should validate platform connectivity and provide precise error ([#1937](https://github.com/opentdf/platform/issues/1937)) ([aa3696d](https://github.com/opentdf/platform/commit/aa3696d848a23ac79029bd64f1b61a15567204d7)) + + +### Bug Fixes + +* **core:** Autobump sdk ([#1873](https://github.com/opentdf/platform/issues/1873)) ([085ac7a](https://github.com/opentdf/platform/commit/085ac7af550d2c9d3fd0b0b2deb389939e7cde8e)) +* **core:** Autobump sdk ([#1894](https://github.com/opentdf/platform/issues/1894)) ([201244e](https://github.com/opentdf/platform/commit/201244e4473115f07fc997dc49c695cc05d9a6ba)) +* **core:** Autobump sdk ([#1917](https://github.com/opentdf/platform/issues/1917)) ([edeeb74](https://github.com/opentdf/platform/commit/edeeb74e9c38b2e6eef7fefa29768912371ec949)) +* **core:** Autobump sdk ([#1941](https://github.com/opentdf/platform/issues/1941)) ([0a5a948](https://github.com/opentdf/platform/commit/0a5a94893836482990586302bfb9838e54c5b6ba)) +* Improve http.Client usage for security and performance ([#1910](https://github.com/opentdf/platform/issues/1910)) ([e6a53a3](https://github.com/opentdf/platform/commit/e6a53a370b13c3ed63752789aa886be660354e1a)) +* **sdk:** bump lib/ocrypto to 0.1.8 ([#1938](https://github.com/opentdf/platform/issues/1938)) ([53fa8ab](https://github.com/opentdf/platform/commit/53fa8ab90236d5bd29541552782b60b96f625405)) +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) +* **sdk:** Removes unnecessary down-cast of `int` ([#1869](https://github.com/opentdf/platform/issues/1869)) ([66f0c14](https://github.com/opentdf/platform/commit/66f0c14a1ef7490a207c0cef8c98ab4af3f128b1)) + ## [0.3.26](https://github.com/opentdf/platform/compare/sdk/v0.3.25...sdk/v0.3.26) (2025-01-21) diff --git a/sdk/auth/oauth/oauth.go b/sdk/auth/oauth/oauth.go index a678360c4..e29b1670d 100644 --- a/sdk/auth/oauth/oauth.go +++ b/sdk/auth/oauth/oauth.go @@ -2,7 +2,6 @@ package oauth import ( "context" - "crypto/tls" "encoding/json" "fmt" "io" @@ -17,6 +16,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/opentdf/platform/sdk/httputil" ) const ( @@ -24,8 +24,8 @@ const ( ) type CertExchangeInfo struct { - TLSConfig *tls.Config - Audience []string + HTTPClient *http.Client + Audience []string } type ClientCredentials struct { @@ -146,6 +146,9 @@ func GetAccessToken(client *http.Client, tokenEndpoint string, scopes []string, if err != nil { return nil, err } + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { @@ -249,6 +252,9 @@ func DoTokenExchange(ctx context.Context, client *http.Client, tokenEndpoint str if err != nil { return nil, err } + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("error making request to IdP for token exchange: %w", err) @@ -313,12 +319,11 @@ func DoCertExchange(ctx context.Context, tokenEndpoint string, exchangeInfo Cert if err != nil { return nil, err } - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: exchangeInfo.TLSConfig, - }, - } + client := exchangeInfo.HTTPClient + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("error making request to IdP for certificate exchange: %w", err) diff --git a/sdk/auth/oauth/oauth_test.go b/sdk/auth/oauth/oauth_test.go index 288497285..8c55bccd2 100644 --- a/sdk/auth/oauth/oauth_test.go +++ b/sdk/auth/oauth/oauth_test.go @@ -23,6 +23,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/opentdf/platform/lib/fixtures" + "github.com/opentdf/platform/sdk/httputil" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" tc "github.com/testcontainers/testcontainers-go" @@ -78,12 +79,15 @@ func (s *OAuthSuite) TestCertExchangeFromKeycloak() { rootCAs, _ := x509.SystemCertPool() rootCAs.AppendCertsFromPEM(ca) s.Require().NoError(err) - tlsConfig := tls.Config{ + tlsConfig := &tls.Config{ MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cert}, RootCAs: rootCAs, } - exhcangeInfo := CertExchangeInfo{TLSConfig: &tlsConfig, Audience: []string{"opentdf-sdk"}} + exhcangeInfo := CertExchangeInfo{ + HTTPClient: httputil.SafeHTTPClientWithTLSConfig(tlsConfig), + Audience: []string{"opentdf-sdk"}, + } tok, err := DoCertExchange( context.Background(), diff --git a/sdk/auth/token_adding_interceptor.go b/sdk/auth/token_adding_interceptor.go index 45f3ea33b..18a438c8f 100644 --- a/sdk/auth/token_adding_interceptor.go +++ b/sdk/auth/token_adding_interceptor.go @@ -14,6 +14,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/opentdf/platform/sdk/httputil" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -25,15 +26,22 @@ const ( ) func NewTokenAddingInterceptor(t AccessTokenSource, c *tls.Config) TokenAddingInterceptor { + return NewTokenAddingInterceptorWithClient(t, httputil.SafeHTTPClientWithTLSConfig(c)) +} + +func NewTokenAddingInterceptorWithClient(t AccessTokenSource, c *http.Client) TokenAddingInterceptor { + if c == nil { + c = httputil.SafeHTTPClient() + } return TokenAddingInterceptor{ tokenSource: t, - tlsConfig: c, + httpClient: c, } } type TokenAddingInterceptor struct { tokenSource AccessTokenSource - tlsConfig *tls.Config + httpClient *http.Client } func (i TokenAddingInterceptor) AddCredentials( @@ -45,12 +53,7 @@ func (i TokenAddingInterceptor) AddCredentials( opts ...grpc.CallOption, ) error { newMetadata := make([]string, 0) - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: i.tlsConfig, - }, - } - accessToken, err := i.tokenSource.AccessToken(ctx, client) + accessToken, err := i.tokenSource.AccessToken(ctx, i.httpClient) if err == nil { newMetadata = append(newMetadata, "Authorization", fmt.Sprintf("DPoP %s", accessToken)) } else { diff --git a/sdk/go.mod b/sdk/go.mod index c8a11f0d7..a1b2064e4 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -8,8 +8,8 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/opentdf/platform/lib/fixtures v0.2.10 - github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 + github.com/opentdf/platform/lib/ocrypto v0.1.8 + github.com/opentdf/platform/protocol/go v0.2.28 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/sdk/go.sum b/sdk/go.sum index dbd686c04..d5657a2ec 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -114,10 +114,10 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXvCTb+nJCuiU2WsWs= github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= +github.com/opentdf/platform/protocol/go v0.2.28 h1:UfX+yFWFGCtxsvCyIO62p4v7CBtcVR+2dCqHq3O0vy4= +github.com/opentdf/platform/protocol/go v0.2.28/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/sdk/httputil/http.go b/sdk/httputil/http.go new file mode 100644 index 000000000..323257c3c --- /dev/null +++ b/sdk/httputil/http.go @@ -0,0 +1,64 @@ +package httputil + +import ( + "crypto/tls" + "net/http" + "time" +) + +const ( + defaultTimeout = 120 * time.Second + // defaults to match DefaultTransport - defined to satisfy lint + maxIdleConns = 100 + idleConnTimeout = 90 * time.Second + tlsHandshakeTimeout = 10 * time.Second + expectContinueTimeout = 1 * time.Second +) + +var preventRedirectCheck = func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse // Prevent following redirects +} + +var safeHTTPClient = &http.Client{ + Transport: http.DefaultTransport, + Timeout: defaultTimeout, + CheckRedirect: preventRedirectCheck, +} + +// SafeHTTPClient returns a default http client which has sensible timeouts, won't follow redirects, and enables idle +// connection pooling. +func SafeHTTPClient() *http.Client { + return safeHTTPClient +} + +// SafeHTTPClientWithTLSConfig returns a http client which has sensible timeouts, won't follow redirects, and if +// specified a http.Transport with the tls.Config provided. +func SafeHTTPClientWithTLSConfig(cfg *tls.Config) *http.Client { + if cfg == nil { + return safeHTTPClient + } + return SafeHTTPClientWithTransport(&http.Transport{ + TLSClientConfig: cfg, + // config below matches DefaultTransport + Proxy: http.ProxyFromEnvironment, + ForceAttemptHTTP2: true, + MaxIdleConns: maxIdleConns, + IdleConnTimeout: idleConnTimeout, + TLSHandshakeTimeout: tlsHandshakeTimeout, + ExpectContinueTimeout: expectContinueTimeout, + }) +} + +// SafeHTTPClientWithTransport returns a http client which has sensible timeouts, won't follow redirects, and if +// specified the provided http.Transport. +func SafeHTTPClientWithTransport(transport *http.Transport) *http.Client { + if transport == nil { + return safeHTTPClient + } + return &http.Client{ + Transport: transport, + // config below matches our values for safeHttpClient + Timeout: defaultTimeout, + CheckRedirect: preventRedirectCheck, + } +} diff --git a/sdk/kas_client.go b/sdk/kas_client.go index 1c4779a28..8c685f25a 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -20,12 +20,16 @@ import ( const ( secondsPerMinute = 60 + statusPermit = "permit" ) type KASClient struct { accessTokenSource auth.AccessTokenSource dialOptions []grpc.DialOption - sessionKey *ocrypto.RsaKeyPair + sessionKey ocrypto.KeyPair + + // Set this to enable legacy, non-batch rewrap requests + supportSingleRewrapEndpoint bool } type kaoResult struct { @@ -39,11 +43,12 @@ type decryptor interface { Decrypt(ctx context.Context, results []kaoResult) (int, error) } -func newKASClient(dialOptions []grpc.DialOption, accessTokenSource auth.AccessTokenSource, sessionKey *ocrypto.RsaKeyPair) *KASClient { +func newKASClient(dialOptions []grpc.DialOption, accessTokenSource auth.AccessTokenSource, sessionKey ocrypto.KeyPair) *KASClient { return &KASClient{ - accessTokenSource: accessTokenSource, - dialOptions: dialOptions, - sessionKey: sessionKey, + accessTokenSource: accessTokenSource, + dialOptions: dialOptions, + sessionKey: sessionKey, + supportSingleRewrapEndpoint: true, } } @@ -71,9 +76,38 @@ func (k *KASClient) makeRewrapRequest(ctx context.Context, requests []*kas.Unsig return nil, fmt.Errorf("error making rewrap request: %w", err) } + upgradeRewrapResponseV1(response, requests) + return response, nil } +// convert v1 responses to v2 +func upgradeRewrapResponseV1(response *kas.RewrapResponse, requests []*kas.UnsignedRewrapRequest_WithPolicyRequest) { + if len(response.GetResponses()) > 0 { + return + } + if len(response.GetEntityWrappedKey()) == 0 { //nolint:staticcheck // SA1019: use of deprecated method required for compatibility + return + } + if len(requests) == 0 { + return + } + response.Responses = []*kas.PolicyRewrapResult{ + { + PolicyId: requests[0].GetPolicy().GetId(), + Results: []*kas.KeyAccessRewrapResult{ + { + KeyAccessObjectId: requests[0].GetKeyAccessObjects()[0].GetKeyAccessObjectId(), + Status: statusPermit, + Result: &kas.KeyAccessRewrapResult_KasWrappedKey{ + KasWrappedKey: response.GetEntityWrappedKey(), //nolint:staticcheck // SA1019: use of deprecated method + }, + }, + }, + }, + } +} + func (k *KASClient) nanoUnwrap(ctx context.Context, requests ...*kas.UnsignedRewrapRequest_WithPolicyRequest) (map[string][]kaoResult, error) { keypair, err := ocrypto.NewECKeyPair(ocrypto.ECCModeSecp256r1) if err != nil { @@ -113,7 +147,7 @@ func (k *KASClient) nanoUnwrap(ctx context.Context, requests ...*kas.UnsignedRew for _, results := range response.GetResponses() { var kaoKeys []kaoResult for _, kao := range results.GetResults() { - if kao.GetStatus() == "permit" { + if kao.GetStatus() == statusPermit { wrappedKey := kao.GetKasWrappedKey() key, err := aesGcm.Decrypt(wrappedKey) if err != nil { @@ -144,6 +178,57 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR return nil, fmt.Errorf("error making rewrap request to kas: %w", err) } + if ocrypto.IsECKeyType(k.sessionKey.GetKeyType()) { + return k.handleECKeyResponse(response) + } + return k.handleRSAKeyResponse(response) +} + +func (k *KASClient) handleECKeyResponse(response *kas.RewrapResponse) (map[string][]kaoResult, error) { + kasEphemeralPublicKey := response.GetSessionPublicKey() + clientPrivateKey, err := k.sessionKey.PrivateKeyInPemFormat() + if err != nil { + return nil, fmt.Errorf("failed to get private key: %w", err) + } + ecdhKey, err := ocrypto.ComputeECDHKey([]byte(clientPrivateKey), []byte(kasEphemeralPublicKey)) + if err != nil { + return nil, fmt.Errorf("ocrypto.ComputeECDHKey failed: %w", err) + } + sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.CalculateHKDF failed: %w", err) + } + + aesGcm, err := ocrypto.NewAESGcm(sessionKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.NewAESGcm failed: %w", err) + } + + return k.processECResponse(response, aesGcm) +} + +func (k *KASClient) processECResponse(response *kas.RewrapResponse, aesGcm ocrypto.AesGcm) (map[string][]kaoResult, error) { + policyResults := make(map[string][]kaoResult) + for _, results := range response.GetResponses() { + var kaoKeys []kaoResult + for _, kao := range results.GetResults() { + if kao.GetStatus() == statusPermit { + key, err := aesGcm.Decrypt(kao.GetKasWrappedKey()) + if err != nil { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: err}) + } else { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), SymmetricKey: key}) + } + } else { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: errors.New(kao.GetError())}) + } + } + policyResults[results.GetPolicyId()] = kaoKeys + } + return policyResults, nil +} + +func (k *KASClient) handleRSAKeyResponse(response *kas.RewrapResponse) (map[string][]kaoResult, error) { clientPrivateKey, err := k.sessionKey.PrivateKeyInPemFormat() if err != nil { return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) @@ -154,13 +239,16 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR return nil, fmt.Errorf("ocrypto.NewAsymDecryption failed: %w", err) } + return k.processRSAResponse(response, asymDecryption) +} + +func (k *KASClient) processRSAResponse(response *kas.RewrapResponse, asymDecryption ocrypto.AsymDecryption) (map[string][]kaoResult, error) { policyResults := make(map[string][]kaoResult) for _, results := range response.GetResponses() { var kaoKeys []kaoResult for _, kao := range results.GetResults() { - if kao.GetStatus() == "permit" { - wrappedKey := kao.GetKasWrappedKey() - key, err := asymDecryption.Decrypt(wrappedKey) + if kao.GetStatus() == statusPermit { + key, err := asymDecryption.Decrypt(kao.GetKasWrappedKey()) if err != nil { kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: err}) } else { @@ -172,7 +260,6 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR } policyResults[results.GetPolicyId()] = kaoKeys } - return policyResults, nil } @@ -197,10 +284,18 @@ func getGRPCAddress(kasURL string) (string, error) { } func (k *KASClient) getRewrapRequest(reqs []*kas.UnsignedRewrapRequest_WithPolicyRequest, pubKey string) (*kas.RewrapRequest, error) { + if len(reqs) == 0 { + return nil, errors.New("no requests provided") + } requestBody := &kas.UnsignedRewrapRequest{ ClientPublicKey: pubKey, Requests: reqs, } + if len(reqs) == 1 && len(reqs[0].GetKeyAccessObjects()) == 1 && k.supportSingleRewrapEndpoint { + requestBody.KeyAccess = reqs[0].GetKeyAccessObjects()[0].GetKeyAccessObject() //nolint:staticcheck // SA1019: use of deprecated method + requestBody.Policy = reqs[0].GetPolicy().GetBody() //nolint:staticcheck // SA1019: use of deprecated method + requestBody.Algorithm = reqs[0].GetAlgorithm() //nolint:staticcheck // SA1019: use of deprecated method + } requestBodyJSON, err := protojson.Marshal(requestBody) if err != nil { diff --git a/sdk/kas_client_test.go b/sdk/kas_client_test.go index a45f32119..0431cc647 100644 --- a/sdk/kas_client_test.go +++ b/sdk/kas_client_test.go @@ -14,6 +14,7 @@ import ( "github.com/opentdf/platform/sdk/auth" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/protojson" ) @@ -21,6 +22,7 @@ import ( type FakeAccessTokenSource struct { dpopKey jwk.Key asymDecryption ocrypto.AsymDecryption + asymEncryption ocrypto.AsymEncryption accessToken string } @@ -36,6 +38,8 @@ func getTokenSource(t *testing.T) FakeAccessTokenSource { dpopKey, _ := ocrypto.NewRSAKeyPair(2048) dpopPEM, _ := dpopKey.PrivateKeyInPemFormat() decryption, _ := ocrypto.NewAsymDecryption(dpopPEM) + dpopPEMPublic, _ := dpopKey.PublicKeyInPemFormat() + encryption, _ := ocrypto.NewAsymEncryption(dpopPEMPublic) dpopJWK, err := jwk.ParseKey([]byte(dpopPEM), jwk.WithPEM(true)) if err != nil { t.Fatalf("error creating JWK: %v", err) @@ -48,6 +52,7 @@ func getTokenSource(t *testing.T) FakeAccessTokenSource { return FakeAccessTokenSource{ dpopKey: dpopJWK, asymDecryption: decryption, + asymEncryption: encryption, accessToken: "thisistheaccesstoken", } } @@ -161,3 +166,51 @@ func Test_StoreKASKeys(t *testing.T) { assert.Nil(t, k2) require.ErrorContains(t, err, "error making request") } + +type TestUpgradeRewrapRequestV1Suite struct { + suite.Suite +} + +func (suite *TestUpgradeRewrapRequestV1Suite) TestUpgradeRewrapRequestV1_Happy() { + response := &kaspb.RewrapResponse{ + EntityWrappedKey: []byte("wrappedKey"), + } + requests := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{ + { + KeyAccessObjects: []*kaspb.UnsignedRewrapRequest_WithKeyAccessObject{ + { + KeyAccessObjectId: "kaoID", + }, + }, + Policy: &kaspb.UnsignedRewrapRequest_WithPolicy{ + Id: "policyID", + }, + }, + } + + upgradeRewrapResponseV1(response, requests) + + suite.Require().Len(response.GetResponses(), 1) + policyResult := response.GetResponses()[0] + suite.Equal("policyID", policyResult.GetPolicyId()) + + suite.Require().Len(policyResult.GetResults(), 1) + kaoResult := policyResult.GetResults()[0] + + suite.Equal("kaoID", kaoResult.GetKeyAccessObjectId()) + suite.NotNil(kaoResult.GetKasWrappedKey()) + suite.Empty(kaoResult.GetError()) +} + +func (suite *TestUpgradeRewrapRequestV1Suite) TestUpgradeRewrapRequestV1_Empty() { + response := &kaspb.RewrapResponse{} + requests := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{} + + upgradeRewrapResponseV1(response, requests) + + suite.EqualExportedValues(&kaspb.RewrapResponse{}, response) +} + +func TestUpgradeRewrapRequestV1(t *testing.T) { + suite.Run(t, new(TestUpgradeRewrapRequestV1Suite)) +} diff --git a/sdk/manifest.go b/sdk/manifest.go index 9316dbf6b..fc3034fdd 100644 --- a/sdk/manifest.go +++ b/sdk/manifest.go @@ -20,15 +20,16 @@ type IntegrityInformation struct { } type KeyAccess struct { - KeyType string `json:"type"` - KasURL string `json:"url"` - Protocol string `json:"protocol"` - WrappedKey string `json:"wrappedKey"` - PolicyBinding interface{} `json:"policyBinding"` - EncryptedMetadata string `json:"encryptedMetadata,omitempty"` - KID string `json:"kid,omitempty"` - SplitID string `json:"sid,omitempty"` - SchemaVersion string `json:"schemaVersion,omitempty"` + KeyType string `json:"type"` + KasURL string `json:"url"` + Protocol string `json:"protocol"` + WrappedKey string `json:"wrappedKey"` + PolicyBinding interface{} `json:"policyBinding"` + EncryptedMetadata string `json:"encryptedMetadata,omitempty"` + KID string `json:"kid,omitempty"` + SplitID string `json:"sid,omitempty"` + SchemaVersion string `json:"schemaVersion,omitempty"` + EphemeralPublicKey string `json:"ephemeralPublicKey,omitempty"` } type PolicyBinding struct { diff --git a/sdk/options.go b/sdk/options.go index 3ec1da618..78d4f5ad7 100644 --- a/sdk/options.go +++ b/sdk/options.go @@ -3,10 +3,12 @@ package sdk import ( "crypto/rsa" "crypto/tls" + "net/http" "github.com/opentdf/platform/lib/ocrypto" "github.com/opentdf/platform/sdk/auth" "github.com/opentdf/platform/sdk/auth/oauth" + "github.com/opentdf/platform/sdk/httputil" "golang.org/x/oauth2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -18,25 +20,26 @@ type Option func(*config) // Internal config struct for building SDK options. type config struct { // Platform configuration structure is subject to change. Consume via accessor methods. - PlatformConfiguration PlatformConfiguration - dialOption grpc.DialOption - tlsConfig *tls.Config - clientCredentials *oauth.ClientCredentials - tokenExchange *oauth.TokenExchangeInfo - tokenEndpoint string - scopes []string - extraDialOptions []grpc.DialOption - certExchange *oauth.CertExchangeInfo - kasSessionKey *ocrypto.RsaKeyPair - dpopKey *ocrypto.RsaKeyPair - ipc bool - tdfFeatures tdfFeatures - nanoFeatures nanoFeatures - customAccessTokenSource auth.AccessTokenSource - oauthAccessTokenSource oauth2.TokenSource - coreConn *grpc.ClientConn - entityResolutionConn *grpc.ClientConn - collectionStore *collectionStore + PlatformConfiguration PlatformConfiguration + dialOption grpc.DialOption + httpClient *http.Client + clientCredentials *oauth.ClientCredentials + tokenExchange *oauth.TokenExchangeInfo + tokenEndpoint string + scopes []string + extraDialOptions []grpc.DialOption + certExchange *oauth.CertExchangeInfo + kasSessionKey *ocrypto.RsaKeyPair + dpopKey *ocrypto.RsaKeyPair + ipc bool + tdfFeatures tdfFeatures + nanoFeatures nanoFeatures + customAccessTokenSource auth.AccessTokenSource + oauthAccessTokenSource oauth2.TokenSource + coreConn *grpc.ClientConn + entityResolutionConn *grpc.ClientConn + collectionStore *collectionStore + shouldValidatePlatformConnectivity bool } // Options specific to TDF protocol features @@ -66,7 +69,7 @@ func WithInsecureSkipVerifyConn() Option { } c.dialOption = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) // used by http client - c.tlsConfig = tlsConfig + c.httpClient = httputil.SafeHTTPClientWithTLSConfig(tlsConfig) } } @@ -83,7 +86,7 @@ func WithInsecurePlaintextConn() Option { c.dialOption = grpc.WithTransportCredentials(insecure.NewCredentials()) // used by http client // FIXME anything to do here - c.tlsConfig = &tls.Config{} + c.httpClient = httputil.SafeHTTPClient() } } @@ -97,7 +100,7 @@ func WithClientCredentials(clientID, clientSecret string, scopes []string) Optio func WithTLSCredentials(tls *tls.Config, audience []string) Option { return func(c *config) { - c.certExchange = &oauth.CertExchangeInfo{TLSConfig: tls, Audience: audience} + c.certExchange = &oauth.CertExchangeInfo{HTTPClient: httputil.SafeHTTPClientWithTLSConfig(tls), Audience: audience} } } @@ -193,6 +196,13 @@ func WithPlatformConfiguration(platformConfiguration PlatformConfiguration) Opti } } +// WithConnectionValidation will validate connection to a healthy, running platform +func WithConnectionValidation() Option { + return func(c *config) { + c.shouldValidatePlatformConnectivity = true + } +} + // WithIPC returns an Option that indicates the SDK should use IPC for communication // this will allow the platform endpoint to be an empty string func WithIPC() Option { diff --git a/sdk/schema/manifest-lax.schema.json b/sdk/schema/manifest-lax.schema.json index 532c95099..a31abd75f 100644 --- a/sdk/schema/manifest-lax.schema.json +++ b/sdk/schema/manifest-lax.schema.json @@ -99,6 +99,10 @@ "encryptedMetadata": { "description": "Metadata associated with the TDF, and the request. The contents of the metadata are freeform, and are used to pass information from the client, and any plugins that may be in use by the KAS. The metadata stored here should not be used for primary access decisions. Base64.", "type": ["string", "null"] + }, + "ephemeralPublicKey": { + "description": "For ECC wrapped keys, the client public key portion used, with the KAS public key identified with the key id, to derive a shared key that encrypts the wrapped key.", + "type": ["string", "null"] } } }, diff --git a/sdk/schema/manifest.schema.json b/sdk/schema/manifest.schema.json index dfb920d38..6488623fa 100644 --- a/sdk/schema/manifest.schema.json +++ b/sdk/schema/manifest.schema.json @@ -52,7 +52,7 @@ "type": { "description": "The type of key access object.", "type": "string", - "enum": ["wrapped", "remote"] + "enum": ["ec-wrapped", "remote", "wrapped"] }, "url": { "description": "A fully qualified URL pointing to a key access service responsible for managing access to the encryption keys.", @@ -64,7 +64,7 @@ "enum": ["kas"] }, "wrappedKey": { - "description": "The symmetric key used to encrypt the payload. It has been encrypted using the public key of the KAS, then base64 encoded.", + "description": "The symmetric key used to encrypt the payload. It has been encrypted using the public key of the KAS, then base64 encoded. Options", "type": "string" }, "sid": { @@ -99,6 +99,10 @@ "encryptedMetadata": { "description": "Metadata associated with the TDF, and the request. The contents of the metadata are freeform, and are used to pass information from the client, and any plugins that may be in use by the KAS. The metadata stored here should not be used for primary access decisions. Base64.", "type": "string" + }, + "ephemeralPublicKey": { + "description": "For ECC wrapped keys, the client public key portion used, with the KAS public key identified with the key id, to derive a shared key that encrypts the wrapped key.", + "type": "string" } } }, diff --git a/sdk/sdk.go b/sdk/sdk.go index 0a9280059..376ee6d37 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -27,10 +27,12 @@ import ( "github.com/opentdf/platform/protocol/go/wellknownconfiguration" "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/sdk/auth" + "github.com/opentdf/platform/sdk/httputil" "github.com/opentdf/platform/sdk/internal/archive" "github.com/xeipuuv/gojsonschema" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + healthpb "google.golang.org/grpc/health/grpc_health_v1" ) const ( @@ -38,6 +40,7 @@ const ( // Check your configuration and/or retry. ErrGrpcDialFailed = Error("failed to dial grpc endpoint") ErrShutdownFailed = Error("failed to shutdown sdk") + ErrPlatformUnreachable = Error("platform unreachable or not responding") ErrPlatformConfigFailed = Error("failed to retrieve platform configuration") ErrPlatformEndpointMalformed = Error("platform endpoint is malformed") ErrPlatformIssuerNotFound = Error("issuer not found in well-known idp configuration") @@ -111,12 +114,19 @@ func New(platformEndpoint string, opts ...Option) (*SDK, error) { dialOptions = append(dialOptions, cfg.extraDialOptions...) } - // IF IPC is disabled we build a connection to the platform + // IF IPC is disabled we build a validated healthy connection to the platform if !cfg.ipc { platformEndpoint, err = SanitizePlatformEndpoint(platformEndpoint) if err != nil { return nil, fmt.Errorf("%w [%v]: %w", ErrPlatformEndpointMalformed, platformEndpoint, err) } + + if cfg.shouldValidatePlatformConnectivity { + err = ValidateHealthyPlatformConnection(platformEndpoint, dialOptions) + if err != nil { + return nil, err + } + } } // If platformConfiguration is not provided, fetch it from the platform @@ -154,7 +164,7 @@ func New(platformEndpoint string, opts ...Option) (*SDK, error) { return nil, err } if accessTokenSource != nil { - interceptor := auth.NewTokenAddingInterceptor(accessTokenSource, cfg.tlsConfig) + interceptor := auth.NewTokenAddingInterceptorWithClient(accessTokenSource, cfg.httpClient) uci = append(uci, interceptor.AddCredentials) } @@ -423,6 +433,23 @@ func fetchPlatformConfiguration(platformEndpoint string, dialOptions []grpc.Dial return getPlatformConfiguration(conn) } +// Test connectability to the platform and validate a healthy status +func ValidateHealthyPlatformConnection(platformEndpoint string, dialOptions []grpc.DialOption) error { + conn, err := grpc.NewClient(platformEndpoint, dialOptions...) + if err != nil { + return errors.Join(ErrGrpcDialFailed, err) + } + defer conn.Close() + + req := healthpb.HealthCheckRequest{} + healthService := healthpb.NewHealthClient(conn) + resp, err := healthService.Check(context.Background(), &req) + if err != nil || resp.GetStatus() != healthpb.HealthCheckResponse_SERVING { + return errors.Join(ErrPlatformUnreachable, err) + } + return nil +} + func getPlatformConfiguration(conn *grpc.ClientConn) (PlatformConfiguration, error) { req := wellknownconfiguration.GetWellKnownConfigurationRequest{} wellKnownConfig := wellknownconfiguration.NewWellKnownServiceClient(conn) @@ -452,13 +479,11 @@ func getTokenEndpoint(c config) (string, error) { return "", err } - httpClient := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: c.tlsConfig, - }, + client := c.httpClient + if client == nil { + client = httputil.SafeHTTPClient() } - - resp, err := httpClient.Do(req) + resp, err := client.Do(req) if err != nil { return "", err } diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 177cb3391..f0d1d0fa3 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -254,14 +254,22 @@ func TestNew_ShouldHaveSameMethods(t *testing.T) { } } -func Test_ShouldCreateNewSDKWithBadEndpoint(t *testing.T) { - // Bad endpoints are not detected until the first call to the platform - t.Skip("Skipping test since this is expected but not great behavior") - // When - s, err := sdk.New(badPlatformEndpoint) - // Then - require.NoError(t, err) - assert.NotNil(t, s) +func Test_New_ShouldFailWithDisconnectedPlatform(t *testing.T) { + s, err := sdk.New(badPlatformEndpoint, + sdk.WithConnectionValidation(), + ) + require.ErrorIs(t, err, sdk.ErrPlatformUnreachable) + assert.Nil(t, s) + + // validates even with platform configuration provided + s, err = sdk.New(badPlatformEndpoint, + sdk.WithPlatformConfiguration(sdk.PlatformConfiguration{ + "platform_issuer": "https://example.org", + }), + sdk.WithConnectionValidation(), + ) + require.ErrorIs(t, err, sdk.ErrPlatformUnreachable) + assert.Nil(t, s) } func Test_ShouldSanitizePlatformEndpoint(t *testing.T) { diff --git a/sdk/tdf.go b/sdk/tdf.go index d286a5389..87d853a46 100644 --- a/sdk/tdf.go +++ b/sdk/tdf.go @@ -34,6 +34,7 @@ const ( tdfZipReference = "reference" kKeySize = 32 kWrapped = "wrapped" + kECWrapped = "ec-wrapped" kKasProtocol = "kas" kSplitKeyType = "split" kGCMCipherAlgorithm = "AES-256-GCM" @@ -65,7 +66,7 @@ type Reader struct { aesGcm ocrypto.AesGcm payloadSize int64 payloadKey []byte - kasSessionKey ocrypto.RsaKeyPair + kasSessionKey ocrypto.KeyPair config TDFReaderConfig } @@ -81,6 +82,11 @@ type tdf3DecryptHandler struct { reader *Reader } +type ecKeyWrappedKeyInfo struct { + publicKey string + wrappedKey string +} + func (r *tdf3DecryptHandler) Decrypt(ctx context.Context, results []kaoResult) (int, error) { err := r.reader.buildKey(ctx, results) if err != nil { @@ -412,12 +418,14 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon conjunction := make(map[string][]KASInfo) var splitIDs []string + keyAlgorithm := string(tdfConfig.keyType) + for _, splitInfo := range tdfConfig.splitPlan { // Public key was passed in with kasInfoList // TODO first look up in attribute information / add to split plan? ki, ok := latestKASInfo[splitInfo.KAS] if !ok || ki.PublicKey == "" { - k, err := s.getPublicKey(ctx, splitInfo.KAS, "rsa:2048") + k, err := s.getPublicKey(ctx, splitInfo.KAS, keyAlgorithm) if err != nil { return fmt.Errorf("unable to retrieve public key from KAS at [%s]: %w", splitInfo.KAS, err) } @@ -451,27 +459,10 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon // add meta data var encryptedMetadata string if len(tdfConfig.metaData) > 0 { - gcm, err := ocrypto.NewAESGcm(symKey) - if err != nil { - return fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) - } - - emb, err := gcm.Encrypt([]byte(tdfConfig.metaData)) + encryptedMetadata, err = encryptMetadata(symKey, tdfConfig.metaData) if err != nil { - return fmt.Errorf("ocrypto.AesGcm.encrypt failed:%w", err) - } - - iv := emb[:ocrypto.GcmStandardNonceSize] - metadata := EncryptedMetadata{ - Cipher: string(ocrypto.Base64Encode(emb)), - Iv: string(ocrypto.Base64Encode(iv)), + return err } - - metadataJSON, err := json.Marshal(metadata) - if err != nil { - return fmt.Errorf(" json.Marshal failed:%w", err) - } - encryptedMetadata = string(ocrypto.Base64Encode(metadataJSON)) } for _, kasInfo := range conjunction[splitID] { @@ -479,27 +470,9 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon return fmt.Errorf("splitID:[%s], kas:[%s]: %w", splitID, kasInfo.URL, errKasPubKeyMissing) } - // wrap the key with kas public key - asymEncrypt, err := ocrypto.NewAsymEncryption(kasInfo.PublicKey) + keyAccess, err := createKeyAccess(tdfConfig, kasInfo, symKey, policyBinding, encryptedMetadata, splitID) if err != nil { - return fmt.Errorf("ocrypto.NewAsymEncryption failed:%w", err) - } - - wrappedKey, err := asymEncrypt.Encrypt(symKey) - if err != nil { - return fmt.Errorf("ocrypto.AsymEncryption.encrypt failed:%w", err) - } - - keyAccess := KeyAccess{ - KeyType: kWrapped, - KasURL: kasInfo.URL, - KID: kasInfo.KID, - Protocol: kKasProtocol, - PolicyBinding: policyBinding, - EncryptedMetadata: encryptedMetadata, - SplitID: splitID, - WrappedKey: string(ocrypto.Base64Encode(wrappedKey)), - SchemaVersion: keyAccessSchemaVersion, + return err } manifest.EncryptionInformation.KeyAccessObjs = append(manifest.EncryptionInformation.KeyAccessObjs, keyAccess) @@ -526,6 +499,121 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon return nil } +func encryptMetadata(symKey []byte, metaData string) (string, error) { + gcm, err := ocrypto.NewAESGcm(symKey) + if err != nil { + return "", fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + emb, err := gcm.Encrypt([]byte(metaData)) + if err != nil { + return "", fmt.Errorf("ocrypto.AesGcm.encrypt failed:%w", err) + } + + iv := emb[:ocrypto.GcmStandardNonceSize] + metadata := EncryptedMetadata{ + Cipher: string(ocrypto.Base64Encode(emb)), + Iv: string(ocrypto.Base64Encode(iv)), + } + + metadataJSON, err := json.Marshal(metadata) + if err != nil { + return "", fmt.Errorf(" json.Marshal failed:%w", err) + } + return string(ocrypto.Base64Encode(metadataJSON)), nil +} + +func createKeyAccess(tdfConfig TDFConfig, kasInfo KASInfo, symKey []byte, policyBinding PolicyBinding, encryptedMetadata, splitID string) (KeyAccess, error) { + keyAccess := KeyAccess{ + KeyType: kWrapped, + KasURL: kasInfo.URL, + KID: kasInfo.KID, + Protocol: kKasProtocol, + PolicyBinding: policyBinding, + EncryptedMetadata: encryptedMetadata, + SplitID: splitID, + SchemaVersion: keyAccessSchemaVersion, + } + + if ocrypto.IsECKeyType(tdfConfig.keyType) { + mode, err := ocrypto.ECKeyTypeToMode(tdfConfig.keyType) + if err != nil { + return KeyAccess{}, err + } + wrappedKeyInfo, err := generateWrapKeyWithEC(mode, kasInfo.PublicKey, symKey) + if err != nil { + return KeyAccess{}, err + } + keyAccess.KeyType = kECWrapped + keyAccess.WrappedKey = wrappedKeyInfo.wrappedKey + keyAccess.EphemeralPublicKey = wrappedKeyInfo.publicKey + } else { + wrappedKey, err := generateWrapKeyWithRSA(kasInfo.PublicKey, symKey) + if err != nil { + return KeyAccess{}, err + } + keyAccess.WrappedKey = wrappedKey + } + + return keyAccess, nil +} + +func generateWrapKeyWithEC(mode ocrypto.ECCMode, kasPublicKey string, symKey []byte) (ecKeyWrappedKeyInfo, error) { + ecKeyPair, err := ocrypto.NewECKeyPair(mode) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.NewECKeyPair failed:%w", err) + } + + emphermalPublicKey, err := ecKeyPair.PublicKeyInPemFormat() + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("failed to get EC public key: %w", err) + } + + emphermalPrivateKey, err := ecKeyPair.PrivateKeyInPemFormat() + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("failed to get EC private key: %w", err) + } + + ecdhKey, err := ocrypto.ComputeECDHKey([]byte(emphermalPrivateKey), []byte(kasPublicKey)) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.ComputeECDHKey failed:%w", err) + } + + sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) + } + + gcm, err := ocrypto.NewAESGcm(sessionKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + wrappedKey, err := gcm.Encrypt(symKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.AESGcm.Encrypt failed:%w", err) + } + + return ecKeyWrappedKeyInfo{ + publicKey: emphermalPublicKey, + wrappedKey: string(ocrypto.Base64Encode(wrappedKey)), + }, nil +} + +func generateWrapKeyWithRSA(publicKey string, symKey []byte) (string, error) { + asymEncrypt, err := ocrypto.NewAsymEncryption(publicKey) + if err != nil { + return "", fmt.Errorf("ocrypto.NewAsymEncryption failed:%w", err) + } + + wrappedKey, err := asymEncrypt.Encrypt(symKey) + if err != nil { + return "", fmt.Errorf("ocrypto.AsymEncryption.encrypt failed:%w", err) + } + + return string(ocrypto.Base64Encode(wrappedKey)), nil +} + // create policy object func createPolicyObject(attributes []AttributeValueFQN) (PolicyObject, error) { uuidObj, err := uuid.NewUUID() @@ -585,7 +673,7 @@ func (s SDK) LoadTDF(reader io.ReadSeeker, opts ...TDFReaderOption) (*Reader, er dialOptions: s.dialOptions, tdfReader: tdfReader, manifest: *manifestObj, - kasSessionKey: *s.config.kasSessionKey, + kasSessionKey: config.kasSessionKey, config: *config, }, nil } @@ -885,8 +973,9 @@ func createRewrapRequest(_ context.Context, r *Reader) (map[string]*kas.Unsigned Hash: hash, Algorithm: alg, }, - SplitId: kao.SplitID, - WrappedKey: key, + SplitId: kao.SplitID, + WrappedKey: key, + EphemeralPublicKey: kao.EphemeralPublicKey, }, } if req, ok := kasReqs[kao.KasURL]; ok { @@ -1095,7 +1184,7 @@ func (r *Reader) buildKey(_ context.Context, results []kaoResult) error { // Unwraps the payload key, if possible, using the access service func (r *Reader) doPayloadKeyUnwrap(ctx context.Context) error { //nolint:gocognit // Better readability keeping it as is - kasClient := newKASClient(r.dialOptions, r.tokenSource, &r.kasSessionKey) + kasClient := newKASClient(r.dialOptions, r.tokenSource, r.kasSessionKey) var kaoResults []kaoResult reqFail := func(err error, req *kas.UnsignedRewrapRequest_WithPolicyRequest) { diff --git a/sdk/tdf_config.go b/sdk/tdf_config.go index e0c182bb6..0159b7a4b 100644 --- a/sdk/tdf_config.go +++ b/sdk/tdf_config.go @@ -13,6 +13,10 @@ const ( maxSegmentSize = defaultSegmentSize * 2 minSegmentSize = 16 * 1024 kasPublicKeyPath = "/kas_public_key" + DefaultRSAKeySize = 2048 + ECKeySize256 = 256 + ECKeySize384 = 384 + ECKeySize521 = 521 ) type TDFFormat = int @@ -63,33 +67,18 @@ type TDFConfig struct { attributeValues []*policy.Value kasInfoList []KASInfo splitPlan []keySplitStep + keyType ocrypto.KeyType } func newTDFConfig(opt ...TDFOption) (*TDFConfig, error) { - rsaKeyPair, err := ocrypto.NewRSAKeyPair(tdf3KeySize) - if err != nil { - return nil, fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) - } - - publicKey, err := rsaKeyPair.PublicKeyInPemFormat() - if err != nil { - return nil, fmt.Errorf("ocrypto.PublicKeyInPemFormat failed: %w", err) - } - - privateKey, err := rsaKeyPair.PublicKeyInPemFormat() - if err != nil { - return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) - } - c := &TDFConfig{ autoconfigure: true, - tdfPrivateKey: privateKey, - tdfPublicKey: publicKey, defaultSegmentSize: defaultSegmentSize, enableEncryption: true, tdfFormat: JSONFormat, integrityAlgorithm: HS256, segmentIntegrityAlgorithm: GMAC, + keyType: ocrypto.RSA2048Key, // default to RSA } for _, o := range opt { @@ -99,9 +88,33 @@ func newTDFConfig(opt ...TDFOption) (*TDFConfig, error) { } } + publicKey, privateKey, err := generateKeyPair(c.keyType) + if err != nil { + return nil, err + } + + c.tdfPrivateKey = privateKey + c.tdfPublicKey = publicKey + return c, nil } +func generateKeyPair(kt ocrypto.KeyType) (string, string, error) { + keyPair, err := ocrypto.NewKeyPair(kt) + if err != nil { + return "", "", fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) + } + publicKey, err := keyPair.PublicKeyInPemFormat() + if err != nil { + return "", "", fmt.Errorf("ocrypto.PublicKeyInPemFormat failed: %w", err) + } + privateKey, err := keyPair.PrivateKeyInPemFormat() + if err != nil { + return "", "", fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) + } + return publicKey, privateKey, nil +} + // WithDataAttributes appends the given data attributes to the bound policy func WithDataAttributes(attributes ...string) TDFOption { return func(c *TDFConfig) error { @@ -213,6 +226,16 @@ func WithAutoconfigure(enable bool) TDFOption { } } +func WithWrappingKeyAlg(keyType ocrypto.KeyType) TDFOption { + return func(c *TDFConfig) error { + if c.keyType == "" { + return fmt.Errorf("key type missing") + } + c.keyType = keyType + return nil + } +} + // Schema Validation where 0 = none (skip), 1 = lax (allowing novel entries, 'falsy' values for unkowns), 2 = strict (rejecting novel entries, strict match to manifest schema) type SchemaValidationIntensity int @@ -230,12 +253,17 @@ type TDFReaderConfig struct { disableAssertionVerification bool schemaValidationIntensity SchemaValidationIntensity + kasSessionKey ocrypto.KeyPair + keyType ocrypto.KeyType } func newTDFReaderConfig(opt ...TDFReaderOption) (*TDFReaderConfig, error) { + var err error c := &TDFReaderConfig{ disableAssertionVerification: false, + keyType: ocrypto.RSA2048Key, } + for _, o := range opt { err := o(c) if err != nil { @@ -243,6 +271,11 @@ func newTDFReaderConfig(opt ...TDFReaderOption) (*TDFReaderConfig, error) { } } + c.kasSessionKey, err = ocrypto.NewKeyPair(c.keyType) + if err != nil { + return nil, fmt.Errorf("failed to create RSA key pair: %w", err) + } + return c, nil } @@ -266,3 +299,13 @@ func WithDisableAssertionVerification(disable bool) TDFReaderOption { return nil } } + +func WithSessionKeyType(keyType ocrypto.KeyType) TDFReaderOption { + return func(c *TDFReaderConfig) error { + if c.keyType == "" { + return fmt.Errorf("key type missing") + } + c.keyType = keyType + return nil + } +} diff --git a/sdk/version.go b/sdk/version.go index 8a168ba19..b8eff71e0 100644 --- a/sdk/version.go +++ b/sdk/version.go @@ -7,5 +7,5 @@ const ( TDFSpecVersion = "4.3.0" // The three-part semantic version number of this SDK - Version = "0.3.26" // x-release-please-version + Version = "0.3.28" // x-release-please-version ) diff --git a/service/CHANGELOG.md b/service/CHANGELOG.md index 6ba22c2c7..a3933ec11 100644 --- a/service/CHANGELOG.md +++ b/service/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [0.4.39](https://github.com/opentdf/platform/compare/service/v0.4.38...service/v0.4.39) (2025-02-27) + + +### Features + +* add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) + + +### Bug Fixes + +* add pagination to list public key mappings response ([#1889](https://github.com/opentdf/platform/issues/1889)) ([9898fbd](https://github.com/opentdf/platform/commit/9898fbda305f4eface291a2aaa98d2df80f0ad05)) +* cleanup kas public key create error messages ([#1887](https://github.com/opentdf/platform/issues/1887)) ([59f7d0e](https://github.com/opentdf/platform/commit/59f7d0e0ab45ef47b2df9326c0904b54fba4b3eb)) +* **core:** Autobump service ([#1875](https://github.com/opentdf/platform/issues/1875)) ([4b6c335](https://github.com/opentdf/platform/commit/4b6c3353913ad90aeef499beb5f8c52144679a61)) +* **core:** Autobump service ([#1895](https://github.com/opentdf/platform/issues/1895)) ([08a2048](https://github.com/opentdf/platform/commit/08a20481a085b4af67fc78e6cfae371f0bccd166)) +* **core:** Autobump service ([#1919](https://github.com/opentdf/platform/issues/1919)) ([f902295](https://github.com/opentdf/platform/commit/f90229560e8f09b64b4bf650b271c5fbb428bc7f)) +* **core:** Autobump service ([#1945](https://github.com/opentdf/platform/issues/1945)) ([d2e37ca](https://github.com/opentdf/platform/commit/d2e37ca081d04f4588c58b752b0c96ef9b0125cb)) +* **core:** Autobump service ([#1950](https://github.com/opentdf/platform/issues/1950)) ([7270080](https://github.com/opentdf/platform/commit/7270080639f19ba9725f1e834970d94d00191994)) +* **core:** Autobump service ([#1952](https://github.com/opentdf/platform/issues/1952)) ([b20123e](https://github.com/opentdf/platform/commit/b20123ef768063eb883d9414d86ec1a0e3009884)) +* **core:** Fixes for ec-wrapped from js client ([#1923](https://github.com/opentdf/platform/issues/1923)) ([3a66485](https://github.com/opentdf/platform/commit/3a6648528e3d3582ec3c5222e4dfc37d0fb13e74)) +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) +* **core:** improve logging and errors on rewrap ([#1906](https://github.com/opentdf/platform/issues/1906)) ([84339d6](https://github.com/opentdf/platform/commit/84339d620717c7bc5de0d6bb6ece656cce5c07be)) +* **core:** Requires unique kids ([#1905](https://github.com/opentdf/platform/issues/1905)) ([c1b380c](https://github.com/opentdf/platform/commit/c1b380cb586a10196a8febc700a57c2c41a51a18)) +* filter total count on list public key operations ([#1884](https://github.com/opentdf/platform/issues/1884)) ([8df0adc](https://github.com/opentdf/platform/commit/8df0adc60dd49aa3dcdaf4d60f094338ca5ad2e9)) +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) + ## [0.4.38](https://github.com/opentdf/platform/compare/service/v0.4.37...service/v0.4.38) (2025-01-21) diff --git a/service/cmd/version.go b/service/cmd/version.go index 23892fbea..7e2a11a83 100644 --- a/service/cmd/version.go +++ b/service/cmd/version.go @@ -2,7 +2,7 @@ package cmd import "github.com/spf13/cobra" -const Version = "0.4.38" // Service Version // x-release-please-version +const Version = "0.4.39" // Service Version // x-release-please-version func init() { rootCmd.AddCommand(&cobra.Command{ diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index fdca07c98..5f680b84b 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -233,9 +233,8 @@ func EntityResolution(ctx context.Context, if exErr != nil { return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeNotFound, ErrNotFound) - } else { - keycloakEntities = expandedRepresentations } + keycloakEntities = expandedRepresentations default: logger.Error("no group found for", slog.String("entity", ident.String())) var entityNotFoundErr entityresolution.EntityNotFoundError diff --git a/service/go.mod b/service/go.mod index fca3e372b..703177b03 100644 --- a/service/go.mod +++ b/service/go.mod @@ -24,9 +24,9 @@ require ( github.com/open-policy-agent/opa v0.68.0 github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/flattening v0.1.3 - github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 - github.com/opentdf/platform/sdk v0.3.26 + github.com/opentdf/platform/lib/ocrypto v0.1.8 + github.com/opentdf/platform/protocol/go v0.2.28 + github.com/opentdf/platform/sdk v0.3.28 github.com/pressly/goose/v3 v3.19.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.18.2 @@ -38,7 +38,6 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 go.opentelemetry.io/otel/sdk v1.31.0 go.opentelemetry.io/otel/trace v1.31.0 - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -79,6 +78,7 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/oauth2 v0.22.0 // indirect ) diff --git a/service/go.sum b/service/go.sum index dcbe9b21b..78570a84e 100644 --- a/service/go.sum +++ b/service/go.sum @@ -277,12 +277,12 @@ github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXv github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= github.com/opentdf/platform/lib/flattening v0.1.3 h1:IuOm/wJVXNrzOV676Ticgr0wyBkL+lVjsoSfh+WSkNo= github.com/opentdf/platform/lib/flattening v0.1.3/go.mod h1:Gs/T+6FGZKk9OAdz2Jf1R8CTGeNRYrq1lZGDeYT3hrY= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= -github.com/opentdf/platform/sdk v0.3.26 h1:cXNQsLd7Ef2Nq6HJ/L+4tvdJ+Op42vplkA6C53rcPW8= -github.com/opentdf/platform/sdk v0.3.26/go.mod h1:rw/4l0qfhkhD9bdwqhXARV2CSpV+18m7Ks1wPRGLzkI= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= +github.com/opentdf/platform/protocol/go v0.2.28 h1:UfX+yFWFGCtxsvCyIO62p4v7CBtcVR+2dCqHq3O0vy4= +github.com/opentdf/platform/protocol/go v0.2.28/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/sdk v0.3.28 h1:rdfZCc5nLXDoljZEDin312T0K/RbNO5mpu1GlMTi8to= +github.com/opentdf/platform/sdk v0.3.28/go.mod h1:25xOGtsBPqbj8VDbn5yN5i6D/9fXNy/WDAM1NSPIXcY= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= diff --git a/service/integration/attribute_values_test.go b/service/integration/attribute_values_test.go index a5ef247df..bb3636f3b 100644 --- a/service/integration/attribute_values_test.go +++ b/service/integration/attribute_values_test.go @@ -183,26 +183,84 @@ func (s *AttributeValuesSuite) Test_ListAttributeValues_Offset_Succeeds() { func (s *AttributeValuesSuite) Test_GetAttributeValue() { f := s.f.GetAttributeValueKey("example.com/attr/attr1/value/value1") - v, err := s.db.PolicyClient.GetAttributeValue(s.ctx, f.ID) - s.Require().NoError(err) - s.NotNil(v) - s.Equal(f.ID, v.GetId()) - s.Equal(f.Value, v.GetValue()) - // s.Equal(f.AttributeDefinitionId, v.AttributeId) - s.Equal("https://example.com/attr/attr1/value/value1", v.GetFqn()) - metadata := v.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: f.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &attributes.GetAttributeValueRequest_ValueId{ValueId: f.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &attributes.GetAttributeValueRequest_Fqn{Fqn: "https://example.com/attr/attr1/value/value1"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + v, err := s.db.PolicyClient.GetAttributeValue(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get AttributeValue by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(v, "Expected non-nil AttributeValue for %s: %v", tc.identifierType, tc.input) + + s.Equal(f.ID, v.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.Value, v.GetValue(), "Value mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.AttributeDefinitionID, v.GetAttribute().GetId(), "AttributeDefinitionID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal("https://example.com/attr/attr1/value/value1", v.GetFqn(), "FQN mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := v.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributeValuesSuite) Test_GetAttributeValue_NotFound() { - attr, err := s.db.PolicyClient.GetAttributeValue(s.ctx, absentAttributeValueUUID) - s.Require().Error(err) - s.Nil(attr) - s.Require().ErrorIs(err, db.ErrNotFound) + testCases := []struct { + name string + input interface{} // Could be string ID or identifier struct if you want to test different not-found scenarios later + identifierType string // For clarity in case you expand test cases + }{ + { + name: "Not Found - Deprecated ID", // Or just "Not Found" if only one case + input: absentAttributeValueUUID, + identifierType: "Deprecated ID", // Or "UUID" or "ID" + }, + { + name: "Not Found - New Identifier - ID", + input: &attributes.GetAttributeValueRequest_ValueId{ValueId: absentAttributeValueUUID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier - FQN", + input: &attributes.GetAttributeValueRequest_Fqn{Fqn: "https://example.com/attr/attr1/value/absent_value"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + attr, err := s.db.PolicyClient.GetAttributeValue(s.ctx, tc.input) + s.Require().Error(err, "Expected an error when AttributeValue is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(attr, "Expected nil AttributeValue when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when AttributeValue is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributeValuesSuite) Test_GetAttributeValue_ContainsKASGrants() { diff --git a/service/integration/attributes_test.go b/service/integration/attributes_test.go index e7a41c49d..7c09e7567 100644 --- a/service/integration/attributes_test.go +++ b/service/integration/attributes_test.go @@ -52,16 +52,16 @@ func (s *AttributesSuite) TearDownSuite() { s.f.TearDown() } -func (s *AttributesSuite) getAttributeFixtures() []fixtures.FixtureDataAttribute { - return []fixtures.FixtureDataAttribute{ - s.f.GetAttributeKey("example.com/attr/attr1"), - s.f.GetAttributeKey("example.com/attr/attr2"), - s.f.GetAttributeKey("example.net/attr/attr1"), - s.f.GetAttributeKey("example.net/attr/attr2"), - s.f.GetAttributeKey("example.net/attr/attr3"), - s.f.GetAttributeKey("example.org/attr/attr1"), - s.f.GetAttributeKey("example.org/attr/attr2"), - s.f.GetAttributeKey("example.org/attr/attr3"), +func (s *AttributesSuite) getAttributeFixtures() map[string]fixtures.FixtureDataAttribute { + return map[string]fixtures.FixtureDataAttribute{ + "example.com/attr/attr1": s.f.GetAttributeKey("example.com/attr/attr1"), + "example.com/attr/attr2": s.f.GetAttributeKey("example.com/attr/attr2"), + "example.net/attr/attr1": s.f.GetAttributeKey("example.net/attr/attr1"), + "example.net/attr/attr2": s.f.GetAttributeKey("example.net/attr/attr2"), + "example.net/attr/attr3": s.f.GetAttributeKey("example.net/attr/attr3"), + "example.org/attr/attr1": s.f.GetAttributeKey("example.org/attr/attr1"), + "example.org/attr/attr2": s.f.GetAttributeKey("example.org/attr/attr2"), + "example.org/attr/attr3": s.f.GetAttributeKey("example.org/attr/attr3"), } } @@ -290,28 +290,85 @@ func (s *AttributesSuite) Test_GetAttribute_OrderOfValuesIsPreserved() { func (s *AttributesSuite) Test_GetAttribute() { fixtures := s.getAttributeFixtures() - for _, f := range fixtures { - gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, f.ID) - s.Require().NoError(err) - s.NotNil(gotAttr) - s.Equal(f.ID, gotAttr.GetId()) - s.Equal(f.Name, gotAttr.GetName()) - s.Equal(fmt.Sprintf("%s%s", policydb.AttributeRuleTypeEnumPrefix, f.Rule), gotAttr.GetRule().Enum().String()) - s.Equal(f.NamespaceID, gotAttr.GetNamespace().GetId()) - metadata := gotAttr.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + for fqn, f := range fixtures { + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: f.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &attributes.GetAttributeRequest_AttributeId{AttributeId: f.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &attributes.GetAttributeRequest_Fqn{Fqn: fqn}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("%s - %s", fqn, tc.name), func() { // Include fqn in test name for clarity + gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get Attribute by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(gotAttr, "Expected non-nil Attribute for %s: %v", tc.identifierType, tc.input) + + s.Equal(f.ID, gotAttr.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.Name, gotAttr.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(fmt.Sprintf("%s%s", policydb.AttributeRuleTypeEnumPrefix, f.Rule), gotAttr.GetRule().Enum().String(), "Rule mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.NamespaceID, gotAttr.GetNamespace().GetId(), "NamespaceID mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := gotAttr.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } } -func (s *AttributesSuite) Test_GetAttribute_WithInvalidIdFails() { - // this uuid does not exist - gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, nonExistentAttrID) - s.Require().Error(err) - s.Nil(gotAttr) - s.Require().ErrorIs(err, db.ErrNotFound) +func (s *AttributesSuite) Test_GetAttribute_NotFound() { + testCases := []struct { + name string + input interface{} // Could be string ID or identifier struct if needed later + identifierType string + }{ + { + name: "Not Found - Deprecated ID", // Or just "Not Found" if only one case is needed + input: nonExistentAttrID, + identifierType: "Deprecated ID", // Or "UUID", "ID" + }, + { + name: "Not Found - New Identifier - ID", + input: &attributes.GetAttributeRequest_AttributeId{AttributeId: nonExistentAttrID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier - FQN", + input: &attributes.GetAttributeRequest_Fqn{Fqn: "https://example.com/attr/non_existent_attr"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, tc.input) + s.Require().Error(err, "Expected error when Attribute is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(gotAttr, "Expected nil Attribute when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when Attribute is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributesSuite) Test_GetAttribute_Deactivated_Succeeds() { diff --git a/service/integration/kas_registry_test.go b/service/integration/kas_registry_test.go index 56a31a609..a31b82cd0 100644 --- a/service/integration/kas_registry_test.go +++ b/service/integration/kas_registry_test.go @@ -145,35 +145,130 @@ func (s *KasRegistrySuite) Test_GetKeyAccessServer() { remoteFixture := s.f.GetKasRegistryKey("key_access_server_1") localFixture := s.f.GetKasRegistryKey("key_access_server_2") - remote, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, remoteFixture.ID) - s.Require().NoError(err) - s.NotNil(remote) - s.Equal(remoteFixture.ID, remote.GetId()) - s.Equal(remoteFixture.URI, remote.GetUri()) - s.Equal(remoteFixture.Name, remote.GetName()) - s.Equal(remoteFixture.PubKey.Remote, remote.GetPublicKey().GetRemote()) + testCases := []struct { + name string + input interface{} // Can be string or struct + expected fixtures.FixtureDataKasRegistry + identifierType string // For clearer test case names + }{ + { + name: "Deprecated ID - Remote", + input: remoteFixture.ID, + expected: remoteFixture, + identifierType: "ID", + }, + { + name: "Deprecated ID - Local", + input: localFixture.ID, + expected: localFixture, + identifierType: "ID", + }, + { + name: "Name Identifier - Remote", + input: &kasregistry.GetKeyAccessServerRequest_Name{Name: remoteFixture.Name}, + expected: remoteFixture, + identifierType: "Name", + }, + { + name: "Name Identifier - Local", + input: &kasregistry.GetKeyAccessServerRequest_Name{Name: localFixture.Name}, + expected: localFixture, + identifierType: "Name", + }, + { + name: "URI Identifier - Remote", + input: &kasregistry.GetKeyAccessServerRequest_Uri{Uri: remoteFixture.URI}, + expected: remoteFixture, + identifierType: "URI", + }, + { + name: "URI Identifier - Local", + input: &kasregistry.GetKeyAccessServerRequest_Uri{Uri: localFixture.URI}, + expected: localFixture, + identifierType: "URI", + }, + } - local, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, localFixture.ID) - s.Require().NoError(err) - s.NotNil(local) - s.Equal(localFixture.ID, local.GetId()) - s.Equal(localFixture.URI, local.GetUri()) - s.Equal(localFixture.Name, local.GetName()) - s.Equal(localFixture.PubKey.Cached, local.GetPublicKey().GetCached()) + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get KeyAccessServer by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(resp, "Expected non-nil response for %s: %v", tc.identifierType, tc.input) + + s.Equal(tc.expected.ID, resp.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(tc.expected.URI, resp.GetUri(), "URI mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(tc.expected.Name, resp.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + + switch tc.expected { + case remoteFixture: + s.Equal(tc.expected.PubKey.Remote, resp.GetPublicKey().GetRemote(), "PublicKey.Remote mismatch for %s: %v", tc.identifierType, tc.input) + case localFixture: + s.Equal(tc.expected.PubKey.Cached, resp.GetPublicKey().GetCached(), "PublicKey.Cached mismatch for %s: %v", tc.identifierType, tc.input) + default: + s.Fail("Unexpected fixture in test case: %s", tc.name) // Should not happen, but good to have for safety + } + }) + } } func (s *KasRegistrySuite) Test_GetKeyAccessServer_WithNonExistentId_Fails() { - resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, nonExistentKasRegistryID) - s.Require().Error(err) - s.Nil(resp) - s.Require().ErrorIs(err, db.ErrNotFound) + testCases := []struct { + name string + input interface{} + }{ + { + name: "string non-existent UUID", + input: nonExistentKasRegistryID, + }, + { + name: "struct non-existent UUID", + input: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: nonExistentKasRegistryID, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().Error(err, "Expected an error for input: %s", tc.input) + s.Nil(resp, "Expected nil response for input: %s", tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound for input: %s", tc.input) + }) + } } func (s *KasRegistrySuite) Test_GetKeyAccessServer_WithInvalidID_Fails() { - resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, "hello") - s.Require().Error(err) - s.Nil(resp) - s.Require().ErrorIs(err, db.ErrUUIDInvalid) + testCases := []struct { + name string + input interface{} + }{ + { + name: "string invalid UUID", + input: "hello", + }, + { + name: "struct invalid UUID", + input: &kasregistry.GetKeyAccessServerRequest_KasId{KasId: "hello"}, + }, + { + name: "empty string", + input: "", + }, + { + name: "struct empty string", + input: &kasregistry.GetKeyAccessServerRequest_KasId{KasId: ""}, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().Error(err) + s.Nil(resp) + s.Require().ErrorIs(err, db.ErrUUIDInvalid) + }) + } } func (s *KasRegistrySuite) Test_CreateKeyAccessServer_Remote() { @@ -1023,7 +1118,9 @@ func (s *KasRegistrySuite) Test_Create_Public_Key() { // The initial rsa2048 public key is created in the fixture and should be active kID := s.f.GetPublicKey("key_1").ID - r1, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r1, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r1) s.True(r1.GetKey().GetIsActive().GetValue()) @@ -1047,7 +1144,9 @@ func (s *KasRegistrySuite) Test_Create_Public_Key() { publicKeyTestUUID = r2.GetKey().GetId() // Now the old key should be inactive - r3, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r3, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r3) s.False(r3.GetKey().GetIsActive().GetValue()) @@ -1150,7 +1249,9 @@ func (s *KasRegistrySuite) Test_Update_Public_Key() { s.Equal(labels, resp.GetKey().GetMetadata().GetLabels()) // Get Key to validate update - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r) s.Equal(labels, r.GetKey().GetMetadata().GetLabels()) @@ -1161,7 +1262,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key() { keyID := s.f.GetPublicKey("key_1").Key.Kid id := s.f.GetPublicKey("key_1").ID - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(r) @@ -1171,7 +1274,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key() { } func (s *KasRegistrySuite) Test_Get_Public_Key_WithInvalidID_Fails() { - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: "invalid-id"}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: "invalid-id"}, + }) s.Require().Error(err) s.Nil(r) @@ -1179,7 +1284,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key_WithInvalidID_Fails() { } func (s *KasRegistrySuite) Test_Get_Public_Key_WithNotFoundID_Fails() { - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: nonExistentKasRegistryID}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: nonExistentKasRegistryID}, + }) s.Require().Error(err) s.Nil(r) @@ -1193,26 +1300,63 @@ func (s *KasRegistrySuite) Test_List_Public_Keys() { s.GreaterOrEqual(len(r.GetKeys()), 2) } -func (s *KasRegistrySuite) Test_List_Public_Keys_ByKasID() { - kasID := s.f.GetKasRegistryKey("key_access_server_1").ID - r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{KasId: kasID}) +func (s *KasRegistrySuite) Test_List_Public_Keys_By_KAS() { + rAllKeys, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{}) s.Require().NoError(err) - s.NotNil(r) - s.GreaterOrEqual(len(r.GetKeys()), 1) - for _, key := range r.GetKeys() { - s.Equal(kasID, key.GetKas().GetId()) - } + s.NotNil(rAllKeys) + totalKeys := rAllKeys.GetPagination().GetTotal() - filteredTotalKeys := r.GetPagination().GetTotal() + kas1 := s.f.GetKasRegistryKey("key_access_server_1") - r, err = s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{}) - s.Require().NoError(err) - s.NotNil(r) + testCases := []struct { + name string + req *kasregistry.ListPublicKeysRequest + identifierType string + }{ + { + name: "List by KAS ID", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: kas1.ID, + }, + }, + identifierType: "KAS ID", + }, + { + name: "List by KAS URI", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: kas1.URI, + }, + }, + identifierType: "KAS URI", + }, + { + name: "List by KAS Name", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: kas1.Name, + }, + }, + identifierType: "KAS Name", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + rFilteredKeys, err := s.db.PolicyClient.ListPublicKeys(s.ctx, tc.req) + s.Require().NoError(err, "Failed to list keys by %s", tc.identifierType) + s.Require().NotNil(rFilteredKeys, "Expected non-nil response when listing keys by %s", tc.identifierType) + s.GreaterOrEqual(len(rFilteredKeys.GetKeys()), 1, "Expected at least 1 key when listing by %s", tc.identifierType) - totalKeys := r.GetPagination().GetTotal() + for _, key := range rFilteredKeys.GetKeys() { + s.Equal(kas1.ID, key.GetKas().GetId(), "Key KAS ID mismatch when listing by %s", tc.identifierType) + } - // Fixtures have multiple kas keys, so the total keys should be greater than the filtered total keys - s.NotEqual(totalKeys, filteredTotalKeys) + filteredTotalKeys := rFilteredKeys.GetPagination().GetTotal() + s.NotEqual(totalKeys, filteredTotalKeys, "Total keys should be different after filtering by %s", tc.identifierType) + }) + } } func (s *KasRegistrySuite) Test_List_Public_Keys_WithLimit_1() { @@ -1227,7 +1371,11 @@ func (s *KasRegistrySuite) Test_List_Public_Keys_WithLimit_1() { } func (s *KasRegistrySuite) Test_List_Public_Keys_WithNonExistentKasID() { - r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{KasId: nonExistentKasRegistryID}) + r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: nonExistentKasRegistryID, + }, + }) s.Require().NoError(err) s.NotNil(r) s.Empty(r.GetKeys()) @@ -1236,7 +1384,11 @@ func (s *KasRegistrySuite) Test_List_Public_Keys_WithNonExistentKasID() { func (s *KasRegistrySuite) Test_List_Public_Key_Mappings() { kasid := s.f.GetPublicKey("key_1").KasID id := s.f.GetPublicKey("key_1").ID - r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{KasId: kasid}) + r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: kasid, + }, + }) s.Require().NoError(err) s.NotNil(r) s.Len(r.GetPublicKeyMappings(), 1) @@ -1271,15 +1423,60 @@ func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_WithLimit_1() { s.Len(r.GetPublicKeyMappings(), 1) } -func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_By_KAS_ID() { - kasID := s.f.GetKasRegistryKey("key_access_server_1").ID - r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{KasId: kasID}) - s.Require().NoError(err) - s.NotNil(r) - s.Len(r.GetPublicKeyMappings(), 1) +func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_By_KAS() { + kas := s.f.GetKasRegistryKey("key_access_server_1") + pk := s.f.GetPublicKey("key_1") + + testCases := []struct { + name string + req *kasregistry.ListPublicKeyMappingRequest + identifierType string + }{ + { + name: "List by KAS ID", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: kas.ID, + }, + }, + identifierType: "KAS ID", + }, + { + name: "List by KAS URI", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: kas.URI, + }, + }, + identifierType: "KAS URI", + }, + { + name: "List by KAS Name", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: kas.Name, + }, + }, + identifierType: "KAS Name", + }, + } - for _, m := range r.GetPublicKeyMappings() { - s.Equal(kasID, m.GetKasId()) + for _, tc := range testCases { + s.Run(tc.name, func() { + r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, tc.req) + s.Require().NoError(err, "Failed to list mappings by %s", tc.identifierType) + s.Require().NotNil(r, "Expected non-nil response when listing mappings by %s", tc.identifierType) + s.Len(r.GetPublicKeyMappings(), 1, "Expected 1 mapping when listing by %s", tc.identifierType) // Assuming fixture setup ensures 1 mapping + + for _, m := range r.GetPublicKeyMappings() { + s.Equal(kas.ID, m.GetKasId(), "KasId mismatch when listing by %s", tc.identifierType) + s.Equal(kas.URI, m.GetKasUri(), "KasUri mismatch when listing by %s", tc.identifierType) + s.Equal(kas.Name, m.GetKasName(), "KasName mismatch when listing by %s", tc.identifierType) + s.True(slices.ContainsFunc(m.GetPublicKeys(), func(key *kasregistry.ListPublicKeyMappingResponse_PublicKey) bool { + return key.GetKey().GetId() == pk.ID + }), "PublicKey not found in mappings when listing by %s", tc.identifierType) + } + }) } } @@ -1303,7 +1500,9 @@ func (s *KasRegistrySuite) Test_Deactivate_Public_Key() { s.NotNil(r) s.Equal(id, r.GetKey().GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(rr) s.False(rr.GetKey().GetIsActive().GetValue()) @@ -1323,7 +1522,9 @@ func (s *KasRegistrySuite) Test_Activate_Public_Key() { s.NotNil(r) s.Equal(id, r.GetKey().GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(rr) s.True(rr.GetKey().GetIsActive().GetValue()) @@ -1343,7 +1544,9 @@ func (s *KasRegistrySuite) Test_UnsafeDelete_Public_Key() { s.NotNil(r) s.Equal(id, r.GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().Error(err) s.Require().ErrorIs(err, db.ErrNotFound) s.Nil(rr) diff --git a/service/integration/namespaces_test.go b/service/integration/namespaces_test.go index 1409db647..802440324 100644 --- a/service/integration/namespaces_test.go +++ b/service/integration/namespaces_test.go @@ -2,6 +2,7 @@ package integration import ( "context" + "fmt" "log/slog" "strings" "testing" @@ -93,22 +94,83 @@ func (s *NamespacesSuite) Test_GetNamespace() { testData := s.getActiveNamespaceFixtures() for _, test := range testData { - gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, test.ID) - s.Require().NoError(err) - s.NotNil(gotNamespace) - // name retrieved by ID equal to name used to create - s.Equal(test.Name, gotNamespace.GetName()) - metadata := gotNamespace.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: test.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &namespaces.GetNamespaceRequest_NamespaceId{NamespaceId: test.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &namespaces.GetNamespaceRequest_Fqn{Fqn: test.Name}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("%s - %s", test.Name, tc.name), func() { // Include namespace name in test name + gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get Namespace by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(gotNamespace, "Expected non-nil Namespace for %s: %v", tc.identifierType, tc.input) + + // name retrieved by ID equal to name used to create + s.Equal(test.Name, gotNamespace.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := gotNamespace.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } +} - // Getting a namespace with an nonExistent id should fail - _, err := s.db.PolicyClient.GetNamespace(s.ctx, nonExistentNamespaceID) - s.Require().Error(err) - s.Require().ErrorIs(err, db.ErrNotFound) +func (s *NamespacesSuite) Test_GetNamespace_NotFound() { + testCases := []struct { + name string + input interface{} // Input to GetNamespace - could be ID string or identifier struct + identifierType string // For descriptive error messages + }{ + { + name: "Not Found - Deprecated ID", + input: nonExistentNamespaceID, // Assuming nonExistentNamespaceID is defined in your test suite + identifierType: "Deprecated ID", + }, + { + name: "Not Found - New Identifier ID", + input: &namespaces.GetNamespaceRequest_NamespaceId{NamespaceId: nonExistentNamespaceID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier FQN", + input: &namespaces.GetNamespaceRequest_Fqn{Fqn: "non-existent-namespace-fqn"}, // Example non-existent FQN + identifierType: "FQN", + }, + // Add more test cases here if you want to test other "not found" scenarios + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, tc.input) + s.Require().Error(err, "Expected error when Namespace is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(gotNamespace, "Expected nil Namespace when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when Namespace is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *NamespacesSuite) Test_GetNamespace_InactiveState_Succeeds() { @@ -122,13 +184,6 @@ func (s *NamespacesSuite) Test_GetNamespace_InactiveState_Succeeds() { s.Equal(inactive.Name, got.GetName()) } -func (s *NamespacesSuite) Test_GetNamespace_DoesNotExist_ShouldFail() { - ns, err := s.db.PolicyClient.GetNamespace(s.ctx, nonExistentNamespaceID) - s.Require().Error(err) - s.Require().ErrorIs(err, db.ErrNotFound) - s.Nil(ns) -} - func (s *NamespacesSuite) Test_ListNamespaces_NoPagination_Succeeds() { testData := s.getActiveNamespaceFixtures() diff --git a/service/internal/security/crypto_provider.go b/service/internal/security/crypto_provider.go index 9538d3d6a..8c535fa55 100644 --- a/service/internal/security/crypto_provider.go +++ b/service/internal/security/crypto_provider.go @@ -19,6 +19,7 @@ type CryptoProvider interface { RSAPublicKey(keyID string) (string, error) RSAPublicKeyAsJSON(keyID string) (string, error) RSADecrypt(hash crypto.Hash, keyID string, keyLabel string, ciphertext []byte) ([]byte, error) + ECDecrypt(keyID string, ephemeralPublicKey, ciphertext []byte) ([]byte, error) ECPublicKey(keyID string) (string, error) ECCertificate(keyID string) (string, error) diff --git a/service/internal/security/standard_crypto.go b/service/internal/security/standard_crypto.go index 3fb91fc49..702e421b4 100644 --- a/service/internal/security/standard_crypto.go +++ b/service/internal/security/standard_crypto.go @@ -2,6 +2,7 @@ package security import ( "crypto" + "crypto/ecdh" "crypto/elliptic" "crypto/sha256" "crypto/x509" @@ -60,6 +61,9 @@ type StandardECCrypto struct { KeyPairInfo ecPrivateKeyPem string ecCertificatePEM string + + // Lazily filled in + sk *ecdh.PrivateKey } // List of keys by identifier @@ -427,3 +431,30 @@ func versionSalt() []byte { digest.Write([]byte(kNanoTDFMagicStringAndVersion)) return digest.Sum(nil) } + +// ECDecrypt uses hybrid ECIES to decrypt the data. +func (s *StandardCrypto) ECDecrypt(keyID string, ephemeralPublicKey, ciphertext []byte) ([]byte, error) { + ska, ok := s.keysByID[keyID] + if !ok { + return nil, fmt.Errorf("key [%s] not found", keyID) + } + sk, ok := ska.(StandardECCrypto) + if !ok { + return nil, fmt.Errorf("key [%s] is not an EC key", keyID) + } + if sk.sk == nil { + // Parse the private key + loaded, err := ocrypto.ECPrivateKeyFromPem([]byte(sk.ecPrivateKeyPem)) + if err != nil { + return nil, fmt.Errorf("failed to parse EC private key: %w", err) + } + sk.sk = loaded + } + + ed, err := ocrypto.NewECDecryptor(sk.sk) + if err != nil { + return nil, fmt.Errorf("failed to create EC decryptor: %w", err) + } + + return ed.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey) +} diff --git a/service/kas/access/keyaccess.go b/service/kas/access/keyaccess.go index 69cd7fe21..ab704124c 100644 --- a/service/kas/access/keyaccess.go +++ b/service/kas/access/keyaccess.go @@ -1,14 +1,15 @@ package access type KeyAccess struct { - EncryptedMetadata string `json:"encryptedMetadata,omitempty"` - PolicyBinding interface{} `json:"policyBinding,omitempty"` - Protocol string `json:"protocol"` - Type string `json:"type"` - URL string `json:"url"` - KID string `json:"kid,omitempty"` - SID string `json:"sid,omitempty"` - WrappedKey []byte `json:"wrappedKey,omitempty"` - Header []byte `json:"header,omitempty"` - Algorithm string `json:"algorithm,omitempty"` + EncryptedMetadata string `json:"encryptedMetadata,omitempty"` + PolicyBinding interface{} `json:"policyBinding,omitempty"` + Protocol string `json:"protocol"` + Type string `json:"type"` + URL string `json:"url"` + KID string `json:"kid,omitempty"` + SID string `json:"sid,omitempty"` + WrappedKey []byte `json:"wrappedKey,omitempty"` + Header []byte `json:"header,omitempty"` + Algorithm string `json:"algorithm,omitempty"` + EphemeralPublicKey string `json:"ephemeralPublicKey,omitempty"` } diff --git a/service/kas/access/provider.go b/service/kas/access/provider.go index c417a72a6..c10f71ddd 100644 --- a/service/kas/access/provider.go +++ b/service/kas/access/provider.go @@ -36,6 +36,11 @@ type KASConfig struct { ECCertID string `mapstructure:"eccertid" json:"eccertid"` // Deprecated RSACertID string `mapstructure:"rsacertid" json:"rsacertid"` + + // Enables experimental EC rewrap support in TDFs + // Enabling is required to parse KAOs with the `ec-wrapped` type, + // and (currently) also enables responding with ECIES encrypted responses. + ECTDFEnabled bool `mapstructure:"ec_tdf_enabled" json:"ec_tdf_enabled"` } // Specifies the preferred/default key for a given algorithm type. diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index e376d1039..209a9a27a 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -65,11 +65,16 @@ type entityInfo struct { } type kaoResult struct { - ID string - Key []byte - Error error + ID string + DEK []byte + Encapped []byte + Error error + + // Optional: Present for EC wrapped responses + EphemeralPublicKey []byte } +// From policy ID to KAO ID to result type policyKAOResults map[string]map[string]kaoResult const ( @@ -152,17 +157,21 @@ func extractAndConvertV1SRTBody(body []byte) (kaspb.UnsignedRewrapRequest, error reqs := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{ { KeyAccessObjects: []*kaspb.UnsignedRewrapRequest_WithKeyAccessObject{ - {KeyAccessObjectId: "kao-0", KeyAccessObject: &kaspb.KeyAccess{ - EncryptedMetadata: kao.EncryptedMetadata, - PolicyBinding: &kaspb.PolicyBinding{Hash: binding, Algorithm: kao.Algorithm}, - Protocol: kao.Protocol, - KeyType: kao.Type, - KasUrl: kao.URL, - Kid: kao.KID, - SplitId: kao.SID, - WrappedKey: kao.WrappedKey, - Header: kao.Header, - }}, + { + KeyAccessObjectId: "kao-0", + KeyAccessObject: &kaspb.KeyAccess{ + EncryptedMetadata: kao.EncryptedMetadata, + PolicyBinding: &kaspb.PolicyBinding{Hash: binding, Algorithm: kao.Algorithm}, + Protocol: kao.Protocol, + KeyType: kao.Type, + KasUrl: kao.URL, + Kid: kao.KID, + SplitId: kao.SID, + WrappedKey: kao.WrappedKey, + Header: kao.Header, + EphemeralPublicKey: kao.EphemeralPublicKey, + }, + }, }, Algorithm: requestBody.Algorithm, Policy: &kaspb.UnsignedRewrapRequest_WithPolicy{ @@ -212,16 +221,20 @@ func extractSRTBody(ctx context.Context, headers http.Header, in *kaspb.RewrapRe } var requestBody kaspb.UnsignedRewrapRequest - err = protojson.Unmarshal([]byte(rbString), &requestBody) + err = protojson.UnmarshalOptions{DiscardUnknown: true}.Unmarshal([]byte(rbString), &requestBody) // if there are no requests then it could be a v1 request - if err != nil || len(requestBody.GetRequests()) == 0 { + if err != nil { + logger.WarnContext(ctx, "invalid SRT", "err.v2", err, "srt", rbString) + return nil, false, err400("invalid request body") + } + if len(requestBody.GetRequests()) == 0 { + logger.DebugContext(ctx, "legacy v1 SRT") var errv1 error - requestBody, errv1 = extractAndConvertV1SRTBody([]byte(rbString)) - if errv1 != nil { - logger.WarnContext(ctx, "invalid SRT", "err.v1", errv1, "err.v2", err) + + if requestBody, errv1 = extractAndConvertV1SRTBody([]byte(rbString)); errv1 != nil { + logger.WarnContext(ctx, "invalid SRT", "err.v1", errv1, "srt", rbString, "rewrap.body", requestBody.String()) return nil, false, err400("invalid request body") } - logger.DebugContext(ctx, "legacy v1 SRT", "err.v2", err) isV1 = true } logger.DebugContext(ctx, "extracted request body", slog.String("rewrap.body", requestBody.String()), slog.Any("rewrap.srt", rbString)) @@ -279,9 +292,15 @@ func verifyPolicyBinding(ctx context.Context, policy []byte, kao *kaspb.Unsigned func extractPolicyBinding(policyBinding interface{}) (string, error) { switch v := policyBinding.(type) { case string: + if v == "" { + return "", fmt.Errorf("empty policy binding") + } return v, nil case map[string]interface{}: if hash, ok := v["hash"].(string); ok { + if hash == "" { + return "", fmt.Errorf("empty policy binding hash field") + } return hash, nil } return "", fmt.Errorf("invalid policy binding object, missing 'hash' field") @@ -334,9 +353,9 @@ func addResultsToResponse(response *kaspb.RewrapResponse, result policyKAOResult case kaoRes.Error != nil: kaoResult.Status = kFailedStatus kaoResult.Result = &kaspb.KeyAccessRewrapResult_Error{Error: kaoRes.Error.Error()} - case kaoRes.Key != nil: + case kaoRes.Encapped != nil: kaoResult.Status = kPermitStatus - kaoResult.Result = &kaspb.KeyAccessRewrapResult_KasWrappedKey{KasWrappedKey: kaoRes.Key} + kaoResult.Result = &kaspb.KeyAccessRewrapResult_KasWrappedKey{KasWrappedKey: kaoRes.Encapped} default: kaoResult.Status = kFailedStatus kaoResult.Result = &kaspb.KeyAccessRewrapResult_Error{Error: "kao not processed by kas"} @@ -387,7 +406,7 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap } var results policyKAOResults if len(tdf3Reqs) > 0 { - results = p.tdf3Rewrap(ctx, tdf3Reqs, body.GetClientPublicKey(), entityInfo) + resp.SessionPublicKey, results = p.tdf3Rewrap(ctx, tdf3Reqs, body.GetClientPublicKey(), entityInfo) addResultsToResponse(resp, results) } else { resp.SessionPublicKey, results = p.nanoTDFRewrap(ctx, nanoReqs, body.GetClientPublicKey(), entityInfo) @@ -396,21 +415,24 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap if isV1 { if len(results) != 1 { - return nil, fmt.Errorf("invalid request") + p.Logger.WarnContext(ctx, "400 due to wrong result set size", "results", results) + return nil, err400("invalid request") } kaoResults := *getMapValue(results) if len(kaoResults) != 1 { - return nil, fmt.Errorf("invalid request") + p.Logger.WarnContext(ctx, "400 due to wrong result set size", "kaoResults", kaoResults, "results", results) + return nil, err400("invalid request") } kao := *getMapValue(kaoResults) if kao.Error != nil { + p.Logger.DebugContext(ctx, "forwarding legacy err", "err", err) return nil, kao.Error } - resp.EntityWrappedKey = kao.Key //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility + resp.EntityWrappedKey = kao.Encapped //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility } - return connect.NewResponse(resp), err + return connect.NewResponse(resp), nil } func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.UnsignedRewrapRequest_WithPolicyRequest) (*Policy, map[string]kaoResult, error) { @@ -431,30 +453,84 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned failedKAORewrap(results, kao, err400("bad request")) continue } - var kidsToCheck []string - if kao.GetKeyAccessObject().GetKid() != "" { - kidsToCheck = []string{kao.GetKeyAccessObject().GetKid()} - } else { - p.Logger.InfoContext(ctx, "kid free kao") - for _, k := range p.KASConfig.Keyring { - if k.Algorithm == security.AlgorithmRSA2048 && k.Legacy { - kidsToCheck = append(kidsToCheck, k.KID) - } - } - if len(kidsToCheck) == 0 { - p.Logger.WarnContext(ctx, "failure to find legacy kids for rsa") + + var symKey []byte + var err error + switch kao.GetKeyAccessObject().GetKeyType() { + case "ec-wrapped": + + if !p.KASConfig.ECTDFEnabled { + p.Logger.WarnContext(ctx, "ec-wrapped not enabled") failedKAORewrap(results, kao, err400("bad request")) continue } - } - symKey, err := p.CryptoProvider.RSADecrypt(crypto.SHA1, kidsToCheck[0], "", kao.GetKeyAccessObject().GetWrappedKey()) - for _, kid := range kidsToCheck[1:] { - p.Logger.WarnContext(ctx, "continue paging through legacy KIDs for kid free kao", "err", err) - if err == nil { - break + // Get the ephemeral public key in PEM format + ephemeralPubKeyPEM := kao.GetKeyAccessObject().GetEphemeralPublicKey() + + // Get EC key size and convert to mode + keySize, err := ocrypto.GetECKeySize([]byte(ephemeralPubKeyPEM)) + if err != nil { + return nil, results, fmt.Errorf("failed to get EC key size: %w", err) + } + + mode, err := ocrypto.ECSizeToMode(keySize) + if err != nil { + return nil, results, fmt.Errorf("failed to convert key size to mode: %w", err) + } + + // Parse the PEM public key + block, _ := pem.Decode([]byte(ephemeralPubKeyPEM)) + if block == nil { + return nil, results, fmt.Errorf("failed to decode PEM block") + } + + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, results, fmt.Errorf("failed to parse public key: %w", err) + } + + ecPub, ok := pub.(*ecdsa.PublicKey) + if !ok { + return nil, results, fmt.Errorf("not an EC public key") + } + + // Compress the public key + compressedKey, err := ocrypto.CompressedECPublicKey(mode, *ecPub) + if err != nil { + return nil, results, fmt.Errorf("failed to compress public key: %w", err) + } + + symKey, err = p.CryptoProvider.ECDecrypt(kao.GetKeyAccessObject().GetKid(), compressedKey, kao.GetKeyAccessObject().GetWrappedKey()) + if err != nil { + return nil, results, fmt.Errorf("failed to decrypt EC key: %w", err) + } + case "wrapped": + var kidsToCheck []string + if kao.GetKeyAccessObject().GetKid() != "" { + kidsToCheck = []string{kao.GetKeyAccessObject().GetKid()} + } else { + p.Logger.InfoContext(ctx, "kid free kao") + for _, k := range p.KASConfig.Keyring { + if k.Algorithm == security.AlgorithmRSA2048 && k.Legacy { + kidsToCheck = append(kidsToCheck, k.KID) + } + } + if len(kidsToCheck) == 0 { + p.Logger.WarnContext(ctx, "failure to find legacy kids for rsa") + failedKAORewrap(results, kao, err400("bad request")) + continue + } + } + + symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kidsToCheck[0], "", kao.GetKeyAccessObject().GetWrappedKey()) + for _, kid := range kidsToCheck[1:] { + p.Logger.WarnContext(ctx, "continue paging through legacy KIDs for kid free kao", "err", err) + if err == nil { + break + } + symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kid, "", kao.GetKeyAccessObject().GetWrappedKey()) } - symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kid, "", kao.GetKeyAccessObject().GetWrappedKey()) } if err != nil { p.Logger.WarnContext(ctx, "failure to decrypt dek", "err", err) @@ -462,14 +538,13 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned continue } - err = verifyPolicyBinding(ctx, []byte(req.GetPolicy().GetBody()), kao, symKey, *p.Logger) - if err != nil { + if err := verifyPolicyBinding(ctx, []byte(req.GetPolicy().GetBody()), kao, symKey, *p.Logger); err != nil { failedKAORewrap(results, kao, err) continue } results[kao.GetKeyAccessObjectId()] = kaoResult{ ID: kao.GetKeyAccessObjectId(), - Key: symKey, + DEK: symKey, } anyValidKAOs = true @@ -487,7 +562,7 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned return policy, results, nil } -func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) policyKAOResults { +func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) (string, policyKAOResults) { if p.Tracer != nil { var span trace.Span ctx, span = p.Tracer.Start(ctx, "rewrap-tdf3") @@ -499,8 +574,11 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew policyReqs := make(map[*Policy]*kaspb.UnsignedRewrapRequest_WithPolicyRequest) for _, req := range requests { policy, kaoResults, err := p.verifyRewrapRequests(ctx, req) - results[req.GetPolicy().GetId()] = kaoResults + policyID := req.GetPolicy().GetId() + results[policyID] = kaoResults if err != nil { + p.Logger.WarnContext(ctx, "rewrap: verifyRewrapRequests failed", "err", err, "policyID", policyID) + // TODO Fail all requests for this policy continue } policies = append(policies, policy) @@ -513,20 +591,44 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew } pdpAccessResults, accessErr := p.canAccess(ctx, tok, policies) if accessErr != nil { + p.Logger.DebugContext(ctx, "tdf3rewrap: cannot access policy", "err", accessErr, "policies", policies) failAllKaos(requests, results, err403("could not perform access")) - return results + return "", results } - asymEncrypt, err := ocrypto.NewAsymEncryption(clientPublicKey) + asymEncrypt, err := ocrypto.FromPublicPEM(clientPublicKey) if err != nil { p.Logger.WarnContext(ctx, "ocrypto.NewAsymEncryption:", "err", err) + failAllKaos(requests, results, err400("invalid request")) + return "", results + } + + var sessionKey string + if e, ok := asymEncrypt.(ocrypto.ECEncryptor); ok { + sessionKey, err = e.PublicKeyInPemFormat() + if err != nil { + p.Logger.ErrorContext(ctx, "unable to serialize ephemeral key", "err", err) + // This may be a 500, but could also be caused by a bad clientPublicKey + failAllKaos(requests, results, err400("invalid request")) + return "", results + } + if !p.KASConfig.ECTDFEnabled { + p.Logger.ErrorContext(ctx, "ec rewrap not enabled") + failAllKaos(requests, results, err400("invalid request")) + return "", results + } } for _, pdpAccess := range pdpAccessResults { policy := pdpAccess.Policy req, ok := policyReqs[policy] - kaoResults := results[req.GetPolicy().GetId()] + if !ok { + p.Logger.WarnContext(ctx, "policy not found in policyReqs", "policy.uuid", policy.UUID) + continue + } + kaoResults, ok := results[req.GetPolicy().GetId()] if !ok { // this should not happen + p.Logger.WarnContext(ctx, "policy not found in policyReq response", "policy.uuid", policy.UUID) continue } access := pdpAccess.Access @@ -535,7 +637,8 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew kasPolicy := ConvertToAuditKasPolicy(*policy) for _, kao := range req.GetKeyAccessObjects() { - kaoRes := kaoResults[kao.GetKeyAccessObjectId()] + kaoID := kao.GetKeyAccessObjectId() + kaoRes := kaoResults[kaoID] if kaoRes.Error != nil { continue } @@ -555,22 +658,23 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew continue } - rewrappedKey, err := asymEncrypt.Encrypt(kaoRes.Key) + rewrappedKey, err := asymEncrypt.Encrypt(kaoRes.DEK) if err != nil { p.Logger.WarnContext(ctx, "rewrap: ocrypto.AsymEncryption.encrypt failed", "err", err, "clientPublicKey", clientPublicKey) p.Logger.Audit.RewrapFailure(ctx, auditEventParams) failedKAORewrap(kaoResults, kao, err400("bad key for rewrap")) continue } - kaoResults[kao.GetKeyAccessObjectId()] = kaoResult{ - ID: kao.GetKeyAccessObjectId(), - Key: rewrappedKey, + kaoResults[kaoID] = kaoResult{ + ID: kaoID, + Encapped: rewrappedKey, + EphemeralPublicKey: asymEncrypt.EphemeralKey(), } p.Logger.Audit.RewrapSuccess(ctx, auditEventParams) } } - return results + return sessionKey, results } func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) (string, policyKAOResults) { @@ -645,7 +749,7 @@ func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.Unsigned failedKAORewrap(kaoResults, kao, err403("forbidden")) continue } - cipherText, err := wrapKeyAES(sessionKey, kaoInfo.Key) + cipherText, err := wrapKeyAES(sessionKey, kaoInfo.DEK) if err != nil { p.Logger.Audit.RewrapFailure(ctx, auditEventParams) failedKAORewrap(kaoResults, kao, err403("forbidden")) @@ -653,8 +757,8 @@ func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.Unsigned } kaoResults[kao.GetKeyAccessObjectId()] = kaoResult{ - ID: kao.GetKeyAccessObjectId(), - Key: cipherText, + ID: kao.GetKeyAccessObjectId(), + Encapped: cipherText, } p.Logger.Audit.RewrapSuccess(ctx, auditEventParams) @@ -725,7 +829,7 @@ func (p *Provider) verifyNanoRewrapRequests(ctx context.Context, req *kaspb.Unsi } results[kao.GetKeyAccessObjectId()] = kaoResult{ ID: kao.GetKeyAccessObjectId(), - Key: symmetricKey, + DEK: symmetricKey, } return policy, results } diff --git a/service/kas/kas.proto b/service/kas/kas.proto index 312540360..72b8913e7 100644 --- a/service/kas/kas.proto +++ b/service/kas/kas.proto @@ -33,7 +33,7 @@ message LegacyPublicKeyRequest { message PolicyBinding { string algorithm = 1 [json_name = "alg"]; - string hash = 2; + string hash = 2; } message KeyAccess { @@ -45,8 +45,12 @@ message KeyAccess { string kid = 6; string split_id = 7 [json_name = "sid"]; bytes wrapped_key = 8; - // header is only used for NanoTDFs + // header is only used for NanoTDFs bytes header = 9; + + // For wrapping with an ECDH derived key, when type=ec-wrapped. + // Should be a PEM-encoded PKCS#8 (asn.1) value. + string ephemeral_public_key = 10; } message UnsignedRewrapRequest { @@ -67,6 +71,13 @@ message UnsignedRewrapRequest { string client_public_key = 1; repeated WithPolicyRequest requests = 2; + + // Used for legacy non-bulk requests + KeyAccess key_access = 3 [deprecated = true]; + // Used for legacy non-bulk requests + string policy = 4 [deprecated = true]; + // Used for legacy non-bulk requests + string algorithm = 5 [deprecated = true]; } message PublicKeyRequest { string algorithm = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "algorithm type rsa: or ec:"}]; @@ -106,8 +117,8 @@ message RewrapResponse { bytes entity_wrapped_key = 2 [deprecated = true]; string session_public_key = 3; string schema_version = 4 [deprecated = true]; - // New Rewrap API changes - repeated PolicyRewrapResult responses = 5; + // New Rewrap API changes + repeated PolicyRewrapResult responses = 5; } // Get app info from the root path diff --git a/service/pkg/db/errors.go b/service/pkg/db/errors.go index c848483a5..dafd3b975 100644 --- a/service/pkg/db/errors.go +++ b/service/pkg/db/errors.go @@ -25,6 +25,8 @@ var ( ErrTxBeginFailed = errors.New("ErrTxBeginFailed: failed to begin DB transaction") ErrTxRollbackFailed = errors.New("ErrTxRollbackFailed: failed to rollback DB transaction") ErrTxCommitFailed = errors.New("ErrTxCommitFailed: failed to commit DB transaction") + ErrSelectIdentifierInvalid = errors.New("ErrSelectIdentifierInvalid: invalid identifier value for select query") + ErrUnknownSelectIdentifier = errors.New("ErrUnknownSelectIdentifier: unknown identifier type for select query") ) // Get helpful error message for PostgreSQL violation @@ -102,6 +104,8 @@ const ( ErrTextRestrictViolation = "intended action would violate a restriction" ErrTextFqnMissingValue = "FQN must specify a valid value and be of format 'https:///attr//value/'" ErrTextListLimitTooLarge = "requested pagination limit must be less than or equal to configured limit" + ErrTextInvalidIdentifier = "value sepcified as the identifier is invalid" + ErrorTextUnknownIdentifier = "could not match identifier to known type" ) func StatusifyError(err error, fallbackErr string, log ...any) error { @@ -134,6 +138,14 @@ func StatusifyError(err error, fallbackErr string, log ...any) error { slog.Error(ErrTextListLimitTooLarge, l...) return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextListLimitTooLarge)) } + if errors.Is(err, ErrSelectIdentifierInvalid) { + slog.Error(ErrTextInvalidIdentifier, l...) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextInvalidIdentifier)) + } + if errors.Is(err, ErrUnknownSelectIdentifier) { + slog.Error(ErrorTextUnknownIdentifier, l...) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrorTextUnknownIdentifier)) + } slog.Error(err.Error(), l...) return connect.NewError(connect.CodeInternal, errors.New(fallbackErr)) } diff --git a/service/pkg/server/start.go b/service/pkg/server/start.go index bc3a80255..5056bbdbd 100644 --- a/service/pkg/server/start.go +++ b/service/pkg/server/start.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "os/signal" + "slices" "syscall" "github.com/opentdf/platform/lib/ocrypto" @@ -23,7 +24,6 @@ import ( "github.com/opentdf/platform/service/pkg/serviceregistry" "github.com/opentdf/platform/service/tracing" wellknown "github.com/opentdf/platform/service/wellknownconfiguration" - "golang.org/x/exp/slices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 287210518..828c487f8 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -105,9 +105,17 @@ func (s *AttributesService) GetAttribute(ctx context.Context, rsp := &attributes.GetAttributeResponse{} - item, err := s.dbClient.GetAttribute(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + item, err := s.dbClient.GetAttribute(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Attribute = item @@ -248,9 +256,17 @@ func (s *AttributesService) ListAttributeValues(ctx context.Context, req *connec func (s *AttributesService) GetAttributeValue(ctx context.Context, req *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { rsp := &attributes.GetAttributeValueResponse{} - item, err := s.dbClient.GetAttributeValue(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + item, err := s.dbClient.GetAttributeValue(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Value = item diff --git a/service/policy/attributes/attributes.proto b/service/policy/attributes/attributes.proto index 42f01708d..f7b614ca5 100644 --- a/service/policy/attributes/attributes.proto +++ b/service/policy/attributes/attributes.proto @@ -86,10 +86,38 @@ message ListAttributesResponse { } message GetAttributeRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.attribute_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'attribute_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.attribute_id) || has(this.fqn)", + message: "Either id or one of attribute_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true - ]; + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string attribute_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } message GetAttributeResponse { policy.Attribute attribute = 1; @@ -167,10 +195,39 @@ message DeactivateAttributeResponse { /// Value RPC messages /// message GetAttributeValueRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.value_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'value_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.value_id) || has(this.fqn)", + message: "Either id or one of value_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true - ]; + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string value_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } + } message GetAttributeValueResponse { policy.Value value = 1; diff --git a/service/policy/attributes/attributes_test.go b/service/policy/attributes/attributes_test.go index 7cf1f9d3f..075678bca 100644 --- a/service/policy/attributes/attributes_test.go +++ b/service/policy/attributes/attributes_test.go @@ -29,6 +29,10 @@ const ( errMessageAttrNameFormat = "attribute_name_format" errMessageAttrValueFormat = "attribute_value_format" errMessageRequired = "required" + errMessageMinLen = "string.min_len" + errMessageURI = "string.uri" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" ) // Create Attributes (definitions) @@ -233,17 +237,118 @@ func TestAttributeKeyAccessServer_Fails(t *testing.T) { } } -func TestGetAttributeRequest(t *testing.T) { - req := &attributes.GetAttributeRequest{} - err := getValidator().Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetAttributeRequest(t *testing.T) { + testCases := []struct { + name string + req *attributes.GetAttributeRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid AttributeId in Identifier (empty string)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid AttributeId in Identifier (invalid UUID)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &attributes.GetAttributeRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &attributes.GetAttributeRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Valid AttributeId in Identifier", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid FQN Identifier", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "https://example.com/valid_fqn", + }, + }, + expectError: false, + }, + { + name: "Invalid FQN Identifier (missing scheme)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "example.com/valid_fqn", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid FQN Identifier (empty string)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &attributes.GetAttributeRequest{ + Id: validUUID, + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "https://example.com/valid_fqn", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &attributes.GetAttributeRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req = &attributes.GetAttributeRequest{ - Id: validUUID, + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) } - err = getValidator().Validate(req) - require.NoError(t, err) } func TestUpdateAttributeRequest(t *testing.T) { @@ -401,17 +506,118 @@ func TestValueKeyAccessServer_Fails(t *testing.T) { } } -func TestGetAttributeValueRequest(t *testing.T) { - req := &attributes.GetAttributeValueRequest{} - err := getValidator().Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetAttributeValueRequest(t *testing.T) { + testCases := []struct { + name string + req *attributes.GetAttributeValueRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid ValueId in Identifier (empty string)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid ValueId in Identifier (invalid UUID)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &attributes.GetAttributeValueRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &attributes.GetAttributeValueRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Valid ValueId in Identifier", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid FQN Identifier", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "https://example.com/valid_fqn_value", + }, + }, + expectError: false, + }, + { + name: "Invalid FQN Identifier (missing scheme)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "example.com/valid_fqn_value", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid FQN Identifier (empty string)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &attributes.GetAttributeValueRequest{ + Id: validUUID, + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "https://example.com/valid_fqn_value", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &attributes.GetAttributeValueRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req = &attributes.GetAttributeValueRequest{ - Id: validUUID, + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) } - err = getValidator().Validate(req) - require.NoError(t, err) } func TestListAttributeValuesRequest(t *testing.T) { diff --git a/service/policy/db/attribute_values.go b/service/policy/db/attribute_values.go index 6f6af26cb..22ac86fa2 100644 --- a/service/policy/db/attribute_values.go +++ b/service/policy/db/attribute_values.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -41,8 +42,38 @@ func (c PolicyDBClient) CreateAttributeValue(ctx context.Context, attributeID st return c.GetAttributeValue(ctx, createdID) } -func (c PolicyDBClient) GetAttributeValue(ctx context.Context, id string) (*policy.Value, error) { - av, err := c.Queries.GetAttributeValue(ctx, id) +func (c PolicyDBClient) GetAttributeValue(ctx context.Context, identifier any) (*policy.Value, error) { + var ( + av GetAttributeValueRow + err error + params GetAttributeValueParams + ) + + switch i := identifier.(type) { + case *attributes.GetAttributeValueRequest_ValueId: + id := pgtypeUUID(i.ValueId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeValueParams{ID: id} + case *attributes.GetAttributeValueRequest_Fqn: + fqn := pgtypeText(i.Fqn) + if !fqn.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetAttributeValueParams{Fqn: fqn} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeValueParams{ID: pgtypeUUID(i)} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + av, err = c.Queries.GetAttributeValue(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } diff --git a/service/policy/db/attributes.go b/service/policy/db/attributes.go index d6c76a9c6..087ae7461 100644 --- a/service/policy/db/attributes.go +++ b/service/policy/db/attributes.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "encoding/json" + "errors" "fmt" "strings" @@ -218,8 +219,38 @@ func (c PolicyDBClient) ListAllAttributes(ctx context.Context) ([]*policy.Attrib return attrsList, nil } -func (c PolicyDBClient) GetAttribute(ctx context.Context, id string) (*policy.Attribute, error) { - attr, err := c.Queries.GetAttribute(ctx, id) +func (c PolicyDBClient) GetAttribute(ctx context.Context, identifier any) (*policy.Attribute, error) { + var ( + attr GetAttributeRow + err error + params GetAttributeParams + ) + + switch i := identifier.(type) { + case *attributes.GetAttributeRequest_AttributeId: + id := pgtypeUUID(i.AttributeId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeParams{ID: id} + case *attributes.GetAttributeRequest_Fqn: + fqn := pgtypeText(i.Fqn) + if !fqn.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetAttributeParams{Fqn: pgtypeText(i.Fqn)} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrSelectIdentifierInvalid, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + attr, err = c.Queries.GetAttribute(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } diff --git a/service/policy/db/key_access_server_registry.go b/service/policy/db/key_access_server_registry.go index d089cea7f..038ff57dc 100644 --- a/service/policy/db/key_access_server_registry.go +++ b/service/policy/db/key_access_server_registry.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "strings" @@ -72,8 +73,44 @@ func (c PolicyDBClient) ListKeyAccessServers(ctx context.Context, r *kasregistry }, nil } -func (c PolicyDBClient) GetKeyAccessServer(ctx context.Context, id string) (*policy.KeyAccessServer, error) { - kas, err := c.Queries.GetKeyAccessServer(ctx, id) +func (c PolicyDBClient) GetKeyAccessServer(ctx context.Context, identifier any) (*policy.KeyAccessServer, error) { + var ( + kas GetKeyAccessServerRow + err error + params GetKeyAccessServerParams + ) + + switch i := identifier.(type) { + case *kasregistry.GetKeyAccessServerRequest_KasId: + id := pgtypeUUID(i.KasId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetKeyAccessServerParams{ID: id} + case *kasregistry.GetKeyAccessServerRequest_Name: + name := pgtypeText(i.Name) + if !name.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetKeyAccessServerParams{Name: name} + case *kasregistry.GetKeyAccessServerRequest_Uri: + uri := pgtypeText(i.Uri) + if !uri.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetKeyAccessServerParams{Uri: uri} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetKeyAccessServerParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + kas, err = c.Queries.GetKeyAccessServer(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } @@ -287,7 +324,11 @@ func (c PolicyDBClient) CreatePublicKey(ctx context.Context, r *kasregistry.Crea } // Get freshly created key - ck, err = txClient.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + ck, err = txClient.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: id, + }, + }) if err != nil { return db.WrapIfKnownInvalidQueryErr(err) } @@ -352,11 +393,11 @@ func (c PolicyDBClient) ListPublicKeys(ctx context.Context, r *kasregistry.ListP } params := listPublicKeysParams{ - KasID: r.GetKasId(), - // KasUri: r.GetKasUri(), - // KasName: r.GetKasName(), - Offset: offset, - Limit: limit, + KasID: r.GetKasId(), + KasUri: r.GetKasUri(), + KasName: r.GetKasName(), + Offset: offset, + Limit: limit, } listRows, err := c.Queries.listPublicKeys(ctx, params) if err != nil { @@ -411,9 +452,9 @@ func (c PolicyDBClient) ListPublicKeyMappings(ctx context.Context, r *kasregistr } params := listPublicKeyMappingsParams{ - KasID: r.GetKasId(), - // KasUri: r.GetKasUri(), - // KasName: r.GetKasName(), + KasID: r.GetKasId(), + KasUri: r.GetKasUri(), + KasName: r.GetKasName(), PublicKeyID: r.GetPublicKeyId(), Offset: offset, Limit: limit, @@ -455,7 +496,11 @@ func (c PolicyDBClient) UpdatePublicKey(ctx context.Context, r *kasregistry.Upda keyID := r.GetId() mdJSON, metadata, err := db.MarshalUpdateMetadata(r.GetMetadata(), r.GetMetadataUpdateBehavior(), func() (*common.Metadata, error) { - k, err := c.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{Id: keyID}) + k, err := c.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: keyID, + }, + }) if err != nil { return nil, err } diff --git a/service/policy/db/namespaces.go b/service/policy/db/namespaces.go index b3dbb8ac3..7bb94b24c 100644 --- a/service/policy/db/namespaces.go +++ b/service/policy/db/namespaces.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -14,8 +15,34 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -func (c PolicyDBClient) GetNamespace(ctx context.Context, id string) (*policy.Namespace, error) { - ns, err := c.Queries.GetNamespace(ctx, id) +func (c PolicyDBClient) GetNamespace(ctx context.Context, identifier any) (*policy.Namespace, error) { + var ( + ns GetNamespaceRow + err error + params GetNamespaceParams + ) + + switch i := identifier.(type) { + case *namespaces.GetNamespaceRequest_NamespaceId: + id := pgtypeUUID(i.NamespaceId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetNamespaceParams{ID: id} + case *namespaces.GetNamespaceRequest_Fqn: + params = GetNamespaceParams{Name: pgtypeText(i.Fqn)} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetNamespaceParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + ns, err = c.Queries.GetNamespace(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } @@ -44,7 +71,7 @@ func (c PolicyDBClient) GetNamespace(ctx context.Context, id string) (*policy.Na } return &policy.Namespace{ - Id: id, + Id: ns.ID, Name: ns.Name, Active: &wrapperspb.BoolValue{Value: ns.Active}, Grants: grants, diff --git a/service/policy/db/query.sql b/service/policy/db/query.sql index 03d700ee5..17fb3c83e 100644 --- a/service/policy/db/query.sql +++ b/service/policy/db/query.sql @@ -87,13 +87,15 @@ OFFSET @offset_; -- name: GetKeyAccessServer :one SELECT - id, - uri, - public_key, - name, + kas.id, + kas.uri, + kas.public_key, + kas.name, JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -FROM key_access_servers -WHERE id = $1; +FROM key_access_servers AS kas +WHERE (sqlc.narg('id')::uuid IS NULL OR kas.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('name')::text IS NULL OR kas.name = sqlc.narg('name')::text) + AND (sqlc.narg('uri')::text IS NULL OR kas.uri = sqlc.narg('uri')::text); -- name: CreateKeyAccessServer :one INSERT INTO key_access_servers (uri, public_key, name, metadata) @@ -490,7 +492,8 @@ LEFT JOIN attribute_definition_key_access_grants adkag ON adkag.attribute_defini LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -WHERE ad.id = $1 +WHERE (sqlc.narg('id')::uuid IS NULL OR ad.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('fqn')::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE(sqlc.narg('fqn')::text, '^https?://', '')) GROUP BY ad.id, n.name, fqns.fqn, k.keys; -- name: CreateAttribute :one @@ -569,7 +572,8 @@ LEFT JOIN attribute_fqns fqns ON av.id = fqns.value_id LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -WHERE av.id = $1 +WHERE (sqlc.narg('id')::uuid IS NULL OR av.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('fqn')::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE(sqlc.narg('fqn')::text, '^https?://', '')) GROUP BY av.id, fqns.fqn, k.keys; -- name: CreateAttributeValue :one @@ -765,7 +769,9 @@ LEFT JOIN attribute_namespace_key_access_grants kas_ns_grants ON kas_ns_grants.n LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL + AND (sqlc.narg('id')::uuid IS NULL OR ns.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('name')::text IS NULL OR ns.name = REGEXP_REPLACE(sqlc.narg('name')::text, '^https?://', '')) GROUP BY ns.id, fqns.fqn, k.keys; -- name: CreateNamespace :one @@ -958,8 +964,11 @@ WHERE k.id = $1; -- name: listPublicKeys :many WITH counted AS ( - SELECT COUNT(k.id) AS total FROM public_keys AS k - WHERE (NULLIF(@kas_id, '') IS NULL OR k.key_access_server_id = @kas_id::uuid) + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id + WHERE (NULLIF(@kas_id, '') IS NULL OR kas.id = @kas_id::uuid) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) ) SELECT @@ -980,13 +989,18 @@ CROSS JOIN counted WHERE ( NULLIF(@kas_id, '') IS NULL OR k.key_access_server_id = @kas_id::uuid ) +AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) +AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) LIMIT @limit_ OFFSET @offset_; -- name: listPublicKeyMappings :many WITH counted AS ( - SELECT COUNT(pk.id) AS total FROM public_keys AS pk + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE (NULLIF(@kas_id, '') IS NULL OR pk.key_access_server_id = @kas_id::uuid) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) AND ( NULLIF(@public_key_id, '') IS NULL OR pk.id = @public_key_id::uuid ) ), base_keys AS ( @@ -1003,6 +1017,8 @@ base_keys AS ( FROM public_keys pk JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE ( NULLIF(@kas_id, '') IS NULL OR kas.id = @kas_id::uuid ) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) AND ( NULLIF(@public_key_id, '') IS NULL OR pk.id = @public_key_id::uuid ) ), namespace_mappings AS ( diff --git a/service/policy/db/query.sql.go b/service/policy/db/query.sql.go index fcb009d56..2da4cb511 100644 --- a/service/policy/db/query.sql.go +++ b/service/policy/db/query.sql.go @@ -487,10 +487,16 @@ LEFT JOIN attribute_definition_key_access_grants adkag ON adkag.attribute_defini LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -WHERE ad.id = $1 +WHERE ($1::uuid IS NULL OR ad.id = $1::uuid) + AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY ad.id, n.name, fqns.fqn, k.keys ` +type GetAttributeParams struct { + ID pgtype.UUID `json:"id"` + Fqn pgtype.Text `json:"fqn"` +} + type GetAttributeRow struct { ID string `json:"id"` AttributeName string `json:"attribute_name"` @@ -551,10 +557,11 @@ type GetAttributeRow struct { // LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id // LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL // LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -// WHERE ad.id = $1 +// WHERE ($1::uuid IS NULL OR ad.id = $1::uuid) +// AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY ad.id, n.name, fqns.fqn, k.keys -func (q *Queries) GetAttribute(ctx context.Context, id string) (GetAttributeRow, error) { - row := q.db.QueryRow(ctx, getAttribute, id) +func (q *Queries) GetAttribute(ctx context.Context, arg GetAttributeParams) (GetAttributeRow, error) { + row := q.db.QueryRow(ctx, getAttribute, arg.ID, arg.Fqn) var i GetAttributeRow err := row.Scan( &i.ID, @@ -594,10 +601,16 @@ LEFT JOIN attribute_fqns fqns ON av.id = fqns.value_id LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -WHERE av.id = $1 +WHERE ($1::uuid IS NULL OR av.id = $1::uuid) + AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY av.id, fqns.fqn, k.keys ` +type GetAttributeValueParams struct { + ID pgtype.UUID `json:"id"` + Fqn pgtype.Text `json:"fqn"` +} + type GetAttributeValueRow struct { ID string `json:"id"` Value string `json:"value"` @@ -632,10 +645,11 @@ type GetAttributeValueRow struct { // LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id // LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id // LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -// WHERE av.id = $1 +// WHERE ($1::uuid IS NULL OR av.id = $1::uuid) +// AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY av.id, fqns.fqn, k.keys -func (q *Queries) GetAttributeValue(ctx context.Context, id string) (GetAttributeValueRow, error) { - row := q.db.QueryRow(ctx, getAttributeValue, id) +func (q *Queries) GetAttributeValue(ctx context.Context, arg GetAttributeValueParams) (GetAttributeValueRow, error) { + row := q.db.QueryRow(ctx, getAttributeValue, arg.ID, arg.Fqn) var i GetAttributeValueRow err := row.Scan( &i.ID, @@ -652,15 +666,23 @@ func (q *Queries) GetAttributeValue(ctx context.Context, id string) (GetAttribut const getKeyAccessServer = `-- name: GetKeyAccessServer :one SELECT - id, - uri, - public_key, - name, + kas.id, + kas.uri, + kas.public_key, + kas.name, JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -FROM key_access_servers -WHERE id = $1 +FROM key_access_servers AS kas +WHERE ($1::uuid IS NULL OR kas.id = $1::uuid) + AND ($2::text IS NULL OR kas.name = $2::text) + AND ($3::text IS NULL OR kas.uri = $3::text) ` +type GetKeyAccessServerParams struct { + ID pgtype.UUID `json:"id"` + Name pgtype.Text `json:"name"` + Uri pgtype.Text `json:"uri"` +} + type GetKeyAccessServerRow struct { ID string `json:"id"` Uri string `json:"uri"` @@ -672,15 +694,17 @@ type GetKeyAccessServerRow struct { // GetKeyAccessServer // // SELECT -// id, -// uri, -// public_key, -// name, +// kas.id, +// kas.uri, +// kas.public_key, +// kas.name, // JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -// FROM key_access_servers -// WHERE id = $1 -func (q *Queries) GetKeyAccessServer(ctx context.Context, id string) (GetKeyAccessServerRow, error) { - row := q.db.QueryRow(ctx, getKeyAccessServer, id) +// FROM key_access_servers AS kas +// WHERE ($1::uuid IS NULL OR kas.id = $1::uuid) +// AND ($2::text IS NULL OR kas.name = $2::text) +// AND ($3::text IS NULL OR kas.uri = $3::text) +func (q *Queries) GetKeyAccessServer(ctx context.Context, arg GetKeyAccessServerParams) (GetKeyAccessServerRow, error) { + row := q.db.QueryRow(ctx, getKeyAccessServer, arg.ID, arg.Name, arg.Uri) var i GetKeyAccessServerRow err := row.Scan( &i.ID, @@ -711,10 +735,17 @@ LEFT JOIN attribute_namespace_key_access_grants kas_ns_grants ON kas_ns_grants.n LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL + AND ($1::uuid IS NULL OR ns.id = $1::uuid) + AND ($2::text IS NULL OR ns.name = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY ns.id, fqns.fqn, k.keys ` +type GetNamespaceParams struct { + ID pgtype.UUID `json:"id"` + Name pgtype.Text `json:"name"` +} + type GetNamespaceRow struct { ID string `json:"id"` Name string `json:"name"` @@ -745,10 +776,12 @@ type GetNamespaceRow struct { // LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id // LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id // LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -// WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +// WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL +// AND ($1::uuid IS NULL OR ns.id = $1::uuid) +// AND ($2::text IS NULL OR ns.name = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY ns.id, fqns.fqn, k.keys -func (q *Queries) GetNamespace(ctx context.Context, id string) (GetNamespaceRow, error) { - row := q.db.QueryRow(ctx, getNamespace, id) +func (q *Queries) GetNamespace(ctx context.Context, arg GetNamespaceParams) (GetNamespaceRow, error) { + row := q.db.QueryRow(ctx, getNamespace, arg.ID, arg.Name) var i GetNamespaceRow err := row.Scan( &i.ID, @@ -3371,9 +3404,12 @@ func (q *Queries) getPublicKey(ctx context.Context, id string) (getPublicKeyRow, const listPublicKeyMappings = `-- name: listPublicKeyMappings :many WITH counted AS ( - SELECT COUNT(pk.id) AS total FROM public_keys AS pk + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE (NULLIF($3, '') IS NULL OR pk.key_access_server_id = $3::uuid) - AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) + AND (NULLIF($4, '') IS NULL OR kas.name = $4) + AND (NULLIF($5, '') IS NULL OR kas.uri = $5) + AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) ), base_keys AS ( SELECT @@ -3389,7 +3425,9 @@ base_keys AS ( FROM public_keys pk JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE ( NULLIF($3, '') IS NULL OR kas.id = $3::uuid ) - AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) + AND (NULLIF($4, '') IS NULL OR kas.name = $4) + AND (NULLIF($5, '') IS NULL OR kas.uri = $5) + AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) ), namespace_mappings AS ( SELECT @@ -3480,6 +3518,8 @@ type listPublicKeyMappingsParams struct { Offset int32 `json:"offset_"` Limit int32 `json:"limit_"` KasID interface{} `json:"kas_id"` + KasName interface{} `json:"kas_name"` + KasUri interface{} `json:"kas_uri"` PublicKeyID interface{} `json:"public_key_id"` } @@ -3491,9 +3531,12 @@ type listPublicKeyMappingsRow struct { // listPublicKeyMappings // // WITH counted AS ( -// SELECT COUNT(pk.id) AS total FROM public_keys AS pk +// SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk +// JOIN key_access_servers kas ON pk.key_access_server_id = kas.id // WHERE (NULLIF($3, '') IS NULL OR pk.key_access_server_id = $3::uuid) -// AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) +// AND (NULLIF($4, '') IS NULL OR kas.name = $4) +// AND (NULLIF($5, '') IS NULL OR kas.uri = $5) +// AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) // ), // base_keys AS ( // SELECT @@ -3509,7 +3552,9 @@ type listPublicKeyMappingsRow struct { // FROM public_keys pk // JOIN key_access_servers kas ON pk.key_access_server_id = kas.id // WHERE ( NULLIF($3, '') IS NULL OR kas.id = $3::uuid ) -// AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) +// AND (NULLIF($4, '') IS NULL OR kas.name = $4) +// AND (NULLIF($5, '') IS NULL OR kas.uri = $5) +// AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) // ), // namespace_mappings AS ( // SELECT @@ -3599,6 +3644,8 @@ func (q *Queries) listPublicKeyMappings(ctx context.Context, arg listPublicKeyMa arg.Offset, arg.Limit, arg.KasID, + arg.KasName, + arg.KasUri, arg.PublicKeyID, ) if err != nil { @@ -3621,8 +3668,11 @@ func (q *Queries) listPublicKeyMappings(ctx context.Context, arg listPublicKeyMa const listPublicKeys = `-- name: listPublicKeys :many WITH counted AS ( - SELECT COUNT(k.id) AS total FROM public_keys AS k - WHERE (NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid) + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id + WHERE (NULLIF($1, '') IS NULL OR kas.id = $1::uuid) + AND (NULLIF($2, '') IS NULL OR kas.name = $2) + AND (NULLIF($3, '') IS NULL OR kas.uri = $3) ) SELECT @@ -3643,14 +3693,18 @@ CROSS JOIN counted WHERE ( NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid ) -LIMIT $3 -OFFSET $2 +AND (NULLIF($2, '') IS NULL OR kas.name = $2) +AND (NULLIF($3, '') IS NULL OR kas.uri = $3) +LIMIT $5 +OFFSET $4 ` type listPublicKeysParams struct { - KasID interface{} `json:"kas_id"` - Offset int32 `json:"offset_"` - Limit int32 `json:"limit_"` + KasID interface{} `json:"kas_id"` + KasName interface{} `json:"kas_name"` + KasUri interface{} `json:"kas_uri"` + Offset int32 `json:"offset_"` + Limit int32 `json:"limit_"` } type listPublicKeysRow struct { @@ -3670,8 +3724,11 @@ type listPublicKeysRow struct { // listPublicKeys // // WITH counted AS ( -// SELECT COUNT(k.id) AS total FROM public_keys AS k -// WHERE (NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid) +// SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk +// JOIN key_access_servers kas ON pk.key_access_server_id = kas.id +// WHERE (NULLIF($1, '') IS NULL OR kas.id = $1::uuid) +// AND (NULLIF($2, '') IS NULL OR kas.name = $2) +// AND (NULLIF($3, '') IS NULL OR kas.uri = $3) // ) // // SELECT @@ -3692,10 +3749,18 @@ type listPublicKeysRow struct { // WHERE ( // NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid // ) -// LIMIT $3 -// OFFSET $2 +// AND (NULLIF($2, '') IS NULL OR kas.name = $2) +// AND (NULLIF($3, '') IS NULL OR kas.uri = $3) +// LIMIT $5 +// OFFSET $4 func (q *Queries) listPublicKeys(ctx context.Context, arg listPublicKeysParams) ([]listPublicKeysRow, error) { - rows, err := q.db.Query(ctx, listPublicKeys, arg.KasID, arg.Offset, arg.Limit) + rows, err := q.db.Query(ctx, listPublicKeys, + arg.KasID, + arg.KasName, + arg.KasUri, + arg.Offset, + arg.Limit, + ) if err != nil { return nil, err } diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index cd8895c3e..c13596c9d 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -102,9 +102,17 @@ func (s KeyAccessServerRegistry) GetKeyAccessServer(ctx context.Context, ) (*connect.Response[kasr.GetKeyAccessServerResponse], error) { rsp := &kasr.GetKeyAccessServerResponse{} - keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.KeyAccessServer = keyAccessServer @@ -311,7 +319,11 @@ func (s KeyAccessServerRegistry) UpdatePublicKey(ctx context.Context, req *conne ObjectID: req.Msg.GetId(), } - original, err := s.dbClient.GetPublicKey(ctx, &kasr.GetPublicKeyRequest{Id: req.Msg.GetId()}) + original, err := s.dbClient.GetPublicKey(ctx, &kasr.GetPublicKeyRequest{ + Identifier: &kasr.GetPublicKeyRequest_Id{ + Id: req.Msg.GetId(), + }, + }) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed) diff --git a/service/policy/kasregistry/key_access_server_registry.proto b/service/policy/kasregistry/key_access_server_registry.proto index 6235fd3b0..e1a1bef3e 100644 --- a/service/policy/kasregistry/key_access_server_registry.proto +++ b/service/policy/kasregistry/key_access_server_registry.proto @@ -9,8 +9,41 @@ import "policy/objects.proto"; import "policy/selectors.proto"; message GetKeyAccessServerRequest { - // Required - string id = 1 [ (buf.validate.field).string.uuid = true ]; + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.kas_id) || has(this.uri) || has(this.name)))", + message: "Either use deprecated 'id' field or one of 'kas_id' or 'uri', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.kas_id) || has(this.uri) || has(this.name)", + message: "Either id or one of kas_id or uri must be set" + }; + + // Deprecated + string id = 1 [ + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string kas_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string name = 3 [ + (buf.validate.field).string.min_len = 1 + ]; + string uri = 4 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } message GetKeyAccessServerResponse { KeyAccessServer key_access_server = 1; } @@ -126,7 +159,9 @@ message CreatePublicKeyRequest { string kas_id = 1 [ (buf.validate.field).string.uuid = true ]; // Required - KasPublicKey key = 2; + KasPublicKey key = 2 [ + (buf.validate.field).required = true + ]; // Common metadata common.MetadataMutable metadata = 100; @@ -134,18 +169,34 @@ message CreatePublicKeyRequest { message CreatePublicKeyResponse { Key key = 1; } -message GetPublicKeyRequest { string id = 1; } +message GetPublicKeyRequest { + oneof identifier { + string id = 1 [ + (buf.validate.field).string.uuid = true + ]; + } +} message GetPublicKeyResponse { Key key = 1; } message ListPublicKeysRequest { - // Optional - string kas_id = 1; - // Future filter by fields - // // Optional - // string kas_name = 2; - // // Optional - // string kas_uri = 3; + oneof kas_filter { + // Optional + string kas_id = 1 [ + (buf.validate.field).string.uuid = true + ]; + // Optional + string kas_name = 2 [ + (buf.validate.field).string.min_len = 1 + ]; + // Optional + string kas_uri = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } // Optional policy.PageRequest pagination = 10; @@ -158,16 +209,29 @@ message ListPublicKeysResponse { } message ListPublicKeyMappingRequest { - // Optional - string kas_id = 1; - // Future filter by fields - // // Optional - // string kas_name = 2; - // // Optional - // string kas_uri = 3; + oneof kas_filter { + // Optional + string kas_id = 1 [ + (buf.validate.field).string.uuid = true + ]; + // Optional + string kas_name = 2 [ + (buf.validate.field).string.min_len = 1 + ]; + // Optional + string kas_uri = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } // Optional Public Key ID - string public_key_id = 4; + string public_key_id = 4 [ + (buf.validate.field).string.uuid = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + ]; // Optional policy.PageRequest pagination = 10; @@ -199,7 +263,9 @@ message ListPublicKeyMappingResponse { message UpdatePublicKeyRequest { // Required - string id = 1; + string id = 1 [ + (buf.validate.field).string.uuid = true + ]; // Optional // Common metadata @@ -211,8 +277,7 @@ message UpdatePublicKeyResponse { Key key = 1;} message DeactivatePublicKeyRequest { string id = 1 [ - (buf.validate.field).string.uuid = true, - (buf.validate.field).required = true + (buf.validate.field).string.uuid = true ]; } @@ -220,14 +285,13 @@ message DeactivatePublicKeyResponse { Key key = 1; } message ActivatePublicKeyRequest { string id = 1 [ - (buf.validate.field).string.uuid = true, - (buf.validate.field).required = true + (buf.validate.field).string.uuid = true ]; } message ActivatePublicKeyResponse { Key key = 1; } -//Deprecated +// Deprecated in favor of ListPublicKeyMapping // TODO: optional validation below should be through a custom validator, which // is too bleeding edge at present without full plugin support diff --git a/service/policy/kasregistry/key_access_server_registry_test.go b/service/policy/kasregistry/key_access_server_registry_test.go index e8af44695..0a4f7b4ef 100644 --- a/service/policy/kasregistry/key_access_server_registry_test.go +++ b/service/policy/kasregistry/key_access_server_registry_test.go @@ -19,10 +19,15 @@ func getValidator() *protovalidate.Validator { } const ( - validSecureURI = "https://example.net" - validInsecureURI = "http://local.something.com" - validUUID = "00000000-0000-0000-0000-000000000000" - errMessageUUID = "string.uuid" + validSecureURI = "https://example.net" + validInsecureURI = "http://local.something.com" + validUUID = "00000000-0000-0000-0000-000000000000" + errMessageUUID = "string.uuid" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" + errMessageURI = "string.uri" + errMessageMinLen = "string.min_len" + errMessageRequired = "required" ) var ( @@ -38,6 +43,8 @@ var ( Keys: []*policy.KasPublicKey{ { Pem: "fake PEM", + Kid: "fake KID", + Alg: policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1, }, }, }, @@ -47,17 +54,153 @@ var ( fakeID = "6321ea85-ca04-466f-aefb-174bcdbc0612" ) -func Test_GetKeyAccessServerRequest_Succeeds(t *testing.T) { - req := &kasregistry.GetKeyAccessServerRequest{} - v := getValidator() +func Test_GetKeyAccessServerRequest(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.GetKeyAccessServerRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid KasId in Identifier (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, // Assuming errMessageUUID is defined elsewhere + }, + { + name: "Invalid KasId in Identifier (invalid UUID)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId in Identifier", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, // Assuming errMessageUUID is defined elsewhere + }, + { + name: "Invalid Deprecated Id (invalid UUID)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid Kas Identifier URI", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid Kas Identifier URI (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid Kas Identifier URI", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: validSecureURI, + }, + }, + expectError: false, + }, + { + name: "Invalid Kas Identifier Name (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid Kas Identifier Name", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "kas-name", + }, + }, + expectError: false, + }, + { + name: "Invalid can't have both Deprecated Id and Identifier", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "kas-name", + }, + Id: validUUID, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &kasregistry.GetKeyAccessServerRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - err := v.Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) + v := getValidator() // Get the validator instance (assuming this is defined elsewhere) - req.Id = validUUID - err = v.Validate(req) - require.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } } func Test_DeleteKeyAccessServerRequest_Succeeds(t *testing.T) { @@ -587,3 +730,516 @@ func Test_Verify_Public_Keys(t *testing.T) { require.Equal(t, key.expectedErr, err, key.description) } } + +func Test_ListPublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ListPublicKeysRequest + expectError bool + errorMessage string + }{ + { + name: "Valid ListPublicKeyRequest", + req: &kasregistry.ListPublicKeysRequest{}, + expectError: false, + }, + { + name: "Invalid KasId filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId filter (invalid UUID)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid KasUri filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid KasUri filter (invalid URI)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid KasUri filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: fakeURI, + }, + }, + expectError: false, + }, + { + name: "Invalid KasName filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid KasName filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: "kas-name", + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_ListPublicKeyMappings_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ListPublicKeyMappingRequest + expectError bool + errorMessage string + }{ + { + name: "Valid ListPublicKeyMappingsRequest", + req: &kasregistry.ListPublicKeyMappingRequest{}, + expectError: false, + }, + { + name: "Invalid KasId filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId filter (invalid UUID)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid KasUri filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid KasUri filter (invalid URI)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid KasUri filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: fakeURI, + }, + }, + expectError: false, + }, + { + name: "Invalid KasName filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid KasName filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: "kas-name", + }, + }, + expectError: false, + }, + { + name: "Invalid KeyId filter (invalid UUID)", + req: &kasregistry.ListPublicKeyMappingRequest{ + PublicKeyId: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + PublicKeyId: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_GetPublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.GetPublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Valid GetPublicKeyRequest", + req: &kasregistry.GetPublicKeyRequest{}, + expectError: false, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: validUUID, + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_CreatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.CreatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid CreatePublicKeyRequest (empty)", + req: &kasregistry.CreatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId (empty string)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: "", + Key: &policy.KasPublicKey{}, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId (invalid UUID)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: "invalid-uuid", + Key: &policy.KasPublicKey{}, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid PublicKey (empty)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: validUUID, + Key: nil, + }, + expectError: true, + errorMessage: errMessageRequired, + }, + { + name: "Valid PublicKey", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: validUUID, + Key: &policy.KasPublicKey{ + Pem: "-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAGvC9aOQpUifTgBQ+aSFm1fn2m5Fb\nOv5Xc+qrT1LcHlX2vYPVfKVsqkjb0dg6LrrKWB6+UuS44y0GDAMln1KPfnkBb2+b\n6gLkYlAUpLV7RtyzBSktmLOkViGauYlR+9gKT2B5+hiL8lsLeh7khj6XEL+CVVgS\nswYGVPb345XuIdrvhBs=\n-----END PUBLIC KEY-----\n", + Kid: "ec384", + Alg: policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1, + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_UpdatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.UpdatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid UpdatePublicKeyRequest (empty)", + req: &kasregistry.UpdatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_DeactivePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.DeactivatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid DeactivatePublicKeyRequest (empty)", + req: &kasregistry.DeactivatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_ActivatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ActivatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid ActivatePublicKeyRequest (empty)", + req: &kasregistry.ActivatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index ae33d8359..4fe43caca 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -75,13 +75,21 @@ func (ns NamespacesService) ListNamespaces(ctx context.Context, req *connect.Req } func (ns NamespacesService) GetNamespace(ctx context.Context, req *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { - ns.logger.Debug("getting namespace", slog.String("id", req.Msg.GetId())) - rsp := &namespaces.GetNamespaceResponse{} - namespace, err := ns.dbClient.GetNamespace(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + ns.logger.Debug("getting namespace", slog.Any("id", identifier)) + + namespace, err := ns.dbClient.GetNamespace(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, "id", req.Msg.GetId()) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Namespace = namespace diff --git a/service/policy/namespaces/namespaces.proto b/service/policy/namespaces/namespaces.proto index de97117f1..1a63f5628 100644 --- a/service/policy/namespaces/namespaces.proto +++ b/service/policy/namespaces/namespaces.proto @@ -48,11 +48,40 @@ message NamespaceKey { */ message GetNamespaceRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.namespace_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'namespace_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.namespace_id) || has(this.fqn)", + message: "Either id or one of namespace_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true ]; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string namespace_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } + message GetNamespaceResponse { policy.Namespace namespace = 1; } diff --git a/service/policy/namespaces/namespaces_test.go b/service/policy/namespaces/namespaces_test.go index 58c73c40e..adce58a5e 100644 --- a/service/policy/namespaces/namespaces_test.go +++ b/service/policy/namespaces/namespaces_test.go @@ -10,9 +10,13 @@ import ( ) const ( - validName = "namespace.org" - validUUID = "390e0058-7ae8-48f6-821c-9db07c831276" - errMessageUUID = "string.uuid" + validName = "namespace.org" + validUUID = "390e0058-7ae8-48f6-821c-9db07c831276" + errMessageUUID = "string.uuid" + errMessageMinLen = "string.min_len" + errMessageURI = "string.uri" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" ) func getValidator() *protovalidate.Validator { @@ -114,17 +118,136 @@ func TestCreateNamespace_NameMissing_Fails(t *testing.T) { require.Contains(t, err.Error(), "[required]") } -func Test_GetNamespaceRequest_Succeeds(t *testing.T) { - req := &namespaces.GetNamespaceRequest{} - v := getValidator() - - err := v.Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetNamespaceRequest(t *testing.T) { + testCases := []struct { + name string + req *namespaces.GetNamespaceRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid NamespaceId in Identifier (empty string)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid NamespaceId in Identifier (invalid UUID)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid NamespaceId in Identifier", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid Deprecated Id", + req: &namespaces.GetNamespaceRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &namespaces.GetNamespaceRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Invalid Deprecated Id (invalid UUID)", + req: &namespaces.GetNamespaceRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid Namespace Identifier URI", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "invalid-fqn", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid Namespace Identifier URI (empty string)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid Namespace Identifier URI (missing scheme)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "namespace.org", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid Namespace Identifier URI", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "https://namespace.org", + }, + }, + expectError: false, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &namespaces.GetNamespaceRequest{ + Id: validUUID, + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "https://namespace.org", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &namespaces.GetNamespaceRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req.Id = validUUID - err = v.Validate(req) - require.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } } func Test_UpdateNamespaceRequest_Succeeds(t *testing.T) { diff --git a/service/policy/objects.proto b/service/policy/objects.proto index f9e209f67..593e4c228 100644 --- a/service/policy/objects.proto +++ b/service/policy/objects.proto @@ -328,15 +328,31 @@ enum KasPublicKeyAlgEnum { // A KAS public key and some associated metadata for further identifcation message KasPublicKey { // x509 ASN.1 content in PEM envelope, usually - string pem = 1; + string pem = 1 [ + (buf.validate.field).string = { + min_len: 1, + max_len: 8192 + } + ]; // A unique string identifier for this key - string kid = 2; + string kid = 2 [ + (buf.validate.field).string = { + min_len : 1, + max_len : 32 + } + ]; // A known algorithm type with any additional parameters encoded. // To start, these may be `rsa:2048` for encrypting ZTDF files and // `ec:secp256r1` for nanoTDF, but more formats may be added as needed. - KasPublicKeyAlgEnum alg = 3; + KasPublicKeyAlgEnum alg = 3 [ + (buf.validate.field).enum = { + defined_only: true, + not_in: [0] + } + + ]; } // Deprecated diff --git a/service/policy/unsafe/unsafe_test.go b/service/policy/unsafe/unsafe_test.go new file mode 100644 index 000000000..8e7d59bcb --- /dev/null +++ b/service/policy/unsafe/unsafe_test.go @@ -0,0 +1,75 @@ +package unsafe + +import ( + "testing" + + "github.com/bufbuild/protovalidate-go" + "github.com/opentdf/platform/protocol/go/policy/unsafe" + "github.com/stretchr/testify/require" +) + +var ( + errMessageUUID = "string.uuid" + validUUID = "00000000-0000-0000-0000-000000000000" +) + +func getValidator() *protovalidate.Validator { + v, err := protovalidate.New() + if err != nil { + panic(err) + } + return v +} + +func Test_UnsafeDeletePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *unsafe.UnsafeDeletePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid UnsafeDeletePublicKey (empty)", + req: &unsafe.UnsafeDeletePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} diff --git a/test/policy-service.bats b/test/policy-service.bats index 47908d0c1..1b31ad5d1 100755 --- a/test/policy-service.bats +++ b/test/policy-service.bats @@ -60,9 +60,9 @@ } @test "gRPC: kas grants assignment" { - go run ./examples --creds opentdf:secret kas add --kas https://a.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" - go run ./examples --creds opentdf:secret kas add --kas https://b.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" - go run ./examples --creds opentdf:secret kas add --kas https://c.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://a.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://b.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://c.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" run go run ./examples --creds opentdf:secret kas ls -l echo "$output" diff --git a/test/start-additional-kas/action.yaml b/test/start-additional-kas/action.yaml index 722ac9bbb..120a88a3e 100644 --- a/test/start-additional-kas/action.yaml +++ b/test/start-additional-kas/action.yaml @@ -12,6 +12,11 @@ inputs: kas-name: required: true description: 'The name for the additional KAS' + ec-tdf-enabled: + default: false + description: 'Whether to enable ECC wrapping for TDFs' + required: false + type: boolean runs: using: 'composite' @@ -23,6 +28,7 @@ runs: opentdf-${{ inputs.kas-name }}.yaml yq e ' (.server.port = ${{ inputs.kas-port }}) | (.mode = ["kas"]) + | (.services.kas.ec_tdf_enabled = ${{ inputs.ec-tdf-enabled }}) | (.sdk_config = {"client_id":"opentdf","client_secret":"secret","core":{"endpoint":"http://localhost:8080","plaintext":true}}) ' && .github/scripts/watch.sh opentdf-${{ inputs.kas-name }}.yaml ./opentdf --config-file ./opentdf-${{ inputs.kas-name }}.yaml start diff --git a/test/start-up-with-containers/action.yaml b/test/start-up-with-containers/action.yaml index 6130bb842..5b17c2f99 100644 --- a/test/start-up-with-containers/action.yaml +++ b/test/start-up-with-containers/action.yaml @@ -11,6 +11,11 @@ inputs: required: false description: A JSON array containing extra keys for the KAS to load. Each object should have 'kid', 'alg', 'private', and 'cert' fields. default: '[]' + ec-tdf-enabled: + default: false + description: 'Whether to enable ECC wrapping for TDFs' + required: false + type: boolean outputs: platform-working-dir: @@ -84,6 +89,12 @@ runs: opentdf.yaml yq e "${yq_command}" working-directory: otdf-test-platform + - name: Enable ECC wrapping for TDFs + shell: bash + if: ${{ inputs.ec-tdf-enabled }} + run: | + yq e '.services.kas.ec_tdf_enabled = true' -i opentdf.yaml + working-directory: otdf-test-platform - name: Trust the generated certs shell: bash run: | diff --git a/test/tdf-roundtrips.bats b/test/tdf-roundtrips.bats index 72604164a..0e323fdcb 100755 --- a/test/tdf-roundtrips.bats +++ b/test/tdf-roundtrips.bats @@ -6,7 +6,7 @@ @test "examples: roundtrip Z-TDF" { # TODO: add subject mapping here to remove reliance on `provision fixtures` echo "[INFO] configure attribute with grant for local kas" - go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 -v value1 go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 go run ./examples --creds opentdf:secret attributes assign -a https://example.com/attr/attr1 -v value1 -k http://localhost:8080 @@ -25,12 +25,40 @@ run go run ./examples decrypt sensitive.txt.tdf echo "$output" printf '%s\n' "$output" | grep "Hello Zero Trust" + + echo "[INFO] decrypting with EC..." + run go run ./examples decrypt -A 'ec:secp256r1' sensitive.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello Zero Trust" +} + +@test "examples: roundtrip Z-TDF with EC wrapped KAO" { + # TODO: add subject mapping here to remove reliance on `provision fixtures` + echo "[INFO] create a tdf3 format file" + run go run ./examples encrypt -o sensitive-with-ec.txt.tdf --autoconfigure=false -A "ec:secp256r1" "Hello EC wrappers!" + echo "[INFO] echoing output; if successful, this is just the manifest" + echo "$output" + + echo "[INFO] Validate the manifest lists the expected kid in its KAO" + kaotype=$(jq -r '.encryptionInformation.keyAccess[0].type' <<<"${output}") + echo "$kaotype" + [ "$kaotype" = ec-wrapped ] + + echo "[INFO] decrypting..." + run go run ./examples decrypt sensitive-with-ec.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello EC wrappers!" + + echo "[INFO] decrypting with EC..." + run go run ./examples decrypt -A 'ec:secp256r1' sensitive-with-ec.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello EC wrappers!" } @test "examples: roundtrip Z-TDF with extra unnecessary, invalid kas" { # TODO: add subject mapping here to remove reliance on `provision fixtures` echo "[INFO] configure attribute with grant for local kas" - go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret kas add --kas http://localhost:9090 --algorithm "rsa:2048" --kid r2 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 -v value1 go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 @@ -210,6 +238,7 @@ logger: services: kas: enabled: true + ec_tdf_enabled: true keyring: - kid: ${ec_current_key} alg: ec:secp256r1