From a7e7aa7dbff18d47d1a2e501eee2c4ee96fecbd3 Mon Sep 17 00:00:00 2001 From: Thibault NORMAND Date: Sun, 27 Feb 2022 21:50:47 +0100 Subject: [PATCH] doc(cli): bundle description and examples. (#134) * doc(cli): bundle description and examples. * feat(ruleset): enable rego engine for ruleset. * doc(changelog): update changelog. * doc(cli): update cli documentation. --- CHANGELOG.md | 44 ++- api/gen/go/cso/v1/validator_api_grpc.pb.go | 4 - api/gen/go/harp/bundle/v1/bundle.pb.go | 323 +++++++++++------- .../go/harp/bundle/v1/bundle_api_grpc.pb.go | 4 - api/gen/go/harp/bundle/v1/ruleset.pb.go | 61 ++-- api/proto/harp/bundle/v1/bundle.proto | 7 + api/proto/harp/bundle/v1/ruleset.proto | 6 +- build/mage/golang/import.go | 2 +- cmd/harp/internal/cmd/bundle_decrypt.go | 39 ++- cmd/harp/internal/cmd/bundle_diff.go | 26 +- cmd/harp/internal/cmd/bundle_dump.go | 36 +- cmd/harp/internal/cmd/bundle_encrypt.go | 33 +- cmd/harp/internal/cmd/bundle_filter.go | 46 +++ cmd/harp/internal/cmd/bundle_lint.go | 17 +- cmd/harp/loader_fips.go | 1 - cmd/harp/loader_nonfips.go | 1 - docs/cmd/harp_bundle.md | 4 +- docs/cmd/harp_bundle_decrypt.md | 35 ++ docs/cmd/harp_bundle_diff.md | 19 +- docs/cmd/harp_bundle_dump.md | 33 ++ docs/cmd/harp_bundle_encrypt.md | 30 ++ docs/cmd/harp_bundle_filter.md | 48 +++ docs/cmd/harp_bundle_lint.md | 17 +- docs/cmd/harp_transform_hash.md | 2 +- docs/cmd/harp_transform_multihash.md | 2 +- .../ruleset/linter/engine/rego/engine.go | 6 +- pkg/bundle/ruleset/linter/package.go | 34 +- pkg/bundle/ruleset/linter/package_test.go | 145 ++++++++ pkg/bundle/ruleset/linter/reader_test.go | 3 + pkg/sdk/value/encoding/reader.go | 4 +- pkg/sdk/value/encoding/writer.go | 4 +- pkg/sdk/value/encryption/transformer_test.go | 1 - pkg/sdk/value/hash/multi.go | 4 +- pkg/sdk/value/hash/writer.go | 5 +- pkg/tasks/bundle/decrypt_test.go | 1 - pkg/tasks/container/recover_test.go | 1 - test/fixtures/ruleset/valid/policy.rego | 10 + test/fixtures/ruleset/valid/rego-file.yaml | 12 + test/fixtures/ruleset/valid/rego.yaml | 21 ++ 39 files changed, 891 insertions(+), 200 deletions(-) create mode 100644 test/fixtures/ruleset/valid/policy.rego create mode 100644 test/fixtures/ruleset/valid/rego-file.yaml create mode 100644 test/fixtures/ruleset/valid/rego.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 265b3f06..f9443a3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,51 @@ FEATURES: +* cli: + * `darwin-amd64` and `darwin-arm64` are code signed and notarized using an + Apple Developer ID certificate to allow harp execution on Silicon M1 based + computers. [#134](https://github.com/elastic/harp/pull/134) + +* cli/transform: + * `compress`/`decompress` commands for various algorithms. [#117](github.com/elastic/harp/pull/117) + * `hash`/`multihash` command for various hashing algorithms. [#117](github.com/elastic/harp/pull/117) + * `encode`/`decode` command for various encoding strategies [#117](github.com/elastic/harp/pull/117) + +* bundle/ruleset: + * enable `rego` language for RuleSet constraint engine. [#134](https://github.com/elastic/harp/pull/134) + +* sdk/api: + * support `user_data` for `Bundle`, `Package`, `SecretChain` to store custom + arbitrary data during pipeline execution. [#134](https://github.com/elastic/harp/pull/134) + * sdk/value: * `encoding` reader / writer factory. [#117](github.com/elastic/harp/pull/117) * `compression` reader/writer factory. [#117](github.com/elastic/harp/pull/117) * `hash` writer factory. [#117](github.com/elastic/harp/pull/117) -* cli/transform: - * `compress`/`decompress` commands for various algorithms [#117](github.com/elastic/harp/pull/117) - * `hash`/`multihash` command for various hashing algorithms. [#117](github.com/elastic/harp/pull/117) - * `encode`/`decode` command for various encoding strategies [#117](github.com/elastic/harp/pull/117) +CHANGES: + +* go: + * FIPS artifact build process is disabled. + +* git: + * the tag `cmd/harp/vX.XX` will never be produced. + +* ci: + * `dependabot` setup to monitor and automate dependency updates. + * the release pipeline has been completely redesigned to use goreleaser. + * SLSA `provenance` is temporary disabled due to a lack of the multiplatform support + for the used action. + +DIST: + +* build/ci: + * SHA256 fingerprint is provided per artifact. + * SBOM is embedded in the artifact archive. + +* build/gha: + * [zntrio/harp-installer](https://github.com/zntrio/harp-installer) github action + could be used to set up harp during your github action pipelines. ## 0.2.7 diff --git a/api/gen/go/cso/v1/validator_api_grpc.pb.go b/api/gen/go/cso/v1/validator_api_grpc.pb.go index b512d463..35914ab2 100644 --- a/api/gen/go/cso/v1/validator_api_grpc.pb.go +++ b/api/gen/go/cso/v1/validator_api_grpc.pb.go @@ -16,10 +16,6 @@ // under the License. // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.4 -// source: cso/v1/validator_api.proto package csov1 diff --git a/api/gen/go/harp/bundle/v1/bundle.pb.go b/api/gen/go/harp/bundle/v1/bundle.pb.go index e4184a90..8fcfa752 100644 --- a/api/gen/go/harp/bundle/v1/bundle.pb.go +++ b/api/gen/go/harp/bundle/v1/bundle.pb.go @@ -29,6 +29,7 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -61,6 +62,8 @@ type Bundle struct { Values *wrapperspb.BytesValue `protobuf:"bytes,6,opt,name=values,proto3" json:"values,omitempty"` // Merkle Tree root MerkleTreeRoot []byte `protobuf:"bytes,7,opt,name=merkle_tree_root,json=merkleTreeRoot,proto3" json:"merkle_tree_root,omitempty"` + // User data storage + UserData map[string]*anypb.Any `protobuf:"bytes,99,rep,name=user_data,json=userData,proto3" json:"user_data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Bundle) Reset() { @@ -144,6 +147,13 @@ func (x *Bundle) GetMerkleTreeRoot() []byte { return nil } +func (x *Bundle) GetUserData() map[string]*anypb.Any { + if x != nil { + return x.UserData + } + return nil +} + // Package is a secret organizational unit. type Package struct { state protoimpl.MessageState @@ -162,6 +172,8 @@ type Package struct { Secrets *SecretChain `protobuf:"bytes,4,opt,name=secrets,proto3" json:"secrets,omitempty"` // SecretChain versions Versions map[uint32]*SecretChain `protobuf:"bytes,5,rep,name=versions,proto3" json:"versions,omitempty" protobuf_key:"fixed32,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // User data storage + UserData map[string]*anypb.Any `protobuf:"bytes,99,rep,name=user_data,json=userData,proto3" json:"user_data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Package) Reset() { @@ -231,6 +243,13 @@ func (x *Package) GetVersions() map[uint32]*SecretChain { return nil } +func (x *Package) GetUserData() map[string]*anypb.Any { + if x != nil { + return x.UserData + } + return nil +} + // SecretChain describe a secret version chain. type SecretChain struct { state protoimpl.MessageState @@ -253,6 +272,8 @@ type SecretChain struct { NextVersion *wrapperspb.UInt32Value `protobuf:"bytes,6,opt,name=next_version,json=nextVersion,proto3" json:"next_version,omitempty"` // Locked buffer when encryption is enabled Locked *wrapperspb.BytesValue `protobuf:"bytes,7,opt,name=locked,proto3" json:"locked,omitempty"` + // User data storage + UserData map[string]*anypb.Any `protobuf:"bytes,99,rep,name=user_data,json=userData,proto3" json:"user_data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *SecretChain) Reset() { @@ -336,6 +357,13 @@ func (x *SecretChain) GetLocked() *wrapperspb.BytesValue { return nil } +func (x *SecretChain) GetUserData() map[string]*anypb.Any { + if x != nil { + return x.UserData + } + return nil +} + // KV contains the key, the value and the type of the value. type KV struct { state protoimpl.MessageState @@ -410,58 +438,38 @@ var file_harp_bundle_v1_bundle_proto_rawDesc = []byte{ 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1d, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xee, 0x03, 0x0a, - 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x12, 0x49, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, - 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, 0x61, 0x72, - 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x34, 0x0a, - 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x65, 0x72, 0x6b, - 0x6c, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0e, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x72, 0x65, 0x65, 0x52, 0x6f, - 0x6f, 0x74, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, - 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf5, 0x03, - 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68, 0x61, 0x72, 0x70, - 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x68, 0x61, - 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x41, 0x0a, - 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x05, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x49, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x61, 0x72, + 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x33, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x74, 0x72, + 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6d, + 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x41, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x63, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, @@ -469,39 +477,84 @@ var file_harp_bundle_v1_bundle_proto_rawDesc = []byte{ 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0d, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x0d, 0x55, + 0x73, 0x65, 0x72, 0x44, 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, 0x2a, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8c, + 0x05, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68, 0x61, 0x72, + 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x68, + 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x41, + 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x42, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x63, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x58, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x0d, 0x55, 0x73, + 0x65, 0x72, 0x44, 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, 0x2a, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb5, 0x05, + 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x04, 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, - 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x07, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4b, 0x56, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, - 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x3f, 0x0a, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x06, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4e, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x07, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x56, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x47, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0c, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x6e, + 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x06, 0x6c, 0x6f, + 0x63, 0x6b, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, + 0x46, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x63, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, @@ -509,21 +562,27 @@ var file_harp_bundle_v1_bundle_proto_rawDesc = []byte{ 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x40, 0x0a, 0x02, 0x4b, 0x56, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x9f, 0x01, 0x0a, 0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x63, 0x6c, 0x6f, 0x75, - 0x64, 0x73, 0x65, 0x63, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, - 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x53, 0x42, 0x58, 0xaa, 0x02, 0x0e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, 0x68, 0x61, 0x72, 0x70, 0x5c, 0x42, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x44, 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, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x40, 0x0a, 0x02, 0x4b, 0x56, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x9f, 0x01, 0x0a, 0x2a, 0x63, 0x6f, 0x6d, 0x2e, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x65, 0x63, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x62, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x76, + 0x31, 0xa2, 0x02, 0x03, 0x53, 0x42, 0x58, 0xaa, 0x02, 0x0e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, 0x68, 0x61, 0x72, 0x70, 0x5c, + 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -538,7 +597,7 @@ func file_harp_bundle_v1_bundle_proto_rawDescGZIP() []byte { return file_harp_bundle_v1_bundle_proto_rawDescData } -var file_harp_bundle_v1_bundle_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_harp_bundle_v1_bundle_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_harp_bundle_v1_bundle_proto_goTypes = []interface{}{ (*Bundle)(nil), // 0: harp.bundle.v1.Bundle (*Package)(nil), // 1: harp.bundle.v1.Package @@ -546,37 +605,47 @@ var file_harp_bundle_v1_bundle_proto_goTypes = []interface{}{ (*KV)(nil), // 3: harp.bundle.v1.KV nil, // 4: harp.bundle.v1.Bundle.LabelsEntry nil, // 5: harp.bundle.v1.Bundle.AnnotationsEntry - nil, // 6: harp.bundle.v1.Package.LabelsEntry - nil, // 7: harp.bundle.v1.Package.AnnotationsEntry - nil, // 8: harp.bundle.v1.Package.VersionsEntry - nil, // 9: harp.bundle.v1.SecretChain.LabelsEntry - nil, // 10: harp.bundle.v1.SecretChain.AnnotationsEntry - (*Template)(nil), // 11: harp.bundle.v1.Template - (*wrapperspb.BytesValue)(nil), // 12: google.protobuf.BytesValue - (*wrapperspb.UInt32Value)(nil), // 13: google.protobuf.UInt32Value + nil, // 6: harp.bundle.v1.Bundle.UserDataEntry + nil, // 7: harp.bundle.v1.Package.LabelsEntry + nil, // 8: harp.bundle.v1.Package.AnnotationsEntry + nil, // 9: harp.bundle.v1.Package.VersionsEntry + nil, // 10: harp.bundle.v1.Package.UserDataEntry + nil, // 11: harp.bundle.v1.SecretChain.LabelsEntry + nil, // 12: harp.bundle.v1.SecretChain.AnnotationsEntry + nil, // 13: harp.bundle.v1.SecretChain.UserDataEntry + (*Template)(nil), // 14: harp.bundle.v1.Template + (*wrapperspb.BytesValue)(nil), // 15: google.protobuf.BytesValue + (*wrapperspb.UInt32Value)(nil), // 16: google.protobuf.UInt32Value + (*anypb.Any)(nil), // 17: google.protobuf.Any } var file_harp_bundle_v1_bundle_proto_depIdxs = []int32{ 4, // 0: harp.bundle.v1.Bundle.labels:type_name -> harp.bundle.v1.Bundle.LabelsEntry 5, // 1: harp.bundle.v1.Bundle.annotations:type_name -> harp.bundle.v1.Bundle.AnnotationsEntry 1, // 2: harp.bundle.v1.Bundle.packages:type_name -> harp.bundle.v1.Package - 11, // 3: harp.bundle.v1.Bundle.template:type_name -> harp.bundle.v1.Template - 12, // 4: harp.bundle.v1.Bundle.values:type_name -> google.protobuf.BytesValue - 6, // 5: harp.bundle.v1.Package.labels:type_name -> harp.bundle.v1.Package.LabelsEntry - 7, // 6: harp.bundle.v1.Package.annotations:type_name -> harp.bundle.v1.Package.AnnotationsEntry - 2, // 7: harp.bundle.v1.Package.secrets:type_name -> harp.bundle.v1.SecretChain - 8, // 8: harp.bundle.v1.Package.versions:type_name -> harp.bundle.v1.Package.VersionsEntry - 9, // 9: harp.bundle.v1.SecretChain.labels:type_name -> harp.bundle.v1.SecretChain.LabelsEntry - 10, // 10: harp.bundle.v1.SecretChain.annotations:type_name -> harp.bundle.v1.SecretChain.AnnotationsEntry - 3, // 11: harp.bundle.v1.SecretChain.data:type_name -> harp.bundle.v1.KV - 13, // 12: harp.bundle.v1.SecretChain.previous_version:type_name -> google.protobuf.UInt32Value - 13, // 13: harp.bundle.v1.SecretChain.next_version:type_name -> google.protobuf.UInt32Value - 12, // 14: harp.bundle.v1.SecretChain.locked:type_name -> google.protobuf.BytesValue - 2, // 15: harp.bundle.v1.Package.VersionsEntry.value:type_name -> harp.bundle.v1.SecretChain - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 14, // 3: harp.bundle.v1.Bundle.template:type_name -> harp.bundle.v1.Template + 15, // 4: harp.bundle.v1.Bundle.values:type_name -> google.protobuf.BytesValue + 6, // 5: harp.bundle.v1.Bundle.user_data:type_name -> harp.bundle.v1.Bundle.UserDataEntry + 7, // 6: harp.bundle.v1.Package.labels:type_name -> harp.bundle.v1.Package.LabelsEntry + 8, // 7: harp.bundle.v1.Package.annotations:type_name -> harp.bundle.v1.Package.AnnotationsEntry + 2, // 8: harp.bundle.v1.Package.secrets:type_name -> harp.bundle.v1.SecretChain + 9, // 9: harp.bundle.v1.Package.versions:type_name -> harp.bundle.v1.Package.VersionsEntry + 10, // 10: harp.bundle.v1.Package.user_data:type_name -> harp.bundle.v1.Package.UserDataEntry + 11, // 11: harp.bundle.v1.SecretChain.labels:type_name -> harp.bundle.v1.SecretChain.LabelsEntry + 12, // 12: harp.bundle.v1.SecretChain.annotations:type_name -> harp.bundle.v1.SecretChain.AnnotationsEntry + 3, // 13: harp.bundle.v1.SecretChain.data:type_name -> harp.bundle.v1.KV + 16, // 14: harp.bundle.v1.SecretChain.previous_version:type_name -> google.protobuf.UInt32Value + 16, // 15: harp.bundle.v1.SecretChain.next_version:type_name -> google.protobuf.UInt32Value + 15, // 16: harp.bundle.v1.SecretChain.locked:type_name -> google.protobuf.BytesValue + 13, // 17: harp.bundle.v1.SecretChain.user_data:type_name -> harp.bundle.v1.SecretChain.UserDataEntry + 17, // 18: harp.bundle.v1.Bundle.UserDataEntry.value:type_name -> google.protobuf.Any + 2, // 19: harp.bundle.v1.Package.VersionsEntry.value:type_name -> harp.bundle.v1.SecretChain + 17, // 20: harp.bundle.v1.Package.UserDataEntry.value:type_name -> google.protobuf.Any + 17, // 21: harp.bundle.v1.SecretChain.UserDataEntry.value:type_name -> google.protobuf.Any + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_harp_bundle_v1_bundle_proto_init() } @@ -641,7 +710,7 @@ func file_harp_bundle_v1_bundle_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_harp_bundle_v1_bundle_proto_rawDesc, NumEnums: 0, - NumMessages: 11, + NumMessages: 14, NumExtensions: 0, NumServices: 0, }, diff --git a/api/gen/go/harp/bundle/v1/bundle_api_grpc.pb.go b/api/gen/go/harp/bundle/v1/bundle_api_grpc.pb.go index 6a6d0521..17009be8 100644 --- a/api/gen/go/harp/bundle/v1/bundle_api_grpc.pb.go +++ b/api/gen/go/harp/bundle/v1/bundle_api_grpc.pb.go @@ -16,10 +16,6 @@ // under the License. // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.4 -// source: harp/bundle/v1/bundle_api.proto package bundlev1 diff --git a/api/gen/go/harp/bundle/v1/ruleset.pb.go b/api/gen/go/harp/bundle/v1/ruleset.pb.go index 75e9f704..1dfe1273 100644 --- a/api/gen/go/harp/bundle/v1/ruleset.pb.go +++ b/api/gen/go/harp/bundle/v1/ruleset.pb.go @@ -242,8 +242,12 @@ type Rule struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // REQUIRED. Rule path matcher filter. Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - // REAQUIRED. Constraint collection. + // OPTIONAL. CEL Constraint collection. Constraints []string `protobuf:"bytes,4,rep,name=constraints,proto3" json:"constraints,omitempty"` + // OPTIONAL. Rego policy. + Rego string `protobuf:"bytes,5,opt,name=rego,proto3" json:"rego,omitempty"` + // OPTIONAL. Rego policy file. + RegoFile string `protobuf:"bytes,6,opt,name=rego_file,json=regoFile,proto3" json:"rego_file,omitempty"` } func (x *Rule) Reset() { @@ -306,6 +310,20 @@ func (x *Rule) GetConstraints() []string { return nil } +func (x *Rule) GetRego() string { + if x != nil { + return x.Rego + } + return "" +} + +func (x *Rule) GetRegoFile() string { + if x != nil { + return x.RegoFile + } + return "" +} + var File_harp_bundle_v1_ruleset_proto protoreflect.FileDescriptor var file_harp_bundle_v1_ruleset_proto_rawDesc = []byte{ @@ -331,25 +349,28 @@ var file_harp_bundle_v1_ruleset_proto_rawDesc = []byte{ 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x61, 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x72, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x42, 0xa0, 0x01, 0x0a, 0x2a, - 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x65, 0x6c, 0x61, 0x73, 0x74, - 0x69, 0x63, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x65, 0x63, 0x2e, 0x68, 0x61, 0x72, 0x70, - 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x52, 0x75, 0x6c, 0x65, - 0x53, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x68, - 0x61, 0x72, 0x70, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x68, - 0x61, 0x72, 0x70, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x62, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x42, 0x58, 0xaa, 0x02, 0x0e, 0x48, - 0x61, 0x72, 0x70, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0e, - 0x48, 0x61, 0x72, 0x70, 0x5c, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x65, 0x67, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x67, 0x6f, + 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x42, 0xa0, 0x01, + 0x0a, 0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x65, 0x6c, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x65, 0x63, 0x2e, 0x68, 0x61, + 0x72, 0x70, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x52, 0x75, + 0x6c, 0x65, 0x53, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, + 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, + 0x2f, 0x68, 0x61, 0x72, 0x70, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x42, 0x58, 0xaa, 0x02, + 0x0e, 0x48, 0x61, 0x72, 0x70, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x0e, 0x48, 0x61, 0x72, 0x70, 0x5c, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5c, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/proto/harp/bundle/v1/bundle.proto b/api/proto/harp/bundle/v1/bundle.proto index 579fef25..160b5f49 100644 --- a/api/proto/harp/bundle/v1/bundle.proto +++ b/api/proto/harp/bundle/v1/bundle.proto @@ -28,6 +28,7 @@ option objc_class_prefix = "SBX"; option php_namespace = "harp\\Bundle\\V1"; import "harp/bundle/v1/template.proto"; +import "google/protobuf/any.proto"; import "google/protobuf/wrappers.proto"; // Bundle is a concrete secret bundle. @@ -48,6 +49,8 @@ message Bundle { google.protobuf.BytesValue values = 6; // Merkle Tree root bytes merkle_tree_root = 7; + // User data storage + map user_data = 99; } // Package is a secret organizational unit. @@ -64,6 +67,8 @@ message Package { SecretChain secrets = 4; // SecretChain versions map versions = 5; + // User data storage + map user_data = 99; } // SecretChain describe a secret version chain. @@ -84,6 +89,8 @@ message SecretChain { google.protobuf.UInt32Value next_version = 6; // Locked buffer when encryption is enabled google.protobuf.BytesValue locked = 7; + // User data storage + map user_data = 99; } // KV contains the key, the value and the type of the value. diff --git a/api/proto/harp/bundle/v1/ruleset.proto b/api/proto/harp/bundle/v1/ruleset.proto index b93393cb..3f6e5d91 100644 --- a/api/proto/harp/bundle/v1/ruleset.proto +++ b/api/proto/harp/bundle/v1/ruleset.proto @@ -65,6 +65,10 @@ message Rule { string description = 2; // REQUIRED. Rule path matcher filter. string path = 3; - // REAQUIRED. Constraint collection. + // OPTIONAL. CEL Constraint collection. repeated string constraints = 4; + // OPTIONAL. Rego policy. + string rego = 5; + // OPTIONAL. Rego policy file. + string rego_file = 6; } diff --git a/build/mage/golang/import.go b/build/mage/golang/import.go index 6c4d8861..91c8d37a 100644 --- a/build/mage/golang/import.go +++ b/build/mage/golang/import.go @@ -30,7 +30,7 @@ func Import() error { color.Cyan("## Process imports") for pth := range CollectedGoFiles { - args := []string{"-w", "-local", "github.com/elastic/harp"} + args := []string{"write", "-s", "Standard", "-s", "Default", "-s", "Prefix(github.com/elastic)"} args = append(args, pth) if err := sh.RunV("gci", args...); err != nil { diff --git a/cmd/harp/internal/cmd/bundle_decrypt.go b/cmd/harp/internal/cmd/bundle_decrypt.go index 38370b41..e0c5eeb0 100644 --- a/cmd/harp/internal/cmd/bundle_decrypt.go +++ b/cmd/harp/internal/cmd/bundle_decrypt.go @@ -39,9 +39,44 @@ type bundleDecryptParams struct { var bundleDecryptCmd = func() *cobra.Command { params := &bundleDecryptParams{} + longDesc := cmdutil.LongDesc(` + Decrypt a bundle content. + + For confidentiality purpose, bundle package value can be encrypted before + the container sealing. It offers confidentiality properties so that the + final consumer must know an additional decryption key to be allowed to + read the package value. + + All package properties (name, labels, annotations) remain a clear-text + message. Only package values (secret K/V) is encrypted. + + In order to decrypt the package value, harp uses the value encryption + transformers. The required key must be provided in a format understandable + by the encryption transformer factory. + + This act as in-transit/in-use encryption. + `) + + examples := cmdutil.Examples(` + # Decrypt a bundle from STDIN and produce output to STDOUT + harp bundle decrypt --key + + # Decrypt a bundle from STDIN using multiple transformer keys + harp bundle decrypt --key --key + + # Decrypt a bundle from STDIN and ignore secrets which could not be decrypted + # with given transformer key (partial decryption / authorization by key) + harp bundle decrypt --skip-not-decryptable --key + + # Decrypt a bundle from STDIN and produce output to a file + harp bundle decrypt --key --out decrypted.bundle + `) + cmd := &cobra.Command{ - Use: "decrypt", - Short: "Decrypt secret values", + Use: "decrypt", + Short: "Decrypt secret values", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-decrypt", conf.Debug.Enable, conf.Instrumentation.Logs.Level) diff --git a/cmd/harp/internal/cmd/bundle_diff.go b/cmd/harp/internal/cmd/bundle_diff.go index 6852b75b..7727a936 100644 --- a/cmd/harp/internal/cmd/bundle_diff.go +++ b/cmd/harp/internal/cmd/bundle_diff.go @@ -31,14 +31,30 @@ type bundleDiffParams struct { sourcePath string destinationPath string generatePatch bool + outputPath string } var bundleDiffCmd = func() *cobra.Command { params := &bundleDiffParams{} + longDesc := cmdutil.LongDesc(` + Compute Bundle object differences. + + Useful to debug a BundlePatch application and watch for a Bundle alteration. + `) + + examples := cmdutil.Examples(` + # Diff a bundle from STD and a file based one + harp bundle diff --old - --new rotated.bundle + + # Generate a BundlePatch from differences + harp bundle diff --old - --new rotated.bundle --patch --out rotation.yaml`) + cmd := &cobra.Command{ - Use: "diff", - Short: "Display container differences", + Use: "diff", + Short: "Display bundle differences", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-diff", conf.Debug.Enable, conf.Instrumentation.Logs.Level) @@ -48,7 +64,7 @@ var bundleDiffCmd = func() *cobra.Command { t := &bundle.DiffTask{ SourceReader: cmdutil.FileReader(params.sourcePath), DestinationReader: cmdutil.FileReader(params.destinationPath), - OutputWriter: cmdutil.StdoutWriter(), + OutputWriter: cmdutil.FileWriter(params.outputPath), GeneratePatch: params.generatePatch, } @@ -61,8 +77,10 @@ var bundleDiffCmd = func() *cobra.Command { // Parameters cmd.Flags().StringVar(¶ms.sourcePath, "old", "", "Container path ('-' for stdin or filename)") + log.CheckErr("unable to mark 'old' flag as required.", cmd.MarkFlagRequired("old")) cmd.Flags().StringVar(¶ms.destinationPath, "new", "", "Container path ('-' for stdin or filename)") - log.CheckErr("unable to mark 'dst' flag as required.", cmd.MarkFlagRequired("dst")) + log.CheckErr("unable to mark 'new' flag as required.", cmd.MarkFlagRequired("new")) + cmd.Flags().StringVar(¶ms.outputPath, "out", "-", "Output ('-' for stdout or filename)") cmd.Flags().BoolVar(¶ms.generatePatch, "patch", false, "Output as a bundle patch") return cmd diff --git a/cmd/harp/internal/cmd/bundle_dump.go b/cmd/harp/internal/cmd/bundle_dump.go index df66d83c..98c31693 100644 --- a/cmd/harp/internal/cmd/bundle_dump.go +++ b/cmd/harp/internal/cmd/bundle_dump.go @@ -39,9 +39,41 @@ type bundleDumpParams struct { var bundleDumpCmd = func() *cobra.Command { params := &bundleDumpParams{} + longDesc := cmdutil.LongDesc(` + Inspect a Bundle object. + + Harp Bundles is a structure designed to hold additional properties associated + to a path (package name) and values (secrets). For your pipeline usages, you + can store annotations, labels and user data which can be consumed and/or + produced during the secret management pipeline execution. + + The Bundle object specification can be consulted here - https://ela.st/harp-spec-bundle + `) + + examples := cmdutil.Examples(` + # Dump a JSON representation of a Bundle object from STDIN + harp bundle dump + + # Dump a JSON map containing package name as key and associated secret kv + harp bundle dump --data-only + + # Dump a JSON map containing package name as key and associated metadata + harp bundle dump --metadata-only + + # Dump all package paths as a list (useful for xargs usage) + harp bundle dump --path-only + + # Dump a Bundle using a JMEFilter query + harp bundle dump --query + + # Dump a bundle content excluding the template used to generate + harp bundle dump --skip-template`) + cmd := &cobra.Command{ - Use: "dump", - Short: "Dump as JSON", + Use: "dump", + Short: "Dump as JSON", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-dump", conf.Debug.Enable, conf.Instrumentation.Logs.Level) diff --git a/cmd/harp/internal/cmd/bundle_encrypt.go b/cmd/harp/internal/cmd/bundle_encrypt.go index da380dd4..8861b7cc 100644 --- a/cmd/harp/internal/cmd/bundle_encrypt.go +++ b/cmd/harp/internal/cmd/bundle_encrypt.go @@ -42,9 +42,38 @@ type bundleEncryptParams struct { var bundleEncryptCmd = func() *cobra.Command { params := &bundleEncryptParams{} + longDesc := cmdutil.LongDesc(` + Apply package content encryption. + + For confidentiality purpose, bundle package value can be encrypted before + the container sealing. It offers confidentiality properties so that the + final consumer must know an additional decryption key to be allowed to + read the package value even if it can unseal the container. + + All package properties (name, labels, annotations) remain a clear-text + message. Only package values (secret K/V) are encrypted. + + This act as in-transit/in-use encryption. + + Annotations: + + * harp.elastic.co/v1/package#encryptionKeyAlias= - Set this + annotation on packages to reference a key alias.`) + + examples := cmdutil.Examples(` + # Encrypt a whole bundle from STDIN and produce output to STDOUT + harp bundle encrypt --key + + # Encrypt partially a bundle using the annotation matcher from STDIN and + # produce output to STDOUT + harp bundle encrypt --key-alias : --key-alias : + `) + cmd := &cobra.Command{ - Use: "encrypt", - Short: "Encrypt secret values", + Use: "encrypt", + Short: "Encrypt secret values", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-encrypt", conf.Debug.Enable, conf.Instrumentation.Logs.Level) diff --git a/cmd/harp/internal/cmd/bundle_filter.go b/cmd/harp/internal/cmd/bundle_filter.go index cd516ea7..a2862181 100644 --- a/cmd/harp/internal/cmd/bundle_filter.go +++ b/cmd/harp/internal/cmd/bundle_filter.go @@ -41,10 +41,56 @@ type bundleFilterParams struct { var bundleFilterCmd = func() *cobra.Command { params := &bundleFilterParams{} + longDesc := cmdutil.LongDesc(` + Create a new Bundle based on applied package matchers. + + Filtering a Bundle consists in reducing the Bundle packages using a matcher + applied on the Bundle and Package model to select them, and export them + in another Bundle. + + In order to filter packages, you can use : + * a package name selector + * a JMES query + * a REGO policy + * a Set of CEL expressions + + Bundle package filtering capabilities are the root of the secret management + by contract. Filter commands can be pipelined to produce complex filtering + pipelines and target the appropriate secrets. + + TIP: Use this command to debug your BundlePatch matchers.`) + + examples := cmdutil.Examples(` + # Exclude specific packages by name from STDIN bundle to STDOUT. + harp bundle filter --exclude "$app/(staging|production)/*" + + # Exclude specific packages by name from file bundle to STDOUT + harp bundle filter --in customer.bundle --exclude "$app/(staging|production)/*" + + # Keep specific packages by name + harp bundle filter --keep "$app/(staging|production)/*" + + # Filter packages using a JMES query (context is the package) + harp bundle filter --query "labels.deprecated == 'true'" + + # Filter packages using a JMES query (context is the package) to a file based bundle. + harp bundle filter --query "labels.deprecated == 'true'" --out deprecated.bundle + + # Filter packages using a REGO policy + harp bundle filter --policy deprecated.rego + + # Filter packages using a CEL matcher expressions (associated with AND logic if multiple) + harp bundle filter --cel "p.match_secret('*Key')" + + # Reverse the matcher logic + harp bundle filter --not `) + cmd := &cobra.Command{ Use: "filter", Aliases: []string{"grep", "f"}, Short: "Filter package names", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-filter", conf.Debug.Enable, conf.Instrumentation.Logs.Level) diff --git a/cmd/harp/internal/cmd/bundle_lint.go b/cmd/harp/internal/cmd/bundle_lint.go index 3f806d87..bdd246e3 100644 --- a/cmd/harp/internal/cmd/bundle_lint.go +++ b/cmd/harp/internal/cmd/bundle_lint.go @@ -35,9 +35,22 @@ type bundleLintParams struct { var bundleLintCmd = func() *cobra.Command { params := &bundleLintParams{} + longDesc := cmdutil.LongDesc(` + Apply a RuleSet specification to the given bundle. + + This command is used to check a Bundle structure (Package => Secrets). + A control gate could be implemented with this command to enforce a bundle + structure by decoupling the bundle content and the usage contract.`) + + examples := cmdutil.Examples(` + # Lint a bundle from STDIN + harp bundle lint --spec cso.yaml`) + cmd := &cobra.Command{ - Use: "lint", - Short: "Lint the bundle using the given ruleset spec", + Use: "lint", + Short: "Lint the bundle using the given RuleSet spec", + Long: longDesc, + Example: examples, Run: func(cmd *cobra.Command, args []string) { // Initialize logger and context ctx, cancel := cmdutil.Context(cmd.Context(), "harp-bundle-lint", conf.Debug.Enable, conf.Instrumentation.Logs.Level) diff --git a/cmd/harp/loader_fips.go b/cmd/harp/loader_fips.go index 88fde3f4..c25356b7 100644 --- a/cmd/harp/loader_fips.go +++ b/cmd/harp/loader_fips.go @@ -20,7 +20,6 @@ package main import ( - // Register encryption transformers _ "github.com/elastic/harp/pkg/sdk/value/encryption/aead" _ "github.com/elastic/harp/pkg/sdk/value/encryption/dae" diff --git a/cmd/harp/loader_nonfips.go b/cmd/harp/loader_nonfips.go index 7ab3acce..258721c0 100644 --- a/cmd/harp/loader_nonfips.go +++ b/cmd/harp/loader_nonfips.go @@ -20,7 +20,6 @@ package main import ( - // Register encryption transformers _ "github.com/elastic/harp/pkg/sdk/value/encryption/aead" _ "github.com/elastic/harp/pkg/sdk/value/encryption/age" diff --git a/docs/cmd/harp_bundle.md b/docs/cmd/harp_bundle.md index 6d2dfac4..19950935 100644 --- a/docs/cmd/harp_bundle.md +++ b/docs/cmd/harp_bundle.md @@ -12,11 +12,11 @@ Bundle commands * [harp](harp.md) - Extensible secret management tool * [harp bundle decrypt](harp_bundle_decrypt.md) - Decrypt secret values -* [harp bundle diff](harp_bundle_diff.md) - Display container differences +* [harp bundle diff](harp_bundle_diff.md) - Display bundle differences * [harp bundle dump](harp_bundle_dump.md) - Dump as JSON * [harp bundle encrypt](harp_bundle_encrypt.md) - Encrypt secret values * [harp bundle filter](harp_bundle_filter.md) - Filter package names -* [harp bundle lint](harp_bundle_lint.md) - Lint the bundle using the given ruleset spec +* [harp bundle lint](harp_bundle_lint.md) - Lint the bundle using the given RuleSet spec * [harp bundle patch](harp_bundle_patch.md) - Apply patch to the given bundle * [harp bundle prefixer](harp_bundle_prefixer.md) - Simple package prefix operaton * [harp bundle read](harp_bundle_read.md) - Read a secret from bundle diff --git a/docs/cmd/harp_bundle_decrypt.md b/docs/cmd/harp_bundle_decrypt.md index dd3b42b7..6fbbbbbb 100644 --- a/docs/cmd/harp_bundle_decrypt.md +++ b/docs/cmd/harp_bundle_decrypt.md @@ -2,10 +2,45 @@ Decrypt secret values +### Synopsis + +Decrypt a bundle content. + +For confidentiality purpose, bundle package value can be encrypted before +the container sealing. It offers confidentiality properties so that the +final consumer must know an additional decryption key to be allowed to +read the package value. + +All package properties (name, labels, annotations) remain a clear-text +message. Only package values (secret K/V) is encrypted. + +In order to decrypt the package value, harp uses the value encryption +transformers. The required key must be provided in a format understandable +by the encryption transformer factory. + +This act as in-transit/in-use encryption. + ``` harp bundle decrypt [flags] ``` +### Examples + +``` + # Decrypt a bundle from STDIN and produce output to STDOUT + harp bundle decrypt --key + + # Decrypt a bundle from STDIN using multiple transformer keys + harp bundle decrypt --key --key + + # Decrypt a bundle from STDIN and ignore secrets which could not be decrypted + # with given transformer key (partial decryption / authorization by key) + harp bundle decrypt --skip-not-decryptable --key + + # Decrypt a bundle from STDIN and produce output to a file + harp bundle decrypt --key --out decrypted.bundle +``` + ### Options ``` diff --git a/docs/cmd/harp_bundle_diff.md b/docs/cmd/harp_bundle_diff.md index b73bda01..4ba12eb9 100644 --- a/docs/cmd/harp_bundle_diff.md +++ b/docs/cmd/harp_bundle_diff.md @@ -1,17 +1,34 @@ ## harp bundle diff -Display container differences +Display bundle differences + +### Synopsis + +Compute Bundle object differences. + +Useful to debug a BundlePatch application and watch for a Bundle alteration. ``` harp bundle diff [flags] ``` +### Examples + +``` + # Diff a bundle from STD and a file based one + harp bundle diff --old - --new rotated.bundle + + # Generate a BundlePatch from differences + harp bundle diff --old - --new rotated.bundle --patch --out rotation.yaml +``` + ### Options ``` -h, --help help for diff --new string Container path ('-' for stdin or filename) --old string Container path ('-' for stdin or filename) + --out string Output ('-' for stdout or filename) (default "-") --patch Output as a bundle patch ``` diff --git a/docs/cmd/harp_bundle_dump.md b/docs/cmd/harp_bundle_dump.md index 46562d10..dd7ac86a 100644 --- a/docs/cmd/harp_bundle_dump.md +++ b/docs/cmd/harp_bundle_dump.md @@ -2,10 +2,43 @@ Dump as JSON +### Synopsis + +Inspect a Bundle object. + +Harp Bundles is a structure designed to hold additional properties associated +to a path (package name) and values (secrets). For your pipeline usages, you +can store annotations, labels and user data which can be consumed and/or +produced during the secret management pipeline execution. + +The Bundle object specification can be consulted here - https://ela.st/harp-spec-bundle + ``` harp bundle dump [flags] ``` +### Examples + +``` + # Dump a JSON representation of a Bundle object from STDIN + harp bundle dump + + # Dump a JSON map containing package name as key and associated secret kv + harp bundle dump --data-only + + # Dump a JSON map containing package name as key and associated metadata + harp bundle dump --metadata-only + + # Dump all package paths as a list (useful for xargs usage) + harp bundle dump --path-only + + # Dump a Bundle using a JMEFilter query + harp bundle dump --query + + # Dump a bundle content excluding the template used to generate + harp bundle dump --skip-template +``` + ### Options ``` diff --git a/docs/cmd/harp_bundle_encrypt.md b/docs/cmd/harp_bundle_encrypt.md index b38b1759..f96e0da9 100644 --- a/docs/cmd/harp_bundle_encrypt.md +++ b/docs/cmd/harp_bundle_encrypt.md @@ -2,10 +2,40 @@ Encrypt secret values +### Synopsis + +Apply package content encryption. + +For confidentiality purpose, bundle package value can be encrypted before +the container sealing. It offers confidentiality properties so that the +final consumer must know an additional decryption key to be allowed to +read the package value even if it can unseal the container. + +All package properties (name, labels, annotations) remain a clear-text +message. Only package values (secret K/V) are encrypted. + +This act as in-transit/in-use encryption. + +Annotations: + +* harp.elastic.co/v1/package#encryptionKeyAlias= - Set this + annotation on packages to reference a key alias. + ``` harp bundle encrypt [flags] ``` +### Examples + +``` + # Encrypt a whole bundle from STDIN and produce output to STDOUT + harp bundle encrypt --key + + # Encrypt partially a bundle using the annotation matcher from STDIN and + # produce output to STDOUT + harp bundle encrypt --key-alias : --key-alias : +``` + ### Options ``` diff --git a/docs/cmd/harp_bundle_filter.md b/docs/cmd/harp_bundle_filter.md index b945aca9..d6576b23 100644 --- a/docs/cmd/harp_bundle_filter.md +++ b/docs/cmd/harp_bundle_filter.md @@ -2,10 +2,58 @@ Filter package names +### Synopsis + +Create a new Bundle based on applied package matchers. + +Filtering a Bundle consists in reducing the Bundle packages using a matcher +applied on the Bundle and Package model to select them, and export them +in another Bundle. + +In order to filter packages, you can use : +* a package name selector +* a JMES query +* a REGO policy +* a Set of CEL expressions + +Bundle package filtering capabilities are the root of the secret management +by contract. Filter commands can be pipelined to produce complex filtering +pipelines and target the appropriate secrets. + +TIP: Use this command to debug your BundlePatch matchers. + ``` harp bundle filter [flags] ``` +### Examples + +``` + # Exclude specific packages by name from STDIN bundle to STDOUT. + harp bundle filter --exclude "$app/(staging|production)/*" + + # Exclude specific packages by name from file bundle to STDOUT + harp bundle filter --in customer.bundle --exclude "$app/(staging|production)/*" + + # Keep specific packages by name + harp bundle filter --keep "$app/(staging|production)/*" + + # Filter packages using a JMES query (context is the package) + harp bundle filter --query "labels.deprecated == 'true'" + + # Filter packages using a JMES query (context is the package) to a file based bundle. + harp bundle filter --query "labels.deprecated == 'true'" --out deprecated.bundle + + # Filter packages using a REGO policy + harp bundle filter --policy deprecated.rego + + # Filter packages using a CEL matcher expressions (associated with AND logic if multiple) + harp bundle filter --cel "p.match_secret('*Key')" + + # Reverse the matcher logic + harp bundle filter --not +``` + ### Options ``` diff --git a/docs/cmd/harp_bundle_lint.md b/docs/cmd/harp_bundle_lint.md index 3a7fdd07..0339daef 100644 --- a/docs/cmd/harp_bundle_lint.md +++ b/docs/cmd/harp_bundle_lint.md @@ -1,11 +1,26 @@ ## harp bundle lint -Lint the bundle using the given ruleset spec +Lint the bundle using the given RuleSet spec + +### Synopsis + +Apply a RuleSet specification to the given bundle. + +This command is used to check a Bundle structure (Package => Secrets). +A control gate could be implemented with this command to enforce a bundle +structure by decoupling the bundle content and the usage contract. ``` harp bundle lint [flags] ``` +### Examples + +``` + # Lint a bundle from STDIN + harp bundle lint --spec cso.yaml +``` + ### Options ``` diff --git a/docs/cmd/harp_transform_hash.md b/docs/cmd/harp_transform_hash.md index f2105f04..adcc68a7 100644 --- a/docs/cmd/harp_transform_hash.md +++ b/docs/cmd/harp_transform_hash.md @@ -9,7 +9,7 @@ Process the input to compute the hash according to selected hash algorithm. The command input is limited to size lower than 250 MB. Supported Algorithms: - blake2b-256, blake2b-384, blake2b-512, md5, sha1, sha224, sha256, sha3-224, sha3-256, sha3-384, sha3-512, sha512, sha512/224, sha512/256 + blake2b-256, blake2b-384, blake2b-512, blake2s-256, md5, sha1, sha224, sha256, sha3-224, sha3-256, sha3-384, sha3-512, sha512, sha512/224, sha512/256 ``` harp transform hash [flags] diff --git a/docs/cmd/harp_transform_multihash.md b/docs/cmd/harp_transform_multihash.md index def75c03..152b228e 100644 --- a/docs/cmd/harp_transform_multihash.md +++ b/docs/cmd/harp_transform_multihash.md @@ -9,7 +9,7 @@ Process the input to compute the hashes according to selected hash algorithms. The command input is limited to size lower than 250 MB. Supported Algorithms: - blake2b-256, blake2b-384, blake2b-512, md5, sha1, sha224, sha256, sha3-224, sha3-256, sha3-384, sha3-512, sha512, sha512/224, sha512/256 + blake2b-256, blake2b-384, blake2b-512, blake2s-256, md5, sha1, sha224, sha256, sha3-224, sha3-256, sha3-384, sha3-512, sha512, sha512/224, sha512/256 ``` harp transform multihash [flags] diff --git a/pkg/bundle/ruleset/linter/engine/rego/engine.go b/pkg/bundle/ruleset/linter/engine/rego/engine.go index ff934f15..4b981074 100644 --- a/pkg/bundle/ruleset/linter/engine/rego/engine.go +++ b/pkg/bundle/ruleset/linter/engine/rego/engine.go @@ -29,9 +29,13 @@ import ( "github.com/elastic/harp/pkg/bundle/ruleset/linter/engine" ) +const ( + maxPolicySize = 5 * 1024 * 1025 // 5MB +) + func New(ctx context.Context, r io.Reader) (engine.PackageLinter, error) { // Read all policy content - policy, err := io.ReadAll(r) + policy, err := io.ReadAll(io.LimitReader(r, maxPolicySize)) if err != nil { return nil, fmt.Errorf("unable to read the policy content: %w", err) } diff --git a/pkg/bundle/ruleset/linter/package.go b/pkg/bundle/ruleset/linter/package.go index 0cf1ded7..4fdafea4 100644 --- a/pkg/bundle/ruleset/linter/package.go +++ b/pkg/bundle/ruleset/linter/package.go @@ -22,6 +22,8 @@ import ( "encoding/base64" "errors" "fmt" + "os" + "strings" "github.com/gobwas/glob" "golang.org/x/crypto/blake2b" @@ -30,6 +32,7 @@ import ( bundlev1 "github.com/elastic/harp/api/gen/go/harp/bundle/v1" "github.com/elastic/harp/pkg/bundle/ruleset/linter/engine" "github.com/elastic/harp/pkg/bundle/ruleset/linter/engine/cel" + "github.com/elastic/harp/pkg/bundle/ruleset/linter/engine/rego" ) // Validate bundle patch. @@ -80,6 +83,7 @@ func Checksum(spec *bundlev1.RuleSet) (string, error) { } // Evaluate given bundl using the loaded ruleset. +//nolint:gocyclo // to refactor func Evaluate(ctx context.Context, b *bundlev1.Bundle, spec *bundlev1.RuleSet) error { // Validate spec if err := Validate(spec); err != nil { @@ -102,10 +106,32 @@ func Evaluate(ctx context.Context, b *bundlev1.Bundle, spec *bundlev1.RuleSet) e return fmt.Errorf("unable to compile path matcher: %w", err) } - // Compile constraints - vm, err := cel.New(r.Constraints) - if err != nil { - return fmt.Errorf("unable to prepare evaluation context: %w", err) + var ( + vm engine.PackageLinter + vmErr error + ) + + switch { + case len(r.Constraints) > 0: + // Compile constraints + vm, vmErr = cel.New(r.Constraints) + case r.RegoFile != "": + // Open policy file + f, err := os.Open(r.RegoFile) + if err != nil { + return fmt.Errorf("unable to open rego policy file: %w", err) + } + + // Create a evaluation context + vm, vmErr = rego.New(ctx, f) + case r.Rego != "": + // Create a evaluation context + vm, vmErr = rego.New(ctx, strings.NewReader(r.Rego)) + default: + return errors.New("one of 'constraints', 'rego' or 'rego_file' property must be defined") + } + if vmErr != nil { + return fmt.Errorf("unable to prepare evaluation context: %w", vmErr) } // A rule must match at least one time. diff --git a/pkg/bundle/ruleset/linter/package_test.go b/pkg/bundle/ruleset/linter/package_test.go index 5322f7f5..f59206b9 100644 --- a/pkg/bundle/ruleset/linter/package_test.go +++ b/pkg/bundle/ruleset/linter/package_test.go @@ -20,10 +20,12 @@ package linter import ( "context" "os" + "path/filepath" "reflect" "testing" bundlev1 "github.com/elastic/harp/api/gen/go/harp/bundle/v1" + fuzz "github.com/google/gofuzz" ) func TestValidate(t *testing.T) { @@ -155,6 +157,10 @@ func TestChecksum(t *testing.T) { } func mustLoadRuleSet(filePath string) *bundlev1.RuleSet { + if err := os.Chdir(filepath.Dir(filePath)); err != nil { + panic(err) + } + f, err := os.Open(filePath) if err != nil { panic(err) @@ -269,6 +275,106 @@ func TestEvaluate(t *testing.T) { }, wantErr: true, }, + { + name: "rego - valid bundle", + args: args{ + spec: mustLoadRuleSet("../../../../test/fixtures/ruleset/valid/rego.yaml"), + b: &bundlev1.Bundle{ + Packages: []*bundlev1.Package{ + { + Name: "app/qa/security/harp/v1.0.0/server/database/credentials", + Annotations: map[string]string{ + "infosec.elastic.co/v1/SecretPolicy#severity": "moderate", + }, + Secrets: &bundlev1.SecretChain{ + Data: []*bundlev1.KV{ + { + Key: "DB_HOST", + }, + { + Key: "DB_NAME", + }, + { + Key: "DB_USER", + }, + { + Key: "DB_PASSWORD", + }, + }, + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "rego - invalid bundle", + args: args{ + spec: mustLoadRuleSet("../../../../test/fixtures/ruleset/valid/rego.yaml"), + b: &bundlev1.Bundle{ + Packages: []*bundlev1.Package{ + { + Name: "app/qa/security/harp/v1.0.0/server/database/credentials", + Secrets: &bundlev1.SecretChain{ + Data: []*bundlev1.KV{}, + }, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "regofile - valid bundle", + args: args{ + spec: mustLoadRuleSet("../../../../test/fixtures/ruleset/valid/rego-file.yaml"), + b: &bundlev1.Bundle{ + Packages: []*bundlev1.Package{ + { + Name: "app/qa/security/harp/v1.0.0/server/database/credentials", + Annotations: map[string]string{ + "infosec.elastic.co/v1/SecretPolicy#severity": "moderate", + }, + Secrets: &bundlev1.SecretChain{ + Data: []*bundlev1.KV{ + { + Key: "DB_HOST", + }, + { + Key: "DB_NAME", + }, + { + Key: "DB_USER", + }, + { + Key: "DB_PASSWORD", + }, + }, + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "regofile - invalid bundle", + args: args{ + spec: mustLoadRuleSet("../../../../test/fixtures/ruleset/valid/rego-file.yaml"), + b: &bundlev1.Bundle{ + Packages: []*bundlev1.Package{ + { + Name: "app/qa/security/harp/v1.0.0/server/database/credentials", + Secrets: &bundlev1.SecretChain{ + Data: []*bundlev1.KV{}, + }, + }, + }, + }, + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -280,3 +386,42 @@ func TestEvaluate(t *testing.T) { }) } } + +func TestEvaluate_Fuzz(t *testing.T) { + // Making sure the descrption never panics + for i := 0; i < 500; i++ { + f := fuzz.New() + + rs := bundlev1.RuleSet{ + ApiVersion: "harp.elastic.co/v1", + Kind: "RuleSet", + Meta: &bundlev1.RuleSetMeta{}, + Spec: &bundlev1.RuleSetSpec{ + Rules: []*bundlev1.Rule{ + {}, + }, + }, + } + file := bundlev1.Bundle{ + Packages: []*bundlev1.Package{ + { + Name: "foo", + Secrets: &bundlev1.SecretChain{ + Data: []*bundlev1.KV{ + { + Key: "k1", + Value: []byte("v1"), + }, + }, + }, + }, + }, + } + + f.Fuzz(&rs) + f.Fuzz(&file) + + // Execute + Evaluate(context.Background(), &file, &rs) + } +} diff --git a/pkg/bundle/ruleset/linter/reader_test.go b/pkg/bundle/ruleset/linter/reader_test.go index 57912d96..0e5e9697 100644 --- a/pkg/bundle/ruleset/linter/reader_test.go +++ b/pkg/bundle/ruleset/linter/reader_test.go @@ -49,6 +49,9 @@ func generateReaderTests(t *testing.T, rootPath, state string, wantErr bool) []r if info.IsDir() { return nil } + if filepath.Ext(path) != "yaml" { + return nil + } tests = append(tests, readerTestCase{ name: fmt.Sprintf("%s-%s", state, filepath.Base(info.Name())), diff --git a/pkg/sdk/value/encoding/reader.go b/pkg/sdk/value/encoding/reader.go index 6827d041..ec1208a8 100644 --- a/pkg/sdk/value/encoding/reader.go +++ b/pkg/sdk/value/encoding/reader.go @@ -34,9 +34,7 @@ func NewReader(r io.Reader, encoding string) (io.Reader, error) { // Normalize input encoding = strings.TrimSpace(strings.ToLower(encoding)) - var ( - decoderReader io.Reader - ) + var decoderReader io.Reader // Apply transformation switch encoding { diff --git a/pkg/sdk/value/encoding/writer.go b/pkg/sdk/value/encoding/writer.go index ac0740ee..7a610c71 100644 --- a/pkg/sdk/value/encoding/writer.go +++ b/pkg/sdk/value/encoding/writer.go @@ -36,9 +36,7 @@ func NewWriter(w io.Writer, encoding string) (io.WriteCloser, error) { // Normalize input encoding = strings.TrimSpace(strings.ToLower(encoding)) - var ( - encoderWriter io.WriteCloser - ) + var encoderWriter io.WriteCloser // Apply transformation switch encoding { diff --git a/pkg/sdk/value/encryption/transformer_test.go b/pkg/sdk/value/encryption/transformer_test.go index 854fb618..ae63ab2e 100644 --- a/pkg/sdk/value/encryption/transformer_test.go +++ b/pkg/sdk/value/encryption/transformer_test.go @@ -27,7 +27,6 @@ import ( "github.com/elastic/harp/pkg/sdk/value" "github.com/elastic/harp/pkg/sdk/value/encryption" - // Register encryption transformers _ "github.com/elastic/harp/pkg/sdk/value/encryption/aead" _ "github.com/elastic/harp/pkg/sdk/value/encryption/age" diff --git a/pkg/sdk/value/hash/multi.go b/pkg/sdk/value/hash/multi.go index c1186e02..06ea9886 100644 --- a/pkg/sdk/value/hash/multi.go +++ b/pkg/sdk/value/hash/multi.go @@ -46,7 +46,7 @@ func NewMultiHash(r io.Reader, algorithms ...string) (map[string]string, error) } // Finalize - var res = make(map[string]string) + res := make(map[string]string) for algo, v := range hashers { res[algo] = hex.EncodeToString(v.Sum(nil)) } @@ -58,7 +58,7 @@ func NewMultiHash(r io.Reader, algorithms ...string) (map[string]string, error) // ----------------------------------------------------------------------------- func hashToMultiWriter(hashers map[string]hash.Hash) io.Writer { - var w = make([]io.Writer, 0, len(hashers)) + w := make([]io.Writer, 0, len(hashers)) for _, v := range hashers { w = append(w, v) } diff --git a/pkg/sdk/value/hash/writer.go b/pkg/sdk/value/hash/writer.go index 218f828c..970c703d 100644 --- a/pkg/sdk/value/hash/writer.go +++ b/pkg/sdk/value/hash/writer.go @@ -33,12 +33,11 @@ import ( // ensure crypto algorithms are initialized _ "golang.org/x/crypto/blake2b" + _ "golang.org/x/crypto/blake2s" _ "golang.org/x/crypto/sha3" ) -var ( - name2Hash = map[string]crypto.Hash{} -) +var name2Hash = map[string]crypto.Hash{} // ----------------------------------------------------------------------------- diff --git a/pkg/tasks/bundle/decrypt_test.go b/pkg/tasks/bundle/decrypt_test.go index e688971c..1f3f6e7f 100644 --- a/pkg/tasks/bundle/decrypt_test.go +++ b/pkg/tasks/bundle/decrypt_test.go @@ -26,7 +26,6 @@ import ( "github.com/elastic/harp/pkg/sdk/cmdutil" "github.com/elastic/harp/pkg/sdk/value" "github.com/elastic/harp/pkg/sdk/value/encryption" - // Import for tests _ "github.com/elastic/harp/pkg/sdk/value/encryption/aead" "github.com/elastic/harp/pkg/sdk/value/identity" diff --git a/pkg/tasks/container/recover_test.go b/pkg/tasks/container/recover_test.go index 9a9862c6..24b9a42d 100644 --- a/pkg/tasks/container/recover_test.go +++ b/pkg/tasks/container/recover_test.go @@ -26,7 +26,6 @@ import ( "github.com/elastic/harp/pkg/sdk/cmdutil" "github.com/elastic/harp/pkg/sdk/value" "github.com/elastic/harp/pkg/sdk/value/encryption" - // Imported for tests _ "github.com/elastic/harp/pkg/sdk/value/encryption/jwe" "github.com/elastic/harp/pkg/sdk/value/identity" diff --git a/test/fixtures/ruleset/valid/policy.rego b/test/fixtures/ruleset/valid/policy.rego new file mode 100644 index 00000000..91324046 --- /dev/null +++ b/test/fixtures/ruleset/valid/policy.rego @@ -0,0 +1,10 @@ +package harp + +default compliant = false + +compliant { + input.annotations["infosec.elastic.co/v1/SecretPolicy#severity"] == "moderate" + secrets := ["DB_HOST","DB_NAME","DB_USER","DB_PASSWORD"] + # Has all secrets + input.secrets.data[_].key == secrets[_] +} diff --git a/test/fixtures/ruleset/valid/rego-file.yaml b/test/fixtures/ruleset/valid/rego-file.yaml new file mode 100644 index 00000000..9b1fe173 --- /dev/null +++ b/test/fixtures/ruleset/valid/rego-file.yaml @@ -0,0 +1,12 @@ +apiVersion: harp.elastic.co/v1 +kind: RuleSet +meta: + name: harp-server + description: Package and secret constraints for harp-server + owner: security@elastic.co +spec: + rules: + - name: HARP-SRV-0001 + description: The target package must have all secrets declared + path: "app/qa/security/harp/v1.0.0/server/database/credentials" + regoFile: policy.rego diff --git a/test/fixtures/ruleset/valid/rego.yaml b/test/fixtures/ruleset/valid/rego.yaml new file mode 100644 index 00000000..352f22f2 --- /dev/null +++ b/test/fixtures/ruleset/valid/rego.yaml @@ -0,0 +1,21 @@ +apiVersion: harp.elastic.co/v1 +kind: RuleSet +meta: + name: harp-server + description: Package and secret constraints for harp-server + owner: security@elastic.co +spec: + rules: + - name: HARP-SRV-0001 + description: The target package must have all secrets declared + path: "app/qa/security/harp/v1.0.0/server/database/credentials" + rego: | + package harp + default compliant = false + + compliant { + input.annotations["infosec.elastic.co/v1/SecretPolicy#severity"] == "moderate" + secrets := ["DB_HOST","DB_NAME","DB_USER","DB_PASSWORD"] + # Has all secrets + input.secrets.data[_].key == secrets[_] + }