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

Add support for HTTP based external auth server #6509

Closed
rajivmordani opened this issue Jun 12, 2024 · 7 comments
Closed

Add support for HTTP based external auth server #6509

rajivmordani opened this issue Jun 12, 2024 · 7 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/needs-triage Indicates that an issue needs to be triaged by a project contributor. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.

Comments

@rajivmordani
Copy link

Currently Contour supports only the gRPC mechanism for external auth. However a lot of open source IAM solutions support HTTP based external auth for envoy which is useful to integrate with. Need to add support for HTTP based external auth in contour in order to integrate with IAM providers like authelia, authentik etc.

@rajivmordani rajivmordani added kind/feature Categorizes issue or PR as related to a new feature. lifecycle/needs-triage Indicates that an issue needs to be triaged by a project contributor. labels Jun 12, 2024
Copy link

Hey @rajivmordani! Thanks for opening your first issue. We appreciate your contribution and welcome you to our community! We are glad to have you here and to have your input on Contour. You can also join us on our mailing list and in our channel in the Kubernetes Slack Workspace

@sunjayBhatia sunjayBhatia added this to the 1.30.0 milestone Jun 12, 2024
@skriss
Copy link
Member

skriss commented Jun 12, 2024

A few initial references in the existing codebase:

  • ExtensionService CRD definition: https://github.com/projectcontour/contour/blob/main/apis/projectcontour/v1alpha1/extensionservice.go
  • conversion of ExtensionService CRD to "DAG" (internal model) representation:
    extension := ExtensionCluster{
    Name: ExtensionClusterName(k8s.NamespacedNameOf(ext)),
    Upstream: ServiceCluster{
    ClusterName: path.Join(
    "extension",
    xds.ClusterLoadAssignmentName(k8s.NamespacedNameOf(ext), ""),
    ),
    },
    Protocol: "h2",
    UpstreamValidation: nil,
    RouteTimeoutPolicy: rtp,
    ClusterTimeoutPolicy: ctp,
    SNI: "",
    ClientCertificate: clientCertSecret,
    UpstreamTLS: p.UpstreamTLS,
    }
    lbPolicy := loadBalancerPolicy(ext.Spec.LoadBalancerPolicy)
    switch lbPolicy {
    case LoadBalancerPolicyCookie, LoadBalancerPolicyRequestHash:
    validCondition.AddWarningf(contour_v1.ConditionTypeSpecError, "IgnoredField",
    "ignoring field %q; %s load balancer policy is not supported for ExtensionClusters",
    ".Spec.LoadBalancerPolicy", lbPolicy)
    // Reset load balancer policy to ensure the default.
    lbPolicy = ""
    }
    extension.LoadBalancerPolicy = lbPolicy
    // Timeouts are specified above the cluster (e.g.
    // in the ext_authz filter). The ext_authz filter
    // doesn't have an idle timeout (only a request
    // timeout), so validate that it is not provided here.
    if timeouts := ext.Spec.TimeoutPolicy; timeouts != nil && timeouts.Idle != "" {
    validCondition.AddWarningf("SpecError", "IgnoredField",
    "ignoring field %q; idle timeouts are not supported for ExtensionClusters",
    ".Spec.TimeoutPolicy.Idle")
    }
    // API server validation ensures that the protocol is "h2" or "h2c".
    if ext.Spec.Protocol != nil {
    extension.Protocol = stringOrDefault(*ext.Spec.Protocol, extension.Protocol)
    }
  • Generation of Envoy ExtAuthz filter config:
    // FilterExternalAuthz returns an `ext_authz` filter configured with the
    // requested parameters.
    func FilterExternalAuthz(externalAuthorization *dag.ExternalAuthorization) *envoy_filter_network_http_connection_manager_v3.HttpFilter {
    authConfig := envoy_filter_http_ext_authz_v3.ExtAuthz{
    Services: &envoy_filter_http_ext_authz_v3.ExtAuthz_GrpcService{
    GrpcService: GrpcService(externalAuthorization.AuthorizationService.Name, externalAuthorization.AuthorizationService.SNI, externalAuthorization.AuthorizationResponseTimeout),
    },
    // Pretty sure we always want this. Why have an
    // external auth service if it is not going to affect
    // routing decisions?
    ClearRouteCache: true,
    FailureModeAllow: externalAuthorization.AuthorizationFailOpen,
    StatusOnError: &envoy_type_v3.HttpStatus{
    Code: envoy_type_v3.StatusCode_Forbidden,
    },
    MetadataContextNamespaces: []string{},
    IncludePeerCertificate: true,
    // TODO(jpeach): When we move to the Envoy v4 API, propagate the
    // `transport_api_version` from ExtensionServiceSpec ProtocolVersion.
    TransportApiVersion: envoy_config_core_v3.ApiVersion_V3,
    }
    if externalAuthorization.AuthorizationServerWithRequestBody != nil {
    authConfig.WithRequestBody = &envoy_filter_http_ext_authz_v3.BufferSettings{
    MaxRequestBytes: externalAuthorization.AuthorizationServerWithRequestBody.MaxRequestBytes,
    AllowPartialMessage: externalAuthorization.AuthorizationServerWithRequestBody.AllowPartialMessage,
    PackAsBytes: externalAuthorization.AuthorizationServerWithRequestBody.PackAsBytes,
    }
    }
    return &envoy_filter_network_http_connection_manager_v3.HttpFilter{
    Name: ExtAuthzFilterName,
    ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{
    TypedConfig: protobuf.MustMarshalAny(&authConfig),
    },
    }
    }

@skriss
Copy link
Member

skriss commented Jun 12, 2024

We'll also need to look through https://www.envoyproxy.io/docs/envoy/v1.30.2/api-v3/extensions/filters/http/ext_authz/v3/ext_authz.proto#envoy-v3-api-msg-extensions-filters-http-ext-authz-v3-httpservice in detail and decide which fields need to be exposed via Contour config.

@sunjayBhatia
Copy link
Member

Thanks for the issue!

Broad strokes first impression this should be a relatively simple addition, some thoughts on TODOs below:

How users let Contour know their External Auth Service is HTTP and not gRPC

Resulting Envoy Config needs a URI/hostname

Integration testing

E2E Testing

@rajivmordani
Copy link
Author

Thanks Steve and Sunjay for the pointers. Let me look and circle back.

@skriss skriss removed this from the 1.30.0 milestone Jul 24, 2024
Copy link

The Contour project currently lacks enough contributors to adequately respond to all Issues.

This bot triages Issues according to the following rules:

  • After 60d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, the Issue is closed

You can:

  • Mark this Issue as fresh by commenting
  • Close this Issue
  • Offer to help out with triage

Please send feedback to the #contour channel in the Kubernetes Slack

@github-actions github-actions bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Sep 23, 2024
Copy link

The Contour project currently lacks enough contributors to adequately respond to all Issues.

This bot triages Issues according to the following rules:

  • After 60d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, the Issue is closed

You can:

  • Mark this Issue as fresh by commenting
  • Close this Issue
  • Offer to help out with triage

Please send feedback to the #contour channel in the Kubernetes Slack

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 24, 2024
@github-project-automation github-project-automation bot moved this to Done in Contour Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/needs-triage Indicates that an issue needs to be triaged by a project contributor. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.
Projects
Status: Done
Development

No branches or pull requests

3 participants