[NET-3091] Update service intentions to support jwt provider references (#17037)

* [NET-3090] Add new JWT provider config entry

* Add initial test cases

* update validations for jwt-provider config entry fields

* more validation

* start improving tests

* more tests

* Normalize

* Improve tests and move validate fns

* usage test update

* Add split between ent and oss for partitions

* fix lint issues

* Added retry backoff, fixed tests, removed unused defaults

* take into account default partitions

* use countTrue and add aliases

* omit audiences if empty

* fix failing tests

* add omit-entry

* Add JWT intentions

* generate proto

* fix deep copy issues

* remove extra field

* added some tests

* more tests

* add validation for creating existing jwt

* fix nil issue

* More tests, fix conflicts and improve memdb call

* fix namespace

* add aliases

* consolidate errors, skip duplicate memdb calls

* reworked iteration over config entries

* logic improvements from review

---------

Co-authored-by: Ronald Ekambi <ronekambi@gmail.com>
This commit is contained in:
Paul Glass 2023-04-19 17:16:39 -05:00 committed by GitHub
parent ac200cfec8
commit f4406e69b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1851 additions and 996 deletions

View File

@ -8,6 +8,7 @@ import (
"fmt"
memdb "github.com/hashicorp/go-memdb"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/configentry"
@ -592,6 +593,13 @@ func validateProposedConfigEntryInGraph(
}
case structs.SamenessGroup:
case structs.ServiceIntentions:
if newEntry != nil {
err := validateJWTProvidersExist(tx, kindName, newEntry)
if err != nil {
return err
}
}
case structs.MeshConfig:
case structs.ExportedServices:
case structs.APIGateway: // TODO Consider checkGatewayClash
@ -608,6 +616,92 @@ func validateProposedConfigEntryInGraph(
return validateProposedConfigEntryInServiceGraph(tx, kindName, newEntry)
}
func getExistingJWTProvidersByName(tx ReadTxn, kn configentry.KindName) (map[string]*structs.JWTProviderConfigEntry, error) {
meta := acl.NewEnterpriseMetaWithPartition(
kn.EnterpriseMeta.PartitionOrDefault(),
acl.DefaultNamespaceName,
)
_, configEntries, err := configEntriesByKindTxn(tx, nil, structs.JWTProvider, &meta)
providerNames := make(map[string]*structs.JWTProviderConfigEntry)
for i := range configEntries {
entry, ok := configEntries[i].(*structs.JWTProviderConfigEntry)
if !ok {
return nil, fmt.Errorf("Invalid type of jwt-provider config entry: %T", configEntries[i])
}
if _, ok := providerNames[entry.Name]; !ok {
providerNames[entry.Name] = entry
}
}
return providerNames, err
}
func validateJWTProvider(existingProviderNames map[string]*structs.JWTProviderConfigEntry, referencedProviderNames map[string]struct{}) error {
var result error
for referencedProvider := range referencedProviderNames {
_, found := existingProviderNames[referencedProvider]
if !found {
result = multierror.Append(result, fmt.Errorf("Referenced JWT Provider does not exist. Provider Name: %s", referencedProvider)).ErrorOrNil()
}
}
return result
}
func getReferencedProviderNames(j *structs.IntentionJWTRequirement, s []*structs.SourceIntention) map[string]struct{} {
providerNames := make(map[string]struct{})
if j != nil {
for _, provider := range j.Providers {
if _, ok := providerNames[provider.Name]; !ok {
providerNames[provider.Name] = struct{}{}
}
}
}
for _, src := range s {
for _, perm := range src.Permissions {
if perm.JWT != nil {
for _, provider := range perm.JWT.Providers {
if _, ok := providerNames[provider.Name]; !ok {
providerNames[provider.Name] = struct{}{}
}
}
}
}
}
return providerNames
}
// This fetches all the jwt-providers config entries and iterates over them
// to validate that any provider referenced exists.
// This is okay because we assume there are very few jwt-providers per partition
func validateJWTProvidersExist(tx ReadTxn, kn configentry.KindName, ce structs.ConfigEntry) error {
var result error
entry, ok := ce.(*structs.ServiceIntentionsConfigEntry)
if !ok {
return fmt.Errorf("Invalid service intention config entry: %T", entry)
}
referencedProvidersNames := getReferencedProviderNames(entry.JWT, entry.Sources)
if len(referencedProvidersNames) > 0 {
jwtProvidersNames, err := getExistingJWTProvidersByName(tx, kn)
if err != nil {
return fmt.Errorf("Failed retrieval of jwt config entries with err: %v", err)
}
result = multierror.Append(result, validateJWTProvider(jwtProvidersNames, referencedProvidersNames)).ErrorOrNil()
}
return result
}
// checkMutualTLSMode validates the MutualTLSMode (in proxy-defaults or
// service-defaults) against the AllowEnablingPermissiveMutualTLS setting in the
// mesh config entry, as follows:

View File

@ -87,6 +87,7 @@ var _ configEntryIndexable = (*structs.ServiceResolverConfigEntry)(nil)
var _ configEntryIndexable = (*structs.ServiceRouterConfigEntry)(nil)
var _ configEntryIndexable = (*structs.ServiceSplitterConfigEntry)(nil)
var _ configEntryIndexable = (*structs.TerminatingGatewayConfigEntry)(nil)
var _ configEntryIndexable = (*structs.JWTProviderConfigEntry)(nil)
func indexFromConfigEntry(c structs.ConfigEntry) ([]byte, error) {
if c.GetName() == "" || c.GetKind() == "" {

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/consul/acl"
)
@ -20,6 +21,8 @@ type ServiceIntentionsConfigEntry struct {
Sources []*SourceIntention
JWT *IntentionJWTRequirement `json:",omitempty"`
Meta map[string]string `json:",omitempty"` // formerly Intention.Meta
acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"` // formerly DestinationNS
@ -57,6 +60,10 @@ func (e *ServiceIntentionsConfigEntry) Clone() *ServiceIntentionsConfigEntry {
e2.Sources[i] = src.Clone()
}
if e.JWT != nil {
e2.JWT = e.JWT.Clone()
}
return &e2
}
@ -131,6 +138,7 @@ func (e *ServiceIntentionsConfigEntry) ToIntention(src *SourceIntention) *Intent
SourceNS: src.NamespaceOrDefault(),
SourceName: src.Name,
SourceType: src.Type,
JWT: e.JWT,
Action: src.Action,
Permissions: src.Permissions,
Meta: meta,
@ -268,6 +276,79 @@ type SourceIntention struct {
Peer string `json:",omitempty"`
}
type IntentionJWTRequirement struct {
// Providers is a list of providers to consider when verifying a JWT.
Providers []*IntentionJWTProvider `json:",omitempty"`
}
func (e *IntentionJWTRequirement) Clone() *IntentionJWTRequirement {
e2 := *e
e2.Providers = make([]*IntentionJWTProvider, len(e.Providers))
for i, src := range e.Providers {
e2.Providers[i] = src.Clone()
}
return &e2
}
func (p *IntentionJWTProvider) Validate() error {
if p.Name == "" {
return fmt.Errorf("JWT provider name is required")
}
return nil
}
func (e *IntentionJWTRequirement) Validate() error {
var result error
for _, provider := range e.Providers {
if err := provider.Validate(); err != nil {
result = multierror.Append(result, err)
}
}
return result
}
type IntentionJWTProvider struct {
// Name is the name of the JWT provider. There MUST be a corresponding
// "jwt-provider" config entry with this name.
Name string `json:",omitempty"`
// VerifyClaims is a list of additional claims to verify in a JWT's payload.
VerifyClaims []*IntentionJWTClaimVerification `json:",omitempty" alias:"verify_claims"`
}
func (e *IntentionJWTProvider) Clone() *IntentionJWTProvider {
e2 := *e
e2.VerifyClaims = make([]*IntentionJWTClaimVerification, len(e.VerifyClaims))
for i, src := range e.VerifyClaims {
e2.VerifyClaims[i] = src.Clone()
}
return &e2
}
type IntentionJWTClaimVerification struct {
// Path is the path to the claim in the token JSON.
Path []string `json:",omitempty"`
// Value is the expected value at the given path:
// - If the type at the path is a list then we verify
// that this value is contained in the list.
//
// - If the type at the path is a string then we verify
// that this value matches.
Value string `json:",omitempty"`
}
func (e *IntentionJWTClaimVerification) Clone() *IntentionJWTClaimVerification {
e2 := *e
e2.Path = stringslice.CloneStringSlice(e.Path)
return &e2
}
type IntentionPermission struct {
Action IntentionAction // required: allow|deny
@ -281,6 +362,8 @@ type IntentionPermission struct {
// If we ever add Sentinel support, this is one place we may
// wish to add it.
JWT *IntentionJWTRequirement `json:",omitempty"`
}
func (p *IntentionPermission) Clone() *IntentionPermission {
@ -288,9 +371,21 @@ func (p *IntentionPermission) Clone() *IntentionPermission {
if p.HTTP != nil {
p2.HTTP = p.HTTP.Clone()
}
if p.JWT != nil {
p2.JWT = p.JWT.Clone()
}
return &p2
}
func (p *IntentionPermission) Validate() error {
var result error
if p.JWT != nil {
result = p.JWT.Validate()
}
return result
}
type IntentionHTTPPermission struct {
// PathExact, PathPrefix, and PathRegex are mutually exclusive.
PathExact string `json:",omitempty" alias:"path_exact"`
@ -562,6 +657,12 @@ func (e *ServiceIntentionsConfigEntry) validate(legacyWrite bool) error {
destIsWild := e.HasWildcardDestination()
if e.JWT != nil {
if err := e.JWT.Validate(); err != nil {
return err
}
}
if legacyWrite {
if len(e.Meta) > 0 {
return fmt.Errorf("Meta must be omitted for legacy intention writes")
@ -762,6 +863,10 @@ func (e *ServiceIntentionsConfigEntry) validate(legacyWrite bool) error {
if permParts == 0 {
return fmt.Errorf(errorPrefix+" should not be empty", i, j)
}
if err := perm.Validate(); err != nil {
return err
}
}
psn := PeeredServiceName{Peer: src.Peer, ServiceName: src.SourceServiceName()}

View File

@ -1265,6 +1265,153 @@ func TestServiceIntentionsConfigEntry(t *testing.T) {
},
validateErr: `Sources[1] defines peer("peer1") "` + fooName.String() + `" more than once`,
},
"JWT - missing provider name": {
entry: &ServiceIntentionsConfigEntry{
Kind: ServiceIntentions,
Name: "test",
JWT: &IntentionJWTRequirement{
Providers: []*IntentionJWTProvider{
{
VerifyClaims: []*IntentionJWTClaimVerification{
{
Value: "api.apps.test.com",
},
},
},
},
},
},
validateErr: `JWT provider name is required`,
},
"JWT - missing 1 provider name with multiple providers": {
entry: &ServiceIntentionsConfigEntry{
Kind: ServiceIntentions,
Name: "test",
JWT: &IntentionJWTRequirement{
Providers: []*IntentionJWTProvider{
{
VerifyClaims: []*IntentionJWTClaimVerification{
{
Path: []string{"aud"},
Value: "another-api.test.com",
},
},
},
{
Name: "okta",
VerifyClaims: []*IntentionJWTClaimVerification{
{
Path: []string{"aud"},
Value: "api.apps.test.com",
},
},
},
},
},
},
validateErr: `JWT provider name is required`,
},
"JWT - missing provider name under permissions": {
entry: &ServiceIntentionsConfigEntry{
Kind: ServiceIntentions,
Name: "test",
Sources: []*SourceIntention{
{
Name: "foo",
Permissions: []*IntentionPermission{
{
Action: IntentionActionAllow,
HTTP: &IntentionHTTPPermission{
PathPrefix: "/foo",
Header: []IntentionHTTPHeaderPermission{
{
Name: "x-abc",
Exact: "foo",
},
{
Name: "x-xyz",
Present: true,
Invert: true,
},
},
Methods: []string{"POST", "PUT", "GET"},
},
JWT: &IntentionJWTRequirement{
Providers: []*IntentionJWTProvider{
{
VerifyClaims: []*IntentionJWTClaimVerification{
{
Path: []string{"aud"},
Value: "another-api.test.com",
},
},
},
},
},
},
},
},
},
},
validateErr: `JWT provider name is required`,
},
"valid JWTs": {
entry: &ServiceIntentionsConfigEntry{
Kind: ServiceIntentions,
Name: "test",
JWT: &IntentionJWTRequirement{
Providers: []*IntentionJWTProvider{
{
Name: "okta",
VerifyClaims: []*IntentionJWTClaimVerification{
{
Path: []string{"aud"},
Value: "another-api.test.com",
},
},
},
},
},
Sources: []*SourceIntention{
{
Name: "foo",
Permissions: []*IntentionPermission{
{
Action: IntentionActionAllow,
HTTP: &IntentionHTTPPermission{
PathPrefix: "/foo",
Header: []IntentionHTTPHeaderPermission{
{
Name: "x-abc",
Exact: "foo",
},
{
Name: "x-xyz",
Present: true,
Invert: true,
},
},
Methods: []string{"POST", "PUT", "GET"},
},
JWT: &IntentionJWTRequirement{
Providers: []*IntentionJWTProvider{
{
Name: "okta",
VerifyClaims: []*IntentionJWTClaimVerification{
{
Path: []string{"aud"},
Value: "another-api.test.com",
},
},
},
},
},
},
},
},
},
},
},
}
for name, tc := range cases {
tc := tc

View File

@ -78,6 +78,9 @@ type Intention struct {
// service-intentions config entry directly.
Permissions []*IntentionPermission `bexpr:"-" json:",omitempty"`
// JWT specifies JWT authn that applies to incoming requests.
JWT *IntentionJWTRequirement `bexpr:"-" json:",omitempty"`
// DefaultAddr is not used.
// Deprecated: DefaultAddr is not used and may be removed in a future version.
DefaultAddr string `bexpr:"-" codec:",omitempty" json:",omitempty"`

View File

@ -565,6 +565,34 @@ func (o *Intention) DeepCopy() *Intention {
}
}
}
if o.JWT != nil {
cp.JWT = new(IntentionJWTRequirement)
*cp.JWT = *o.JWT
if o.JWT.Providers != nil {
cp.JWT.Providers = make([]*IntentionJWTProvider, len(o.JWT.Providers))
copy(cp.JWT.Providers, o.JWT.Providers)
for i4 := range o.JWT.Providers {
if o.JWT.Providers[i4] != nil {
cp.JWT.Providers[i4] = new(IntentionJWTProvider)
*cp.JWT.Providers[i4] = *o.JWT.Providers[i4]
if o.JWT.Providers[i4].VerifyClaims != nil {
cp.JWT.Providers[i4].VerifyClaims = make([]*IntentionJWTClaimVerification, len(o.JWT.Providers[i4].VerifyClaims))
copy(cp.JWT.Providers[i4].VerifyClaims, o.JWT.Providers[i4].VerifyClaims)
for i7 := range o.JWT.Providers[i4].VerifyClaims {
if o.JWT.Providers[i4].VerifyClaims[i7] != nil {
cp.JWT.Providers[i4].VerifyClaims[i7] = new(IntentionJWTClaimVerification)
*cp.JWT.Providers[i4].VerifyClaims[i7] = *o.JWT.Providers[i4].VerifyClaims[i7]
if o.JWT.Providers[i4].VerifyClaims[i7].Path != nil {
cp.JWT.Providers[i4].VerifyClaims[i7].Path = make([]string, len(o.JWT.Providers[i4].VerifyClaims[i7].Path))
copy(cp.JWT.Providers[i4].VerifyClaims[i7].Path, o.JWT.Providers[i4].VerifyClaims[i7].Path)
}
}
}
}
}
}
}
}
if o.Meta != nil {
cp.Meta = make(map[string]string, len(o.Meta))
for k2, v2 := range o.Meta {
@ -593,6 +621,34 @@ func (o *IntentionPermission) DeepCopy() *IntentionPermission {
copy(cp.HTTP.Methods, o.HTTP.Methods)
}
}
if o.JWT != nil {
cp.JWT = new(IntentionJWTRequirement)
*cp.JWT = *o.JWT
if o.JWT.Providers != nil {
cp.JWT.Providers = make([]*IntentionJWTProvider, len(o.JWT.Providers))
copy(cp.JWT.Providers, o.JWT.Providers)
for i4 := range o.JWT.Providers {
if o.JWT.Providers[i4] != nil {
cp.JWT.Providers[i4] = new(IntentionJWTProvider)
*cp.JWT.Providers[i4] = *o.JWT.Providers[i4]
if o.JWT.Providers[i4].VerifyClaims != nil {
cp.JWT.Providers[i4].VerifyClaims = make([]*IntentionJWTClaimVerification, len(o.JWT.Providers[i4].VerifyClaims))
copy(cp.JWT.Providers[i4].VerifyClaims, o.JWT.Providers[i4].VerifyClaims)
for i7 := range o.JWT.Providers[i4].VerifyClaims {
if o.JWT.Providers[i4].VerifyClaims[i7] != nil {
cp.JWT.Providers[i4].VerifyClaims[i7] = new(IntentionJWTClaimVerification)
*cp.JWT.Providers[i4].VerifyClaims[i7] = *o.JWT.Providers[i4].VerifyClaims[i7]
if o.JWT.Providers[i4].VerifyClaims[i7].Path != nil {
cp.JWT.Providers[i4].VerifyClaims[i7].Path = make([]string, len(o.JWT.Providers[i4].VerifyClaims[i7].Path))
copy(cp.JWT.Providers[i4].VerifyClaims[i7].Path, o.JWT.Providers[i4].VerifyClaims[i7].Path)
}
}
}
}
}
}
}
}
return &cp
}

View File

@ -12,6 +12,7 @@ type ServiceIntentionsConfigEntry struct {
Namespace string `json:",omitempty"`
Sources []*SourceIntention
JWT *IntentionJWTRequirement `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
@ -47,6 +48,7 @@ func (e *ServiceIntentionsConfigEntry) GetModifyIndex() uint64 { return e.Mo
type IntentionPermission struct {
Action IntentionAction
HTTP *IntentionHTTPPermission `json:",omitempty"`
JWT *IntentionJWTRequirement `json:",omitempty"`
}
type IntentionHTTPPermission struct {
@ -68,3 +70,30 @@ type IntentionHTTPHeaderPermission struct {
Regex string `json:",omitempty"`
Invert bool `json:",omitempty"`
}
type IntentionJWTRequirement struct {
// Providers is a list of providers to consider when verifying a JWT.
Providers []*IntentionJWTProvider `json:",omitempty"`
}
type IntentionJWTProvider struct {
// Name is the name of the JWT provider. There MUST be a corresponding
// "jwt-provider" config entry with this name.
Name string `json:",omitempty"`
// VerifyClaims is a list of additional claims to verify in a JWT's payload.
VerifyClaims []*IntentionJWTClaimVerification `json:",omitempty" alias:"verify_claims"`
}
type IntentionJWTClaimVerification struct {
// Path is the path to the claim in the token JSON.
Path []string `json:",omitempty"`
// Value is the expected value at the given path:
// - If the type at the path is a list then we verify
// that this value is contained in the list.
//
// - If the type at the path is a string then we verify
// that this value matches.
Value string `json:",omitempty"`
}

View File

@ -944,6 +944,82 @@ func IntentionHTTPPermissionFromStructs(t *structs.IntentionHTTPPermission, s *I
}
s.Methods = t.Methods
}
func IntentionJWTClaimVerificationToStructs(s *IntentionJWTClaimVerification, t *structs.IntentionJWTClaimVerification) {
if s == nil {
return
}
t.Path = s.Path
t.Value = s.Value
}
func IntentionJWTClaimVerificationFromStructs(t *structs.IntentionJWTClaimVerification, s *IntentionJWTClaimVerification) {
if s == nil {
return
}
s.Path = t.Path
s.Value = t.Value
}
func IntentionJWTProviderToStructs(s *IntentionJWTProvider, t *structs.IntentionJWTProvider) {
if s == nil {
return
}
t.Name = s.Name
{
t.VerifyClaims = make([]*structs.IntentionJWTClaimVerification, len(s.VerifyClaims))
for i := range s.VerifyClaims {
if s.VerifyClaims[i] != nil {
var x structs.IntentionJWTClaimVerification
IntentionJWTClaimVerificationToStructs(s.VerifyClaims[i], &x)
t.VerifyClaims[i] = &x
}
}
}
}
func IntentionJWTProviderFromStructs(t *structs.IntentionJWTProvider, s *IntentionJWTProvider) {
if s == nil {
return
}
s.Name = t.Name
{
s.VerifyClaims = make([]*IntentionJWTClaimVerification, len(t.VerifyClaims))
for i := range t.VerifyClaims {
if t.VerifyClaims[i] != nil {
var x IntentionJWTClaimVerification
IntentionJWTClaimVerificationFromStructs(t.VerifyClaims[i], &x)
s.VerifyClaims[i] = &x
}
}
}
}
func IntentionJWTRequirementToStructs(s *IntentionJWTRequirement, t *structs.IntentionJWTRequirement) {
if s == nil {
return
}
{
t.Providers = make([]*structs.IntentionJWTProvider, len(s.Providers))
for i := range s.Providers {
if s.Providers[i] != nil {
var x structs.IntentionJWTProvider
IntentionJWTProviderToStructs(s.Providers[i], &x)
t.Providers[i] = &x
}
}
}
}
func IntentionJWTRequirementFromStructs(t *structs.IntentionJWTRequirement, s *IntentionJWTRequirement) {
if s == nil {
return
}
{
s.Providers = make([]*IntentionJWTProvider, len(t.Providers))
for i := range t.Providers {
if t.Providers[i] != nil {
var x IntentionJWTProvider
IntentionJWTProviderFromStructs(t.Providers[i], &x)
s.Providers[i] = &x
}
}
}
}
func IntentionPermissionToStructs(s *IntentionPermission, t *structs.IntentionPermission) {
if s == nil {
return
@ -954,6 +1030,11 @@ func IntentionPermissionToStructs(s *IntentionPermission, t *structs.IntentionPe
IntentionHTTPPermissionToStructs(s.HTTP, &x)
t.HTTP = &x
}
if s.JWT != nil {
var x structs.IntentionJWTRequirement
IntentionJWTRequirementToStructs(s.JWT, &x)
t.JWT = &x
}
}
func IntentionPermissionFromStructs(t *structs.IntentionPermission, s *IntentionPermission) {
if s == nil {
@ -965,6 +1046,11 @@ func IntentionPermissionFromStructs(t *structs.IntentionPermission, s *Intention
IntentionHTTPPermissionFromStructs(t.HTTP, &x)
s.HTTP = &x
}
if t.JWT != nil {
var x IntentionJWTRequirement
IntentionJWTRequirementFromStructs(t.JWT, &x)
s.JWT = &x
}
}
func LeastRequestConfigToStructs(s *LeastRequestConfig, t *structs.LeastRequestConfig) {
if s == nil {
@ -1350,6 +1436,11 @@ func ServiceIntentionsToStructs(s *ServiceIntentions, t *structs.ServiceIntentio
}
}
}
if s.JWT != nil {
var x structs.IntentionJWTRequirement
IntentionJWTRequirementToStructs(s.JWT, &x)
t.JWT = &x
}
t.Meta = s.Meta
}
func ServiceIntentionsFromStructs(t *structs.ServiceIntentionsConfigEntry, s *ServiceIntentions) {
@ -1366,6 +1457,11 @@ func ServiceIntentionsFromStructs(t *structs.ServiceIntentionsConfigEntry, s *Se
}
}
}
if t.JWT != nil {
var x IntentionJWTRequirement
IntentionJWTRequirementFromStructs(t.JWT, &x)
s.JWT = &x
}
s.Meta = t.Meta
}
func ServiceResolverToStructs(s *ServiceResolver, t *structs.ServiceResolverConfigEntry) {

View File

@ -287,6 +287,36 @@ func (msg *ServiceIntentions) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *IntentionJWTRequirement) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *IntentionJWTRequirement) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *IntentionJWTProvider) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *IntentionJWTProvider) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *IntentionJWTClaimVerification) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *IntentionJWTClaimVerification) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *SourceIntention) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)

File diff suppressed because it is too large Load Diff

View File

@ -374,6 +374,36 @@ message HTTPHeaderModifiers {
message ServiceIntentions {
repeated SourceIntention Sources = 1;
map<string, string> Meta = 2;
IntentionJWTRequirement JWT = 3;
}
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.IntentionJWTRequirement
// output=config_entry.gen.go
// name=Structs
message IntentionJWTRequirement {
repeated IntentionJWTProvider Providers = 1;
}
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.IntentionJWTProvider
// output=config_entry.gen.go
// name=Structs
message IntentionJWTProvider {
string Name = 1;
repeated IntentionJWTClaimVerification VerifyClaims = 2;
}
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.IntentionJWTClaimVerification
// output=config_entry.gen.go
// name=Structs
message IntentionJWTClaimVerification {
repeated string Path = 1;
string Value = 2;
}
// mog annotation:
@ -420,6 +450,7 @@ message IntentionPermission {
// mog: func-to=intentionActionToStructs func-from=intentionActionFromStructs
IntentionAction Action = 1;
IntentionHTTPPermission HTTP = 2;
IntentionJWTRequirement JWT = 3;
}
// mog annotation: