From f771a0c32c95625d191b04432673e9080c8dbea1 Mon Sep 17 00:00:00 2001 From: Nik Ogura Date: Wed, 24 Sep 2025 14:31:44 -0700 Subject: [PATCH] add support for RFC 8693 Section 2.1 'audience parameters' Signed-off-by: Nik Ogura --- server/handlers.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/server/handlers.go b/server/handlers.go index f8d0ed64..371bf519 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -1366,6 +1366,11 @@ func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, cli subjectTokenType := q.Get("subject_token_type") // REQUIRED connID := q.Get("connector_id") // REQUIRED, not in RFC + // RFC 8693 Section 2.1: "audience" parameter (OPTIONAL) + // "The logical name of the target service where the client intends to use the requested token" + // When present, should be used as the audience of the issued token + audience := q.Get("audience") + switch subjectTokenType { case tokenTypeID, tokenTypeAccess: // ok, continue default: @@ -1409,12 +1414,22 @@ func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, cli IssuedTokenType: requestedTokenType, TokenType: "bearer", } + // RFC 8693 Section 2.1: Use audience parameter if provided, otherwise default to client.ID + // "The service can then use the aud claim to verify that it is an intended audience for the token" + tokenAudience := client.ID + if audience != "" { + s.logger.InfoContext(r.Context(), "Using custom audience from request", "audience", audience, "clientID", client.ID) + tokenAudience = audience + } else { + s.logger.InfoContext(r.Context(), "No audience parameter provided, using client ID", "clientID", client.ID) + } + var expiry time.Time switch requestedTokenType { case tokenTypeID: - resp.AccessToken, expiry, err = s.newIDToken(r.Context(), client.ID, claims, scopes, "", "", "", connID) + resp.AccessToken, expiry, err = s.newIDToken(r.Context(), tokenAudience, claims, scopes, "", "", "", connID) case tokenTypeAccess: - resp.AccessToken, expiry, err = s.newAccessToken(r.Context(), client.ID, claims, scopes, "", connID) + resp.AccessToken, expiry, err = s.newAccessToken(r.Context(), tokenAudience, claims, scopes, "", connID) default: s.tokenErrHelper(w, errRequestNotSupported, "Invalid requested_token_type.", http.StatusBadRequest) return