Adding Sign In to Multicloud Applications Without Code Changes

By: Aaron Liberatore and Anton Aleksandrov

Adding sign in to multicloud applications without code changes

Development teams shifting workloads to the cloud are increasingly adopting multicloud deployment models. As of 2019, more than 85% of enterprises use clouds from multiple providers (multicloud) and/or a combination of on- and off-premise (hybrid cloud) solutions [1]. These heterogenous deployment models help teams preserve existing infrastructure investments and avoid vendor lock-in, but they come with a number of new challenges, including identity and access control management for their custom enterprise applications.

In this post, we will explore a proof of concept illustrating how we can leverage identity federation using a single IBM Cloud App ID instance along with common operational patterns, such as Kubernetes and Istio, to create a centralized identity and access management model that can transparently secure applications/services across cloud environments.

An overview of multicloud architectures

multicloud computing environment combines multiple cloud and/or private computing environments into a single network architecture.

An overview of multicloud architectures

By distributing workloads across multiple cloud environments, development teams can often find improved resiliency, flexibility, and greater cost-efficiency.

At the core of any good multicloud architecture is a DevOps-driven, portable software stack. To achieve this flexibility, teams are shifting to container-based applications using a CaaS orchestration layer, such as Kubernetes. These containerized orchestration platforms offer DevOps teams the ability to seamlessly transfer and recreate workloads across cloud environments. The videos “Kubernetes Explained” and “Kubernetes vs. Docker: It’s Not an Either/Or Question” provide a deeper dive into container orchestration with Kubernetes.

Using a containerized approach fundamentally decouples software applications from any individual cloud provider’s proprietary stacks, offering the potential to reduce the risk of service disruptions, minimize pricing risks, and leverage the benefits of each cloud environment independently. Check out the video “Containerization Explained” for more info.

Utilizing multicloud strategies, however, comes with its own set of special challenges. In particular, they immediately introduce operational and development complexity. Not only must teams learn to provision and manage systems in each environment, but they must also deal with additional concerns around control, tracking, and synchronization.

One area that requires careful consideration is identity and access management. Ensuring an application in a single environment is properly secured can be difficult enough, and in a multicloud environment, this can quickly become a development and operational burden that can reduce development speed and limit the flexibility gained from a multicloud/containerized approach. In the worst case, poorly managed access and identity management can expose your applications/services to security vulnerabilities.

Authentication in multicloud environments

Though multicloud architectures can provide considerable benefits, by their nature, they can create additional security challenges that would never exist within a single cloud model.

Challenge 1: Identity silos

The key challenge in multicloud/hybrid cloud ecosystems is the management of identity silos that are specific to each platform. Multicloud systems can evolve strategically or organically over time, yet in both cases, applications and services can become coupled to a platform’s specific set of identity providers (IdP) and data stores. Further, the identifying information provided by IdPs is often only meaningful within the ecosystem in which it was created.

Because of this, identity silos lead to reduced productivity due to the scope limitations of disparate IdPs and to reduced security as applications must manage multiple identities and credentials across different platforms. This inherently weakens the overall security of your system architecture as it becomes reduced to the weakest security link across the various clouds.

Challenge 2: Lack of standards

Security protocols define the way users and applications are granted authorization to protected resources.

Standardized protocols are rigorously developed to ensure the validity of an authorization flow and provide a universal interface for consumption. Because no global standard exists, multicloud environments can become exposed to multiple protocols—both standard and proprietary. This fragmentation makes it difficult to consume authentication data from different sources and requires developers with highly specific domain knowledge across a range of detailed authentication flows.

Challenge 3: Maintenance

As the number of applications/services grows, consolidating access and identity management policies can become increasingly difficult, particularly in multicloud environments. Under traditional identity and access control models, each microservice requires custom application logic, which forces a service’s development team to apply patches and policy updates to authorization systems across the entire ecosystem. Similar maintenance costs extend to compliancy and service monitoring.

App ID and Istio

One approach we’ve been experimenting with to address the problem of identity and access management in multicloud architectures is integrating a federated identity and access management service, such as App ID, with Istio.

