Repository: istio/istio
File: pilot/pkg/model/authorization.go (Go)

Code before:
			Name:        config.Name,
			Namespace:   config.Namespace,
			Annotations: config.Annotations,
			Spec:        config.Spec.(*authpb.AuthorizationPolicy),
		}
		policy.NamespaceToPolicies[config.Namespace] = append(policy.NamespaceToPolicies[config.Namespace], authzConfig)
	}

	return policy
}

type AuthorizationPoliciesResult struct {
	Custom []AuthorizationPolicy
	Deny   []AuthorizationPolicy
	Allow  []AuthorizationPolicy
	Audit  []AuthorizationPolicy
}

// ListAuthorizationPolicies returns authorization policies applied to the workload in the given namespace.
func (policy *AuthorizationPolicies) ListAuthorizationPolicies(namespace string, workload labels.Instance) AuthorizationPoliciesResult {
	ret := AuthorizationPoliciesResult{}
	if policy == nil {
		return ret
	}

	var namespaces []string
	if policy.RootNamespace != "" {
		namespaces = append(namespaces, policy.RootNamespace)
	}
	// To prevent duplicate policies in case root namespace equals proxy's namespace.
	if namespace != policy.RootNamespace {
		namespaces = append(namespaces, namespace)
	}

	for _, ns := range namespaces {
		for _, config := range policy.NamespaceToPolicies[ns] {
			spec := config.Spec
			selector := labels.Instance(spec.GetSelector().GetMatchLabels())
			if selector.SubsetOf(workload) {
				switch config.Spec.GetAction() {
				case authpb.AuthorizationPolicy_ALLOW:
					ret.Allow = append(ret.Allow, config)
				case authpb.AuthorizationPolicy_DENY:
					ret.Deny = append(ret.Deny, config)
				case authpb.AuthorizationPolicy_AUDIT:
					ret.Audit = append(ret.Audit, config)
				case authpb.AuthorizationPolicy_CUSTOM:
					ret.Custom = append(ret.Custom, config)
				default:
					log.Errorf("ignored authorization policy %s.%s with unsupported action: %s",
						config.Namespace, config.Name, config.Spec.GetAction())

Review comment (security):
Does `selectorAuthorizationPolicies` in pkg/serviceregistry/kube/controller/authorization.go also need to be updated to handle `targetRef`? If so, will this be addressed in a follow-up PR?

Code after:
			Name:        config.Name,
			Namespace:   config.Namespace,
			Annotations: config.Annotations,
			Spec:        config.Spec.(*authpb.AuthorizationPolicy),
		}
		policy.NamespaceToPolicies[config.Namespace] = append(policy.NamespaceToPolicies[config.Namespace], authzConfig)
	}

	return policy
}

type AuthorizationPoliciesResult struct {
	Custom []AuthorizationPolicy
	Deny   []AuthorizationPolicy
	Allow  []AuthorizationPolicy
	Audit  []AuthorizationPolicy
}

// ListAuthorizationPolicies returns authorization policies applied to the workload in the given namespace.
func (policy *AuthorizationPolicies) ListAuthorizationPolicies(selectionOpts WorkloadSelectionOpts) AuthorizationPoliciesResult {
	configs := AuthorizationPoliciesResult{}
	if policy == nil {
		return configs
	}
	rootNamespace := policy.RootNamespace
	namespace := selectionOpts.Namespace
	workloadLabels := selectionOpts.WorkloadLabels
	var lookupInNamespaces []string

	if namespace != rootNamespace {
		// Only check the root namespace if the (workload) namespace is not already the root namespace
		// to avoid double inclusion.
		lookupInNamespaces = []string{rootNamespace, namespace}
	} else {
		lookupInNamespaces = []string{namespace}
	}

	for _, ns := range lookupInNamespaces {
		for _, config := range policy.NamespaceToPolicies[ns] {
			spec := config.Spec
			switch getPolicyMatcher(gvk.AuthorizationPolicy, config.Name, selectionOpts, spec) {
			case policyMatchSelector:
				selector := labels.Instance(spec.GetSelector().GetMatchLabels())
				if selector.SubsetOf(workloadLabels) {
					configs = updateAuthorizationPoliciesResult(configs, config)
				}
			case policyMatchDirect:
				configs = updateAuthorizationPoliciesResult(configs, config)
			}
		}
	}