Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: SecurityPolicy #1845

Closed
Alice-Lilith opened this issue Aug 29, 2023 · 12 comments
Closed

proposal: SecurityPolicy #1845

Alice-Lilith opened this issue Aug 29, 2023 · 12 comments
Assignees
Labels
area/api API-related issues area/policy kind/enhancement New feature or request kind/question Further information is requested no stalebot
Milestone

Comments

@Alice-Lilith
Copy link
Member

Alice-Lilith commented Aug 29, 2023

Relates to

#1492
#1821
#1846

What is this?

SecurityPolicy is a proposal for a new policy attachment resource that can be applied to Gateways and xRoute resources. It is meant to supplement a lot of config that Gateway API currently lacks while also providing a way to specify global defaults. It is similar to the proposal for an UpstreamTrafficPolicy with the notable difference that this tackles authentication based features and will thus support overrides and defaults.

How would I use this resource?

You can attach an SecurityPolicy to a Gateway to set global defaults that will apply to all children xRoute objects of that Gateway. You can also create an SecurityPolicy to attach to an xRoute object to configure things on a route-to-route basis and override global defaults if needed.

How will the overrides and defaults work?

If there is an SecurityPolicy X attached to a Gateway, and an SecurityPolicy Y attached to an HTTPRoute:

  • overrides from policy X will win in a conflict with overrides from policy Y.
    • This is to support the use-case of a cluster admin/operator setting some global overrides that are not allowed to be changed on a route level
  • defaults from policy Y will win in a conflict with defaults from policy X.
    • While cluster admins/operators might want to provide sane defaults, developers creating xRoute objects should still be able to override those defaults on a route-to-route basis (unless otherwise enforced by Gateway level overrides in the above scenario)

What if Gateway API implements a GEP that delivers the same functionality as some of the fields of this resource?

If Gateway improves any of their existing resources to deliver functionality that meets all of the needs of any of the below config,
then we will deprecate the field in this resource and use the Gateway API config instead. Ideally, a lot of this config can be
upstreamed into Gateway API in some form eventually since this resource only exists to solve areas where Gateway API is lacking for the needs of Envoy Gateway.

Can you use multiple SecurityPolicy resources at the same time?

You may use multiple AuthPolicies that target different resources, but you may not attach multiple AuthPolicies
to the same resource. For example, it is invalid to attach two AuthPolicies to the same Gateway. Merging config in this scenario would quickly become convoluted and confusing, and there are many edge-case scenarios that make supporting this undesirable.

How will this be developed/implemented?

This issue serves as a proposal for the high-level design and fields of the API, but that does not mean that every field included below will be immediately available. My plan for the implementation is to add and implement one high-level field at a time until the whole resource is implemented.

API outline

---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: example-policy
spec:
  # defaults and overrides will have the same configuration options.
  # If there is an SecurityPolicy A attached to a Gateway, and an SecurityPolicy B
  # attached to an xRoute, `overrides` from policy A win and `defaults` win for policy B
  # This allows for global defaults, changing those defaults on a route to route basis and enforcing
  # certain settings at a Gateway level.
  defaults:
  overrides:
    connections: # optional
      ipBlocking: # optional
        mode: Enum(allow-list/deny-list) # required
        ips: # required, minItems=1
        - type: Enum(peer/remote) # required
          value: string # required (example: 127.0.0.1 or 99.99.0.0/16)
    cors: # optional
      allowedOrigins: []string # required
      allowedMethods: []string # optional
      allowedHeaders: []string # optional
      allowCredentials: bool # optional
      exposedHeaders: []string # optional
      maxAge: string # optional
    authentication: # optional
      bypassAuth: bool # optional
      filters: # optional (allows setting default auth filter(s) or forcing them)
        # action controls how the filter is added. add will add the filter to the list of existing filters, 
        # replace will remove any existing AuthenticationFilters first.
        action: Enum (add/replace) # optional, default=add
        # priority determines the ordering of the filter if there are other filters on the resource.
        # The derfault priority of all filters is interpreted as 0 which will cause the filter to be 
        # appended to the list if other filters exist. negative values can prepend the filter(s) to any existing ones.
        priority: int # optional, default=0.
        targetRef: # required
          group: string
          kind: string # only Envoy Gateway's AuthenticationFilter will be supported for now
          name: string
  targetRef: # required
    group: string
    kind: string # must be a Gateway or xRoute object reference
    name: string