As an identity and access management solution, App ID federates identities from other IdPs using both standard and proprietary protocols into a centralized management system. This enables organizations to map multiple identity repositories across organizations into a single system and allows them to offload development costs around scaling access and identity infrastructure.

On its own, App ID’s identity federation can mitigate challenges around identity silos and protocol conformance, but when combined with the Istio service mesh, it can become a scalable, integrated identity solution for multicloud architectures that does not require any custom application code changes.

Istio

At a high level, Istio is a completely open source service mesh that layers transparently onto existing distributed applications, helping to reduce the complexity of multicloud deployments models by providing behavioral insights and operational control over the service mesh as a whole.

Istio

Istio logically divides its service mesh into a data plane and a control plane:

  • The data plane is composed of intelligent proxy sidecars, which mediate and control all network communication between microservices along with Mixer.

  • The control plane manages and configures proxies to route traffic while using Mixer to enforce policies.

At the core of this system is a platform-independent component called Mixer.

Telemetry for all traffic across the service mesh is continuously reported to Mixer, which can make decisions regarding the enforcement of access control and usage policies using its flexible plugin model.

Check out the video “What is Istio?” for more of an overview, and read more about Istio’s architecture in their documentation.

Adapting Istio and App ID to multicloud architectures

We can leverage Mixer’s plugin model to abstract authentication/authorization policy configurations from the cluster level to the multicloud level.

More concretely, we can create a Mixer adapter that is responsible for communicating with a centralized management platform and enforcing the authorization policies defined there.

Adapting Istio and App ID to multicloud architectures

Prototype of the App ID Multicloud Identity and Access Manager Dashboard

Using our prototyped App ID Mixer adapter, each cluster automatically registers with the centralized App ID Multicloud Identity and Access Manager (IAM) and begins monitoring the service mesh of your cluster to collect network topology information. This information is then coalesced into a single unified management UI where developers can easily configure authentication policies across cloud environments.

Incorporating a centralized identity management system comes with immediate development-time benefits. Once a cluster is set up with Istio, the adapter can be installed with a single command and then any access control policies can be defined from a single user interface.

For the purposes of this experiment, the dashboard only provides explicit policy support for service API protection; however, it could very easily be extended to support other types of policies and authentication flows.

We should note that as of the latest release Istio (1.0.5), Istio’s gRPC-based internal networking does not support outbound status code or response header mapping. This limitation prevents OAuth web authentication redirect flows from occurring; however, the changes are in active development and should be available in the next round of releases.

Before moving onto the demo, check out the adapter in action.

App ID Multicloud Identity and Access Manager sample

This tutorial uses both a multicloud management application and a Hello World application composed of two microservices to demonstrate a centralized authentication management system using App ID and the Istio service mesh.

The appid-multi-cloud-iam-management-dashboard (Golang) acts as a centralized dashboard for controlling identity and policy decisions across cloud environments.

The Hello World application consists of two microservices:

  1. hello-world-frontend (Node.js): The frontend microservice calls the backend application to retrieve user information.

  2. hello-world-backend (Node.js): The backend application contains user information that will be returned to the frontend.

The end-to-end architecture of the entire system is shown below:

The end-to-end architecture of the entire system

Although both of the Hello World microservices are written in Node.js, it’s important to note that both applications could just as easily have been written in any other server-side language. The authentication architecture relies solely on the Kubernetes and Istio infrastructure.

Before you begin

Requirements:

A note on Istio

For the full multicloud experience, you will need Istio in two Kubernetes environments; however, you can adapt the tutorial to use a single cluster. For the purpose of this tutorial, we will assume you are using the IBM Cloud Kubernetes Service with a standard paid cluster when referring to configuration commands.

If you haven’t already done so, create an App ID instance and set up Istio in your IBM Cloud Kubernetes Service clusters.

With IBM Cloud Kubernetes Service, you can automatically add Istio to your cluster from the Add-ons tab:

Add-ons tab

For other environments, you should follow the instructions corresponding to your platform’s installation guide.

Deploying the Multicloud Identity and Access Manager Dashboard

First, we will deploy the Multicloud Identity and Access Manager Dashboard to our first cluster.

