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

[Feature Request]: JWT authentication for api gateway #2954

Open
1 of 3 tasks
matteo-s opened this issue Jun 15, 2023 · 0 comments
Open
1 of 3 tasks

[Feature Request]: JWT authentication for api gateway #2954

matteo-s opened this issue Jun 15, 2023 · 0 comments

Comments

@matteo-s
Copy link

Feature Type

  • Adding new functionality to Nuclio

  • Changing existing functionality in Nuclio

  • Removing existing functionality in Nuclio

Problem Description

Api gateway currently can expose nuclio functions by writing an Ingress with optional authentication.
Authentication modes (from code) are:

const (
	AuthenticationModeNone      AuthenticationMode = "none"
	AuthenticationModeBasicAuth AuthenticationMode = "basicAuth"
	AuthenticationModeAccessKey AuthenticationMode = "accessKey"
	AuthenticationModeOauth2    AuthenticationMode = "oauth2"
)

Given that OAuth2 and JWT access tokens are widely used and adopted, I'd like to use tokens to protect nuclio functions which expose some kind of API. While OAuth2 is currently supported, this is done via a proxy, which will trigger an interactive authentication flow.
This is incompatible with APIs consumed by clients, which can not interact with users to perform the auth flow. OAuth2 access tokens, mostly in the JWT format, are widely used to protect API ("resource servers").

Feature Description

The support for JWT Authentication can easily be added by integrating an authentication helper for the nginx ingress controller, which will validate the JWT and resolve the authorization via the same scheme already adopted for oauth2.

On the controller side, config can be generated by adding annotations to the Ingress creation, pointing the auth-url to the pre-configured authentication helper.

An additional AuthenticationMode could be added to the CR, similar to the following, which will specify the audience required for the given resource.

type APIGatewayAuthenticationSpec struct {
	BasicAuth *BasicAuth       `json:"basicAuth,omitempty"`
	DexAuth   *ingress.DexAuth `json:"dexAuth,omitempty"`
	JwtAuth   *JwtAuth         `json:"jwtAuth,omitempty"`
}

type JwtAuth struct {
	Audience string `json:"audience"`
}

Also for ingress types

type Authentication struct {
	BasicAuth *BasicAuth `json:"basicAuth,omitempty"`
	DexAuth   *DexAuth   `json:"dexAuth,omitempty"`
	JwtAuth   *JwtAuth   `json:"jwtAuth,omitempty"`
}

type JwtAuth struct {
	Audience string `json:"audience"`
}

const (
	AuthenticationModeNone      AuthenticationMode = "none"
	AuthenticationModeBasicAuth AuthenticationMode = "basicAuth"
	AuthenticationModeAccessKey AuthenticationMode = "accessKey"
	AuthenticationModeOauth2    AuthenticationMode = "oauth2"
	AuthenticationModeJwt       AuthenticationMode = "jwt"
)

And then eventually wire things while building the ingress definition.

	// formatted for ingress-nginx-validate-jwt
	authURL := fmt.Sprintf("%s?inject-claim=sub,scope&aud=%s", m.platformConfiguration.IngressConfig.JwtAuthURL, audience)

	return map[string]string{
		"nginx.ingress.kubernetes.io/auth-url":              authURL,
		"nginx.ingress.kubernetes.io/configuration-snippet": `auth_request_set $sub $upstream_http_sub;auth_request_set $scope $upstream_http_scope;proxy_set_header X-JWT-User $sub;proxy_set_header X-JWT-Scope $scope;`,
	}, nil

Alternative Solutions

An alternative solution, when the scenario requires the usage of JWT tokens, is to drop the apigateway and either:

  • manually write the Ingress definition with all the annotations
  • migrate to another (generic) apigw solution.

Additional Context

Given that this feature is relevant for our use cases, I've already implemented the feature in our fork.
If you guys think this is valuable I can open a pull request to contribute it back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant