containersibm-cloudkubernetes-ingressibm-appid

IBM Cloud: How to enable App ID for app on Kubernetes cluster with K8s Ingress and ALB OAuth Proxy?


I am trying to configure App ID-based authentication for an app deployed to IBM Cloud Kubernetes Service (IKS) running in a VPC. In the past it worked well with IBM's own Ingress. However, that has been deprecated. Now, I am following the guide here which is using the community Ingress and talks about adding IBM App Id.

I seem to have configured everything, but the host / site cannot be reached. Here is how the Ingress resource looks like:

"apiVersion": "networking.k8s.io/v1beta1",
    "kind": "Ingress",
    "metadata": {
        "annotations": {
            "kubernetes.io/ingress.class": "public-iks-k8s-nginx",
            "nginx.ingress.kubernetes.io/auth-signin": "https://$host/oauth2-myappid/start?rd=$escaped_request_uri",
            "nginx.ingress.kubernetes.io/auth-url": "https://$host/oauth2-myappid",
            "nginx.ingress.kubernetes.io/configuration-snippet": "auth_request_set $access_token $upstream_http_x_auth_request_access_token;
        access_by_lua_block {
         if ngx.var.access_token ~= \"\" then
           ngx.req.set_header(\"Authorization\", \"Bearer \" .. ngx.var.access_token)
         end
        }
        "
        },
        "name": "ingress-for-mytest",
        "namespace": "sfs"
    },
    "spec": {
        "rules": [
            {
                "host": "myhost.henrik-cluster-cd5d3f574d7d8057a176af82152f5-0000.eu-de.containers.appdomain.cloud",
                "http": {
                    "paths": [
                        {
                            "backend": {
                                "serviceName": "my-service",
                                "servicePort": 8081
                            },
                            "path": "/"
                        }
                    ]
                }
            }
        ],
        "tls": [
            {
                "hosts": [
                    "myhost.henrik-cluster-cd5d3f574d7d8057a176af82152f5-0000.eu-de.containers.appdomain.cloud"
                ],
                "secretName": "henrik-cluster-cd5d3f574d7d8057a176af82152f5-0000"
            }
        ]
    }
}

Solution

  • I got it to work with the following definition:

    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-for-mytest
      annotations:
        kubernetes.io/ingress.class: "public-iks-k8s-nginx"
        nginx.ingress.kubernetes.io/auth-url: https://$host/oauth2-myappid/auth
        nginx.ingress.kubernetes.io/auth-signin: https://$host/oauth2-myappid/start?rd=$escaped_request_uri
        nginx.ingress.kubernetes.io/configuration-snippet: |
          auth_request_set $access_token $upstream_http_x_auth_request_access_token;
          auth_request_set $id_token $upstream_http_authorization;
          access_by_lua_block {
            if ngx.var.id_token ~= "" and ngx.var.access_token ~= "" then
              ngx.req.set_header("Authorization", "Bearer " .. ngx.var.access_token .. " " .. ngx.var.id_token:match("%s*Bearer%s*(.*)"))
            end
          }
    spec:
      tls:
      - hosts:
        - myhost
        secretName: ingress-secret-for-mytest
      rules:
      - host: myhost
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-service
                port: 
                  number: 8081
    

    It is important to note that the OAuth2 proxy (see the steps regarding the proxy add-on and App ID integration) will only deploy successfully to a non-default Kubernetes namespace if the (cluster) Ingress secret is copied into that namespace.

    You can find the Ingress secret using the following command and watching for the secret in the default namespace:

    ibmcloud ks ingress secret ls -c your-cluster-name
    

    Thereafter, (re)create that secret in the non-default namespace, copying the CRN and name of that secret:

    ibmcloud ks ingress secret create -c your-cluster-name -n your-namespace
        --cert-crn the-crn-shown-in-the-output-above --name the-secret-name-shown-above