Configure your Kubernetes environment

  1. Get the command to set your Kubernetes cluster env and download the configuration files.

    $ ibmcloud ks cluster-config --cluster 
  2. Set the KUBECONFIG environment variable. Copy the output from the previous command and paste it in your terminal. The command output should look similar to the following.

    $ export KUBECONFIG=/Users/$USER/.bluemix/plugins/container-service/clusters/Cluster1/kube-config-hou02/CLUSTER1.yml

Configure your App ID Multicloud Identity and Access Manager’s credentials

Update the template under ./appid-multi-cloud-iam-manager/helm/config.yaml with your App ID credentials. You can find your App ID credentials under the Service credentials tab on the dashboard.

Example:
   ingress_host: mycluster-681765.us-south.containers.appdomain.cloud
   tls_cert_secret_name: mycluster-681765
   tenant_id: "xxxxxxxx-xxxx-xxxx-xxxx-dad68cd4ed6f"
   client_id: "xxxxxxxx-xxxx-xxxx-xxxx-425f03aecec6"
   secret: "xxxxXXXXxxxxXXXXxxxxXXXXxxxxXXXXxxxxXXXXxxxxXXX"
   appid_url: "https://us-south.appid.cloud.ibm.com/oauth/v3/xxxxxxxx-xxxx-xxxx-xxxx-dad68cd4ed6f"
   withIngress: true

Deploy your application

$ helm init
$ helm install --name mciapm --namespace multi-cloud-tech-preview-dashboard ./appid-multi-cloud-iam-manager/helm/appid-multi-cloud-iam-manager -f ./appid-multi-cloud-iam-manager/helm/config.yaml


NAME:   mciapm
LAST DEPLOYED: Tue Mar 26 10:08:07 2019
NAMESPACE: multi-cloud-tech-preview-dashboard
STATUS: DEPLOYED
...
App ID Multi-Cloud IAM Management Dashboard installed successfully!

Test your application deployment

Find your publicly exposed endpoint and keep it handy. We’ll refer to it later as $MULTI_CLOUD_DASHBOARD_URL. Access the endpoint and validate you can see the empty management dashboard.

Test your application deployment

Summary

In this section, we deployed the App ID Multicloud Identity and Access Manager Dashboard. From this dashboard, we will be able to configure identity and access management policies. In the next two sections, we will deploy the backend and frontend services of our application and link them to our dashboard.

Deploying the Hello World backend

We will now deploy the backend application to the same cluster as the appid-multi-cloud-iam-manager.

Configure your Istio installation and deploy the application

In order to connect your deployment to the Istio service mesh, each pod must be running an Istio compatible sidecar. Here, you can use istioctl to automatically inject the sidecar configuration into your deployment file. See the Istio docs for more information on sidecar injection.

  1. Inject the Istio sidecar into your backend deployment and apply the yaml configuration files:

    $ istioctl kube-inject -f ./hello-world-backend/kubernetes/hello-world-backend.yaml | kubectl apply -f -
    
    namespace "multi-cloud-tech-preview" created
    gateway "gw-hello-world-backend" created
    virtualservice "vsvc-hello-world-backend" created
    deployment "dpl-hello-world-backend" created
    service "svc-hello-world-backend" created

Test your application deployment

Again, find your publicly exposed Istio endpoint and keep it handy. We’ll refer to it later as $HELLO_WORLD_BACKEND_URL. Access the $HELLO_WORLD_BACKEND_URL/api/user/data and validate that you receive a “user not found” error message.

NOTE: If you need help finding your exposed endpoint through the Istio gateway, check out the Istio docs.

Deploy the App ID adapter

