Skip to content

Commit

Permalink
remove unnecessary len checks, simplify JWTInfos
Browse files Browse the repository at this point in the history
  • Loading branch information
roncodingenthusiast committed Jul 12, 2023
1 parent d674f3f commit a48e214
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 57 deletions.
15 changes: 3 additions & 12 deletions agent/xds/jwt_authn.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,14 @@ func makeJWTAuthFilter(pCE map[string]*structs.JWTProviderConfigEntry, intention

cfg := &envoy_http_jwt_authn_v3.JwtAuthentication{
Providers: providers,
}
// only add rules if any of the existing providers are referenced by intentions
if len(jwtRequirements) > 0 {
cfg.Rules = []*envoy_http_jwt_authn_v3.RequirementRule{
Rules: []*envoy_http_jwt_authn_v3.RequirementRule{
{
Match: &envoy_route_v3.RouteMatch{
PathSpecifier: &envoy_route_v3.RouteMatch_Prefix{Prefix: "/"},
},
RequirementType: makeJWTRequirementRule(andJWTRequirements(jwtRequirements)),
},
}
},
}
return makeEnvoyHTTPFilter(jwtEnvoyFilter, cfg)
}
Expand All @@ -87,7 +84,7 @@ func makeJWTRequirementRule(r *envoy_http_jwt_authn_v3.JwtRequirement) *envoy_ht
func andJWTRequirements(reqs []*envoy_http_jwt_authn_v3.JwtRequirement) *envoy_http_jwt_authn_v3.JwtRequirement {
switch len(reqs) {
case 0:
return anyJWTRequirement()
return nil
case 1:
return reqs[0]
default:
Expand All @@ -101,12 +98,6 @@ func andJWTRequirements(reqs []*envoy_http_jwt_authn_v3.JwtRequirement) *envoy_h
}
}

func anyJWTRequirement() *envoy_http_jwt_authn_v3.JwtRequirement {
return &envoy_http_jwt_authn_v3.JwtRequirement{
RequiresType: &envoy_http_jwt_authn_v3.JwtRequirement_RequiresAny{},
}
}

