sigs.k8s.io/gateway-api@v1.0.0/geps/gep-713.md (about)

     1  # GEP-713: Metaresources and Policy Attachment
     2  
     3  * Issue: [#713](https://github.com/kubernetes-sigs/gateway-api/issues/713)
     4  * Status: Experimental
     5  
     6  > **Note**: This GEP is exempt from the [Probationary Period][expprob] rules of
     7  > our GEP overview as it existed before those rules did, and so it has been
     8  > explicitly grandfathered in.
     9  
    10  [expprob]:https://gateway-api.sigs.k8s.io/geps/overview/#probationary-period
    11  
    12  ## TLDR
    13  
    14  This GEP aims to standardize terminology and processes around using one Kubernetes
    15  object to modify the functions of one or more other objects.
    16  
    17  This GEP defines some terms, firstly: _Metaresource_.
    18  
    19  A Kubernetes object that _augments_ the behavior of an object
    20  in a standard way is called a _Metaresource_.
    21  
    22  This document proposes controlling the creation of configuration in the underlying
    23  Gateway data plane using two types of Policy Attachment.
    24  A "Policy Attachment" is a specific type of _metaresource_ that can affect specific
    25  settings across either one object (this is "Direct Policy Attachment"), or objects
    26  in a hierarchy (this is "Inherited Policy Attachment").
    27  
    28  Individual policy APIs:
    29  - must be their own CRDs (e.g. `TimeoutPolicy`, `RetryPolicy` etc),
    30  - can be included in the Gateway API group and installation or be defined by
    31    implementations
    32  - and must include a common `TargetRef` struct in their specification to identify
    33    how and where to apply that policy.
    34  - _may_ include either a `defaults` section, an `overrides` section, or both. If
    35    these are included, the Policy is an Inherited Policy, and should use the
    36    inheritance rules defined in this document.
    37  
    38  For Inherited Policies, this GEP also describes a set of expected behaviors
    39  for how settings can flow across a defined hierarchy.
    40  
    41  
    42  ## Goals
    43  
    44  * Establish a pattern for Policy resources which will be used for any policies
    45    included in the Gateway API spec
    46  * Establish a pattern for Policy attachment, whether Direct or Inherited,
    47    which must be used for any implementation specific policies used with
    48    Gateway API resources
    49  * Provide a way to distinguish between required and default values for all
    50    policy API implementations
    51  * Enable policy attachment at all relevant scopes, including Gateways, Routes,
    52    Backends, along with how values should flow across a hierarchy if necessary
    53  * Ensure the policy attachment specification is generic and forward thinking
    54    enough that it could be easily adapted to other grouping mechanisms like
    55    Namespaces in the future
    56  * Provide a means of attachment that works for both ingress and mesh
    57    implementations of this API
    58  * Provide a consistent specification that will ensure familiarity between both
    59    included and implementation-specific policies so they can both be interpreted
    60    the same way.
    61  
    62  ## Out of scope
    63  
    64  * Define all potential policies that may be attached to resources
    65  * Design the full structure and configuration of policies
    66  
    67  ## Background and concepts
    68  
    69  When designing Gateway API, one of the things we’ve found is that we often need to be
    70  able change the behavior of objects without being able to make changes to the spec
    71  of those objects. Sometimes, this is because we can’t change the spec of the object
    72  to hold the information we need ( ReferenceGrant, from
    73  [GEP-709](https://gateway-api.sigs.k8s.io/geps/gep-709/), affecting Secrets
    74  and Services is an example, as is Direct Policy Attachment), and sometimes it’s
    75  because we want the behavior change to flow across multiple objects
    76  (this is what Inherited Policy Attachment is for).
    77  
    78  To put this another way, sometimes we need ways to be able to affect how an object
    79  is interpreted in the API, without representing the description of those effects
    80  inside the spec of the object.
    81  
    82  This document describes the ways we design objects to meet these two use cases,
    83  and why you might choose one or the other.
    84  
    85  We use the term “metaresource” to describe the class of objects that _only_ augment
    86  the behavior of another Kubernetes object, regardless of what they are targeting.
    87  
    88  “Meta” here is used in its Greek sense of “more comprehensive”
    89  or “transcending”, and “resource” rather than “object” because “metaresource”
    90  is more pronounceable than “metaobject”. Additionally, a single word is better
    91  than a phrase like “wrapper object” or “wrapper resource” overall, although both
    92  of those terms are effectively synonymous with “metaresource”.
    93  
    94  A "Policy Attachment" is a metaresource that affects the fields in existing objects
    95  (like Gateway or Routes), or influences the configuration that's generated in an
    96  underlying data plane.
    97  
    98  "Direct Policy Attachment" is when a Policy object references a single object _only_,
    99  and only modifies the fields of or the configuration associated with that object.
   100  
   101  "Inherited Policy Attachment" is when a Policy object references a single object
   102  _and any child objects of that object_ (according to some defined hierarchy), and
   103  modifies fields of the child objects, or configuration associated with the child
   104  objects.
   105  
   106  In either case, a Policy may either affect an object by controlling the value
   107  of one of the existing _fields_ in the `spec` of an object, or it may add
   108  additional fields that are _not_ in the `spec` of the object.
   109  
   110  ### Direct Policy Attachment
   111  
   112  A Direct Policy Attachment is tightly bound to one instance of a particular
   113  Kind within a single namespace (or to an instance of a single Kind at cluster scope),
   114  and only modifies the behavior of the object that matches its binding.
   115  
   116  As an example, one use case that Gateway API currently does not support is how
   117  to configure details of the TLS required to connect to a backend (in other words,
   118  if the process running inside the backend workload expects TLS, not that some
   119  automated infrastructure layer is provisioning TLS as in the Mesh case).
   120  
   121  A hypothetical TLSConnectionPolicy that targets a Service could be used for this,
   122  using the functionality of the Service as describing a set of endpoints. (It
   123  should also be noted this is not the only way to solve this problem, just an
   124  example to illustrate Direct Policy Attachment.)
   125  
   126  The TLSConnectionPolicy would look something like this:
   127  
   128  ```yaml
   129  apiVersion: gateway.networking.k8s.io/v1alpha2
   130  kind: TLSConnectionPolicy
   131  metadata:
   132    name: tlsport8443
   133    namespace: foo
   134  spec:
   135    targetRef: # This struct is defined as part of Gateway API
   136      group: "" # Empty string means core - this is a standard convention
   137      kind: Service
   138      name: fooService
   139    tls:
   140      certificateAuthorityRefs:
   141        - name: CAcert
   142      port: 8443
   143  
   144  ```
   145  
   146  All this does is tell an implementation, that for connecting to port `8443` on the
   147  Service `fooService`, it should assume that the connection is TLS, and expect the
   148  service's certificate to be validated by the chain in the `CAcert` Secret.
   149  
   150  Importantly, this would apply to _every_ usage of that Service across any HTTPRoutes
   151  in that namespace, which could be useful for a Service that is reused in a lot of
   152  HTTPRoutes.
   153  
   154  With these two examples in mind, here are some guidelines for when to consider
   155  using Direct Policy Attachment:
   156  
   157  * The number or scope of objects to be modified is limited or singular. Direct
   158    Policy Attachments must target one specific object.
   159  * The modifications to be made to the objects don’t have any transitive information -
   160    that is, the modifications only affect the single object that the targeted
   161    metaresource is bound to, and don’t have ramifications that flow beyond that
   162    object.
   163  * In terms of status, it should be reasonably easy for a user to understand that
   164    everything is working - basically, as long as the targeted object exists, and
   165    the modifications are valid, the metaresource is valid, and this should be
   166    straightforward to communicate in one or two Conditions. Note that at the time
   167    of writing, this is *not* completed.
   168  * Direct Policy Attachment _should_ only be used to target objects in the same
   169    namespace as the Policy object. Allowing cross-namespace references brings in
   170    significant security concerns, and/or difficulties about merging cross-namespace
   171    policy objects. Notably, Mesh use cases may need to do something like this for
   172    consumer policies, but in general, Policy objects that modify the behavior of
   173    things outside their own namespace should be avoided unless it uses a handshake
   174    of some sort, where the things outside the namespace can opt–out of the behavior.
   175    (Notably, this is the design that we used for ReferenceGrant).
   176  
   177  ### Inherited Policy Attachment: It's all about the defaults and overrides
   178  
   179  Because a Inherited Policy is a metaresource, it targets some other resource
   180  and _augments_ its behavior.
   181  
   182  But why have this distinct from other types of metaresource? Because Inherited
   183  Policy resources are designed to have a way for settings to flow down a hierarchy.
   184  
   185  Defaults set the default value for something, and can be overridden by the
   186  “lower” objects (like a connection timeout default policy on a Gateway being
   187  overridable inside a HTTPRoute), and Overrides cannot be overridden by “lower”
   188  objects (like setting a maximum client timeout to some non-infinite value at the
   189  Gateway level to stop HTTPRoute owners from leaking connections over time).
   190  
   191  Here are some guidelines for when to consider using a Inherited Policy object:
   192  
   193  * The settings or configuration are bound to one containing object, but affect
   194    other objects attached to that one (for example, affecting HTTPRoutes attached
   195    to a single Gateway, or all HTTPRoutes in a GatewayClass).
   196  * The settings need to able to be defaulted, but can be overridden on a per-object
   197    basis.
   198  * The settings must be enforced by one persona, and not modifiable or removable
   199    by a lesser-privileged persona. (The owner of a GatewayClass may want to restrict
   200    something about all Gateways in a GatewayClass, regardless of who owns the Gateway,
   201    or a Gateway owner may want to enforce some setting across all attached HTTPRoutes).
   202  * In terms of status, a good accounting for how to record that the Policy is
   203    attached is easy, but recording what resources the Policy is being applied to
   204    is not, and needs to be carefully designed to avoid fanout apiserver load.
   205    (This is not built at all in the current design either).
   206  
   207  When multiple Inherited Policies are used, they can interact in various ways,
   208  which are governed by the following rules, which will be expanded on later in this document.
   209  
   210  * If a Policy does not affect an object's fields directly, then the resultant
   211    Policy should be the set of all distinct fields inside the relevant Policy objects,
   212    as set out by the rules below.
   213  * For Policies that affect an object's existing fields, multiple instances of the
   214    same Policy Kind affecting an object's fields will be evaluated as
   215    though only a single Policy "wins" the right to affect each field. This operation
   216    is performed on a _per-distinct-field_ basis.
   217  * Settings in `overrides` stanzas will win over the same setting in a `defaults`
   218    stanza.
   219  * `overrides` settings operate in a "less specific beats more specific" fashion -
   220    Policies attached _higher_ up the hierarchy will beat the same type of Policy
   221    attached further down the hierarchy.
   222  * `defaults` settings operate in a "more specific beats less specific" fashion -
   223    Policies attached _lower down_ the hierarchy will beat the same type of Policy
   224    attached further _up_ the hierarchy.
   225  * For `defaults`, the _most specific_ value is the one _inside the object_ that
   226    the Policy applies to; that is, if a Policy specifies a `default`, and an object
   227    specifies a value, the _object's_ value will win.
   228  * Policies interact with the fields they are controlling in a "replace value"
   229    fashion.
   230    * For fields where the `value` is a scalar, (like a string or a number)
   231      should have their value _replaced_ by the value in the Policy if it wins.
   232      Notably, this means that a `default` will only ever replace an empty or unset
   233      value in an object.
   234    * For fields where the value is an object, the Policy should include the fields
   235      in the object in its definition, so that the replacement can be on simple fields
   236      rather than complex ones.
   237    * For fields where the final value is non-scalar, but is not an _object_ with
   238      fields of its own, the value should be entirely replaced, _not_ merged. This
   239      means that lists of strings or lists of ints specified in a Policy will overwrite
   240      the empty list (in the case of a `default`) or any specified list (in the case
   241      of an `override`). The same applies to `map[string]string` fields. An example
   242      here would be a field that stores a map of annotations - specifying a Policy
   243      that overrides annotations will mean that a final object specifying those
   244      annotations will have its value _entirely replaced_ by an `override` setting.
   245  * In the case that two Policies of the same type specify different fields, then
   246    _all_ of the specified fields should take effect on the affected object.
   247  
   248  Examples to further illustrate these rules are given below.
   249  
   250  ## Naming Policy objects
   251  
   252  The preceding rules discuss how Policy objects should _behave_, but this section
   253  describes how Policy objects should be _named_.
   254  
   255  Policy objects should be clearly named so as to indicate that they are Policy
   256  metaresources.
   257  
   258  The simplest way to do that is to ensure that the type's name contains the `Policy`
   259  string.
   260  
   261  Implementations _should_ use `Policy` as the last part of the names of object types
   262  that use this pattern.
   263  
   264  If an implementation does not, then they _must_ clearly document what objects
   265  are Policy metaresources in their documentation. Again, this is _not recommended_
   266  without a _very_ good reason.
   267  
   268  ## Policy Attachment examples and behavior
   269  
   270  This approach is building on concepts from all of the alternatives discussed
   271  below. This is very similar to the (now removed) BackendPolicy resource in the API,
   272  but also borrows some concepts from the [ServicePolicy
   273  proposal](https://github.com/kubernetes-sigs/gateway-api/issues/611).
   274  
   275  ### Policy Attachment for Ingress
   276  Attaching a Directly Attached Policy to Gateway resources for ingress use cases
   277  is relatively straightforward. A policy can reference the resource it wants to
   278  apply to.
   279  
   280  Access is granted with RBAC - anyone that has access to create a RetryPolicy in
   281  a given namespace can attach it to any resource within that namespace.
   282  
   283  ![Simple Ingress Example](images/713-ingress-simple.png)
   284  
   285  An Inherited Policy can attach to a parent resource, and then each policy
   286  applies to the referenced resource and everything below it in terms of hierarchy.
   287  Although this example is likely more complex than many real world
   288  use cases, it helps demonstrate how policy attachment can work across
   289  namespaces.
   290  
   291  ![Complex Ingress Example](images/713-ingress-complex.png)
   292  
   293  ### Policy Attachment for Mesh
   294  Although there is a great deal of overlap between ingress and mesh use cases,
   295  mesh enables more complex policy attachment scenarios. For example, you may want
   296  to apply policy to requests from a specific namespace to a backend in another
   297  namespace.
   298  
   299  ![Simple Mesh Example](images/713-mesh-simple.png)
   300  
   301  Policy attachment can be quite simple with mesh. Policy can be applied to any
   302  resource in any namespace but it can only apply to requests from the same
   303  namespace if the target is in a different namespace.
   304  
   305  At the other extreme, policy can be used to apply to requests from a specific
   306  workload to a backend in another namespace. A route can be used to intercept
   307  these requests and split them between different backends (foo-a and foo-b in
   308  this case).
   309  
   310  ![Complex Mesh Example](images/713-mesh-complex.png)
   311  
   312  ### Policy TargetRef API
   313  
   314  Each Policy resource MUST include a single `targetRef` field. It must not
   315  target more than one resource at a time, but it can be used to target larger
   316  resources such as Gateways or Namespaces that may apply to multiple child
   317  resources.
   318  
   319  As with most APIs, there are countless ways we could choose to expand this in
   320  the future. This includes supporting multiple targetRefs and/or label selectors.
   321  Although this would enable compelling functionality, it would increase the
   322  complexity of an already complex API and potentially result in more conflicts
   323  between policies. Although we may choose to expand the targeting capabilities
   324  in the future, at this point it is strongly preferred to start with a simpler
   325  pattern that still leaves room for future expansion.
   326  
   327  The `targetRef` field MUST have the following structure:
   328  
   329  ```go
   330  // PolicyTargetReference identifies an API object to apply policy to.
   331  type PolicyTargetReference struct {
   332      // Group is the group of the target resource.
   333      //
   334      // +kubebuilder:validation:MinLength=1
   335      // +kubebuilder:validation:MaxLength=253
   336      Group string `json:"group"`
   337  
   338      // Kind is kind of the target resource.
   339      //
   340      // +kubebuilder:validation:MinLength=1
   341      // +kubebuilder:validation:MaxLength=253
   342      Kind string `json:"kind"`
   343  
   344      // Name is the name of the target resource.
   345      //
   346      // +kubebuilder:validation:MinLength=1
   347      // +kubebuilder:validation:MaxLength=253
   348      Name string `json:"name"`
   349  
   350      // Namespace is the namespace of the referent. When unspecified, the local
   351      // namespace is inferred. Even when policy targets a resource in a different
   352      // namespace, it may only apply to traffic originating from the same
   353      // namespace as the policy.
   354      //
   355      // +kubebuilder:validation:MinLength=1
   356      // +kubebuilder:validation:MaxLength=253
   357      // +optional
   358      Namespace string `json:"namespace,omitempty"`
   359  }
   360  ```
   361  
   362  ### Sample Policy API
   363  The following structure can be used as a starting point for any Policy resource
   364  using this API pattern. Note that the PolicyTargetReference struct defined above
   365  will be distributed as part of the Gateway API.
   366  
   367  ```go
   368  // ACMEServicePolicy provides a way to apply Service policy configuration with
   369  // the ACME implementation of the Gateway API.
   370  type ACMEServicePolicy struct {
   371      metav1.TypeMeta   `json:",inline"`
   372      metav1.ObjectMeta `json:"metadata,omitempty"`
   373  
   374      // Spec defines the desired state of ACMEServicePolicy.
   375      Spec ACMEServicePolicySpec `json:"spec"`
   376  
   377      // Status defines the current state of ACMEServicePolicy.
   378      Status ACMEServicePolicyStatus `json:"status,omitempty"`
   379  }
   380  
   381  // ACMEServicePolicySpec defines the desired state of ACMEServicePolicy.
   382  type ACMEServicePolicySpec struct {
   383      // TargetRef identifies an API object to apply policy to.
   384      TargetRef gatewayv1a2.PolicyTargetReference `json:"targetRef"`
   385  
   386      // Override defines policy configuration that should override policy
   387      // configuration attached below the targeted resource in the hierarchy.
   388      // +optional
   389      Override *ACMEPolicyConfig `json:"override,omitempty"`
   390  
   391      // Default defines default policy configuration for the targeted resource.
   392      // +optional
   393      Default *ACMEPolicyConfig `json:"default,omitempty"`
   394  }
   395  
   396  // ACMEPolicyConfig contains ACME policy configuration.
   397  type ACMEPolicyConfig struct {
   398      // Add configurable policy here
   399  }
   400  
   401  // ACMEServicePolicyStatus defines the observed state of ACMEServicePolicy.
   402  type ACMEServicePolicyStatus struct {
   403      // Conditions describe the current conditions of the ACMEServicePolicy.
   404      //
   405      // +optional
   406      // +listType=map
   407      // +listMapKey=type
   408      // +kubebuilder:validation:MaxItems=8
   409      Conditions []metav1.Condition `json:"conditions,omitempty"`
   410  }
   411  ```
   412  
   413  ### Hierarchy
   414  Each policy MAY include default or override values. Default values are given
   415  precedence from the bottom up, while override values are top down. That means
   416  that a default attached to a Backend will have the highest precedence among
   417  default values while an override value attached to a GatewayClass will have the
   418  highest precedence overall.
   419  
   420  ![Ingress and Sidecar Hierarchy](images/713-hierarchy.png)
   421  
   422  To illustrate this, consider 3 resources with the following hierarchy:
   423  A > B > C. When attaching the concept of defaults and overrides to that, the
   424  hierarchy would be expanded to this:
   425  
   426  A override > B override > C override > C default > B default > A default.
   427  
   428  Note that the hierarchy is reversed for defaults. The rationale here is that
   429  overrides usually need to be enforced top down while defaults should apply to
   430  the lowest resource first. For example, if an admin needs to attach required
   431  policy, they can attach it as an override to a Gateway. That would have
   432  precedence over Routes and Services below it. On the other hand, an app owner
   433  may want to set a default timeout for their Service. That would have precedence
   434  over defaults attached at higher levels such as Route or Gateway.
   435  
   436  If using defaults _and_ overrides, each policy resource MUST include 2 structs
   437  within the spec. One with override values and the other with default values.
   438  
   439  In the following example, the policy attached to the Gateway requires cdn to
   440  be enabled and provides some default configuration for that. The policy attached
   441  to the Route changes the value for one of those fields (includeQueryString).
   442  
   443  ```yaml
   444  kind: CDNCachingPolicy # Example of implementation specific policy name
   445  spec:
   446    override:
   447      cdn:
   448        enabled: true
   449    default:
   450      cdn:
   451        cachePolicy:
   452          includeHost: true
   453          includeProtocol: true
   454          includeQueryString: true
   455    targetRef:
   456      kind: Gateway
   457      name: example
   458  ---
   459  kind: CDNCachingPolicy
   460  spec:
   461    default:
   462      cdn:
   463        cachePolicy:
   464          includeQueryString: false
   465    targetRef:
   466      type: direct
   467      kind: HTTPRoute
   468      name: example
   469  ```
   470  
   471  In this final example, we can see how the override attached to the Gateway has
   472  precedence over the default drainTimeout value attached to the Route. At the
   473  same time, we can see that the default connectionTimeout attached to the Route
   474  has precedence over the default attached to the Gateway.
   475  
   476  Also note how the different resources interact - fields that are not common across
   477  objects _may_ both end up affecting the final object.
   478  
   479  ![Inherited Policy Example](images/713-policy-hierarchy.png)
   480  
   481  #### Supported Resources
   482  It is important to note that not every implementation will be able to support
   483  policy attachment to each resource described in the hierarchy above. When that
   484  is the case, implementations MUST clearly document which resources a policy may
   485  be attached to.
   486  
   487  #### Attaching Policy to GatewayClass
   488  GatewayClass may be the trickiest resource to attach policy to. Policy
   489  attachment relies on the policy being defined within the same scope as the
   490  target. This ensures that only users with write access to a policy resource in a
   491  given scope will be able to modify policy at that level. Since GatewayClass is a
   492  cluster scoped resource, this means that any policy attached to it must also be
   493  cluster scoped.
   494  
   495  GatewayClass parameters provide an alternative to policy attachment that may be
   496  easier for some implementations to support. These parameters can similarly be
   497  used to set defaults and requirements for an entire GatewayClass.
   498  
   499  ### Targeting External Services
   500  In some cases (likely limited to mesh) we may want to apply policies to requests
   501  to external services. To accomplish this, implementations can choose to support
   502  a reference to a virtual resource type:
   503  
   504  ```yaml
   505  apiVersion: networking.acme.io/v1alpha1
   506  kind: RetryPolicy
   507  metadata:
   508    name: foo
   509  spec:
   510    default:
   511      maxRetries: 5
   512    targetRef:
   513      group: networking.acme.io
   514      kind: ExternalService
   515      name: foo.com
   516  ```
   517  
   518  ### Merging into existing `spec` fields
   519  
   520  It's possible (even likely) that configuration in a Policy may need to be merged
   521  into an existing object's fields somehow, particularly for Inherited policies.
   522  
   523  When merging into an existing fields inside an object, Policy objects should
   524  merge values at a scalar level, not at a struct or object level.
   525  
   526  For example, in the `CDNCachingPolicy` example above, the `cdn` struct contains
   527  a `cachePolicy` struct that contains fields. If an implementation was merging
   528  this configuration into an existing object that contained the same fields, it
   529  should merge the fields at a scalar level, with the `includeHost`,
   530  `includeProtocol`, and `includeQueryString` values being defaulted if they were
   531  not specified in the object being controlled. Similarly, for `overrides`, the
   532  values of the innermost scalar fields should overwrite the scalar fields in the
   533  affected object.
   534  
   535  Implementations should not copy any structs from the Policy object directly into the
   536  affected object, any fields that _are_ overridden should be overridden on a per-field
   537  basis.
   538  
   539  In the case that the field in the Policy affects a struct that is a member of a list,
   540  each existing item in the list in the affected object should have each of its
   541  fields compared to the corresponding fields in the Policy.
   542  
   543  For non-scalar field _values_, like a list of strings, or a `map[string]string`
   544  value, the _entire value_ must be overwritten by the value from the Policy. No
   545  merging should take place. This mainly applies to `overrides`, since for
   546  `defaults`, there should be no value present in a field on the final object.
   547  
   548  This table shows how this works for various types:
   549  
   550  |Type|Object config|Override Policy config|Result|
   551  |----|-------------|----------------------|------|
   552  |string| `key: "foo"` | `key: "bar"`  | `key: "bar"` |
   553  |list| `key: ["a","b"]` | `key: ["c","d"]` | `key: ["c","d"]` |
   554  |`map[string]string`| `key: {"foo": "a", "bar": "b"}` | `key: {"foo": "c", "bar": "d"}` | `key: {"foo": "c", "bar": "d"}` |
   555  
   556  
   557  ### Conflict Resolution
   558  It is possible for multiple policies to target the same object _and_ the same
   559  fields inside that object. If multiple policy resources target
   560  the same resource _and_ have an identical field specified with different values,
   561  precedence MUST be determined in order of the following criteria, continuing on
   562  ties:
   563  
   564  * Direct Policies override Inherited Policies. If preventing settings from
   565    being overwritten is important, implementations should only use Inherited
   566    Policies, and the `override` stanza that implies. Note also that it's not
   567    intended that Direct and Inherited Policies should overlap, so this should
   568    only come up in exceptional circumstances.
   569  * Inside Inherited Policies, the same setting in `overrides` beats the one in
   570    `defaults`.
   571  * The oldest Policy based on creation timestamp. For example, a Policy with a
   572    creation timestamp of "2021-07-15 01:02:03" is given precedence over a Policy
   573    with a creation timestamp of "2021-07-15 01:02:04".
   574  * The Policy appearing first in alphabetical order by `{namespace}/{name}`. For
   575    example, foo/bar is given precedence over foo/baz.
   576  
   577  For a better user experience, a validating webhook can be implemented to prevent
   578  these kinds of conflicts all together.
   579  
   580  ## Status and the Discoverability Problem
   581  
   582  So far, this document has talked about what Policy Attachment is, different types
   583  of attachment, and how those attachments work.
   584  
   585  Probably the biggest impediment to this GEP moving forward is the discoverability
   586  problem; that is, it’s critical that an object owner be able to know what policy
   587  is affecting their object, and ideally its contents.
   588  
   589  To understand this a bit better, let’s consider this parable, with thanks to Flynn:
   590  
   591  ### The Parable
   592  
   593  It's a sunny Wednesday afternoon, and the lead microservices developer for
   594  Evil Genius Cupcakes is windsurfing. Work has been eating Ana alive for the
   595  past two and a half weeks, but after successfully deploying version 3.6.0 of
   596  the `baker` service this morning, she's escaped early to try to unwind a bit.
   597  
   598  Her shoulders are just starting to unknot when her phone pings with a text
   599  from Charlie, down in the NOC. Waterproof phones are a blessing, but also a
   600  curse.
   601  
   602  **Charlie**: _Hey Ana. Things are still running, more or less, but latencies
   603  on everything in the `baker` namespace are crazy high after your last rollout,
   604  and `baker` itself has a weirdly high load. Sorry to interrupt you on the lake
   605  but can you take a look? Thanks!!_
   606  
   607  Ana stares at the phone for a long moment, heart sinking, then sighs and
   608  turns back to shore.
   609  
   610  What she finds when dries off and grabs her laptop is strange. `baker` does
   611  seem to be taking much more load than its clients are sending, and its clients
   612  report much higher latencies than they’d expect. She doublechecks the
   613  Deployment, the Service, and all the HTTPRoutes around `baker`; everything
   614  looks good. `baker`’s logs show her mostly failed requests... with a lot of
   615  duplicates? Ana checks her HTTPRoute again, though she's pretty sure you
   616  can't configure retries there, and finds nothing. But it definitely looks like
   617  clients are retrying when they shouldn’t be.
   618  
   619  She pings Charlie.
   620  
   621  **Ana**: _Hey Charlie. Something weird is up, looks like requests to `baker`
   622  are failing but getting retried??_
   623  
   624  A minute later they answer.
   625  
   626  **Charlie**: 🤷 _Did you configure retries?_
   627  
   628  **Ana**: _Dude. I don’t even know how to._ 😂
   629  
   630  **Charlie**: _You just attach a RetryPolicy to your HTTPRoute._
   631  
   632  **Ana**: _Nope. Definitely didn’t do that._
   633  
   634  She types `kubectl get retrypolicy -n baker` and gets a permission error.
   635  
   636  **Ana**: _Huh, I actually don’t have permissions for RetryPolicy._ 🤔
   637  
   638  **Charlie**: 🤷 _Feels like you should but OK, guess that can’t be it._
   639  
   640  Minutes pass while both look at logs.
   641  
   642  **Charlie**: _I’m an idiot. There’s a RetryPolicy for the whole namespace –
   643  sorry, too many policies in the dashboard and I missed it. Deleting that since
   644  you don’t want retries._
   645  
   646  **Ana**: _Are you sure that’s a good–_
   647  
   648  Ana’s phone shrills while she’s typing, and she drops it. When she picks it
   649  up again she sees a stack of alerts. She goes pale as she quickly flips
   650  through them: there’s one for every single service in the `baker` namespace.
   651  
   652  **Ana**: _PUT IT BACK!!_
   653  
   654  **Charlie**: _Just did. Be glad you couldn't hear all the alarms here._ 😕
   655  
   656  **Ana**: _What the hell just happened??_
   657  
   658  **Charlie**: _At a guess, all the workloads in the `baker` namespace actually
   659  fail a lot, but they seem OK because there are retries across the whole
   660  namespace?_ 🤔
   661  
   662  Ana's blood runs cold.
   663  
   664  **Charlie**: _Yeah. Looking a little closer, I think your `baker` rollout this
   665  morning would have failed without those retries._ 😕
   666  
   667  There is a pause while Ana's mind races through increasingly unpleasant
   668  possibilities.
   669  
   670  **Ana**: _I don't even know where to start here. How long did that
   671  RetryPolicy go in? Is it the only thing like it?_
   672  
   673  **Charlie**: _Didn’t look closely before deleting it, but I think it said a few
   674  months ago. And there are lots of different kinds of policy and lots of
   675  individual policies, hang on a minute..._
   676  
   677  **Charlie**: _Looks like about 47 for your chunk of the world, a couple hundred
   678  system-wide._
   679  
   680  **Ana**: 😱 _Can you tell me what they’re doing for each of our services? I
   681  can’t even_ look _at these things._ 😕
   682  
   683  **Charlie**: _That's gonna take awhile. Our tooling to show us which policies
   684  bind to a given workload doesn't go the other direction._
   685  
   686  **Ana**: _...wait. You have to_ build tools _to know if retries are turned on??_
   687  
   688  Pause.
   689  
   690  **Charlie**: _Policy attachment is more complex than we’d like, yeah._ 😐
   691  _Look, how ‘bout roll back your `baker` change for now? We can get together in
   692  the morning and start sorting this out._
   693  
   694  Ana shakes her head and rolls back her edits to the `baker` Deployment, then
   695  sits looking out over the lake as the deployment progresses.
   696  
   697  **Ana**: _Done. Are things happier now?_
   698  
   699  **Charlie**: _Looks like, thanks. Reckon you can get back to your sailboard._ 🙂
   700  
   701  Ana sighs.
   702  
   703  **Ana**: _Wish I could. Wind’s died down, though, and it'll be dark soon.
   704  Just gonna head home._
   705  
   706  **Charlie**: _Ouch. Sorry to hear that._ 😐
   707  
   708  One more look out at the lake.
   709  
   710  **Ana**: _Thanks for the help. Wish we’d found better answers._ 😢
   711  
   712  ### The Problem, restated
   713  What this parable makes clear is that, in the absence of information about what
   714  Policy is affecting an object, it’s very easy to make poor decisions.
   715  
   716  It’s critical that this proposal solve the problem of showing up to three things,
   717  listed in increasing order of desirability:
   718  
   719  - _That_ some Policy is affecting a particular object
   720  - _Which_ Policy is (or Policies are) affecting a particular object
   721  - _What_ settings in the Policy are affecting the object.
   722  
   723  In the parable, if Ana and Charlie had known that there were Policies affecting
   724  the relevant object, then they could have gone looking for the relevant Policies
   725  and things would have played out differently. If they knew which Policies, they
   726  would need to look less hard, and if they knew what the settings being applied
   727  were, then the parable would have been able to be very short indeed.
   728  
   729  (There’s also another use case to consider, in that Charlie should have been able
   730  to see that the Policy on the namespace was in use in many places before deleting
   731  it.)
   732  
   733  To put this another way, Policy Attachment is effectively adding a fourth Persona,
   734  the Policy Admin, to Gateway API’s persona list, and without a solution to the
   735  discoverability problem, their actions are largely invisible to the Application
   736  Developer. Not only that, but their concerns cut across the previously established
   737  levels.
   738  
   739  ![Gateway API diagram with Policy Admin](images/713-the-diagram-with-policy-admin.png)
   740  
   741  
   742  From the Policy Admin’s point of view, they need to know across their whole remit
   743  (which conceivably could be the whole cluster):
   744  
   745  - _What_ Policy has been created
   746  - _Where_ it’s applied
   747  - _What_ the resultant policy is saying
   748  
   749  Which again, come down to discoverability, and can probably be addressed in similar
   750  ways at an API level to the Application Developer's concerns.
   751  
   752  An important note here is that a key piece of information for Policy Admins and
   753  Cluster Operators is “How many things does this Policy affect?”. In the parable,
   754  this would have enabled Charlie to know that deleting the Namespace Policy would
   755  affect many other people than just Ana.
   756  
   757  ### Problems we need to solve
   758  
   759  Before we can get into solutions, we need to discuss the problems that solutions
   760  may need to solve, so that we have some criteria for evaluating those solutions.
   761  
   762  #### User discoverability
   763  
   764  Let's go through the various users of Gateway API and what they need to know about
   765  Policy Attachment.
   766  
   767  In all of these cases, we should aim to keep the troubleshooting distance low;
   768  that is, that there should be a minimum of hops required between objects from the
   769  one owned by the user to the one responsible for a setting.
   770  
   771  Another way to think of the troubleshooting distance in this context is "How many
   772  `kubectl` commands would the user need to do to understand that a Policy is relevant,
   773  which Policy is relevant, and what configuration the full set of Policy is setting?"
   774  
   775  ##### Application Developer Discoverability
   776  
   777  How does Ana, or any Application Developer who owns one or more Route objects know
   778  that their object is affected by Policy, which Policy is affecting it, and what
   779  the content of the Policy is?
   780  
   781  The best outcome is that Ana needs to look only at a specific route to know what
   782  Policy settings are being applied to that Route, and where they come from.
   783  However, some of the other problems below make it very difficult to achieve this.
   784  
   785  ##### Policy Admin Discoverability
   786  
   787  How does the Policy Admin know what Policy is applied where, and what the content
   788  of that Policy is?
   789  How do they validate that Policy is being used in ways acceptable to their organization?
   790  For any given Policy object, how do they know how many places it's being used?
   791  
   792  ##### Cluster Admin Discoverability
   793  
   794  The Cluster Admin has similar concerns to the Policy Admin, but with a focus on
   795  being able to determine what's relevant when something is broken.
   796  
   797  How does the Cluster Admin know what Policy is applied where, and what the content
   798  of that Policy is?
   799  
   800  For any given Policy object, how do they know how many places it's being used?
   801  
   802  #### Evaluating and Displaying Resultant Policy
   803  
   804  For any given Policy type, whether Direct Attached or Inherited, implementations
   805  will need to be able to _calculate_ the resultant set of Policy to be able to
   806  apply that Policy to the correct parts of their data plane configuration.
   807  However, _displaying_ that resultant set of Policy in a way that is straightforward
   808  for the various personas to consume is much harder.
   809  
   810  The easiest possible option for Application Developers would be for the
   811  implementation to make the full resultant set of Policy available in the status
   812  of objects that the Policy affects. However, this runs into a few problems:
   813  
   814  - The status needs to be namespaced by the implementation
   815  - The status could get large if there are a lot of Policy objects affecting an
   816    object
   817  - Building a common data representation pattern that can fit into a single common
   818    schema is not straightforward.
   819  - Updating one Policy object could cause many affected objects to need to be
   820    updated themselves. This sort of fan-out problem can be very bad for apiserver
   821    load, particularly if Policy changes rapidly, there are a lot of objects, or both.
   822  
   823  ##### Status needs to be namespaced by implementation
   824  
   825  Because an object can be affected by multiple implementations at once, any status
   826  we add must be namespaced by the implementation.
   827  
   828  In Route Parent status, we've used the parentRef plus the controller name for this.
   829  
   830  For Policy, we can do something similar and namespace by the reference to the
   831  implementation's controller name.
   832  
   833  We can't easily namespace by the originating Policy because the source could be
   834  more than one Policy object.
   835  
   836  ##### Creating common data representation patterns
   837  
   838  The problem here is that we need to have a _common_ pattern for including the
   839  details of an _arbitrarily defined_ object, that needs to be included in the base
   840  API.
   841  
   842  So we can't use structured data, because we have no way of knowing what the
   843  structure will be beforehand.
   844  
   845  This suggests that we need to use unstructured data for representing the main
   846  body of an arbitrary Policy object.
   847  
   848  Practically, this will need to be a string representation of the YAML form of the
   849  body of the Policy object (absent the metadata part of every Kubernetes object).
   850  
   851  Policy Attachment does not mandate anything about the design of the object's top
   852  level except that it must be a Kubernetes object, so the only thing we can rely
   853  on is the presence of the Kubernetes metadata elements: `apiVersion`, `kind`,
   854  and `metadata`.
   855  
   856  A string representation of the rest of the file is the best we can do here.
   857  
   858  ##### Fanout status update problems
   859  
   860  The fanout problem is that, when an update takes place in a single object (a
   861  Policy, or an object with a Policy attached), an implementation may need to
   862  update _many_ objects if it needs to place details of what Policy applies, or
   863  what the resultant set of policy is on _every_ object.
   864  
   865  Historically, this is a risky strategy and needs to be carefully applied, as
   866  it's an excellent way to create apiserver load problems, which can produce a large
   867  range of bad effects for cluster stability.
   868  
   869  This does not mean that we can't do anything at all that affects multiple objects,
   870  but that we need to carefully consider what information is stored in status so 
   871  that _every_ Policy update does not require a status update.
   872  
   873  #### Solution summary
   874  
   875  Because Policy Attachment is a pattern for APIs, not an API, and needs to address
   876  all the problems above, the strategy this GEP proposes is to define a range of
   877  options for increasing the discoverabilty of Policy resources, and provide
   878  guidelines for when they should be used.
   879  
   880  It's likely that at some stage, the Gateway API CRDs will include some Policy
   881  resources, and these will be designed with all these discoverabiity solutions
   882  in mind.
   883  
   884  
   885  ### Solution cookbook
   886  
   887  This section contains some required patterns for Policy objects and some
   888  suggestions. Each will be marked as MUST, SHOULD, or MAY, using the standard 
   889  meanings of those terms.
   890  
   891  Additionally, the status of each solution is noted at the beginning of the section.
   892  
   893  #### Standard label on CRD objects
   894  
   895  Status: Required
   896  
   897  Each CRD that defines a Policy object MUST include a label that specifies that
   898  it is a Policy object, and that label MUST specify the _type_ of Policy attachment
   899  in use.
   900  
   901  The label is `gateway.networking.k8s.io/policy: inherited|direct`.
   902  
   903  This solution is intended to allow both users and tooling to identify which CRDs
   904  in the cluster should be treated as Policy objects, and so is intended to help
   905  with discoverability generally. It will also be used by the forthcoming `kubectl`
   906  plugin.
   907  
   908  ##### Design considerations
   909  
   910  This is already part of the API pattern, but is being lifted to more prominience
   911  here.
   912  
   913  #### Standard status struct
   914  
   915  Status: Experimental
   916  
   917  Policy objects SHOULD use the upstream `PolicyAncestorStatus` struct in their respective
   918  Status structs. Please see the included `PolicyAncestorStatus` struct, and its use in
   919  the `BackendTLSPolicy` object for detailed examples. Included here is a representative
   920  version.
   921  
   922  This pattern enables different conditions to be set for different "Ancestors"
   923  of the target resource. This is particularly helpful for policies that may be
   924  implemented by multiple controllers or attached to resources with different
   925  capabilities. This pattern also provides a clear view of what resources a
   926  policy is affecting.
   927  
   928  For the best integration with community tooling and consistency across
   929  the broader community, we recommend that all implementations transition 
   930  to Policy status with this kind of nested structure.
   931  
   932  This is an `Ancestor` status rather than a `Parent` status, as in the Route status
   933  because for Policy attachment, the relevant object may or may not be the direct
   934  parent.
   935  
   936  For example, `BackendTLSPolicy` directly attaches to a Service, which may be included
   937  in multiple Routes, in multiple Gateways. However, for many implementations, 
   938  the status of the `BackendTLSPolicy` will be different only at the Gateway level, 
   939  so Gateway is the relevant Ancestor for the status.
   940  
   941  Each Gateway that has a Route that includes a backend with an attached `BackendTLSPolicy`
   942  MUST have a separate `PolicyAncestorStatus` section in the `BackendTLSPolicy`'s
   943  `status.ancestors` stanza, which mandates that entries must be distinct using the
   944  combination of the `AncestorRef` and the `ControllerName` fields as a key.
   945  
   946  See [GEP-1897][gep-1897] for the exact details.
   947  
   948  [gep-1897]: /geps/gep-1897
   949  
   950  ```go
   951  // PolicyAncestorStatus describes the status of a route with respect to an
   952  // associated Ancestor.
   953  //
   954  // Ancestors refer to objects that are either the Target of a policy or above it in terms
   955  // of object hierarchy. For example, if a policy targets a Service, an Ancestor could be
   956  // a Route or a Gateway. 
   957  
   958  // In the context of policy attachment, the Ancestor is used to distinguish which
   959  // resource results in a distinct application of this policy. For example, if a policy
   960  // targets a Service, it may have a distinct result per attached Gateway.
   961  // 
   962  // Policies targeting the same resource may have different effects depending on the 
   963  // ancestors of those resources. For example, different Gateways targeting the same
   964  // Service may have different capabilities, especially if they have different underlying
   965  // implementations. 
   966  //
   967  // For example, in BackendTLSPolicy, the Policy attaches to a Service that is
   968  // used as a backend in a HTTPRoute that is itself attached to a Gateway.
   969  // In this case, the relevant object for status is the Gateway, and that is the
   970  // ancestor object referred to in this status.
   971  //
   972  // Note that a Target of a Policy is also a valid Ancestor, so for objects where
   973  // the Target is the relevant object for status, this struct SHOULD still be used.
   974  type PolicyAncestorStatus struct {
   975  	// AncestorRef corresponds with a ParentRef in the spec that this
   976  	// RouteParentStatus struct describes the status of.
   977  	AncestorRef ParentReference `json:"ancestorRef"`
   978  
   979  	// ControllerName is a domain/path string that indicates the name of the
   980  	// controller that wrote this status. This corresponds with the
   981  	// controllerName field on GatewayClass.
   982  	//
   983  	// Example: "example.net/gateway-controller".
   984  	//
   985  	// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
   986  	// valid Kubernetes names
   987  	// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
   988  	//
   989  	// Controllers MUST populate this field when writing status. Controllers should ensure that
   990  	// entries to status populated with their ControllerName are cleaned up when they are no
   991  	// longer necessary.
   992  	ControllerName GatewayController `json:"controllerName"`
   993  
   994  	// Conditions describes the status of the Policy with respect to the given Ancestor.
   995  	//
   996  	// +listType=map
   997  	// +listMapKey=type
   998  	// +kubebuilder:validation:MinItems=1
   999  	// +kubebuilder:validation:MaxItems=8
  1000  	Conditions []metav1.Condition `json:"conditions,omitempty"`
  1001  }
  1002  
  1003  
  1004  // PolicyStatus defines the common attributes that all Policies SHOULD include
  1005  // within their status.
  1006  type PolicyStatus struct {
  1007  	// Ancestors is a list of ancestor resources (usually Gateways) that are
  1008  	// associated with the route, and the status of the route with respect to
  1009  	// each ancestor. When this route attaches to a parent, the controller that
  1010  	// manages the parent and the ancestors MUST add an entry to this list when
  1011  	// the controller first sees the route and SHOULD update the entry as
  1012  	// appropriate when the relevant ancestor is modified.
  1013  	//
  1014  	// Note that choosing the relevant ancestor is left to the Policy designers;
  1015  	// an important part of Policy design is designing the right object level at
  1016  	// which to namespace this status.
  1017  	//
  1018  	// Note also that implementations MUST ONLY populate ancestor status for 
  1019  	// the Ancestor resources they are responsible for. Implementations MUST
  1020  	// use the ControllerName field to uniquely identify the entries in this list
  1021  	// that they are responsible for.
  1022  	//
  1023  	// A maximum of 32 ancestors will be represented in this list. An empty list
  1024  	// means the Policy is not relevant for any ancestors.
  1025  	//
  1026  	// +kubebuilder:validation:MaxItems=32
  1027  	Ancestors []PolicyAncestorStatus `json:"ancestors"`
  1028  }
  1029  ```
  1030  
  1031  ##### Design considerations
  1032  
  1033  This is recommended as the base for Policy object's status. As Policy Attachment
  1034  is a pattern, not an API, "recommended" is the strongest we can make this, but
  1035  we believe that standardizing this will help a lot with discoverability.
  1036  
  1037  Note that is likely that all Gateway API tooling will expect policy status to follow
  1038  this structure. To benefit from broader consistency and discoverability, we
  1039  recommend transitioning to this structure for all Gateway API Policies.
  1040  
  1041  #### Standard status Condition on Policy-affected objects
  1042  
  1043  Support: Provisional
  1044  
  1045  This solution is IN PROGRESS and so is not binding yet.
  1046  
  1047  This solution requires definition in a GEP of its own to become binding.
  1048  
  1049  **The description included here is intended to illustrate the sort of solution
  1050  that an eventual GEP will need to provide, _not to be a binding design.**
  1051  
  1052  Implementations that use Policy objects MUST put a Condition into `status.Conditions`
  1053  of any objects affected by a Policy.
  1054  
  1055  That Condition must have a `type` ending in `PolicyAffected` (like
  1056  `gateway.networking.k8s.io/PolicyAffected`),
  1057  and have the optional `observedGeneration` field kept up to date when the `spec`
  1058  of the Policy-attached object changes.
  1059  
  1060  Implementations _should_ use their own unique domain prefix for this Condition
  1061  `type` - it is recommended that implementations use the same domain as in the
  1062  `controllerName` field on GatewayClass (or some other implementation-unique
  1063  domain for implementations that do not use GatewayClass).)
  1064  
  1065  For objects that do _not_ have a `status.Conditions` field available (`Secret`
  1066  is a good example), that object MUST instead have an annotation of
  1067  `gateway.networking.k8s.io/PolicyAffected: true` (or with an
  1068  implementation-specific domain prefix) added instead.
  1069  
  1070  
  1071  ##### Design Considerations
  1072  The intent here is to add at least a breadcrumb that leads object owners to have
  1073  some way to know that their object is being affected by another object, while
  1074  minimizing the number of updates necessary.
  1075  
  1076  Minimizing the object updates is done by only having an update be necessary when
  1077  the affected object starts or stops being affected by a Policy, rather than if
  1078  the Policy itself has been updated.
  1079  
  1080  There is already a similar Condition to be placed on _Policy_ objects, rather
  1081  than on the _targeted_ objects, so this solution is also being included in the
  1082  Condiions section below.
  1083  
  1084  #### GatewayClass status Extension Types listing
  1085  
  1086  Support: Provisional
  1087  
  1088  This solution is IN PROGRESS, and so is not binding yet.
  1089  
  1090  Each implementation MUST list all relevant CRDs in its GatewayClass status (like
  1091  Policy, and other extension types, like paramsRef targets, filters, and so on). 
  1092  
  1093  This is going to be tracked in its own GEP, https://github.com/kubernetes-sigs/gateway-api/discussions/2118
  1094  is the initial discussion. This document will be updated with the details once
  1095  that GEP is opened.
  1096  
  1097  ##### Design Considerations
  1098  
  1099  This solution:
  1100  
  1101  - is low cost in terms of apiserver updates (because it's only on the GatewayClass,
  1102    and only on implementation startup)
  1103  - provides a standard place for all users to look for relevant objects
  1104  - ties in to the Conformance Profiles design and other efforts about GatewayClass 
  1105    status
  1106  
  1107  #### Standard status stanza
  1108  
  1109  Support: Provisional
  1110  
  1111  This solution is IN PROGRESS and so is not binding yet.
  1112  
  1113  This solution requires definition in a GEP of its own to become binding.
  1114  
  1115  **The description included here is intended to illustrate the sort of solution
  1116  that an eventual GEP will need to provide, _not to be a binding design. THIS IS
  1117  AN EXPERIMENTAL SOLUTION DO NOT USE THIS YET.**
  1118  
  1119  An implementation SHOULD include the name, namespace, apiGroup and Kind of Policies
  1120  affecting an object in the new `effectivePolicy` status stanza on Gateway API
  1121  objects.
  1122  
  1123  This stanza looks like this:
  1124  ```yaml
  1125  kind: Gateway
  1126  ...
  1127  status:
  1128    effectivePolicy:
  1129    - name: some-policy
  1130      namespace: some-namespace
  1131      apiGroup: implementation.io
  1132      kind: AwesomePolicy
  1133    ...
  1134  ```
  1135  
  1136  ##### Design Considerations
  1137  
  1138  This solution is designed to limit the number of status updates required by an
  1139  implementation to when a Policy starts or stops being relevant for an object,
  1140  rather than if that Policy's settings are updated.
  1141  
  1142  It helps a lot with discoverability, but comes at the cost of a reasonably high
  1143  fanout cost. Implementations using this solution should ensure that status updates
  1144  are deduplicated and only sent to the apiserver when absolutely necessary.
  1145  
  1146  Ideally, these status updates SHOULD be in a separate, lower-priority queue than
  1147  other status updates or similar solution.
  1148  
  1149  #### PolicyBinding resource
  1150  
  1151  Support: Provisional
  1152  
  1153  This solution is IN PROGRESS and so is not binding yet.
  1154  
  1155  This solution requires definition in a GEP of its own to become binding.
  1156  
  1157  **The description included here is intended to illustrate the sort of solution
  1158  that the eventual GEP will need to provide, _not to be a binding design. THIS IS
  1159  AN EXPERIMENTAL SOLUTION DO NOT USE THIS YET.**
  1160  
  1161  Implementations SHOULD create an instance of a new `gateway.networking.k8s.io/EffectivePolicy`
  1162  object when one or more Policy objects become relevant to the target object.
  1163  
  1164  The `EffectivePolicy` object MUST be in the same namespace as the object targeted
  1165  by the Policy, and must have the _same name_ as the object targeted like the Policy.
  1166  This is intended to mirror the Services/Endpoints naming convention, to allow for
  1167  ease of discovery.
  1168  
  1169  The `EffectivePolicy` object MUST set the following information:
  1170  
  1171  - The name, namespace, apiGroup and Kind of Policy objects affecting the targeted
  1172    object.
  1173  - The full resultant set of Policy affecting the targeted object.
  1174  
  1175  The above details MUST be namespaced using the `controllerName` of the implementation
  1176  (could also be by GatewayClass), similar to Route status being namespaced by
  1177  `parentRef`.
  1178  
  1179  An example `EffectivePolicy` object is included here - this may be superseded by
  1180  a later GEP and should be updated or removed in that case. Note that it does
  1181  _not_ contain a `spec` and a `status` stanza - by definition this object _only_
  1182  contains `status` information.
  1183  
  1184  ```yaml
  1185  kind: EffectivePolicy
  1186  apiVersion: gateway.networkking.k8s.io/v1alpha2
  1187  metadata:
  1188    name: targeted-object
  1189    namespace: targeted-object-namespace
  1190  policies:
  1191  - controllerName: implementation.io/ControllerName
  1192    objects:
  1193    - name: some-policy
  1194      namespace: some-namespace
  1195      apiGroup: implementation.io
  1196      kind: AwesomePolicy
  1197    resultantPolicy:
  1198      awesomePolicy:
  1199        configitem1:
  1200          defaults:
  1201            foo: 1
  1202          overrides:
  1203            bar: important-setting
  1204  
  1205  ```
  1206  
  1207  Note here that the `resultantPolicy` setting is defined using the same mechanisms
  1208  as an `unstructured.Unstructured` object in the Kubernetes Go libraries - it's
  1209  effectively a `map[string]struct{}` that is stored as a `map[string]string` -
  1210  which allows an arbitrary object to be specified there.
  1211  
  1212  Users or tools reading the config underneath `resultantPolicy` SHOULD display
  1213  it in its encoded form, and not try to deserialize it in any way.
  1214  
  1215  The rendered YAML MUST be usable as the `spec` for the type given.
  1216  
  1217  ##### Design considerations
  1218  
  1219  This will provide _full_ visibility to end users of the _actual settings_ being
  1220  applied to their object, which is a big discoverability win.
  1221  
  1222  However, it relies on the establishment and communication of a convention ("An 
  1223  EffectivePolicy is right next to your affected object"), that may not be desirable.
  1224  
  1225  Thus its status as EXPERIMENTAL DO NOT USE YET.
  1226  
  1227  #### Validating Admission Controller to inform users about relevant Policy
  1228  
  1229  Implementations MAY supply a Validating Admission Webhook that will return a
  1230  WARNING message when an applied object is affected by some Policy, which may be 
  1231  an inherited or indirect one.
  1232  
  1233  The warning message MAY include the name, namespace, apiGroup and Kind of relevant
  1234  Policy objects.
  1235  
  1236  ##### Design Considerations
  1237  
  1238  Pro:
  1239  
  1240  - This gives object owners a very clear signal that something some Policy is
  1241    going to affect their object, at apply time, which helps a lot with discoverability.
  1242  
  1243  Cons:
  1244  
  1245  - Implementations would have to have a webhook, which is another thing to run.
  1246  - The webhook will need to have the same data model that the implementation uses,
  1247    and keep track of which GatewayClasses, Gateways, Routes, and Policies are
  1248    relevant. Experience suggests this will not be a trivial engineering exercise,and will add a lot of implementation complexity.
  1249  
  1250  #### `kubectl` plugin or command-line tool
  1251  To help improve UX and standardization, a kubectl plugin will be developed that
  1252  will be capable of describing the computed sum of policy that applies to a given
  1253  resource, including policies applied to parent resources.
  1254  
  1255  Each Policy CRD that wants to be supported by this plugin will need to follow
  1256  the API structure defined above and add a `gateway.networking.k8s.io/policy: true`
  1257  label to the CRD.
  1258  
  1259  ### Conditions
  1260  
  1261  Implementations using Policy objects MUST include a `spec` and `status` stanza, and the `status` stanza MUST contain a `conditions` stanza, using the standard Condition format.
  1262  
  1263  Policy authors should consider namespacing the `conditions` stanza with a
  1264  `controllerName`, as in Route status, if more than one implementation will be
  1265  reconciling the Policy type.
  1266  
  1267  #### On `Policy` objects
  1268  
  1269  Controllers using the Gateway API policy attachment model MUST populate the 
  1270  `Accepted` condition and reasons as defined below on policy resources to provide
  1271  a consistent experience across implementations.
  1272  
  1273  ```go
  1274  // PolicyConditionType is a type of condition for a policy.
  1275  type PolicyConditionType string
  1276  
  1277  // PolicyConditionReason is a reason for a policy condition.
  1278  type PolicyConditionReason string
  1279  
  1280  const (
  1281    // PolicyConditionAccepted indicates whether the policy has been accepted or rejected
  1282    // by a targeted resource, and why.
  1283    //
  1284    // Possible reasons for this condition to be True are:
  1285    //
  1286    // * "Accepted"
  1287    //
  1288    // Possible reasons for this condition to be False are:
  1289    //
  1290    // * "Conflicted"
  1291    // * "Invalid"
  1292    // * "TargetNotFound"
  1293    //
  1294    PolicyConditionAccepted PolicyConditionType = "Accepted"
  1295  
  1296    // PolicyReasonAccepted is used with the "Accepted" condition when the policy has been
  1297    // accepted by the targeted resource.
  1298    PolicyReasonAccepted PolicyConditionReason = "Accepted"
  1299  
  1300    // PolicyReasonConflicted is used with the "Accepted" condition when the policy has not
  1301    // been accepted by a targeted resource because there is another policy that targets the same
  1302    // resource and a merge is not possible.
  1303    PolicyReasonConflicted PolicyConditionReason = "Conflicted"
  1304  
  1305    // PolicyReasonInvalid is used with the "Accepted" condition when the policy is syntactically
  1306    // or semantically invalid.
  1307    PolicyReasonInvalid PolicyConditionReason = "Invalid"
  1308  
  1309    // PolicyReasonTargetNotFound is used with the "Accepted" condition when the policy is attached to
  1310    // an invalid target resource
  1311    PolicyReasonTargetNotFound PolicyConditionReason = "TargetNotFound"
  1312  )
  1313  ```
  1314  
  1315  #### On targeted resources
  1316  
  1317  (copied from [Standard Status Condition][#standard-status-condition])
  1318  
  1319  This solution requires definition in a GEP of its own to become binding.
  1320  
  1321  **The description included here is intended to illustrate the sort of solution
  1322  that an eventual GEP will need to provide, _not to be a binding design.**
  1323  
  1324  Implementations that use Policy objects MUST put a Condition into `status.Conditions`
  1325  of any objects affected by a Policy.
  1326  
  1327  That Condition must have a `type` ending in `PolicyAffected` (like
  1328  `gateway.networking.k8s.io/PolicyAffected`),
  1329  and have the optional `observedGeneration` field kept up to date when the `spec`
  1330  of the Policy-attached object changes.
  1331  
  1332  Implementations _should_ use their own unique domain prefix for this Condition
  1333  `type` - it is recommended that implementations use the same domain as in the
  1334  `controllerName` field on GatewayClass (or some other implementation-unique
  1335  domain for implementations that do not use GatewayClass).)
  1336  
  1337  For objects that do _not_ have a `status.Conditions` field available (`Secret`
  1338  is a good example), that object MUST instead have an annotation of
  1339  `gateway.networking.k8s.io/PolicyAffected: true` (or with an
  1340  implementation-specific domain prefix) added instead.
  1341  
  1342  ### Interaction with Custom Filters and other extension points
  1343  There are multiple methods of custom extension in the Gateway API. Policy
  1344  attachment and custom Route filters are two of these. Policy attachment is
  1345  designed to provide arbitrary configuration fields that decorate Gateway API
  1346  resources. Route filters provide custom request/response filters embedded inside
  1347  Route resources. Both are extension methods for fields that cannot easily be
  1348  standardized as core or extended fields of the Gateway API. The following
  1349  guidance should be considered when introducing a custom field into any Gateway
  1350  controller implementation:
  1351  
  1352  1. For any given field that a Gateway controller implementation needs, the
  1353     possibility of using core or extended should always be considered before
  1354     using custom policy resources. This is encouraged to promote standardization
  1355     and, over time, to absorb capabilities into the API as first class fields,
  1356     which offer a more streamlined UX than custom policy attachment.
  1357  
  1358  2. Although it's possible that arbitrary fields could be supported by custom
  1359     policy, custom route filters, and core/extended fields concurrently, it is
  1360     recommended that implementations only use multiple mechanisms for
  1361     representing the same fields when those fields really _need_ the defaulting
  1362     and/or overriding behavior that Policy Attachment provides. For example, a
  1363     custom filter that allowed the configuration of Authentication inside a
  1364     HTTPRoute object might also have an associated Policy resource that allowed
  1365     the filter's settings to be defaulted or overridden. It should be noted that
  1366     doing this in the absence of a solution to the status problem is likely to
  1367     be *very* difficult to troubleshoot.
  1368  
  1369  ### Conformance Level
  1370  This policy attachment pattern is associated with an "EXTENDED" conformance
  1371  level. The implementations that support this policy attachment model will have
  1372  the same behavior and semantics, although they may not be able to support
  1373  attachment of all types of policy at all potential attachment points.
  1374  
  1375  ### Apply Policies to Sections of a Resource
  1376  Policies can target specific matches within nested objects. For instance, rather than
  1377  applying a policy to the entire Gateway, we may want to attach it to a particular Gateway listener.
  1378  
  1379  To achieve this, an optional `sectionName` field can be set in the `targetRef` of a policy
  1380  to refer to a specific listener within the target Gateway.
  1381  
  1382  ```yaml
  1383  apiVersion: gateway.networking.k8s.io/v1beta1
  1384  kind: Gateway
  1385  metadata:
  1386    name: foo-gateway
  1387  spec:
  1388    gatewayClassName: foo-lb
  1389    listeners:
  1390    - name: bar
  1391      ...
  1392  ---
  1393  apiVersion: networking.acme.io/v1alpha2
  1394  kind: AuthenticationPolicy
  1395  metadata:
  1396    name: foo
  1397  spec:
  1398    provider:
  1399      issuer: "https://oidc.example.com"
  1400    targetRef:
  1401      name: foo-gateway
  1402      group: gateway.networking.k8s.io
  1403      kind: Gateway
  1404      sectionName: bar
  1405  ```
  1406  
  1407  The `sectionName` field can also be used to target a specific section of other resources:
  1408  
  1409  * Service.Ports.Name
  1410  * xRoute.Rules.Name
  1411  
  1412  For example, the RetryPolicy below applies to a RouteRule inside an HTTPRoute.
  1413  
  1414  ```yaml
  1415  apiVersion: gateway.networking.k8s.io/v1alpha2
  1416  kind: HTTPRoute
  1417  metadata:
  1418    name: http-app-1
  1419    labels:
  1420      app: foo
  1421  spec:
  1422    hostnames:
  1423    - "foo.com"
  1424    rules:
  1425    - name: bar
  1426      matches:
  1427      - path:
  1428          type: Prefix
  1429          value: /bar
  1430      forwardTo:
  1431      - serviceName: my-service1
  1432        port: 8080
  1433  ---
  1434  apiVersion: networking.acme.io/v1alpha2
  1435  kind: RetryPolicy
  1436  metadata:
  1437    name: foo
  1438  spec:
  1439    maxRetries: 5
  1440    targetRef:
  1441      name: foo
  1442      group: gateway.networking.k8s.io
  1443      kind: HTTPRoute
  1444      sectionName: bar
  1445  ```
  1446  
  1447  This would require adding a `name` field to those sub-resources that currently lack a name. For example,
  1448  a `name` field could be added to the `RouteRule` object:
  1449  ```go
  1450  type RouteRule struct {
  1451      // Name is the name of the Route rule. If more than one Route Rule is
  1452      // present, each Rule MUST specify a name. The names of Rules MUST be unique
  1453      // within a Route.
  1454      //
  1455      // Support: Core
  1456      //
  1457      // +kubebuilder:validation:MinLength=1
  1458      // +kubebuilder:validation:MaxLength=253
  1459      // +optional
  1460      Name string `json:"name,omitempty"`
  1461      // ...
  1462  }
  1463  ```
  1464  
  1465  If a `sectionName` is specified, but does not exist on the targeted object, the Policy must fail to attach,
  1466  and the policy implementation should record a `resolvedRefs` or similar Condition in the Policy's status.
  1467  
  1468  When multiple Policies of the same type target the same object, one with a `sectionName` specified, and one without,
  1469  the one with a `sectionName` is more specific, and so will have all its settings apply. The less-specific Policy will
  1470  not attach to the target.
  1471  
  1472  Note that the `sectionName` is currently intended to be used only for Direct Policy Attachment when references to
  1473  SectionName are actually needed. Inherited Policies are always applied to the entire object. 
  1474  The `PolicyTargetReferenceWithSectionName` API can be used to apply a direct Policy to a section of an object.
  1475  
  1476  ### Advantages
  1477  * Incredibly flexible approach that should work well for both ingress and mesh
  1478  * Conceptually similar to existing ServicePolicy proposal and BackendPolicy
  1479    pattern
  1480  * Easy to attach policy to resources we don’t control (Service, ServiceImport,
  1481    etc)
  1482  * Minimal API changes required
  1483  * Simplifies packaging an application for deployment as policy references do not
  1484    need to be part of the templating
  1485  
  1486  ### Disadvantages
  1487  * May be difficult to understand which policies apply to a request
  1488  
  1489  ## Examples
  1490  
  1491  This section provides some examples of various types of Policy objects, and how
  1492  merging, `defaults`, `overrides`, and other interactions work.
  1493  
  1494  ### Direct Policy Attachment
  1495  
  1496  The following Policy sets the minimum TLS version required on a Gateway Listener:
  1497  ```yaml
  1498  apiVersion: networking.example.io/v1alpha1
  1499  kind: TLSMinimumVersionPolicy
  1500  metadata:
  1501    name: minimum12
  1502    namespace: appns
  1503  spec:
  1504    minimumTLSVersion: 1.2
  1505    targetRef:
  1506      name: internet
  1507      group: gateway.networking.k8s.io
  1508      kind: Gateway
  1509  ```
  1510  
  1511  Note that because there is no version controlling the minimum TLS version in the
  1512  Gateway `spec`, this is an example of a non-field Policy.
  1513  
  1514  ### Inherited Policy Attachment
  1515  
  1516  It also could be useful to be able to _default_ the `minimumTLSVersion` setting
  1517  across multiple Gateways.
  1518  
  1519  This version of the above Policy allows this:
  1520  ```yaml
  1521  apiVersion: networking.example.io/v1alpha1
  1522  kind: TLSMinimumVersionPolicy
  1523  metadata:
  1524    name: minimum12
  1525    namespace: appns
  1526  spec:
  1527    defaults:
  1528      minimumTLSVersion: 1.2
  1529    targetRef:
  1530      name: appns
  1531      group: ""
  1532      kind: namespace
  1533  ```
  1534  
  1535  This Inherited Policy is using the implicit hierarchy that all resources belong
  1536  to a namespace, so attaching a Policy to a namespace means affecting all possible
  1537  resources in a namespace. Multiple hierarchies are possible, even within Gateway
  1538  API, for example Gateway -> Route, Gateway -> Route -> Backend, Gateway -> Route
  1539  -> Service. GAMMA Policies could conceivably use a hierarchy of Service -> Route
  1540  as well.
  1541  
  1542  Note that this will not be very discoverable for Gateway owners in the absence of
  1543  a solution to the Policy status problem. This is being worked on and this GEP will
  1544  be updated once we have a design.
  1545  
  1546  Conceivably, a security or admin team may want to _force_ Gateways to have at least
  1547  a minimum TLS version of `1.2` - that would be a job for `overrides`, like so:
  1548  
  1549  ```yaml
  1550  apiVersion: networking.example.io/v1alpha1
  1551  kind: TLSMinimumVersionPolicy
  1552  metadata:
  1553    name: minimum12
  1554    namespace: appns
  1555  spec:
  1556    overrides:
  1557      minimumTLSVersion: 1.2
  1558    targetRef:
  1559      name: appns
  1560      group: ""
  1561      kind: namespace
  1562  ```
  1563  
  1564  This will make it so that _all Gateways_ in the `default` namespace _must_ use
  1565  a minimum TLS version of `1.2`, and this _cannot_ be changed by Gateway owners.
  1566  Only the Policy owner can change this Policy.
  1567  
  1568  ### Handling non-scalar values
  1569  
  1570  In this example, we will assume that at some future point, HTTPRoute has grown
  1571  fields to configure retries, including a field called `retryOn` that reflects
  1572  the HTTP status codes that should be retried. The _value_ of this field is a
  1573  list of strings, being the HTTP codes that must be retried. The `retryOn` field
  1574  has no defaults in the field definitions (which is probably a bad design, but we
  1575  need to show this interaction somehow!)
  1576  
  1577  We also assume that a Inherited `RetryOnPolicy` exists that allows both
  1578  defaulting and overriding of the `retryOn` field.
  1579  
  1580  A full `RetryOnPolicy` to default the field to the codes `501`, `502`, and `503`
  1581  would look like this:
  1582  ```yaml
  1583  apiVersion: networking.example.io/v1alpha1
  1584  kind: RetryOnPolicy
  1585  metadata:
  1586    name: retryon5xx
  1587    namespace: appns
  1588  spec:
  1589    defaults:
  1590      retryOn:
  1591        - "501"
  1592        - "502"
  1593        - "503"
  1594    targetRef:
  1595      kind: Gateway
  1596      group: gateway.networking.k8s.io
  1597      name: we-love-retries
  1598  ```
  1599  
  1600  This means that, for HTTPRoutes that do _NOT_ explicitly set this field to something
  1601  else, (in other words, they contain an empty list), then the field will be set to
  1602  a list containing `501`, `502`, and `503`. (Notably, because of Go zero values, this
  1603  would also occur if the user explicitly set the value to the empty list.)
  1604  
  1605  However, if a HTTPRoute owner sets any value other than the empty list, then that
  1606  value will remain, and the Policy will have _no effect_. These values are _not_
  1607  merged.
  1608  
  1609  If the Policy used `overrides` instead:
  1610  ```yaml
  1611  apiVersion: networking.example.io/v1alpha1
  1612  kind: RetryOnPolicy
  1613  metadata:
  1614    name: retryon5xx
  1615    namespace: appns
  1616  spec:
  1617    overrides:
  1618      retryOn:
  1619        - "501"
  1620        - "502"
  1621        - "503"
  1622    targetRef:
  1623      kind: Gateway
  1624      group: gateway.networking.k8s.io
  1625      name: you-must-retry
  1626  ```
  1627  
  1628  Then no matter what the value is in the HTTPRoute, it will be set to `501`, `502`,
  1629  `503` by the Policy override.
  1630  
  1631  ### Interactions between defaults, overrides, and field values
  1632  
  1633  All HTTPRoutes that attach to the `YouMustRetry` Gateway will have any value
  1634  _overwritten_ by this policy. The empty list, or any number of values, will all
  1635  be replaced with `501`, `502`, and `503`.
  1636  
  1637  Now, let's also assume that we use the Namespace -> Gateway hierarchy on top of
  1638  the Gateway -> HTTPRoute hierarchy, and allow attaching a `RetryOnPolicy` to a
  1639  _namespace_. The expectation here is that this will affect all Gateways in a namespace
  1640  and all HTTPRoutes that attach to those Gateways. (Note that the HTTPRoutes
  1641  themselves may not necessarily be in the same namespace though.)
  1642  
  1643  If we apply the default policy from earlier to the namespace:
  1644  ```yaml
  1645  apiVersion: networking.example.io/v1alpha1
  1646  kind: RetryOnPolicy
  1647  metadata:
  1648    name: retryon5xx
  1649    namespace: appns
  1650  spec:
  1651    defaults:
  1652      retryOn:
  1653        - "501"
  1654        - "502"
  1655        - "503"
  1656    targetRef:
  1657      kind: Namespace
  1658      group: ""
  1659      name: appns
  1660  ```
  1661  
  1662  Then this will have the same effect as applying that Policy to every Gateway in
  1663  the `default` namespace - namely that every HTTPRoute that attaches to every
  1664  Gateway will have its `retryOn` field set to `501`, `502`, `503`, _if_ there is no
  1665  other setting in the HTTPRoute itself.
  1666  
  1667  With two layers in the hierarchy, we have a more complicated set of interactions
  1668  possible.
  1669  
  1670  Let's look at some tables for a particular HTTPRoute, assuming that it does _not_
  1671  configure the `retryOn` field, for various types of Policy at different levels.
  1672  
  1673  #### Overrides interacting with defaults for RetryOnPolicy, empty list in HTTPRoute
  1674  
  1675  ||None|Namespace override|Gateway override|HTTPRoute override|
  1676  |----|-----|-----|----|----|
  1677  |No default|Empty list|Namespace override| Gateway override Policy| HTTPRoute override|
  1678  |Namespace default| Namespace default| Namespace override | Gateway override | HTTPRoute override |
  1679  |Gateway default| Gateway default | Namespace override | Gateway override | HTTPRoute override |
  1680  |HTTPRoute default| HTTPRoute default | Namespace override | Gateway override | HTTPRoute override|
  1681  
  1682  #### Overrides interacting with other overrides for RetryOnPolicy, empty list in HTTPRoute
  1683  ||No override|Namespace override A|Gateway override A|HTTPRoute override A|
  1684  |----|-----|-----|----|----|
  1685  |No override|Empty list|Namespace override| Gateway override| HTTPRoute override|
  1686  |Namespace override B| Namespace override B| Namespace override<br />first created wins<br />otherwise first alphabetically | Namespace override B | Namespace override B|
  1687  |Gateway override B| Gateway override B | Namespace override A| Gateway override<br />first created wins<br />otherwise first alphabetically | Gateway override B|
  1688  |HTTPRoute override B| HTTPRoute override B | Namespace override A| Gateway override A| HTTPRoute override<br />first created wins<br />otherwise first alphabetically|
  1689  
  1690  #### Defaults interacting with other defaults for RetryOnPolicy, empty list in HTTPRoute
  1691  ||No default|Namespace default A|Gateway default A|HTTPRoute default A|
  1692  |----|-----|-----|----|----|
  1693  |No default|Empty list|Namespace default| Gateway default| HTTPRoute default A|
  1694  |Namespace default B| Namespace default B| Namespace default<br />first created wins<br />otherwise first alphabetically | Gateway default A | HTTPRoute default A|
  1695  |Gateway default B| Gateway default B| Gateway default B| Gateway default<br />first created wins<br />otherwise first alphabetically | HTTPRoute default A|
  1696  |HTTPRoute default B| HTTPRoute default B| HTTPRoute default B| HTTPRoute default B| HTTPRoute default<br />first created wins<br />otherwise first alphabetically|
  1697  
  1698  
  1699  Now, if the HTTPRoute _does_ specify a RetryPolicy,
  1700  it's a bit easier, because we can basically disregard all defaults:
  1701  
  1702  #### Overrides interacting with defaults for RetryOnPolicy, value in HTTPRoute
  1703  
  1704  ||None|Namespace override|Gateway override|HTTPRoute override|
  1705  |----|-----|-----|----|----|
  1706  |No default| Value in HTTPRoute|Namespace override| Gateway override | HTTPRoute override|
  1707  |Namespace default|  Value in HTTPRoute| Namespace override | Gateway override | HTTPRoute override |
  1708  |Gateway default|  Value in HTTPRoute | Namespace override | Gateway override | HTTPRoute override |
  1709  |HTTPRoute default| Value in HTTPRoute | Namespace override | Gateway override | HTTPRoute override|
  1710  
  1711  #### Overrides interacting with other overrides for RetryOnPolicy, value in HTTPRoute
  1712  ||No override|Namespace override A|Gateway override A|HTTPRoute override A|
  1713  |----|-----|-----|----|----|
  1714  |No override|Value in HTTPRoute|Namespace override A| Gateway override A| HTTPRoute override A|
  1715  |Namespace override B| Namespace override B| Namespace override<br />first created wins<br />otherwise first alphabetically | Namespace override B| Namespace override B|
  1716  |Gateway override B| Gateway override B| Namespace override A| Gateway override<br />first created wins<br />otherwise first alphabetically | Gateway override B|
  1717  |HTTPRoute override B| HTTPRoute override B | Namespace override A| Gateway override A| HTTPRoute override<br />first created wins<br />otherwise first alphabetically|
  1718  
  1719  #### Defaults interacting with other defaults for RetryOnPolicy, value in HTTPRoute
  1720  ||No default|Namespace default A|Gateway default A|HTTPRoute default A|
  1721  |----|-----|-----|----|----|
  1722  |No default|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|
  1723  |Namespace default B|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|
  1724  |Gateway default B|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|
  1725  |HTTPRoute default B|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|Value in HTTPRoute|
  1726  
  1727  
  1728  ## Removing BackendPolicy
  1729  BackendPolicy represented the initial attempt to cover policy attachment for
  1730  Gateway API. Although this proposal ended up with a similar structure to
  1731  BackendPolicy, it is not clear that we ever found sufficient value or use cases
  1732  for BackendPolicy. Given that this proposal provides more powerful ways to
  1733  attach policy, BackendPolicy was removed.
  1734  
  1735  ## Alternatives
  1736  
  1737  ### 1. ServiceBinding for attaching Policies and Routes for Mesh
  1738  A new ServiceBinding resource has been proposed for mesh use cases. This would
  1739  provide a way to attach policies, including Routes to a Service.
  1740  
  1741  Most notably, these provide a way to attach different policies to requests
  1742  coming from namespaces or specific Gateways. In the example below, a
  1743  ServiceBinding in the consumer namespace would be applied to the selected
  1744  Gateway and affect all requests from that Gateway to the foo Service. Beyond
  1745  policy attachment, this would also support attaching Routes as policies, in this
  1746  case the attached HTTPRoute would split requests between the foo-a and foo-b
  1747  Service instead of the foo Service.
  1748  
  1749  ![Simple Service Binding Example](images/713-servicebinding-simple.png)
  1750  
  1751  This approach can be used to attach a default set of policies to all requests
  1752  coming from a namespace. The example below shows a ServiceBinding defined in the
  1753  producer namespace that would apply to all requests from within the same
  1754  namespace or from other namespaces that did not have their own ServiceBindings
  1755  defined.
  1756  
  1757  ![Complex Service Binding Example](images/713-servicebinding-complex.png)
  1758  
  1759  #### Advantages
  1760  * Works well for mesh and any use cases where requests don’t always transit
  1761    through Gateways and Routes.
  1762  * Allows policies to apply to an entire namespace.
  1763  * Provides very clear attachment of polices, routes, and more to a specific
  1764    Service.
  1765  * Works well for ‘shrink-wrap application developers’ - the packaged app does
  1766    not need to know about hostnames or policies or have extensive templates.
  1767  * Works well for ‘dynamic’ / programmatic creation of workloads ( Pods,etc - see
  1768    CertManager)
  1769  * It is easy to understand what policy applies to a workload - by listing the
  1770    bindings in the namespace.
  1771  
  1772  #### Disadvantages
  1773  * Unclear how this would work with an ingress model. If Gateways, Routes, and
  1774    Backends are all in different namespaces, and each of those namespaces has
  1775    different ServiceBindings applying different sets of policies, it’s difficult
  1776    to understand which policy would be applied.
  1777  * Unclear if/how this would interact with existing the ingress focused policy
  1778    proposal described below. If both coexisted, would it be possible for a user
  1779    to understand which policies were being applied to their requests?
  1780  * Route status could get confusing when Routes were referenced as a policy by
  1781    ServiceBinding
  1782  * Introduces a new mesh specific resource.
  1783  
  1784  ### 2. Attaching Policies for Ingress
  1785  An earlier proposal for policy attachment in the Gateway API suggested adding
  1786  policy references to each Resource. This works very naturally for Ingress use
  1787  cases where all requests follow a path through Gateways, Routes, and Backends.
  1788  Adding policy attachment at each level enables different roles to define
  1789  defaults and allow overrides at different levels.
  1790  
  1791  ![Simple Ingress Attachment Example](images/713-ingress-attachment.png)
  1792  
  1793  #### Advantages
  1794  * Consistent policy attachment at each level
  1795  * Clear which policies apply to each component
  1796  * Naturally translates to hierarchical Ingress model with ability to delegate
  1797    policy decisions to different roles
  1798  
  1799  #### Disadvantages
  1800  * Policy overrides could become complicated
  1801  * At least initially, policy attachment on Service would have to rely on Service
  1802    annotations or references from policy to Service(s)
  1803  * No way to attach policy to other resources such as namespace or ServiceImport
  1804  * May be difficult to modify Routes and Services if other components/roles are
  1805    managing them (eg Knative)
  1806  
  1807  ### 3. Shared Policy Resource
  1808  This is really just a slight variation or extension of the main proposal in this
  1809  GEP. We would introduce a shared policy resource. This resource would follow the
  1810  guidelines described above, including the `targetRef` as defined as well as
  1811  `default` and `override` fields. Instead of carefully crafted CRD schemas for
  1812  each of the `default` and `override` fields, we would use more generic
  1813  `map[string]string` values. This would allow similar flexibility to annotations
  1814  while still enabling the default and override concepts that are key to this
  1815  proposal.
  1816  
  1817  Unfortunately this would be difficult to validate and would come with many of
  1818  the downsides of annotations. A validating webhook would be required for any
  1819  validation which could result in just as much or more work to maintain than
  1820  CRDs. At this point we believe that the best experience will be from
  1821  implementations providing their own policy CRDs that follow the patterns
  1822  described in this GEP. We may want to explore tooling or guidance to simplify
  1823  the creation of these policy CRDs to help simplify implementation and extension
  1824  of this API.
  1825  
  1826  ## References
  1827  
  1828  **Issues**
  1829  * [Extensible Service Policy and Configuration](https://github.com/kubernetes-sigs/gateway-api/issues/611)
  1830  
  1831  **Docs**
  1832  * [Policy Attachment and Binding](https://docs.google.com/document/d/13fyptUtO9NV_ZAgkoJlfukcBf2PVGhsKWG37yLkppJo/edit?resourcekey=0-Urhtj9gBkGBkSL1gHgbWKw)