Now, we will deploy the App ID adapter using the provided helm chart to begin monitoring the backend service.

  1. Modify the ./appid-istio-mixer-adapter/helm/cluster1.yaml configuration template provided with the adapter. hello-world-backend/kubernetes
  2. Deploy the adapter using the following command:
    $ helm install ./appid-istio-mixer-adapter/helm/multi-cloud-identity-and-access-policy-manager-adapter -f ./appid-istio-mixer-adapter/helm/cluster1.yaml --name appid-adapter
    
    NAME:   appid-adapter
    LAST DEPLOYED: Tue Mar 26 08:42:34 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    ....
    Multi-Cloud Identity and Access Policy Manager Adapter installed successfully!
  3. After the adapter deploys, return to the App ID Multicloud IAM and verify your Kubernetes cluster is now visible and the backend service is shown.
    return to the App ID Multicloud IAM and verify your Kubernetes cluster is now visible and the backend service

  4. Try enabling the hello-world-backend and then return to your backend application at $HELLO_WORLD_BACKEND_URL/api/user/data. Keep in mind Istio (1.0.5) may take up to a minute to clear its Mixer response cache. Once the cache is cleared, your request should receive an unauthorized error after being intercepted by the App ID Mixer adapter.
    UNAUTHENTICATED:handler-appid-api.handler.istio-system:Unauthorized. Authorization header not found., handler-appid-api.handler.istio-system:Unauthorized. Authorization header not found.
  5. Before moving on, be sure to disable protection on the backend

Summary

In short, we have deployed our backend microservice and shown how we can configure our App ID Istio adapter to begin monitoring our cluster’s services in conjunction with the App ID Multicloud Dashboard. In the next section, we will deploy the frontend service to our secondary cluster to complete our system architecture.

Deploying the Hello World frontend

Now, we will deploy our frontend application to our second Kubernetes cluster.

Configure your Kubernetes environment

Use the same steps from the appid-multi-cloud-iam-manager section to set your local Kubernetes environment to point to your second cluster.

Configure your App ID Redirect URI

  1. First, find your publicly exposed endpoint and keep it handy. We’ll refer to as $HELLO_WORLD_FRONTED_URL.

  2. In order for you to log into your application, be sure to whitelist its callback endpoint within App ID by adding $HELLO_WORLD_FRONTED_URL/appid/login to your redirect URI list.

For help configuring your App ID redirect URI see the docs.

Configure your application environment and deploy your application

  1. Modify the config map template near the top of ./multi-cloud-tech-preview/hello-world-frontend/hello-world-frontend.yaml to include your App ID credentials and the cluster endpoints we found earlier:

    Example:
        tenant_id: "f3034232-dddd-cccc-bbbb-aaaaaaaaaaaa"
        client_id: "9cf21234-cccc-dddd-aaaa-123456678910"
        secret: "zzzyZWZjM4L0o2U1Yy00OGZmLTg2Ymfd1zU4YzI0MzE5Naaa"
        appid_url: "https://us-south.appid.cloud.ibm.com/oauth/v3/f3034232-dddd-cccc-bbbb-aaaaaaaaaaaa"
        backend_url: $HELLO_WORLD_BACKEND_URL
        public_web_url: $HELLO_WORLD_FRONTED_URL
  2. Inject the Istio sidecar and deploy the frontend application:

    $ istioctl kube-inject -f ./hello-world-frontend/kubernetes/hello-world-frontend.yaml | kubectl apply -f -
    
    namespace "multi-cloud-tech-preview" created
    configmap "cfgmap-hello-world-frontend" created
    service "svc-hello-world-api" created
    service "svc-hello-world-web" created
    gateway "gw-hello-world-frontend" created
    virtualservice "vsvc-hello-world-frontend" created
    deployment "dpl-hello-world-frontend" created

Test your application deployment

Access your application using $HELLO_WORLD_FRONTEND_URL and validate you receive the following:

{
    msg: "Hello anonymous user",
    backendResponse: "User not found"
}

Since our frontend does not have any protection enabled, it recognizes the user as anonymous and similarly the backend has no identifying information, so it responds with a “User not found” message.

Deploy the App ID adapter

As before, deploy the App ID adapter using the provided helm chart.

  1. Modify ./appid-istio-mixer-adapter/helm/cluster2.yaml configuration template provided with the adapter.

  2. Deploy the adapter using the following command

    $ helm init
    $ helm install ./appid-istio-mixer-adapter/helm/multi-cloud-identity-and-access-policy-manager-adapter -f ./appid-istio-mixer-adapter/helm/cluster2.yaml --name appid-adapter
    
    
    NAME:   appid-adapter
    LAST DEPLOYED: Tue Mar 26 08:42:34 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    ....
    Multicloud Identity and Access Policy Manager Adapter installed successfully!
  3. After the adapter is deployed, return to the App ID Multicloud Identity and Access Manager and verify your second Kubernetes cluster is visible and the frontend services are shown.

return to the App ID Multicloud Identity and Access Manager and verify your second Kubernetes cluster is visible and the frontend services

Handling web redirects

As noted previously, Istio (1.0.5) does not currently support web redirects initiated from Mixer. As a temporary workaround, the frontend is built with two service entry points: svc-hello-world-api  (entry point to /api paths) and svc-hello-world-web (entry point to all web paths). When a request passes through the web service, a custom middleware sends an internal request to svc-hello-world-api/api/is_protected.

If Istio protection is enabled and Mixer returns a 401, the middleware triggers a redirect and begins an authentication flow with App ID. Within the next round of releases, Istio will support this functionality and then we can truly have one-click authentication to web services.

Handling web redirects

  1. An end user makes an external request to the frontend: $HELLO_WORLD_FRONTED_URL/.

  2. The request passes through the unprotected service svc-hello-world-web to the application.

  3. An application-level middleware makes a new request to https://svc-hello-world-api/api/is_protected.

  4. The api service routes the request to Mixer, which evaluates the security policy.

  5. If Mixer returns unauthorized, the middleware begins an authentication flow with App ID.

Summary

In this section, we deployed the frontend service for our application, completing our system architecture. From the App ID Multicloud IAM Dashboard, we can now see our entire network across clusters. In the next and final section, we will look at how we can configure different access policies and effortlessly secure different parts of the system.

Configure cloud policies

When configuring authentication policies, keep in mind that as of Istio 1.0.5, updating mixer policies can take up to a minute due to Mixer response caching. You can sign-out using the endpoint: $HELLO_WORLD_FRONTED_URL/appid/logout.

Our application supports three primary states:

  1. Neither Hello-World-Frontend nor Hello-World-Backend require authentication.

    • Disable all protection from the dashboard, if you haven’t already done so:
      Configure cloud policies

    • When we issue a request to the frontend, we receive the message:

      {
          msg: "Hello anonymous user",
          backendResponse: "User not found"
      }

      In this case, we do not protect any services with App ID. Here, we are an unauthenticated anonymous user and cannot retrieve information from the backend because it does not know anything about the user.

  2. Hello-World-Backend requires authentication, but Hello-World-Frontend does not.

    • Here, we enable the svc-hello-world-backend service from the management dashboard:
      Hello-World-Backend

    • After issuing another request to the frontend, we will receive the following message:

      {
          msg: "Hello anonymous user",
          backendResponse: "Unauthorized"
      }

      Again, the frontend recognizes us as an anonymous user, but now the request telemetry data is pre-processed by the App ID Mixer adapter, which returns an unauthorized response, since it does not have an authorization context.

  3. Hello-World-Frontend and Hello-World-Backend both require authentication.

    • Now, enable the svc-hello-world-backend and svc-hello-world-api services from the management dashboard:
      svc-hello-world-backend and svc-hello-world-api

    • When we issue a request to the frontend, the application immediately redirects to authenticate with App ID. Once authenticated, we will receive identifying information from both the frontend and the backend:

      {
          msg: "Hello Aaron Liberatore",
          userInfo: {
              total_donations: "$1234.56",
              locale: "en-us"
          }
      }

Clean up

After experimenting with the App ID Multicloud IAM Manager, clean up your environment:

Cluster 1

$ kubectl delete -f ./hello-world-backend/kubernetes/hello-world-backend.yaml

$ helm delete --purge mciapm

$ helm delete --purge appid-adapter

Cluster 2

$ kubectl delete -f ./hello-world-frontend/kubernetes/hello-world-frontend.yaml

$ helm delete --purge appid-adapter

References

  1. IBM Multicloud Survey

Be the first to hear about news, product updates, and innovation from IBM Cloud