// providerToJWTRequirement builds the envoy jwtRequirement.
//
// Note: since the rbac filter is in charge of making decisions of allow/denied, this
Expand Down
6 changes: 3 additions & 3 deletions agent/xds/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -1365,9 +1365,9 @@ func (s *ResourceGenerator) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot
logger: s.Logger,
}
if useHTTPFilter {
jwtFilter, jwtFilterErr := makeJWTAuthFilter(cfgSnap.JWTProviders, cfgSnap.ConnectProxy.Intentions)
if jwtFilterErr != nil {
return nil, jwtFilterErr
jwtFilter, err := makeJWTAuthFilter(cfgSnap.JWTProviders, cfgSnap.ConnectProxy.Intentions)
if err != nil {
return nil, err
}
rbacFilter, err := makeRBACHTTPFilter(
cfgSnap.ConnectProxy.Intentions,
Expand Down
67 changes: 25 additions & 42 deletions agent/xds/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,28 +226,25 @@ func removePermissionPrecedence(perms []*rbacPermission, intentionDefaultAction
}

func (p *rbacPermission) GenerateJWTPermissions() *envoy_rbac_v3.Permission {
if p.jwtInfos == nil {
if len(p.jwtInfos) == 0 {
return p.ComputedPermission
}

var jwtPerms []*envoy_rbac_v3.Permission

for _, info := range p.jwtInfos {
claimsPermission := jwtInfosToPermission(info.ProviderRequirement.VerifyClaims, info.MetadataPayloadKey)
segments := pathToSegments([]string{"iss"}, info.MetadataPayloadKey)
issuerPermission := segmentToPermission(segments, info.Provider.Issuer)
claimsPermission := jwtInfosToPermission(info.Provider.VerifyClaims, buildPayloadInMetadataKey(info.Provider.Name))
segments := pathToSegments([]string{"iss"}, buildPayloadInMetadataKey(info.Provider.Name))
issuerPermission := segmentToPermission(segments, info.Issuer)

perm := andPermissions([]*envoy_rbac_v3.Permission{
issuerPermission, claimsPermission,
})
jwtPerms = append(jwtPerms, perm)
}
if len(jwtPerms) > 0 {
jwtPerm := orPermissions(jwtPerms)
return andPermissions([]*envoy_rbac_v3.Permission{p.ComputedPermission, jwtPerm})
}

return p.ComputedPermission
jwtPerm := orPermissions(jwtPerms)
return andPermissions([]*envoy_rbac_v3.Permission{p.ComputedPermission, jwtPerm})
}

func intentionToIntermediateRBACForm(
Expand Down Expand Up @@ -280,12 +277,10 @@ func intentionToIntermediateRBACForm(
if !ok {
return nil, fmt.Errorf("provider specified in intention does not exist. Provider name: %s", prov.Name)
}
jwts = append(jwts, makeJWTInfos(prov, jwtProvider))
jwts = append(jwts, newJWTInfo(prov, jwtProvider))
}

if len(jwts) > 0 {
rixn.jwtInfos = jwts
}
rixn.jwtInfos = jwts
}

if len(ixn.Permissions) > 0 {
Expand All @@ -306,7 +301,7 @@ func intentionToIntermediateRBACForm(
if !ok {
return nil, fmt.Errorf("provider specified in intention does not exist. Provider name: %s", prov.Name)
}
jwts = append(jwts, makeJWTInfos(prov, jwtProvider))
jwts = append(jwts, newJWTInfo(prov, jwtProvider))
}
if len(jwts) > 0 {
rbacPerm.jwtInfos = jwts
Expand All @@ -325,20 +320,21 @@ func intentionToIntermediateRBACForm(
return rixn, nil
}

func makeJWTInfos(p *structs.IntentionJWTProvider, ce *structs.JWTProviderConfigEntry) *JWTInfo {
func newJWTInfo(p *structs.IntentionJWTProvider, ce *structs.JWTProviderConfigEntry) *JWTInfo {
return &JWTInfo{
ProviderRequirement: p,
MetadataPayloadKey: buildPayloadInMetadataKey(p.Name),
Provider: ce,
Provider: p,
Issuer: ce.Issuer,
}
}

type intentionAction int

type JWTInfo struct {
Provider *structs.JWTProviderConfigEntry
MetadataPayloadKey string
ProviderRequirement *structs.IntentionJWTProvider
// Provider issuer
// this information is coming from the config entry
Issuer string
// Provider is the intention provider
Provider *structs.IntentionJWTProvider
}

const (
Expand Down Expand Up @@ -632,7 +628,7 @@ func makeRBACRules(
for i, rbacIxn := range rbacIxns {
var infos []*JWTInfo
if isHTTP {
infos = collectTopLevelJWTInfos(rbacIxn)
infos = rbacIxn.jwtInfos
}
if rbacIxn.Action == intentionActionLayer7 {
if len(rbacIxn.Permissions) == 0 {
Expand All @@ -643,9 +639,7 @@ func makeRBACRules(
}

rbacPrincipals := optimizePrincipals([]*envoy_rbac_v3.Principal{rbacIxn.ComputedPrincipal})
if len(infos) > 0 {
rbacPrincipals = addJWTPrincipals(rbacPrincipals, infos)
}
rbacPrincipals = addJWTPrincipals(rbacPrincipals, infos)
// For L7: we should generate one Policy per Principal and list all of the Permissions
policy := &envoy_rbac_v3.Policy{
Principals: rbacPrincipals,
Expand All @@ -659,9 +653,7 @@ func makeRBACRules(
// For L4: we should generate one big Policy listing all Principals
principalsL4 = append(principalsL4, rbacIxn.ComputedPrincipal)
// Append JWT principals to list of principals
if len(infos) > 0 {
principalsL4 = addJWTPrincipals(principalsL4, infos)
}
principalsL4 = addJWTPrincipals(principalsL4, infos)
}
}
if len(principalsL4) > 0 {
Expand Down Expand Up @@ -692,12 +684,14 @@ func addJWTPrincipals(p []*envoy_rbac_v3.Principal, infos []*JWTInfo) []*envoy_r
}
jwtPrincipals := make([]*envoy_rbac_v3.Principal, 0)
for _, info := range infos {
payloadKey := buildPayloadInMetadataKey(info.Provider.Name)

// build jwt provider issuer principal
segments := pathToSegments([]string{"iss"}, info.MetadataPayloadKey)
p := segmentToPrincipal(segments, info.Provider.Issuer)
segments := pathToSegments([]string{"iss"}, payloadKey)
p := segmentToPrincipal(segments, info.Issuer)

// add jwt provider claims principal if any
if cp := jwtClaimsToPrincipals(info.ProviderRequirement.VerifyClaims, info.MetadataPayloadKey); cp != nil {
if cp := jwtClaimsToPrincipals(info.Provider.VerifyClaims, payloadKey); cp != nil {
p = andPrincipals([]*envoy_rbac_v3.Principal{p, cp})
}
jwtPrincipals = append(jwtPrincipals, p)
Expand All @@ -717,17 +711,6 @@ func addJWTPrincipals(p []*envoy_rbac_v3.Principal, infos []*JWTInfo) []*envoy_r
return res
}

// collectTopLevelJWTInfos extracts all the top level jwt infos.
func collectTopLevelJWTInfos(rbacIxn *rbacIntention) []*JWTInfo {
infos := make([]*JWTInfo, 0, len(rbacIxn.jwtInfos))

if len(rbacIxn.jwtInfos) > 0 {
infos = append(infos, rbacIxn.jwtInfos...)
}

return infos
}

func jwtClaimsToPrincipals(claims []*structs.IntentionJWTClaimVerification, payloadkey string) *envoy_rbac_v3.Principal {
ps := make([]*envoy_rbac_v3.Principal, 0)

Expand Down

0 comments on commit a48e214

Please sign in to comment.