Open questions

  • This resource can be attached to a Gateway, but you can configure multiple listeners on a single Gateway. Realistically, this resource makes the most sense targeting listeners instead of forcing this to apply to the entire gateway. There should be a way to specify which listeners it applies to so that you can have different config for each listener.

Edits

  • Changed name from AuthPolicy to SecurityPolicy
@Alice-Lilith Alice-Lilith added kind/enhancement New feature or request kind/question Further information is requested area/api API-related issues no stalebot labels Aug 29, 2023
@Alice-Lilith Alice-Lilith self-assigned this Aug 29, 2023
@zhaohuabing
Copy link
Member

zhaohuabing commented Aug 30, 2023

@AliceProxy this looks overall good. I have a few questions:

  • EG will also need to support Authorization, for example, define which identify can access which Gateway/Listener/Route/Path. Do you plan to incorporate authorization in the AuthPolicy API, or propose a separate Authorization Policy?
  • I don't understand the filters part inside the authentication. Is it a Envoy filter reference, or a Gateway API resource, or an EG resource? Could you please elaborate on that?

Thanks.

@arkodg
Copy link
Contributor

arkodg commented Aug 30, 2023

wanted to highlight that the usage of overrides & defaults here and not in UpstreamTrafficPolicy feels weird and adds cognitive load on user to remember that some Inherited Policy Attachments APIs use overrides and defaults and some dont.
I would vote to just introduce overrides and defaults in the UpstreamTrafficPolicy and combine the 2 APIs

@Alice-Lilith
Copy link
Member Author

@zhaohuabing

EG will also need to support Authorization, for example, define which identify can access which Gateway/Listener/Route/Path. Do you plan to incorporate authorization in the AuthPolicy API, or propose a separate Authorization Policy?

I'm sure this policy isn't exhaustive, but yes, I would like to use this resource for any authorization/authentication features and config knobs we would like to support in the future adding any additional top-level fields or expanding existing fields.

I don't understand the filters part inside the authentication. Is it a Envoy filter reference, or a Gateway API resource, or an EG resource? Could you please elaborate on that?

The filters is currently meant to reference our AuthenticationFilter resource so that you could specify default filters that you want to run on all children xRoutes of a Gateway unless otherwise overridden, or even to configure Gateway level filters that must be enforced on all routes and cannot be removed by any other config.

@arkodg was mentioning that if this resource is implemented and is successful, we might even deprecate the AuthenticaitonFilter and only use this policy resource to in-line the same configuration so that we reduce the total number of CRDs we are adding on top of Gateway API.

@zhaohuabing
Copy link
Member

zhaohuabing commented Aug 31, 2023

I'm sure this policy isn't exhaustive, but yes, I would like to use this resource for any authorization/authentication features and config knobs we would like to support in the future adding any additional top-level fields or expanding existing fields.

I incline to have a separate authorization policy, as Authn and Authz repsent two different facets of security considerations. In most systems, such as Kubernetes and Istio, these two aspects are managed separately.

The filters is currently meant to reference our AuthenticationFilter resource so that you could specify default filters that you want to run on all children xRoutes of a Gateway unless otherwise overridden, or even to configure Gateway level filters that must be enforced on all routes and cannot be removed by any other config.

IMO, it's a bit weird to put all other auth-related configurations in the AuthPolicy and only leave JWT authentication to a standalone resource. We should do it one way or another. It looks to me that the preference of this proposal is to keep all auth-related configurations within the AuthPolicy, so I suggest merging the specs of AuthenticationFilter into it and phasing out the original AuthenticationFilter API.

@arkodg
Copy link
Contributor

arkodg commented Sep 1, 2023

thinking about this again, it makes sense to have a separate API for authn & authz instead of collapsing this into UpstreamTrafficPolicy to provide flexibility in authorship, allowing the platform admin persona to be split up into net admin and sec admin .

Reg naming, prefer SecurityPolicy over AuthPolicy

@Alice-Lilith Alice-Lilith changed the title proposal: AuthPolicy resource proposal: SecurityPolicy resource Sep 1, 2023
@zhaohuabing
Copy link
Member

