diff --git a/.changeset/shiny-meals-chew.md b/.changeset/shiny-meals-chew.md new file mode 100644 index 0000000000..b1763a610f --- /dev/null +++ b/.changeset/shiny-meals-chew.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Fixed a bug where the proxy endpoint would error when used in combination with +a local kubectl proxy process and a token-based auth strategy on-cluster. diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 1bd79e9401..199ef404ad 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -548,15 +548,17 @@ describe('KubernetesProxy', () => { }); worker.use( - rest.get('http://localhost:8001/api/v1/namespaces', (_req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - kind: 'NamespaceList', - apiVersion: 'v1', - items: [], - }), - ); + rest.get('http://localhost:8001/api/v1/namespaces', (req, res, ctx) => { + return req.headers.get('Authorization') + ? res(ctx.status(401)) + : res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); }), ); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index b0f2e2759b..ec9bbb346e 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -93,14 +93,12 @@ export class KubernetesProxy { ): RequestHandler { const { permissionApi } = options; return async (req, res, next) => { - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); - const authorizeResponse = await permissionApi.authorize( [{ permission: kubernetesProxyPermission }], { - token, + token: getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ), }, ); const auth = authorizeResponse[0]; @@ -110,15 +108,19 @@ export class KubernetesProxy { return; } - req.headers.authorization = - req.header(HEADER_KUBERNETES_AUTH) ?? - `Bearer ${ - ( - await this.getClusterForRequest(req).then(cd => - this.authTranslator.decorateClusterDetailsWithAuth(cd, {}), - ) - ).serviceAccountToken - }`; + const authHeader = req.header(HEADER_KUBERNETES_AUTH); + if (authHeader) { + req.headers.authorization = authHeader; + } else { + const { serviceAccountToken } = await this.getClusterForRequest( + req, + ).then(cd => + this.authTranslator.decorateClusterDetailsWithAuth(cd, {}), + ); + if (serviceAccountToken) { + req.headers.authorization = `Bearer ${serviceAccountToken}`; + } + } const middleware = await this.getMiddleware(req); middleware(req, res, next);