oidc icon indicating copy to clipboard operation
oidc copied to clipboard

Support of RFC-8707

Open zekth opened this issue 3 months ago • 1 comments

Preflight Checklist

  • [x] I could not find a solution in the existing issues, docs, nor discussions
  • [x] I have joined the ZITADEL chat

Describe your problem

Current implementation of oidc.AuthRequest doesn't support resource as specified in RFC-8707. This is useful for MCP servers implementations.

Describe your ideal solution

Add support in oidc.AuthRequest. Ideally the implementation would also add the resource parsing a middleware to validate inputs for resource values as the RFC states:

resource

Indicates the target service or resource to which access is being requested. Its value MUST be an absolute URI, as specified by Section 4.3 of [RFC3986]. The URI MUST NOT include a fragment component. It SHOULD NOT include a query component, but it is recognized that there are cases that make a query component a useful and necessary part of the resource parameter, such as when one or more query parameters are used to scope requests to an application. The resource parameter URI value is an identifier representing the identity of the resource, which MAY be a locator that corresponds to a network-addressable location where the target resource is hosted. Multiple resource parameters MAY be used to indicate that the requested token is intended to be used at multiple resources.

Something like this would do the job:

// AuthRequest according to:
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
type AuthRequest struct {
	Scopes       SpaceDelimitedArray `json:"scope" schema:"scope"`
	ResponseType ResponseType        `json:"response_type" schema:"response_type"`
	ClientID     string              `json:"client_id" schema:"client_id"`
	RedirectURI  string              `json:"redirect_uri" schema:"redirect_uri"`

	State string `json:"state" schema:"state"`
	Nonce string `json:"nonce" schema:"nonce"`

	ResponseMode ResponseMode        `json:"response_mode" schema:"response_mode"`
	Display      Display             `json:"display" schema:"display"`
	Prompt       SpaceDelimitedArray `json:"prompt" schema:"prompt"`
	MaxAge       *uint               `json:"max_age" schema:"max_age"`
	UILocales    Locales             `json:"ui_locales" schema:"ui_locales"`
	IDTokenHint  string              `json:"id_token_hint" schema:"id_token_hint"`
	LoginHint    string              `json:"login_hint" schema:"login_hint"`
	ACRValues    SpaceDelimitedArray `json:"acr_values" schema:"acr_values"`
+	Resource    []string             `json:"resource" schema:"resource"`

	CodeChallenge       string              `json:"code_challenge" schema:"code_challenge"`
	CodeChallengeMethod CodeChallengeMethod `json:"code_challenge_method" schema:"code_challenge_method"`

	// RequestParam enables OIDC requests to be passed in a single, self-contained parameter (as JWT, called Request Object)
	RequestParam string `schema:"request"`
}
values := r.URL.Query()
for i := range values["resource"] {
	u, err := url.ParseRequestURI(values["resource"][i])
	if err != nil {
		// todo: render oauth error with `invalid_target`
	}

	if len(u.Fragment) > 0 {
		// todo: render oauth error with `invalid_target`
	}
}

Version

No response

Environment

Self-hosted

Additional Context

Happy to make a PR if the implementation works for the team

zekth avatar Sep 01 '25 20:09 zekth

Sounds like a good addition. However, for the moment we are not accepting new features to the library because we temporarily lack the resources to implement or review: https://github.com/zitadel/oidc/discussions/785

muhlemmer avatar Sep 08 '25 08:09 muhlemmer