zhaohuabing commented Sep 6, 2023

After discussion with @AliceProxy at this week's EG meeting, we agreed that the OIDCAuthenticationPolicy should be merged with this one to provide users a more unified auth AP. I would also like to suggest incorporating the JwtAuthenticationFilter in this Policy so that all authentication configurations can be found in just one CRD.

kind: SecurityPolicy
metadata:
  name: example-policy
spec:
  # defaults and overrides will have the same configuration options.
  # If there is an SecurityPolicy A attached to a Gateway, and an SecurityPolicy B
  # attached to an xRoute, `overrides` from policy A win and `defaults` win for policy B
  # This allows for global defaults, changing those defaults on a route to route basis and enforcing
  # certain settings at a Gateway level.
  defaults:
  overrides:
    connections: # optional
      ipBlocking: # optional
        mode: Enum(allow-list/deny-list) # required
        ips: # required, minItems=1
        - type: Enum(peer/remote) # required
          value: string # required (example: 127.0.0.1 or 99.99.0.0/16)
    cors: # optional
      allowedOrigins: []string # required
      allowedMethods: []string # optional
      allowedHeaders: []string # optional
      allowCredentials: bool # optional
      exposedHeaders: []string # optional
      maxAge: string # optional
    authentication: # optional
      bypassAuth: bool # optional
      oidc: # oidc authentication configuration
        provider: # the information of the OIDC identity provider
          issuer: string # The OIDC identity provider's issuer identifier. It’s also an URL which can be used by EG to discover the provider’s AuthorizationEndpoint and TokenEndpoint. An example: "https://accounts.google.com" 
          AuthorizationEndpoint: string # optional The URL to which users are redirected in the authentication flow. If not provided,TEG will obtain it from the provider's Well-Known Configuration Endpoint through the OIDC discovery mechanism.
          TokenEndpoint: The URL where your application exchanges the authorization code for an access token. It’s an optional field.  If not provided,EG will obtain it from the provider's Well-Known Configuration Endpoint through the OIDC discovery mechanism.
        clientID: string # This is an unique identifier assigned to your application by the OIDC identity provider. An Example "xxx.apps.googleusercontent.com"
        clientSecret: The Kubernetes secret which contains the OIDC client secret, which is a confidential token shared between your application and the OIDC identity provider to authenticate your application.
          name: "oidc-client-secret"
          namespace:  string # optional
        scopes: []string # optional, if not specified, "openid" is used.
      jwt: # jwt authentication configuration
        issuer: # optional Issuer is the principal that issued the JWT and takes the form of a URL or email address.If not provided, the JWT issuer is not checked.
        audiences: # optinal Audiences is a list of JWT audiences allowed access. If not provided, JWT audiences are not checked.
        remoteJWKS: # RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote HTTP/HTTPS endpoint.
          uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/jwks.json
        claimToHeaders: # optinal A list of JWT claims that must be extracted into HTTP request headers  
  targetRef: # required
    group: string
    kind: string # must be a Gateway or xRoute object reference
    name: string

A few other things I'd like to bring up:

  • Regarding the override/default: I'm not sure that we should support override/default though. The final policy would be a combination of the policy attached to the gateway and the policy attached to the route. It would become very hard to figure out which configuration form which policy and why it is applied when some thing goes wrong. We probably need different traffic policy, such as timeout, connection pool size, retries, for different routes, but we normally don't need disctinct security configurations at route level. I think we should keep it simple and only support one policy per gateway (very likely another level at listener when this API Gateway proposal is accepted) and one policy per route. When there're multiple policies at different levels, all settings from policy with the most specific wins.
  • Should Authn and Authz be in one CRD or two? I'm leaning slightly towards creating two CRDs, as Authn and Authz repsent two distinct facets of security considerations. In most systems, such as Kubernetes and Istio, these two aspects are managed separately. However, I don't have a very strong preference for this option. My main objective is to provide rational for choosing either one CRD or two.

@Xunzhuo Xunzhuo changed the title proposal: SecurityPolicy resource proposal: SecurityPolicy Sep 15, 2023
@arkodg
Copy link
Contributor

arkodg commented Sep 18, 2023

