diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..325cb71 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,10 @@ +version: v1 +plugins: + - plugin: buf.build/protocolbuffers/go:v1.32.0 + out: . + opt: + - paths=source_relative + - plugin: buf.build/bufbuild/validate-go + out: . + opt: + - paths=source_relative diff --git a/buf.lock b/buf.lock new file mode 100644 index 0000000..0a49027 --- /dev/null +++ b/buf.lock @@ -0,0 +1,8 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: envoyproxy + repository: protoc-gen-validate + commit: 71881f09a0c5420a9545a07987a86728 + digest: shake256:d320bbf06653b1b2b45a1f95bfa82bf7b998221a777a042708c50d6f86a30d1a85b50c5704c597142d9b308280efe1295d39d76d1abea5f7046d3df4c8cc3cef diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 0000000..7684dcd --- /dev/null +++ b/buf.yaml @@ -0,0 +1,3 @@ +version: v1 +deps: + - buf.build/envoyproxy/protoc-gen-validate diff --git a/config/config.pb.go b/config/config.pb.go new file mode 100644 index 0000000..3a7a2a1 --- /dev/null +++ b/config/config.pb.go @@ -0,0 +1,874 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc (unknown) +// source: config/config.proto + +package config + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + mock "github.com/tetrateio/authservice/config/mock" + oidc "github.com/tetrateio/authservice/config/oidc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Specifies how a request can be matched to a filter chain. +type Match struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the http header used to match against. + // Required. + Header string `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + // The criteria by which to match. + // Must be one of `prefix` or `equality`. + // Required. + // + // Types that are assignable to Criteria: + // + // *Match_Prefix + // *Match_Equality + Criteria isMatch_Criteria `protobuf_oneof:"criteria"` +} + +func (x *Match) Reset() { + *x = Match{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Match) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Match) ProtoMessage() {} + +func (x *Match) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Match.ProtoReflect.Descriptor instead. +func (*Match) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{0} +} + +func (x *Match) GetHeader() string { + if x != nil { + return x.Header + } + return "" +} + +func (m *Match) GetCriteria() isMatch_Criteria { + if m != nil { + return m.Criteria + } + return nil +} + +func (x *Match) GetPrefix() string { + if x, ok := x.GetCriteria().(*Match_Prefix); ok { + return x.Prefix + } + return "" +} + +func (x *Match) GetEquality() string { + if x, ok := x.GetCriteria().(*Match_Equality); ok { + return x.Equality + } + return "" +} + +type isMatch_Criteria interface { + isMatch_Criteria() +} + +type Match_Prefix struct { + // The expected prefix. If the actual value of the header starts with this prefix, + // then it will be considered a match. + Prefix string `protobuf:"bytes,2,opt,name=prefix,proto3,oneof"` +} + +type Match_Equality struct { + // The expected value. If the actual value of the header exactly equals this value, + // then it will be considered a match. + Equality string `protobuf:"bytes,3,opt,name=equality,proto3,oneof"` +} + +func (*Match_Prefix) isMatch_Criteria() {} + +func (*Match_Equality) isMatch_Criteria() {} + +// A filter configuration. +type Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type of filter. Currently, the only valid types are `oidc` + // and `mock`. Required. + // + // Types that are assignable to Type: + // + // *Filter_Oidc + // *Filter_OidcOverride + // *Filter_Mock + Type isFilter_Type `protobuf_oneof:"type"` +} + +func (x *Filter) Reset() { + *x = Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Filter) ProtoMessage() {} + +func (x *Filter) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Filter.ProtoReflect.Descriptor instead. +func (*Filter) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{1} +} + +func (m *Filter) GetType() isFilter_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *Filter) GetOidc() *oidc.OIDCConfig { + if x, ok := x.GetType().(*Filter_Oidc); ok { + return x.Oidc + } + return nil +} + +func (x *Filter) GetOidcOverride() *oidc.OIDCConfig { + if x, ok := x.GetType().(*Filter_OidcOverride); ok { + return x.OidcOverride + } + return nil +} + +func (x *Filter) GetMock() *mock.MockConfig { + if x, ok := x.GetType().(*Filter_Mock); ok { + return x.Mock + } + return nil +} + +type isFilter_Type interface { + isFilter_Type() +} + +type Filter_Oidc struct { + // An OpenID Connect filter configuration. + Oidc *oidc.OIDCConfig `protobuf:"bytes,1,opt,name=oidc,proto3,oneof"` +} + +type Filter_OidcOverride struct { + // This value will be used when `default_oidc_config` exists. + // It will override values of them. If that doesn't exist, + // this configuration will be rejected. + OidcOverride *oidc.OIDCConfig `protobuf:"bytes,2,opt,name=oidc_override,json=oidcOverride,proto3,oneof"` +} + +type Filter_Mock struct { + // Mock filter configuration for testing and letting + // AuthService run even if no OIDC providers are configured. + Mock *mock.MockConfig `protobuf:"bytes,3,opt,name=mock,proto3,oneof"` +} + +func (*Filter_Oidc) isFilter_Type() {} + +func (*Filter_OidcOverride) isFilter_Type() {} + +func (*Filter_Mock) isFilter_Type() {} + +// A chain of one or more filters that will sequentially process an HTTP request. +type FilterChain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A user-defined identifier for the processing chain used in log messages. + // Required. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // A rule to determine whether an HTTP request should be processed by the filter chain. + // If not defined, the filter chain will match every request. + // Optional. + Match *Match `protobuf:"bytes,2,opt,name=match,proto3" json:"match,omitempty"` + // The configuration of one of more filters in the filter chain. When the filter chain + // matches an incoming request, then this list of filters will be applied to the request + // in the order that they are declared. + // All filters are evaluated until one of them returns a non-OK response. + // If all filters return OK, the envoy proxy is notified that the request may continue. + // The first filter that returns a non-OK response causes the request to be rejected with + // the filter's returned status and any remaining filters are skipped. + // At least one `Filter` is required in this array. + Filters []*Filter `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"` +} + +func (x *FilterChain) Reset() { + *x = FilterChain{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FilterChain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilterChain) ProtoMessage() {} + +func (x *FilterChain) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilterChain.ProtoReflect.Descriptor instead. +func (*FilterChain) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{2} +} + +func (x *FilterChain) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *FilterChain) GetMatch() *Match { + if x != nil { + return x.Match + } + return nil +} + +func (x *FilterChain) GetFilters() []*Filter { + if x != nil { + return x.Filters + } + return nil +} + +// The top-level configuration object. +// For a simple example, see the [sample JSON in the bookinfo configmap template](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/authservice-configmap-template-for-authn-and-authz.yaml). +type Config struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Each incoming http request is matched against the list of filters in the chain, in order, + // until a matching filter is found. The first matching filter is then applied to the request. + // After the first match is made, other filters in the chain are ignored. + // Order of chain declaration is therefore important. + // At least one `FilterChain` is required in this array. + Chains []*FilterChain `protobuf:"bytes,1,rep,name=chains,proto3" json:"chains,omitempty"` + // The IP address for the Authservice to listen for incoming requests to process. + // Required. + ListenAddress string `protobuf:"bytes,2,opt,name=listen_address,json=listenAddress,proto3" json:"listen_address,omitempty"` + // The TCP port for the Authservice to listen for incoming requests to process. + // Required. + ListenPort int32 `protobuf:"varint,3,opt,name=listen_port,json=listenPort,proto3" json:"listen_port,omitempty"` + // The verbosity of logs generated by the Authservice. + // Must be one of `trace`, `debug`, `info', 'error' or 'critical'. + // Required. + LogLevel string `protobuf:"bytes,4,opt,name=log_level,json=logLevel,proto3" json:"log_level,omitempty"` + // The number of threads in the thread pool to use for processing. + // The main thread will be used for accepting connections, before sending them to the thread-pool + // for processing. The total number of running threads, including the main thread, will be N+1. + // Required. + Threads uint32 `protobuf:"varint,5,opt,name=threads,proto3" json:"threads,omitempty"` + // List of trigger rules to decide if the Authservice should be used to authenticate the + // request. The Authservice authentication happens if any one of the rules matched. + // If the list is not empty and none of the rules matched, the request will be allowed + // to proceed without Authservice authentication. + // The format and semantics of `trigger_rules` are the same as the `triggerRules` setting + // on the Istio Authentication Policy + // (see https://istio.io/docs/reference/config/security/istio.authentication.v1alpha1). + // CAUTION: Be sure that your configured `OIDCConfig.callback` and `OIDCConfig.logout` paths + // each satisfies at least one of the trigger rules, or else the Authservice will not be able to + // intercept requests made to those paths to perform the appropriate login/logout behavior. + // Optional. Leave this empty to always trigger authentication for all paths. + TriggerRules []*TriggerRule `protobuf:"bytes,9,rep,name=trigger_rules,json=triggerRules,proto3" json:"trigger_rules,omitempty"` + // Global configuration of OIDC. This value will be applied to all filter definition + // when it defined as `oidc_override`. + // Optional. + DefaultOidcConfig *oidc.OIDCConfig `protobuf:"bytes,10,opt,name=default_oidc_config,json=defaultOidcConfig,proto3" json:"default_oidc_config,omitempty"` + // If true will allow the the requests even no filter chain match is found. Default false. + // Optional. + AllowUnmatchedRequests bool `protobuf:"varint,11,opt,name=allow_unmatched_requests,json=allowUnmatchedRequests,proto3" json:"allow_unmatched_requests,omitempty"` +} + +func (x *Config) Reset() { + *x = Config{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{3} +} + +func (x *Config) GetChains() []*FilterChain { + if x != nil { + return x.Chains + } + return nil +} + +func (x *Config) GetListenAddress() string { + if x != nil { + return x.ListenAddress + } + return "" +} + +func (x *Config) GetListenPort() int32 { + if x != nil { + return x.ListenPort + } + return 0 +} + +func (x *Config) GetLogLevel() string { + if x != nil { + return x.LogLevel + } + return "" +} + +func (x *Config) GetThreads() uint32 { + if x != nil { + return x.Threads + } + return 0 +} + +func (x *Config) GetTriggerRules() []*TriggerRule { + if x != nil { + return x.TriggerRules + } + return nil +} + +func (x *Config) GetDefaultOidcConfig() *oidc.OIDCConfig { + if x != nil { + return x.DefaultOidcConfig + } + return nil +} + +func (x *Config) GetAllowUnmatchedRequests() bool { + if x != nil { + return x.AllowUnmatchedRequests + } + return false +} + +// Trigger rule to match against a request. The trigger rule is satisfied if +// and only if both rules, excluded_paths and include_paths are satisfied. +type TriggerRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of paths to be excluded from the request. The rule is satisfied if + // request path does not match to any of the path in this list. + // Optional. + ExcludedPaths []*StringMatch `protobuf:"bytes,1,rep,name=excluded_paths,json=excludedPaths,proto3" json:"excluded_paths,omitempty"` + // List of paths that the request must include. If the list is not empty, the + // rule is satisfied if request path matches at least one of the path in the list. + // If the list is empty, the rule is ignored, in other words the rule is always satisfied. + // Optional. + IncludedPaths []*StringMatch `protobuf:"bytes,2,rep,name=included_paths,json=includedPaths,proto3" json:"included_paths,omitempty"` +} + +func (x *TriggerRule) Reset() { + *x = TriggerRule{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TriggerRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerRule) ProtoMessage() {} + +func (x *TriggerRule) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerRule.ProtoReflect.Descriptor instead. +func (*TriggerRule) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{4} +} + +func (x *TriggerRule) GetExcludedPaths() []*StringMatch { + if x != nil { + return x.ExcludedPaths + } + return nil +} + +func (x *TriggerRule) GetIncludedPaths() []*StringMatch { + if x != nil { + return x.IncludedPaths + } + return nil +} + +// Describes how to match a given string. Match is case-sensitive. +type StringMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to MatchType: + // + // *StringMatch_Exact + // *StringMatch_Prefix + // *StringMatch_Suffix + // *StringMatch_Regex + MatchType isStringMatch_MatchType `protobuf_oneof:"match_type"` +} + +func (x *StringMatch) Reset() { + *x = StringMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_config_config_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StringMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringMatch) ProtoMessage() {} + +func (x *StringMatch) ProtoReflect() protoreflect.Message { + mi := &file_config_config_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringMatch.ProtoReflect.Descriptor instead. +func (*StringMatch) Descriptor() ([]byte, []int) { + return file_config_config_proto_rawDescGZIP(), []int{5} +} + +func (m *StringMatch) GetMatchType() isStringMatch_MatchType { + if m != nil { + return m.MatchType + } + return nil +} + +func (x *StringMatch) GetExact() string { + if x, ok := x.GetMatchType().(*StringMatch_Exact); ok { + return x.Exact + } + return "" +} + +func (x *StringMatch) GetPrefix() string { + if x, ok := x.GetMatchType().(*StringMatch_Prefix); ok { + return x.Prefix + } + return "" +} + +func (x *StringMatch) GetSuffix() string { + if x, ok := x.GetMatchType().(*StringMatch_Suffix); ok { + return x.Suffix + } + return "" +} + +func (x *StringMatch) GetRegex() string { + if x, ok := x.GetMatchType().(*StringMatch_Regex); ok { + return x.Regex + } + return "" +} + +type isStringMatch_MatchType interface { + isStringMatch_MatchType() +} + +type StringMatch_Exact struct { + // exact string match. + Exact string `protobuf:"bytes,1,opt,name=exact,proto3,oneof"` +} + +type StringMatch_Prefix struct { + // prefix-based match. + Prefix string `protobuf:"bytes,2,opt,name=prefix,proto3,oneof"` +} + +type StringMatch_Suffix struct { + // suffix-based match. + Suffix string `protobuf:"bytes,3,opt,name=suffix,proto3,oneof"` +} + +type StringMatch_Regex struct { + // ECMAscript style regex-based match as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + // Example: "^/pets/(.*?)?" + Regex string `protobuf:"bytes,4,opt,name=regex,proto3,oneof"` +} + +func (*StringMatch_Exact) isStringMatch_MatchType() {} + +func (*StringMatch_Prefix) isStringMatch_MatchType() {} + +func (*StringMatch_Suffix) isStringMatch_MatchType() {} + +func (*StringMatch_Regex) isStringMatch_MatchType() {} + +var File_config_config_proto protoreflect.FileDescriptor + +var file_config_config_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x18, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2f, 0x6f, 0x69, 0x64, 0x63, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, + 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x01, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x1f, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x12, 0x21, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x12, 0x25, 0x0a, 0x08, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, + 0x00, 0x52, 0x08, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x0f, 0x0a, 0x08, 0x63, + 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xd7, 0x01, 0x0a, + 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x04, 0x6f, 0x69, 0x64, 0x63, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, + 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x04, 0x6f, 0x69, + 0x64, 0x63, 0x12, 0x4a, 0x0a, 0x0d, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, + 0x69, 0x64, 0x63, 0x2e, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, + 0x52, 0x0c, 0x6f, 0x69, 0x64, 0x63, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x39, + 0x0a, 0x04, 0x6d, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, + 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x6d, 0x6f, 0x63, 0x6b, 0x2e, 0x4d, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x6f, 0x63, 0x6b, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0x9b, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x3e, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x07, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x73, 0x22, 0xe8, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x41, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x70, 0x01, 0x52, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x1a, 0x04, 0x10, 0x80, + 0x80, 0x04, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x47, + 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27, 0x72, 0x25, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x52, + 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x08, 0x6c, + 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x21, 0x0a, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, + 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x28, + 0x01, 0x52, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x44, 0x0a, 0x0d, 0x74, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x0c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x53, 0x0a, 0x13, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6f, 0x69, 0x64, 0x63, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x69, 0x64, 0x63, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x75, + 0x6e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x6e, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, + 0x9d, 0x01, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, + 0x46, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x46, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, + 0x7f, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, + 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x12, 0x18, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x05, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x67, + 0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x74, 0x65, 0x69, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_config_config_proto_rawDescOnce sync.Once + file_config_config_proto_rawDescData = file_config_config_proto_rawDesc +) + +func file_config_config_proto_rawDescGZIP() []byte { + file_config_config_proto_rawDescOnce.Do(func() { + file_config_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_config_proto_rawDescData) + }) + return file_config_config_proto_rawDescData +} + +var file_config_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_config_config_proto_goTypes = []interface{}{ + (*Match)(nil), // 0: authservice.config.Match + (*Filter)(nil), // 1: authservice.config.Filter + (*FilterChain)(nil), // 2: authservice.config.FilterChain + (*Config)(nil), // 3: authservice.config.Config + (*TriggerRule)(nil), // 4: authservice.config.TriggerRule + (*StringMatch)(nil), // 5: authservice.config.StringMatch + (*oidc.OIDCConfig)(nil), // 6: authservice.config.oidc.OIDCConfig + (*mock.MockConfig)(nil), // 7: authservice.config.mock.MockConfig +} +var file_config_config_proto_depIdxs = []int32{ + 6, // 0: authservice.config.Filter.oidc:type_name -> authservice.config.oidc.OIDCConfig + 6, // 1: authservice.config.Filter.oidc_override:type_name -> authservice.config.oidc.OIDCConfig + 7, // 2: authservice.config.Filter.mock:type_name -> authservice.config.mock.MockConfig + 0, // 3: authservice.config.FilterChain.match:type_name -> authservice.config.Match + 1, // 4: authservice.config.FilterChain.filters:type_name -> authservice.config.Filter + 2, // 5: authservice.config.Config.chains:type_name -> authservice.config.FilterChain + 4, // 6: authservice.config.Config.trigger_rules:type_name -> authservice.config.TriggerRule + 6, // 7: authservice.config.Config.default_oidc_config:type_name -> authservice.config.oidc.OIDCConfig + 5, // 8: authservice.config.TriggerRule.excluded_paths:type_name -> authservice.config.StringMatch + 5, // 9: authservice.config.TriggerRule.included_paths:type_name -> authservice.config.StringMatch + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_config_config_proto_init() } +func file_config_config_proto_init() { + if File_config_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_config_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Match); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FilterChain); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Config); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TriggerRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StringMatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_config_config_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Match_Prefix)(nil), + (*Match_Equality)(nil), + } + file_config_config_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Filter_Oidc)(nil), + (*Filter_OidcOverride)(nil), + (*Filter_Mock)(nil), + } + file_config_config_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*StringMatch_Exact)(nil), + (*StringMatch_Prefix)(nil), + (*StringMatch_Suffix)(nil), + (*StringMatch_Regex)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_config_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_config_config_proto_goTypes, + DependencyIndexes: file_config_config_proto_depIdxs, + MessageInfos: file_config_config_proto_msgTypes, + }.Build() + File_config_config_proto = out.File + file_config_config_proto_rawDesc = nil + file_config_config_proto_goTypes = nil + file_config_config_proto_depIdxs = nil +} diff --git a/config/config.pb.validate.go b/config/config.pb.validate.go new file mode 100644 index 0000000..a512cc0 --- /dev/null +++ b/config/config.pb.validate.go @@ -0,0 +1,1212 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: config/config.proto + +package config + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on Match with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Match) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Match with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in MatchMultiError, or nil if none found. +func (m *Match) ValidateAll() error { + return m.validate(true) +} + +func (m *Match) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetHeader()) < 1 { + err := MatchValidationError{ + field: "Header", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + oneofCriteriaPresent := false + switch v := m.Criteria.(type) { + case *Match_Prefix: + if v == nil { + err := MatchValidationError{ + field: "Criteria", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + oneofCriteriaPresent = true + + if utf8.RuneCountInString(m.GetPrefix()) < 1 { + err := MatchValidationError{ + field: "Prefix", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + case *Match_Equality: + if v == nil { + err := MatchValidationError{ + field: "Criteria", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + oneofCriteriaPresent = true + + if utf8.RuneCountInString(m.GetEquality()) < 1 { + err := MatchValidationError{ + field: "Equality", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + default: + _ = v // ensures v is used + } + if !oneofCriteriaPresent { + err := MatchValidationError{ + field: "Criteria", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return MatchMultiError(errors) + } + + return nil +} + +// MatchMultiError is an error wrapping multiple validation errors returned by +// Match.ValidateAll() if the designated constraints aren't met. +type MatchMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m MatchMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m MatchMultiError) AllErrors() []error { return m } + +// MatchValidationError is the validation error returned by Match.Validate if +// the designated constraints aren't met. +type MatchValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e MatchValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e MatchValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e MatchValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e MatchValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e MatchValidationError) ErrorName() string { return "MatchValidationError" } + +// Error satisfies the builtin error interface +func (e MatchValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sMatch.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = MatchValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = MatchValidationError{} + +// Validate checks the field values on Filter with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Filter) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Filter with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in FilterMultiError, or nil if none found. +func (m *Filter) ValidateAll() error { + return m.validate(true) +} + +func (m *Filter) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + oneofTypePresent := false + switch v := m.Type.(type) { + case *Filter_Oidc: + if v == nil { + err := FilterValidationError{ + field: "Type", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + oneofTypePresent = true + + if all { + switch v := interface{}(m.GetOidc()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, FilterValidationError{ + field: "Oidc", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, FilterValidationError{ + field: "Oidc", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetOidc()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return FilterValidationError{ + field: "Oidc", + reason: "embedded message failed validation", + cause: err, + } + } + } + + case *Filter_OidcOverride: + if v == nil { + err := FilterValidationError{ + field: "Type", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + oneofTypePresent = true + + if all { + switch v := interface{}(m.GetOidcOverride()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, FilterValidationError{ + field: "OidcOverride", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, FilterValidationError{ + field: "OidcOverride", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetOidcOverride()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return FilterValidationError{ + field: "OidcOverride", + reason: "embedded message failed validation", + cause: err, + } + } + } + + case *Filter_Mock: + if v == nil { + err := FilterValidationError{ + field: "Type", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + oneofTypePresent = true + + if all { + switch v := interface{}(m.GetMock()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, FilterValidationError{ + field: "Mock", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, FilterValidationError{ + field: "Mock", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMock()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return FilterValidationError{ + field: "Mock", + reason: "embedded message failed validation", + cause: err, + } + } + } + + default: + _ = v // ensures v is used + } + if !oneofTypePresent { + err := FilterValidationError{ + field: "Type", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return FilterMultiError(errors) + } + + return nil +} + +// FilterMultiError is an error wrapping multiple validation errors returned by +// Filter.ValidateAll() if the designated constraints aren't met. +type FilterMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m FilterMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m FilterMultiError) AllErrors() []error { return m } + +// FilterValidationError is the validation error returned by Filter.Validate if +// the designated constraints aren't met. +type FilterValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e FilterValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e FilterValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e FilterValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e FilterValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e FilterValidationError) ErrorName() string { return "FilterValidationError" } + +// Error satisfies the builtin error interface +func (e FilterValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sFilter.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = FilterValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = FilterValidationError{} + +// Validate checks the field values on FilterChain with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *FilterChain) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on FilterChain with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in FilterChainMultiError, or +// nil if none found. +func (m *FilterChain) ValidateAll() error { + return m.validate(true) +} + +func (m *FilterChain) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetName()) < 1 { + err := FilterChainValidationError{ + field: "Name", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetMatch()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, FilterChainValidationError{ + field: "Match", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, FilterChainValidationError{ + field: "Match", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMatch()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return FilterChainValidationError{ + field: "Match", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(m.GetFilters()) < 1 { + err := FilterChainValidationError{ + field: "Filters", + reason: "value must contain at least 1 item(s)", + } + if !all { + return err + } + errors = append(errors, err) + } + + for idx, item := range m.GetFilters() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, FilterChainValidationError{ + field: fmt.Sprintf("Filters[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, FilterChainValidationError{ + field: fmt.Sprintf("Filters[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return FilterChainValidationError{ + field: fmt.Sprintf("Filters[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return FilterChainMultiError(errors) + } + + return nil +} + +// FilterChainMultiError is an error wrapping multiple validation errors +// returned by FilterChain.ValidateAll() if the designated constraints aren't met. +type FilterChainMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m FilterChainMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m FilterChainMultiError) AllErrors() []error { return m } + +// FilterChainValidationError is the validation error returned by +// FilterChain.Validate if the designated constraints aren't met. +type FilterChainValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e FilterChainValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e FilterChainValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e FilterChainValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e FilterChainValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e FilterChainValidationError) ErrorName() string { return "FilterChainValidationError" } + +// Error satisfies the builtin error interface +func (e FilterChainValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sFilterChain.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = FilterChainValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = FilterChainValidationError{} + +// Validate checks the field values on Config with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Config) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Config with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in ConfigMultiError, or nil if none found. +func (m *Config) ValidateAll() error { + return m.validate(true) +} + +func (m *Config) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(m.GetChains()) < 1 { + err := ConfigValidationError{ + field: "Chains", + reason: "value must contain at least 1 item(s)", + } + if !all { + return err + } + errors = append(errors, err) + } + + for idx, item := range m.GetChains() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ConfigValidationError{ + field: fmt.Sprintf("Chains[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ConfigValidationError{ + field: fmt.Sprintf("Chains[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ConfigValidationError{ + field: fmt.Sprintf("Chains[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if ip := net.ParseIP(m.GetListenAddress()); ip == nil { + err := ConfigValidationError{ + field: "ListenAddress", + reason: "value must be a valid IP address", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetListenPort() >= 65536 { + err := ConfigValidationError{ + field: "ListenPort", + reason: "value must be less than 65536", + } + if !all { + return err + } + errors = append(errors, err) + } + + if _, ok := _Config_LogLevel_InLookup[m.GetLogLevel()]; !ok { + err := ConfigValidationError{ + field: "LogLevel", + reason: "value must be in list [trace debug info error critical]", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetThreads() < 1 { + err := ConfigValidationError{ + field: "Threads", + reason: "value must be greater than or equal to 1", + } + if !all { + return err + } + errors = append(errors, err) + } + + for idx, item := range m.GetTriggerRules() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ConfigValidationError{ + field: fmt.Sprintf("TriggerRules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ConfigValidationError{ + field: fmt.Sprintf("TriggerRules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ConfigValidationError{ + field: fmt.Sprintf("TriggerRules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if all { + switch v := interface{}(m.GetDefaultOidcConfig()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ConfigValidationError{ + field: "DefaultOidcConfig", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ConfigValidationError{ + field: "DefaultOidcConfig", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetDefaultOidcConfig()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ConfigValidationError{ + field: "DefaultOidcConfig", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for AllowUnmatchedRequests + + if len(errors) > 0 { + return ConfigMultiError(errors) + } + + return nil +} + +// ConfigMultiError is an error wrapping multiple validation errors returned by +// Config.ValidateAll() if the designated constraints aren't met. +type ConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ConfigMultiError) AllErrors() []error { return m } + +// ConfigValidationError is the validation error returned by Config.Validate if +// the designated constraints aren't met. +type ConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ConfigValidationError) ErrorName() string { return "ConfigValidationError" } + +// Error satisfies the builtin error interface +func (e ConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ConfigValidationError{} + +var _Config_LogLevel_InLookup = map[string]struct{}{ + "trace": {}, + "debug": {}, + "info": {}, + "error": {}, + "critical": {}, +} + +// Validate checks the field values on TriggerRule with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *TriggerRule) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on TriggerRule with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in TriggerRuleMultiError, or +// nil if none found. +func (m *TriggerRule) ValidateAll() error { + return m.validate(true) +} + +func (m *TriggerRule) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetExcludedPaths() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, TriggerRuleValidationError{ + field: fmt.Sprintf("ExcludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, TriggerRuleValidationError{ + field: fmt.Sprintf("ExcludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return TriggerRuleValidationError{ + field: fmt.Sprintf("ExcludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + for idx, item := range m.GetIncludedPaths() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, TriggerRuleValidationError{ + field: fmt.Sprintf("IncludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, TriggerRuleValidationError{ + field: fmt.Sprintf("IncludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return TriggerRuleValidationError{ + field: fmt.Sprintf("IncludedPaths[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return TriggerRuleMultiError(errors) + } + + return nil +} + +// TriggerRuleMultiError is an error wrapping multiple validation errors +// returned by TriggerRule.ValidateAll() if the designated constraints aren't met. +type TriggerRuleMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m TriggerRuleMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m TriggerRuleMultiError) AllErrors() []error { return m } + +// TriggerRuleValidationError is the validation error returned by +// TriggerRule.Validate if the designated constraints aren't met. +type TriggerRuleValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e TriggerRuleValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e TriggerRuleValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e TriggerRuleValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e TriggerRuleValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e TriggerRuleValidationError) ErrorName() string { return "TriggerRuleValidationError" } + +// Error satisfies the builtin error interface +func (e TriggerRuleValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sTriggerRule.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = TriggerRuleValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = TriggerRuleValidationError{} + +// Validate checks the field values on StringMatch with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *StringMatch) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StringMatch with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in StringMatchMultiError, or +// nil if none found. +func (m *StringMatch) ValidateAll() error { + return m.validate(true) +} + +func (m *StringMatch) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + switch v := m.MatchType.(type) { + case *StringMatch_Exact: + if v == nil { + err := StringMatchValidationError{ + field: "MatchType", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + // no validation rules for Exact + case *StringMatch_Prefix: + if v == nil { + err := StringMatchValidationError{ + field: "MatchType", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + // no validation rules for Prefix + case *StringMatch_Suffix: + if v == nil { + err := StringMatchValidationError{ + field: "MatchType", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + // no validation rules for Suffix + case *StringMatch_Regex: + if v == nil { + err := StringMatchValidationError{ + field: "MatchType", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + // no validation rules for Regex + default: + _ = v // ensures v is used + } + + if len(errors) > 0 { + return StringMatchMultiError(errors) + } + + return nil +} + +// StringMatchMultiError is an error wrapping multiple validation errors +// returned by StringMatch.ValidateAll() if the designated constraints aren't met. +type StringMatchMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StringMatchMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StringMatchMultiError) AllErrors() []error { return m } + +// StringMatchValidationError is the validation error returned by +// StringMatch.Validate if the designated constraints aren't met. +type StringMatchValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StringMatchValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StringMatchValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StringMatchValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StringMatchValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StringMatchValidationError) ErrorName() string { return "StringMatchValidationError" } + +// Error satisfies the builtin error interface +func (e StringMatchValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStringMatch.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StringMatchValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StringMatchValidationError{} diff --git a/config/config.proto b/config/config.proto new file mode 100644 index 0000000..2bb377d --- /dev/null +++ b/config/config.proto @@ -0,0 +1,163 @@ +syntax = "proto3"; + +package authservice.config; + +import "config/oidc/config.proto"; +import "config/mock/config.proto"; +import "validate/validate.proto"; + +option go_package = "github.com/tetrateio/authservice/config"; + +// Specifies how a request can be matched to a filter chain. +message Match { + + // The name of the http header used to match against. + // Required. + string header = 1 [(validate.rules).string.min_len = 1]; + + // The criteria by which to match. + // Must be one of `prefix` or `equality`. + // Required. + oneof criteria { + option (validate.required) = true; + + // The expected prefix. If the actual value of the header starts with this prefix, + // then it will be considered a match. + string prefix = 2 [(validate.rules).string.min_len = 1]; + + // The expected value. If the actual value of the header exactly equals this value, + // then it will be considered a match. + string equality = 3 [(validate.rules).string.min_len = 1]; + } +} + +// A filter configuration. +message Filter { + + // The type of filter. Currently, the only valid types are `oidc` + // and `mock`. Required. + oneof type { + option (validate.required) = true; + + // An OpenID Connect filter configuration. + oidc.OIDCConfig oidc = 1; + + // This value will be used when `default_oidc_config` exists. + // It will override values of them. If that doesn't exist, + // this configuration will be rejected. + oidc.OIDCConfig oidc_override = 2; + + // Mock filter configuration for testing and letting + // AuthService run even if no OIDC providers are configured. + mock.MockConfig mock = 3; + } +} + +// A chain of one or more filters that will sequentially process an HTTP request. +message FilterChain { + + // A user-defined identifier for the processing chain used in log messages. + // Required. + string name = 1 [(validate.rules).string.min_len = 1]; + + // A rule to determine whether an HTTP request should be processed by the filter chain. + // If not defined, the filter chain will match every request. + // Optional. + Match match = 2; + + // The configuration of one of more filters in the filter chain. When the filter chain + // matches an incoming request, then this list of filters will be applied to the request + // in the order that they are declared. + // All filters are evaluated until one of them returns a non-OK response. + // If all filters return OK, the envoy proxy is notified that the request may continue. + // The first filter that returns a non-OK response causes the request to be rejected with + // the filter's returned status and any remaining filters are skipped. + // At least one `Filter` is required in this array. + repeated Filter filters = 3 [(validate.rules).repeated.min_items = 1]; +} + +// The top-level configuration object. +// For a simple example, see the [sample JSON in the bookinfo configmap template](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/authservice-configmap-template-for-authn-and-authz.yaml). +message Config { + + // Each incoming http request is matched against the list of filters in the chain, in order, + // until a matching filter is found. The first matching filter is then applied to the request. + // After the first match is made, other filters in the chain are ignored. + // Order of chain declaration is therefore important. + // At least one `FilterChain` is required in this array. + repeated FilterChain chains = 1 [(validate.rules).repeated.min_items = 1]; + + // The IP address for the Authservice to listen for incoming requests to process. + // Required. + string listen_address = 2 [(validate.rules).string.ip = true]; + + // The TCP port for the Authservice to listen for incoming requests to process. + // Required. + int32 listen_port = 3 [(validate.rules).int32.lt = 65536]; + + // The verbosity of logs generated by the Authservice. + // Must be one of `trace`, `debug`, `info', 'error' or 'critical'. + // Required. + string log_level = 4 [(validate.rules).string = {in: ["trace", "debug", "info", "error", "critical"]}]; + + // The number of threads in the thread pool to use for processing. + // The main thread will be used for accepting connections, before sending them to the thread-pool + // for processing. The total number of running threads, including the main thread, will be N+1. + // Required. + uint32 threads = 5 [(validate.rules).uint32.gte = 1]; + + // List of trigger rules to decide if the Authservice should be used to authenticate the + // request. The Authservice authentication happens if any one of the rules matched. + // If the list is not empty and none of the rules matched, the request will be allowed + // to proceed without Authservice authentication. + // The format and semantics of `trigger_rules` are the same as the `triggerRules` setting + // on the Istio Authentication Policy + // (see https://istio.io/docs/reference/config/security/istio.authentication.v1alpha1). + // CAUTION: Be sure that your configured `OIDCConfig.callback` and `OIDCConfig.logout` paths + // each satisfies at least one of the trigger rules, or else the Authservice will not be able to + // intercept requests made to those paths to perform the appropriate login/logout behavior. + // Optional. Leave this empty to always trigger authentication for all paths. + repeated TriggerRule trigger_rules = 9; + + // Global configuration of OIDC. This value will be applied to all filter definition + // when it defined as `oidc_override`. + // Optional. + oidc.OIDCConfig default_oidc_config = 10; + + // If true will allow the the requests even no filter chain match is found. Default false. + // Optional. + bool allow_unmatched_requests = 11; +} + +// Trigger rule to match against a request. The trigger rule is satisfied if +// and only if both rules, excluded_paths and include_paths are satisfied. +message TriggerRule { + // List of paths to be excluded from the request. The rule is satisfied if + // request path does not match to any of the path in this list. + // Optional. + repeated StringMatch excluded_paths = 1; + + // List of paths that the request must include. If the list is not empty, the + // rule is satisfied if request path matches at least one of the path in the list. + // If the list is empty, the rule is ignored, in other words the rule is always satisfied. + // Optional. + repeated StringMatch included_paths = 2; +} + +// Describes how to match a given string. Match is case-sensitive. +message StringMatch { + oneof match_type { + // exact string match. + string exact = 1; + + // prefix-based match. + string prefix = 2; + + // suffix-based match. + string suffix = 3; + + // ECMAscript style regex-based match as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + // Example: "^/pets/(.*?)?" + string regex = 4; + } +} diff --git a/config/mock/config.pb.go b/config/mock/config.pb.go new file mode 100644 index 0000000..de5adf1 --- /dev/null +++ b/config/mock/config.pb.go @@ -0,0 +1,152 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc (unknown) +// source: config/mock/config.proto + +package mock + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Mock filter config. The only thing which can be defined is whether it +// allows or rejects any request it matches. +type MockConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Boolean specifying whether the filter should return OK for any + // request it matches. Defaults to false (not OK). + Allow bool `protobuf:"varint,1,opt,name=allow,proto3" json:"allow,omitempty"` +} + +func (x *MockConfig) Reset() { + *x = MockConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_mock_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MockConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MockConfig) ProtoMessage() {} + +func (x *MockConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_mock_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MockConfig.ProtoReflect.Descriptor instead. +func (*MockConfig) Descriptor() ([]byte, []int) { + return file_config_mock_config_proto_rawDescGZIP(), []int{0} +} + +func (x *MockConfig) GetAllow() bool { + if x != nil { + return x.Allow + } + return false +} + +var File_config_mock_config_proto protoreflect.FileDescriptor + +var file_config_mock_config_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x61, 0x75, 0x74, 0x68, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6d, + 0x6f, 0x63, 0x6b, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0a, + 0x4d, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x74, 0x65, 0x69, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_config_mock_config_proto_rawDescOnce sync.Once + file_config_mock_config_proto_rawDescData = file_config_mock_config_proto_rawDesc +) + +func file_config_mock_config_proto_rawDescGZIP() []byte { + file_config_mock_config_proto_rawDescOnce.Do(func() { + file_config_mock_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_mock_config_proto_rawDescData) + }) + return file_config_mock_config_proto_rawDescData +} + +var file_config_mock_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_config_mock_config_proto_goTypes = []interface{}{ + (*MockConfig)(nil), // 0: authservice.config.mock.MockConfig +} +var file_config_mock_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_config_mock_config_proto_init() } +func file_config_mock_config_proto_init() { + if File_config_mock_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_config_mock_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MockConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_config_mock_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_config_mock_config_proto_goTypes, + DependencyIndexes: file_config_mock_config_proto_depIdxs, + MessageInfos: file_config_mock_config_proto_msgTypes, + }.Build() + File_config_mock_config_proto = out.File + file_config_mock_config_proto_rawDesc = nil + file_config_mock_config_proto_goTypes = nil + file_config_mock_config_proto_depIdxs = nil +} diff --git a/config/mock/config.pb.validate.go b/config/mock/config.pb.validate.go new file mode 100644 index 0000000..379cbf1 --- /dev/null +++ b/config/mock/config.pb.validate.go @@ -0,0 +1,137 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: config/mock/config.proto + +package mock + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on MockConfig with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *MockConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on MockConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in MockConfigMultiError, or +// nil if none found. +func (m *MockConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *MockConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Allow + + if len(errors) > 0 { + return MockConfigMultiError(errors) + } + + return nil +} + +// MockConfigMultiError is an error wrapping multiple validation errors +// returned by MockConfig.ValidateAll() if the designated constraints aren't met. +type MockConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m MockConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m MockConfigMultiError) AllErrors() []error { return m } + +// MockConfigValidationError is the validation error returned by +// MockConfig.Validate if the designated constraints aren't met. +type MockConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e MockConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e MockConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e MockConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e MockConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e MockConfigValidationError) ErrorName() string { return "MockConfigValidationError" } + +// Error satisfies the builtin error interface +func (e MockConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sMockConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = MockConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = MockConfigValidationError{} diff --git a/config/mock/config.proto b/config/mock/config.proto new file mode 100644 index 0000000..e7ccd0e --- /dev/null +++ b/config/mock/config.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package authservice.config.mock; + +import "validate/validate.proto"; + +option go_package = "github.com/tetrateio/authservice/config/mock"; + +// Mock filter config. The only thing which can be defined is whether it +// allows or rejects any request it matches. +message MockConfig { + // Boolean specifying whether the filter should return OK for any + // request it matches. Defaults to false (not OK). + bool allow = 1; +} diff --git a/config/oidc/config.pb.go b/config/oidc/config.pb.go new file mode 100644 index 0000000..cf4f0db --- /dev/null +++ b/config/oidc/config.pb.go @@ -0,0 +1,807 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc (unknown) +// source: config/oidc/config.proto + +package oidc + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Defines how a token obtained through an OIDC flow is forwarded to services. +type TokenConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the header that Authservice adds to the request when forwarding to services. + // The value of this header will contain the `preamble` and the token. + // This value is case-insensitive, as http header names are case-insensitive. + // Note that this value must be `Authorization` for the + // [Istio Authentication Policy](https://istio.io/docs/tasks/security/authn-policy/) + // to inspect the token. + // Required. + Header string `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + // The authentication scheme of the token. + // For example, when the preamble is `Bearer` and `header` is `Authorization`, the following + // header will be added to the request to the service: `Authorization: Bearer ID_TOKEN_VALUE`. + // Note that this value must be `Bearer`, case-sensitive, when header is `Authorization`. + // Optional. + Preamble string `protobuf:"bytes,2,opt,name=preamble,proto3" json:"preamble,omitempty"` +} + +func (x *TokenConfig) Reset() { + *x = TokenConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_oidc_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TokenConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TokenConfig) ProtoMessage() {} + +func (x *TokenConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_oidc_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TokenConfig.ProtoReflect.Descriptor instead. +func (*TokenConfig) Descriptor() ([]byte, []int) { + return file_config_oidc_config_proto_rawDescGZIP(), []int{0} +} + +func (x *TokenConfig) GetHeader() string { + if x != nil { + return x.Header + } + return "" +} + +func (x *TokenConfig) GetPreamble() string { + if x != nil { + return x.Preamble + } + return "" +} + +// When specified, the Authservice will use the configured Redis server to store session data +type RedisConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The Redis server uri, e.g. "tcp://127.0.0.1:6379" + ServerUri string `protobuf:"bytes,1,opt,name=server_uri,json=serverUri,proto3" json:"server_uri,omitempty"` +} + +func (x *RedisConfig) Reset() { + *x = RedisConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_oidc_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RedisConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RedisConfig) ProtoMessage() {} + +func (x *RedisConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_oidc_config_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RedisConfig.ProtoReflect.Descriptor instead. +func (*RedisConfig) Descriptor() ([]byte, []int) { + return file_config_oidc_config_proto_rawDescGZIP(), []int{1} +} + +func (x *RedisConfig) GetServerUri() string { + if x != nil { + return x.ServerUri + } + return "" +} + +// When specified, the Authservice will destroy the Authservice session when a request is +// made to the configured path. +type LogoutConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A http request path that the Authservice matches against to initiate logout. + // Whenever a request is made to that path, the Authservice will remove the Authservice-specific + // cookies and respond with a redirect to the configured `redirect_uri`. Removing the cookies + // causes the user to be unauthenticated in future requests. + // If the service application has its own logout controller, then it may be desirable to have its + // logout controller redirect to this path. If the service application does not need its own logout + // controller, then the application's logout button/link's href can GET or POST directly to this path. + // Required. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // A URI specifying the destination to which the Authservice will redirect any request made to the + // logout `path`. For example, it may be desirable to redirect the logged out user to the homepage + // of the service application, or to the + // [logout endpoint of the OIDC Provider](https://openid.net/specs/openid-connect-session-1_0.html#RPLogout). + // As with all redirects, the user's browser will perform a GET to this URI. + // Required. + RedirectUri string `protobuf:"bytes,2,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"` +} + +func (x *LogoutConfig) Reset() { + *x = LogoutConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_oidc_config_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogoutConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutConfig) ProtoMessage() {} + +func (x *LogoutConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_oidc_config_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutConfig.ProtoReflect.Descriptor instead. +func (*LogoutConfig) Descriptor() ([]byte, []int) { + return file_config_oidc_config_proto_rawDescGZIP(), []int{2} +} + +func (x *LogoutConfig) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *LogoutConfig) GetRedirectUri() string { + if x != nil { + return x.RedirectUri + } + return "" +} + +// The configuration of an OpenID Connect filter that can be used to retrieve identity and access tokens +// via the standard authorization code grant flow from an OIDC Provider. +type OIDCConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). + // Required. + AuthorizationUri string `protobuf:"bytes,1,opt,name=authorization_uri,json=authorizationUri,proto3" json:"authorization_uri,omitempty"` + // The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint). + // Required. + TokenUri string `protobuf:"bytes,2,opt,name=token_uri,json=tokenUri,proto3" json:"token_uri,omitempty"` + // This value will be used as the `redirect_uri` param of the authorization code grant + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // This URL must be one of the Redirection URI values for the Client pre-registered at the OIDC provider. + // Note: The Istio gateway's VirtualService must be prepared to ensure that this URL will get routed to + // the service so that the Authservice can intercept the request and handle it + // (see [example](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/bookinfo-gateway.yaml)). + // Required. + CallbackUri string `protobuf:"bytes,3,opt,name=callback_uri,json=callbackUri,proto3" json:"callback_uri,omitempty"` + // Types that are assignable to JwksConfig: + // + // *OIDCConfig_Jwks + // *OIDCConfig_JwksFetcher + JwksConfig isOIDCConfig_JwksConfig `protobuf_oneof:"jwks_config"` + // The OIDC client ID assigned to the filter to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // Required. + ClientId string `protobuf:"bytes,5,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // The OIDC client secret assigned to the filter to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // Required. + ClientSecret string `protobuf:"bytes,6,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"` + // Additional scopes passed to the OIDC Provider in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // The `openid` scope is always sent to the OIDC Provider, and does not need to be specified here. + // Required, but an empty array is allowed. + Scopes []string `protobuf:"bytes,7,rep,name=scopes,proto3" json:"scopes,omitempty"` + // A unique identifier of the Authservice's browser cookies. Can be any string. + // Needed when multiple services in the same domain are each protected by + // their own Authservice, in which case each service's Authservice should have + // a unique value to avoid cookie name conflicts. Also needed when an Authservice + // is configured with multiple `oidc` filters (across multiple `chains`), each + // sharing a Redis server for their session storage, to avoid having those + // `oidc` filters read/write the same sessions in Redis. + // Optional. + CookieNamePrefix string `protobuf:"bytes,8,opt,name=cookie_name_prefix,json=cookieNamePrefix,proto3" json:"cookie_name_prefix,omitempty"` + // The configuration for adding ID Tokens as headers to requests forwarded to a service. + // Required. + IdToken *TokenConfig `protobuf:"bytes,9,opt,name=id_token,json=idToken,proto3" json:"id_token,omitempty"` + // The configuration for adding Access Tokens as headers to requests forwarded to a service. + // Optional. + AccessToken *TokenConfig `protobuf:"bytes,10,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` + // When specified, the Authservice will destroy the Authservice session when a request is + // made to the configured path. + // Optional. + Logout *LogoutConfig `protobuf:"bytes,11,opt,name=logout,proto3" json:"logout,omitempty"` + // The Authservice associates obtained OIDC tokens with a session ID in a session store. + // It also stores some temporary information during the login process into the session store, + // which will be removed when the user finishes the login. + // This configuration option sets the number of seconds since a user's session with the Authservice has started + // until that session should expire. + // When configured to `0`, which is the default value, the session will never timeout based on the time + // that it was started, but can still timeout due to being idle. + // When both `absolute_session_timeout` and `idle_session_timeout` are zero, then sessions will never + // expire. These settings do not affect how quickly the OIDC tokens contained inside the user's session expire. + // Optional. + AbsoluteSessionTimeout uint32 `protobuf:"varint,12,opt,name=absolute_session_timeout,json=absoluteSessionTimeout,proto3" json:"absolute_session_timeout,omitempty"` + // The Authservice associates obtained OIDC tokens with a session ID in a session store. + // It also stores some temporary information during the login process into the session store, + // which will be removed when the user finishes the login. + // This configuration option sets the number of seconds since the most recent incoming request from that user + // until the user's session with the Authservice should expire. + // When configured to `0`, which is the default value, session expiration will not consider idle time, + // but can still consider timeout based on maximum absolute time since added. + // When both `absolute_session_timeout` and `idle_session_timeout` are zero, then sessions will never + // expire. These settings do not affect how quickly the OIDC tokens contained inside the user's session expire. + // Optional. + IdleSessionTimeout uint32 `protobuf:"varint,13,opt,name=idle_session_timeout,json=idleSessionTimeout,proto3" json:"idle_session_timeout,omitempty"` + // When specified, the Authservice will trust the specified Certificate Authority when performing HTTPS calls to + // the Token Endpoint of the OIDC Identity Provider. + // Optional. + TrustedCertificateAuthority string `protobuf:"bytes,14,opt,name=trusted_certificate_authority,json=trustedCertificateAuthority,proto3" json:"trusted_certificate_authority,omitempty"` + // The Authservice makes two kinds of direct network connections directly to the OIDC Provider. + // Both are POST requests to the configured `token_uri` of the OIDC Provider. + // The first is to exchange the authorization code for tokens, and the other is to use the + // refresh token to obtain new tokens. Configure the `proxy_uri` when + // both of these requests should be made through a web proxy. The format of `proxy_uri` is + // `http://proxyserver.example.com:8080`, where `:` is optional. + // Userinfo (usernames and passwords) in the `proxy_uri` setting are not yet supported. + // The `proxy_uri` should always start with `http://`. + // The Authservice will upgrade the connection to the OIDC provider to HTTPS using + // an HTTP CONNECT request to the proxy server. The proxy server will see the hostname and port number + // of the OIDC provider in plain text in the CONNECT request, but all other communication will occur + // over an encrypted HTTPS connection negotiated directly between the Authservice and + // the OIDC provider. See also the related `trusted_certificate_authority` configuration option. + // Optional. + ProxyUri string `protobuf:"bytes,15,opt,name=proxy_uri,json=proxyUri,proto3" json:"proxy_uri,omitempty"` + // When specified, the Authservice will use the configured Redis server to store session data. + // Optional. + RedisSessionStoreConfig *RedisConfig `protobuf:"bytes,16,opt,name=redis_session_store_config,json=redisSessionStoreConfig,proto3" json:"redis_session_store_config,omitempty"` + // If set to true, the verification of the destination certificate will be skipped when + // making a request to the Token Endpoint. This option is useful when you want to use a + // self-signed certificate for testing purposes, but basically should not be set to true + // in any other cases. + // Optional. + SkipVerifyPeerCert bool `protobuf:"varint,18,opt,name=skip_verify_peer_cert,json=skipVerifyPeerCert,proto3" json:"skip_verify_peer_cert,omitempty"` +} + +func (x *OIDCConfig) Reset() { + *x = OIDCConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_oidc_config_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OIDCConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OIDCConfig) ProtoMessage() {} + +func (x *OIDCConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_oidc_config_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OIDCConfig.ProtoReflect.Descriptor instead. +func (*OIDCConfig) Descriptor() ([]byte, []int) { + return file_config_oidc_config_proto_rawDescGZIP(), []int{3} +} + +func (x *OIDCConfig) GetAuthorizationUri() string { + if x != nil { + return x.AuthorizationUri + } + return "" +} + +func (x *OIDCConfig) GetTokenUri() string { + if x != nil { + return x.TokenUri + } + return "" +} + +func (x *OIDCConfig) GetCallbackUri() string { + if x != nil { + return x.CallbackUri + } + return "" +} + +func (m *OIDCConfig) GetJwksConfig() isOIDCConfig_JwksConfig { + if m != nil { + return m.JwksConfig + } + return nil +} + +func (x *OIDCConfig) GetJwks() string { + if x, ok := x.GetJwksConfig().(*OIDCConfig_Jwks); ok { + return x.Jwks + } + return "" +} + +func (x *OIDCConfig) GetJwksFetcher() *OIDCConfig_JwksFetcherConfig { + if x, ok := x.GetJwksConfig().(*OIDCConfig_JwksFetcher); ok { + return x.JwksFetcher + } + return nil +} + +func (x *OIDCConfig) GetClientId() string { + if x != nil { + return x.ClientId + } + return "" +} + +func (x *OIDCConfig) GetClientSecret() string { + if x != nil { + return x.ClientSecret + } + return "" +} + +func (x *OIDCConfig) GetScopes() []string { + if x != nil { + return x.Scopes + } + return nil +} + +func (x *OIDCConfig) GetCookieNamePrefix() string { + if x != nil { + return x.CookieNamePrefix + } + return "" +} + +func (x *OIDCConfig) GetIdToken() *TokenConfig { + if x != nil { + return x.IdToken + } + return nil +} + +func (x *OIDCConfig) GetAccessToken() *TokenConfig { + if x != nil { + return x.AccessToken + } + return nil +} + +func (x *OIDCConfig) GetLogout() *LogoutConfig { + if x != nil { + return x.Logout + } + return nil +} + +func (x *OIDCConfig) GetAbsoluteSessionTimeout() uint32 { + if x != nil { + return x.AbsoluteSessionTimeout + } + return 0 +} + +func (x *OIDCConfig) GetIdleSessionTimeout() uint32 { + if x != nil { + return x.IdleSessionTimeout + } + return 0 +} + +func (x *OIDCConfig) GetTrustedCertificateAuthority() string { + if x != nil { + return x.TrustedCertificateAuthority + } + return "" +} + +func (x *OIDCConfig) GetProxyUri() string { + if x != nil { + return x.ProxyUri + } + return "" +} + +func (x *OIDCConfig) GetRedisSessionStoreConfig() *RedisConfig { + if x != nil { + return x.RedisSessionStoreConfig + } + return nil +} + +func (x *OIDCConfig) GetSkipVerifyPeerCert() bool { + if x != nil { + return x.SkipVerifyPeerCert + } + return false +} + +type isOIDCConfig_JwksConfig interface { + isOIDCConfig_JwksConfig() +} + +type OIDCConfig_Jwks struct { + // The JSON JWKS response from the OIDC provider’s `jwks_uri` URI which can be found in + // the OIDC provider's + // [configuration response](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). + // Note that this JSON value must be escaped when embedded in a json configmap + // (see [example](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/authservice-configmap-template.yaml)). + // Used during token verification. + Jwks string `protobuf:"bytes,4,opt,name=jwks,proto3,oneof"` +} + +type OIDCConfig_JwksFetcher struct { + // Configuration to allow JWKs to be retrieved and updated asynchronously at regular intervals. + JwksFetcher *OIDCConfig_JwksFetcherConfig `protobuf:"bytes,17,opt,name=jwks_fetcher,json=jwksFetcher,proto3,oneof"` +} + +func (*OIDCConfig_Jwks) isOIDCConfig_JwksConfig() {} + +func (*OIDCConfig_JwksFetcher) isOIDCConfig_JwksConfig() {} + +// This message defines a setting to allow asynchronous retrieval and update of the JWK for +// JWT validation at regular intervals. +type OIDCConfig_JwksFetcherConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Request URI that has the JWKs. + // Required. + JwksUri string `protobuf:"bytes,1,opt,name=jwks_uri,json=jwksUri,proto3" json:"jwks_uri,omitempty"` + // Request interval to check whether new JWKs are available. If not specified, + // default to 1200 seconds, 20min. + // Optional. + PeriodicFetchIntervalSec uint32 `protobuf:"varint,2,opt,name=periodic_fetch_interval_sec,json=periodicFetchIntervalSec,proto3" json:"periodic_fetch_interval_sec,omitempty"` + // If set to true, the verification of the destination certificate will be skipped when + // making a request to the JWKs URI. This option is useful when you want to use a + // self-signed certificate for testing purposes, but basically should not be set to + // true in any other cases. + // Optional. + SkipVerifyPeerCert bool `protobuf:"varint,3,opt,name=skip_verify_peer_cert,json=skipVerifyPeerCert,proto3" json:"skip_verify_peer_cert,omitempty"` +} + +func (x *OIDCConfig_JwksFetcherConfig) Reset() { + *x = OIDCConfig_JwksFetcherConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_config_oidc_config_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OIDCConfig_JwksFetcherConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OIDCConfig_JwksFetcherConfig) ProtoMessage() {} + +func (x *OIDCConfig_JwksFetcherConfig) ProtoReflect() protoreflect.Message { + mi := &file_config_oidc_config_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OIDCConfig_JwksFetcherConfig.ProtoReflect.Descriptor instead. +func (*OIDCConfig_JwksFetcherConfig) Descriptor() ([]byte, []int) { + return file_config_oidc_config_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *OIDCConfig_JwksFetcherConfig) GetJwksUri() string { + if x != nil { + return x.JwksUri + } + return "" +} + +func (x *OIDCConfig_JwksFetcherConfig) GetPeriodicFetchIntervalSec() uint32 { + if x != nil { + return x.PeriodicFetchIntervalSec + } + return 0 +} + +func (x *OIDCConfig_JwksFetcherConfig) GetSkipVerifyPeerCert() bool { + if x != nil { + return x.SkipVerifyPeerCert + } + return false +} + +var File_config_oidc_config_proto protoreflect.FileDescriptor + +var file_config_oidc_config_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x69, 0x64, 0x63, 0x2f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x61, 0x75, 0x74, 0x68, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, + 0x69, 0x64, 0x63, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, 0x0b, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x70, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x22, 0x35, 0x0a, 0x0b, 0x52, 0x65, 0x64, 0x69, + 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x72, 0x69, 0x22, + 0x57, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x1b, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, + 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x0c, + 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x72, 0x65, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x22, 0x88, 0x09, 0x0a, 0x0a, 0x4f, 0x49, 0x44, + 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x11, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x10, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x69, 0x12, 0x24, 0x0a, + 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x55, 0x72, 0x69, 0x12, 0x2a, 0x0a, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, + 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x0b, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x72, 0x69, 0x12, + 0x14, 0x0a, 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x12, 0x5a, 0x0a, 0x0c, 0x6a, 0x77, 0x6b, 0x73, 0x5f, 0x66, 0x65, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x4a, 0x77, 0x6b, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x6a, 0x77, 0x6b, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x12, 0x24, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x2c, 0x0a, + 0x12, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x49, 0x0a, 0x08, 0x69, + 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x69, + 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x47, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, + 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x3d, 0x0a, 0x06, 0x6c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x6c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x38, + 0x0a, 0x18, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x16, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x64, 0x6c, 0x65, + 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x69, 0x64, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x42, 0x0a, 0x1d, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x1b, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1b, + 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, 0x12, 0x61, 0x0a, 0x1a, 0x72, + 0x65, 0x64, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x69, 0x64, 0x63, 0x2e, 0x52, 0x65, 0x64, 0x69, 0x73, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x17, 0x72, 0x65, 0x64, 0x69, 0x73, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x31, + 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x65, + 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, + 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, + 0x74, 0x1a, 0xa0, 0x01, 0x0a, 0x11, 0x4a, 0x77, 0x6b, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6a, 0x77, 0x6b, 0x73, 0x5f, + 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6a, 0x77, 0x6b, 0x73, 0x55, + 0x72, 0x69, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x5f, 0x66, + 0x65, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, + 0x63, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x65, + 0x63, 0x12, 0x31, 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x65, 0x65, 0x72, + 0x43, 0x65, 0x72, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x6a, 0x77, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x74, 0x65, 0x69, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, + 0x69, 0x64, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_config_oidc_config_proto_rawDescOnce sync.Once + file_config_oidc_config_proto_rawDescData = file_config_oidc_config_proto_rawDesc +) + +func file_config_oidc_config_proto_rawDescGZIP() []byte { + file_config_oidc_config_proto_rawDescOnce.Do(func() { + file_config_oidc_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_oidc_config_proto_rawDescData) + }) + return file_config_oidc_config_proto_rawDescData +} + +var file_config_oidc_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_config_oidc_config_proto_goTypes = []interface{}{ + (*TokenConfig)(nil), // 0: authservice.config.oidc.TokenConfig + (*RedisConfig)(nil), // 1: authservice.config.oidc.RedisConfig + (*LogoutConfig)(nil), // 2: authservice.config.oidc.LogoutConfig + (*OIDCConfig)(nil), // 3: authservice.config.oidc.OIDCConfig + (*OIDCConfig_JwksFetcherConfig)(nil), // 4: authservice.config.oidc.OIDCConfig.JwksFetcherConfig +} +var file_config_oidc_config_proto_depIdxs = []int32{ + 4, // 0: authservice.config.oidc.OIDCConfig.jwks_fetcher:type_name -> authservice.config.oidc.OIDCConfig.JwksFetcherConfig + 0, // 1: authservice.config.oidc.OIDCConfig.id_token:type_name -> authservice.config.oidc.TokenConfig + 0, // 2: authservice.config.oidc.OIDCConfig.access_token:type_name -> authservice.config.oidc.TokenConfig + 2, // 3: authservice.config.oidc.OIDCConfig.logout:type_name -> authservice.config.oidc.LogoutConfig + 1, // 4: authservice.config.oidc.OIDCConfig.redis_session_store_config:type_name -> authservice.config.oidc.RedisConfig + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_config_oidc_config_proto_init() } +func file_config_oidc_config_proto_init() { + if File_config_oidc_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_config_oidc_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TokenConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_oidc_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RedisConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_oidc_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogoutConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_oidc_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OIDCConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_config_oidc_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OIDCConfig_JwksFetcherConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_config_oidc_config_proto_msgTypes[3].OneofWrappers = []interface{}{ + (*OIDCConfig_Jwks)(nil), + (*OIDCConfig_JwksFetcher)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_config_oidc_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_config_oidc_config_proto_goTypes, + DependencyIndexes: file_config_oidc_config_proto_depIdxs, + MessageInfos: file_config_oidc_config_proto_msgTypes, + }.Build() + File_config_oidc_config_proto = out.File + file_config_oidc_config_proto_rawDesc = nil + file_config_oidc_config_proto_goTypes = nil + file_config_oidc_config_proto_depIdxs = nil +} diff --git a/config/oidc/config.pb.validate.go b/config/oidc/config.pb.validate.go new file mode 100644 index 0000000..0db07fc --- /dev/null +++ b/config/oidc/config.pb.validate.go @@ -0,0 +1,839 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: config/oidc/config.proto + +package oidc + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on TokenConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *TokenConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on TokenConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in TokenConfigMultiError, or +// nil if none found. +func (m *TokenConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *TokenConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetHeader()) < 1 { + err := TokenConfigValidationError{ + field: "Header", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for Preamble + + if len(errors) > 0 { + return TokenConfigMultiError(errors) + } + + return nil +} + +// TokenConfigMultiError is an error wrapping multiple validation errors +// returned by TokenConfig.ValidateAll() if the designated constraints aren't met. +type TokenConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m TokenConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m TokenConfigMultiError) AllErrors() []error { return m } + +// TokenConfigValidationError is the validation error returned by +// TokenConfig.Validate if the designated constraints aren't met. +type TokenConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e TokenConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e TokenConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e TokenConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e TokenConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e TokenConfigValidationError) ErrorName() string { return "TokenConfigValidationError" } + +// Error satisfies the builtin error interface +func (e TokenConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sTokenConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = TokenConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = TokenConfigValidationError{} + +// Validate checks the field values on RedisConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *RedisConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on RedisConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in RedisConfigMultiError, or +// nil if none found. +func (m *RedisConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *RedisConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetServerUri()) < 1 { + err := RedisConfigValidationError{ + field: "ServerUri", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return RedisConfigMultiError(errors) + } + + return nil +} + +// RedisConfigMultiError is an error wrapping multiple validation errors +// returned by RedisConfig.ValidateAll() if the designated constraints aren't met. +type RedisConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m RedisConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m RedisConfigMultiError) AllErrors() []error { return m } + +// RedisConfigValidationError is the validation error returned by +// RedisConfig.Validate if the designated constraints aren't met. +type RedisConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e RedisConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e RedisConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e RedisConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e RedisConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e RedisConfigValidationError) ErrorName() string { return "RedisConfigValidationError" } + +// Error satisfies the builtin error interface +func (e RedisConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sRedisConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = RedisConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = RedisConfigValidationError{} + +// Validate checks the field values on LogoutConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *LogoutConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LogoutConfig with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in LogoutConfigMultiError, or +// nil if none found. +func (m *LogoutConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *LogoutConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetPath()) < 1 { + err := LogoutConfigValidationError{ + field: "Path", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetRedirectUri()) < 1 { + err := LogoutConfigValidationError{ + field: "RedirectUri", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return LogoutConfigMultiError(errors) + } + + return nil +} + +// LogoutConfigMultiError is an error wrapping multiple validation errors +// returned by LogoutConfig.ValidateAll() if the designated constraints aren't met. +type LogoutConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LogoutConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LogoutConfigMultiError) AllErrors() []error { return m } + +// LogoutConfigValidationError is the validation error returned by +// LogoutConfig.Validate if the designated constraints aren't met. +type LogoutConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LogoutConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LogoutConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LogoutConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LogoutConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LogoutConfigValidationError) ErrorName() string { return "LogoutConfigValidationError" } + +// Error satisfies the builtin error interface +func (e LogoutConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLogoutConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LogoutConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LogoutConfigValidationError{} + +// Validate checks the field values on OIDCConfig with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *OIDCConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OIDCConfig with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in OIDCConfigMultiError, or +// nil if none found. +func (m *OIDCConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *OIDCConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetAuthorizationUri()) < 1 { + err := OIDCConfigValidationError{ + field: "AuthorizationUri", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetTokenUri()) < 1 { + err := OIDCConfigValidationError{ + field: "TokenUri", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetCallbackUri()) < 1 { + err := OIDCConfigValidationError{ + field: "CallbackUri", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetClientId()) < 1 { + err := OIDCConfigValidationError{ + field: "ClientId", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetClientSecret()) < 1 { + err := OIDCConfigValidationError{ + field: "ClientSecret", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for CookieNamePrefix + + if m.GetIdToken() == nil { + err := OIDCConfigValidationError{ + field: "IdToken", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetIdToken()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "IdToken", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "IdToken", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetIdToken()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OIDCConfigValidationError{ + field: "IdToken", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetAccessToken()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "AccessToken", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "AccessToken", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetAccessToken()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OIDCConfigValidationError{ + field: "AccessToken", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetLogout()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "Logout", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "Logout", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetLogout()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OIDCConfigValidationError{ + field: "Logout", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for AbsoluteSessionTimeout + + // no validation rules for IdleSessionTimeout + + // no validation rules for TrustedCertificateAuthority + + // no validation rules for ProxyUri + + if all { + switch v := interface{}(m.GetRedisSessionStoreConfig()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "RedisSessionStoreConfig", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "RedisSessionStoreConfig", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetRedisSessionStoreConfig()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OIDCConfigValidationError{ + field: "RedisSessionStoreConfig", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for SkipVerifyPeerCert + + switch v := m.JwksConfig.(type) { + case *OIDCConfig_Jwks: + if v == nil { + err := OIDCConfigValidationError{ + field: "JwksConfig", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + // no validation rules for Jwks + case *OIDCConfig_JwksFetcher: + if v == nil { + err := OIDCConfigValidationError{ + field: "JwksConfig", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetJwksFetcher()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "JwksFetcher", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OIDCConfigValidationError{ + field: "JwksFetcher", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetJwksFetcher()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OIDCConfigValidationError{ + field: "JwksFetcher", + reason: "embedded message failed validation", + cause: err, + } + } + } + + default: + _ = v // ensures v is used + } + + if len(errors) > 0 { + return OIDCConfigMultiError(errors) + } + + return nil +} + +// OIDCConfigMultiError is an error wrapping multiple validation errors +// returned by OIDCConfig.ValidateAll() if the designated constraints aren't met. +type OIDCConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OIDCConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OIDCConfigMultiError) AllErrors() []error { return m } + +// OIDCConfigValidationError is the validation error returned by +// OIDCConfig.Validate if the designated constraints aren't met. +type OIDCConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OIDCConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OIDCConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OIDCConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OIDCConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OIDCConfigValidationError) ErrorName() string { return "OIDCConfigValidationError" } + +// Error satisfies the builtin error interface +func (e OIDCConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOIDCConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OIDCConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OIDCConfigValidationError{} + +// Validate checks the field values on OIDCConfig_JwksFetcherConfig with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *OIDCConfig_JwksFetcherConfig) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OIDCConfig_JwksFetcherConfig with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OIDCConfig_JwksFetcherConfigMultiError, or nil if none found. +func (m *OIDCConfig_JwksFetcherConfig) ValidateAll() error { + return m.validate(true) +} + +func (m *OIDCConfig_JwksFetcherConfig) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for JwksUri + + // no validation rules for PeriodicFetchIntervalSec + + // no validation rules for SkipVerifyPeerCert + + if len(errors) > 0 { + return OIDCConfig_JwksFetcherConfigMultiError(errors) + } + + return nil +} + +// OIDCConfig_JwksFetcherConfigMultiError is an error wrapping multiple +// validation errors returned by OIDCConfig_JwksFetcherConfig.ValidateAll() if +// the designated constraints aren't met. +type OIDCConfig_JwksFetcherConfigMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OIDCConfig_JwksFetcherConfigMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OIDCConfig_JwksFetcherConfigMultiError) AllErrors() []error { return m } + +// OIDCConfig_JwksFetcherConfigValidationError is the validation error returned +// by OIDCConfig_JwksFetcherConfig.Validate if the designated constraints +// aren't met. +type OIDCConfig_JwksFetcherConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OIDCConfig_JwksFetcherConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OIDCConfig_JwksFetcherConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OIDCConfig_JwksFetcherConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OIDCConfig_JwksFetcherConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OIDCConfig_JwksFetcherConfigValidationError) ErrorName() string { + return "OIDCConfig_JwksFetcherConfigValidationError" +} + +// Error satisfies the builtin error interface +func (e OIDCConfig_JwksFetcherConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOIDCConfig_JwksFetcherConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OIDCConfig_JwksFetcherConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OIDCConfig_JwksFetcherConfigValidationError{} diff --git a/config/oidc/config.proto b/config/oidc/config.proto new file mode 100644 index 0000000..8288dba --- /dev/null +++ b/config/oidc/config.proto @@ -0,0 +1,207 @@ +syntax = "proto3"; + +package authservice.config.oidc; + +import "validate/validate.proto"; + +option go_package = "github.com/tetrateio/authservice/config/oidc"; + +// Defines how a token obtained through an OIDC flow is forwarded to services. +message TokenConfig { + + // The name of the header that Authservice adds to the request when forwarding to services. + // The value of this header will contain the `preamble` and the token. + // This value is case-insensitive, as http header names are case-insensitive. + // Note that this value must be `Authorization` for the + // [Istio Authentication Policy](https://istio.io/docs/tasks/security/authn-policy/) + // to inspect the token. + // Required. + string header = 1 [(validate.rules).string.min_len = 1]; + + // The authentication scheme of the token. + // For example, when the preamble is `Bearer` and `header` is `Authorization`, the following + // header will be added to the request to the service: `Authorization: Bearer ID_TOKEN_VALUE`. + // Note that this value must be `Bearer`, case-sensitive, when header is `Authorization`. + // Optional. + string preamble = 2; +} + +// When specified, the Authservice will use the configured Redis server to store session data +message RedisConfig { + + // The Redis server uri, e.g. "tcp://127.0.0.1:6379" + string server_uri = 1 [(validate.rules).string.min_len = 1]; +} + +// When specified, the Authservice will destroy the Authservice session when a request is +// made to the configured path. +message LogoutConfig { + + // A http request path that the Authservice matches against to initiate logout. + // Whenever a request is made to that path, the Authservice will remove the Authservice-specific + // cookies and respond with a redirect to the configured `redirect_uri`. Removing the cookies + // causes the user to be unauthenticated in future requests. + // If the service application has its own logout controller, then it may be desirable to have its + // logout controller redirect to this path. If the service application does not need its own logout + // controller, then the application's logout button/link's href can GET or POST directly to this path. + // Required. + string path = 1 [(validate.rules).string.min_len = 1]; + + // A URI specifying the destination to which the Authservice will redirect any request made to the + // logout `path`. For example, it may be desirable to redirect the logged out user to the homepage + // of the service application, or to the + // [logout endpoint of the OIDC Provider](https://openid.net/specs/openid-connect-session-1_0.html#RPLogout). + // As with all redirects, the user's browser will perform a GET to this URI. + // Required. + string redirect_uri = 2 [(validate.rules).string.min_len = 1]; +} + +// The configuration of an OpenID Connect filter that can be used to retrieve identity and access tokens +// via the standard authorization code grant flow from an OIDC Provider. +message OIDCConfig { + + // The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). + // Required. + string authorization_uri = 1 [(validate.rules).string.min_len = 1]; + + // The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint). + // Required. + string token_uri = 2 [(validate.rules).string.min_len = 1]; + + // This value will be used as the `redirect_uri` param of the authorization code grant + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // This URL must be one of the Redirection URI values for the Client pre-registered at the OIDC provider. + // Note: The Istio gateway's VirtualService must be prepared to ensure that this URL will get routed to + // the service so that the Authservice can intercept the request and handle it + // (see [example](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/bookinfo-gateway.yaml)). + // Required. + string callback_uri = 3 [(validate.rules).string.min_len = 1]; + + // This message defines a setting to allow asynchronous retrieval and update of the JWK for + // JWT validation at regular intervals. + message JwksFetcherConfig { + // Request URI that has the JWKs. + // Required. + string jwks_uri = 1; + + // Request interval to check whether new JWKs are available. If not specified, + // default to 1200 seconds, 20min. + // Optional. + uint32 periodic_fetch_interval_sec = 2; + + // If set to true, the verification of the destination certificate will be skipped when + // making a request to the JWKs URI. This option is useful when you want to use a + // self-signed certificate for testing purposes, but basically should not be set to + // true in any other cases. + // Optional. + bool skip_verify_peer_cert = 3; + } + + oneof jwks_config { + // The JSON JWKS response from the OIDC provider’s `jwks_uri` URI which can be found in + // the OIDC provider's + // [configuration response](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). + // Note that this JSON value must be escaped when embedded in a json configmap + // (see [example](https://github.com/istio-ecosystem/authservice/blob/master/bookinfo-example/config/authservice-configmap-template.yaml)). + // Used during token verification. + string jwks = 4; + + // Configuration to allow JWKs to be retrieved and updated asynchronously at regular intervals. + JwksFetcherConfig jwks_fetcher = 17; + } + + // The OIDC client ID assigned to the filter to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // Required. + string client_id = 5 [(validate.rules).string.min_len = 1]; + + // The OIDC client secret assigned to the filter to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // Required. + string client_secret = 6 [(validate.rules).string.min_len = 1]; + + // Additional scopes passed to the OIDC Provider in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // The `openid` scope is always sent to the OIDC Provider, and does not need to be specified here. + // Required, but an empty array is allowed. + repeated string scopes = 7; + + // A unique identifier of the Authservice's browser cookies. Can be any string. + // Needed when multiple services in the same domain are each protected by + // their own Authservice, in which case each service's Authservice should have + // a unique value to avoid cookie name conflicts. Also needed when an Authservice + // is configured with multiple `oidc` filters (across multiple `chains`), each + // sharing a Redis server for their session storage, to avoid having those + // `oidc` filters read/write the same sessions in Redis. + // Optional. + string cookie_name_prefix = 8; + + // The configuration for adding ID Tokens as headers to requests forwarded to a service. + // Required. + TokenConfig id_token = 9 [(validate.rules).message.required = true]; + + // The configuration for adding Access Tokens as headers to requests forwarded to a service. + // Optional. + TokenConfig access_token = 10; + + // When specified, the Authservice will destroy the Authservice session when a request is + // made to the configured path. + // Optional. + LogoutConfig logout = 11; + + // The Authservice associates obtained OIDC tokens with a session ID in a session store. + // It also stores some temporary information during the login process into the session store, + // which will be removed when the user finishes the login. + // This configuration option sets the number of seconds since a user's session with the Authservice has started + // until that session should expire. + // When configured to `0`, which is the default value, the session will never timeout based on the time + // that it was started, but can still timeout due to being idle. + // When both `absolute_session_timeout` and `idle_session_timeout` are zero, then sessions will never + // expire. These settings do not affect how quickly the OIDC tokens contained inside the user's session expire. + // Optional. + uint32 absolute_session_timeout = 12; + + // The Authservice associates obtained OIDC tokens with a session ID in a session store. + // It also stores some temporary information during the login process into the session store, + // which will be removed when the user finishes the login. + // This configuration option sets the number of seconds since the most recent incoming request from that user + // until the user's session with the Authservice should expire. + // When configured to `0`, which is the default value, session expiration will not consider idle time, + // but can still consider timeout based on maximum absolute time since added. + // When both `absolute_session_timeout` and `idle_session_timeout` are zero, then sessions will never + // expire. These settings do not affect how quickly the OIDC tokens contained inside the user's session expire. + // Optional. + uint32 idle_session_timeout = 13; + + // When specified, the Authservice will trust the specified Certificate Authority when performing HTTPS calls to + // the Token Endpoint of the OIDC Identity Provider. + // Optional. + string trusted_certificate_authority = 14; + + // The Authservice makes two kinds of direct network connections directly to the OIDC Provider. + // Both are POST requests to the configured `token_uri` of the OIDC Provider. + // The first is to exchange the authorization code for tokens, and the other is to use the + // refresh token to obtain new tokens. Configure the `proxy_uri` when + // both of these requests should be made through a web proxy. The format of `proxy_uri` is + // `http://proxyserver.example.com:8080`, where `:` is optional. + // Userinfo (usernames and passwords) in the `proxy_uri` setting are not yet supported. + // The `proxy_uri` should always start with `http://`. + // The Authservice will upgrade the connection to the OIDC provider to HTTPS using + // an HTTP CONNECT request to the proxy server. The proxy server will see the hostname and port number + // of the OIDC provider in plain text in the CONNECT request, but all other communication will occur + // over an encrypted HTTPS connection negotiated directly between the Authservice and + // the OIDC provider. See also the related `trusted_certificate_authority` configuration option. + // Optional. + string proxy_uri = 15; + + // When specified, the Authservice will use the configured Redis server to store session data. + // Optional. + RedisConfig redis_session_store_config = 16; + + // If set to true, the verification of the destination certificate will be skipped when + // making a request to the Token Endpoint. This option is useful when you want to use a + // self-signed certificate for testing purposes, but basically should not be set to true + // in any other cases. + // Optional. + bool skip_verify_peer_cert = 18; +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..abda438 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/tetrateio/authservice + +go 1.21 + +require ( + github.com/envoyproxy/protoc-gen-validate v1.0.4 + google.golang.org/protobuf v1.32.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..973c7ec --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=