solo-io / gloo

The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy
https://docs.solo.io/
Apache License 2.0
4.08k stars 438 forks source link

Support headerSecretRef in stagedTransformations #7774

Open havard-fjaer opened 1 year ago

havard-fjaer commented 1 year ago

Version

1.12.x

Is your feature request related to a problem? Please describe.

We are using Gloo Edge to encapsulate a long-term migration from our legacy basic auth, to a more modern JWT based authentication. In order to support this encapsulation, we need to map the azp claim in the JWT token to a corresponding "Authentication: Basic " header. The Basic auth header value is stored in a Secret; it can not be part of the yaml code we commit to our repositories. (Note: The code below is handwritten based on the documentation based on the API reference, there may be slight syntax and naming errors, but the concept should still be valid.) In our current implementation we are able to set the Authorization header using a secret like this:

apiVersion: v1
kind: Secret
metadata:
    name: my-client-basic-auth
type: gloo.solo.io/header
data:
    Authorization: <base64>
And apply it as a header to a route like this:
spec:
    routes:
          ...
          options:
            headerManipulation:
                requestHeadersToAdd:
                    - headerSecretRef:
                        name: my-client-basic-auth
                        namespace: our-ns

However, this creates a one-to-one mapping between the client and the API. The username in the basic authentication header is the value used to identify the client in backend, not any values from the access token the client is actually sending to us. (This is the legacy part we are trying to encapsulate) To get around this we have looked at mapping claims to headers, and use that header in the matcher provided in stagedTransformations. Fist, map the claim to header:

spec:
    virtualHost:
        options:
            jwt:
                providers:
                    kube:
                        claimsToHeaders:
                            - claim: azp
                              header: X-Amp-Azp
                              append: false

And later, in the same virtual service, use staged transformations to match on the X-Amp-Azp header:

spec:
    virtualHost:
        options:
            stagedTransformations:
                inheritTransformation: true
                regular:
                    requestTransforms:
                        matcher:
                            - headers: 
                              - name: X-Amp-Azp
                                value: my-service-account-client-id
                        requestTransformation:
                          transformationTemplate:
                              headersToAppend:
                                  - key: Authorization
                                    value: Basic <base64>

Our problem arises at headersToAppend, as we need to reference a secret, not use plain text.

Describe the solution you'd like

Allow for headerSecretRef in stagedTransformations...transformationTemplate, same as is supported in headerManipulation. I.e:

spec:
    virtualHost:
        options:
            stagedTransformations:
                inheritTransformation: true
                regular:
                    requestTransforms:
                        matcher:
                            - headers: 
                              - name: X-Amp-Azp
                                value: my-service-account-client-id
                        requestTransformation:
                          transformationTemplate:
                              headersToAppend:
                              - headerSecretRef:
                                  name: my-client-basic-auth
                                  namespace: our-ns

Describe alternatives you've considered

At the moment, route tables for API's that need more than one client, are duplicated and given separate URL's, and let the URL identify the client instead of the claim on the token. Not at all an ideal solution, but at the moment few enough that it is manageable.

It has been suggested that we use OPA to get around this, but we really would like to avoid fragmenting our logic and configuration, and use the product as a whole to cover our needs.

Additional Context

No response

github-actions[bot] commented 4 months ago

This issue has been marked as stale because of no activity in the last 180 days. It will be closed in the next 180 days unless it is tagged "no stalebot" or other activity occurs.