was chatting with @ZackButcher about this earlier today and summarizing some of our discussions

  • here are the relevant features that could get clubbed into the same SecurityPolicy API
    • jwt
    • oidc
    • ext authz
    • basic auth
    • api key
    • cors
  • some of above features likes jwt & ext authz can be used for authn and authz which makes it hard to divide it into explicit authn and authz APIs or even top level fields.
  • implicit overrides similar to BackendTrafficPolicy makes sense here i.e. a Gateway / Platform admin can set a SecurityPolicy with a cors value set and attach it to the Gateway. If the platform admin has provided access to the app owner to also create a SecurityPolicy in their app namespace, its okay for the app owner to create another SecurityPolicy with a new cors value that implicitly overrides the more generic value.
  • we agreed that ipBlocking doesnt fit in this API because its something that will never be relevant for App Owners, instead the ClientTrafficPolicy might be a good home for it.

@zhaohuabing
Copy link
Member

was chatting with @ZackButcher about this earlier today and summarizing some of our discussions

  • here are the relevant features that could get clubbed into the same SecurityPolicy API

    • jwt
    • oidc
    • ext authz
    • basic auth
    • api key
    • cors
  • some of above features likes jwt & ext authz can be used for authn and authz which makes it hard to divide it into explicit authn and authz APIs or even top level fields.

  • implicit overrides similar to BackendTrafficPolicy makes sense here i.e. a Gateway / Platform admin can set a SecurityPolicy with a cors value set and attach it to the Gateway. If the platform admin has provided access to the app owner to also create a SecurityPolicy in their app namespace, its okay for the app owner to create another SecurityPolicy with a new cors value that implicitly overrides the more generic value.

  • we agreed that ipBlocking doesnt fit in this API because its something that will never be relevant for App Owners, instead the ClientTrafficPolicy might be a good home for it.

  • Some of the above combinations work, while others may not make sense. For example: CORS can work with others, but specifying both OIDC and ext authz isn't meaningful.

  • Should RBAC aslo be included in the SecurityPolicy?

@arkodg
Copy link
Contributor

arkodg commented Sep 19, 2023

@zhaohuabing specifying OIDC and ext authz may make sense, if OIDC is being used for authn and ext authz is being used for authz (using OPA).

  • from the Envoy RBAC filter, which feature fields do you think we should be exposing that we haven't planned to do so yet ?

@zhaohuabing
Copy link
Member

@zhaohuabing specifying OIDC and ext authz may make sense, if OIDC is being used for authn and ext authz is being used for authz (using OPA).

  • from the Envoy RBAC filter, which feature fields do you think we should be exposing that we haven't planned to do so yet ?

Maybe I missed something, but I didn't see any authz regarding RBAC in the SecurityPolicy.

@arkodg
Copy link
Contributor

arkodg commented Sep 19, 2023

the openapi spec's security section https://spec.openapis.org/oas/v3.1.0#security-scheme-object is another good datapoint which has outlined all features mentioned in #1845 (comment)

@kflynn
Copy link
Contributor

kflynn commented Sep 21, 2023

I would concur with removing the defaults/overrides separation and simply relying on K8s RBAC for that sort of thing, and with moving IP blocking into ClientTrafficPolicy.

I think it probably makes sense to leave CORS in the SecurityPolicy: Ana is likely to care a lot about things like how to do load balancing for her specific workloads, but I'm not sure she's ever in a great position to be messing with CORS, IP blocking, etc.

@arkodg arkodg added this to the 0.6.0-rc1 milestone Sep 21, 2023
@arkodg arkodg self-assigned this Oct 11, 2023
arkodg added a commit to arkodg/gateway that referenced this issue Oct 11, 2023
Relates to envoyproxy#1845

Signed-off-by: Arko Dasgupta <[email protected]>
arkodg added a commit that referenced this issue Oct 25, 2023
* design: SecurityPolicy

Relates to #1845

Signed-off-by: Arko Dasgupta <[email protected]>

* update policy hierrachy

Signed-off-by: Arko Dasgupta <[email protected]>

---------

Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: zirain <[email protected]>
Co-authored-by: zirain <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/api API-related issues area/policy kind/enhancement New feature or request kind/question Further information is requested no stalebot
Projects
None yet
Development

No branches or pull requests

5 participants