copyright | lastupdated | keywords | subcollection | ||
---|---|---|---|---|---|
|
2019-12-12 |
ingress controller, ingress, istio, access, subdomain, custom domain, service, containerized apps, containers, kube, networking, policy, policies, secure apps, authentication, authorization |
appid |
{:external: target="_blank" .external} {:shortdesc: .shortdesc} {:screen: .screen} {:pre: .pre} {:table: .aria-labeledby="caption"} {:codeblock: .codeblock} {:tip: .tip} {:note: .note} {:important: .important} {:deprecated: .deprecated} {:download: .download}
{: #kube-auth}
You can consistently enforce policy-driven security by using the Ingress networking capability in {{site.data.keyword.containerlong}} or {{site.data.keyword.openshiftshort}}. With this approach, you can enable authorization and authentication for all of the applications in your cluster at the same time, without ever changing your app code! {: shortdesc}
Check out the following diagram to see the authentication flow.
{: caption="Figure 1. {{site.data.keyword.appid_short_notm}} Kubernetes integration architecture" caption-side="bottom"}
- A user opens your application and triggers a request to the web app or API.
- For the API flow, the Ingress controller attempts to validate the supplied tokens. If the web flow is used, it kicks off a three-leg OIDC authentication process.
- {{site.data.keyword.appid_short_notm}} begins the authentication process by displaying the Login Widget.
- The user provides a username or email and password.
- The Ingress controller obtains access and identity tokens from {{site.data.keyword.appid_short_notm}} for authorization.
- Every request that is validated and forwarded by the Ingress Controller to your apps has an authorization header that contains the tokens.
The {{site.data.keyword.appid_short_notm}} Ingress annotation does not currently support refresh tokens. When access and identity tokens expire, user's must reauthenticate. {: note}
{: #video-ingress}
Updating your Ingress annotation works the same way in both {{site.data.keyword.containerlong}} or {{site.data.keyword.openshiftshort}}. To see how quickly you can be up and running with {{site.data.keyword.openshiftshort}} check out the following video.
<iframe class="embed-responsive-item" id="kube-video" title="Protecting IBM Kubernetes Service OpenShift Applications with {{site.data.keyword.appid_short_notm}}" type="text/html" width="640" height="390" src="//www.youtube.com/embed/sqGS7naTkoU?rel=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen> </iframe>{: #kube-prereqs}
Before you can get started, ensure that you have the following prerequisites. {: shortdesc}
-
An app or sample app.
-
A standard Kubernetes cluster with at least two worker nodes per zone. If you are using Ingress in multizone clusters review the extra prerequisites in the Kubernetes Service documentation.
-
An instance of {{site.data.keyword.appid_short_notm}} in the same region in which your cluster is deployed. Ensure that the service name does not contain any spaces.
-
The following {{site.data.keyword.cloud_notm}} IAM roles:
- Cluster: Administrator platform role
- Kubernetes namespaces: Manager service role
-
The following CLIs:
-
The following CLI plug-ins:
- {{site.data.keyword.containershort}}
- {{site.data.keyword.registryshort_notm}}
For help with getting the CLIs and plug-ins downloaded and your Kubernetes Service environment configured, check out the tutorial creating Kubernetes clusters. {: tip}
{: #kube-create-appid}
By binding your instance of {{site.data.keyword.appid_short_notm}} to your cluster, you can enforce protection for all of the apps that run in your cluster.
- Log in to the {{site.data.keyword.cloud_notm}} CLI. Follow the prompts in the CLI to complete logging in. If you're using a federated ID, be sure to append the
--sso
flag to the end of the command.
ibmcloud login -a cloud.ibm.com -r <region>
{: codeblock}
Region | Endpoint |
---|---|
Dallas | us-south |
Frankfurt | eu-de |
Sydney | au-syd |
London | eu-gb |
Tokyo | jp-tok |
-
Set the context for your cluster.
-
Get the command to set the environment variable and download the Kubernetes configuration files.
```
ibmcloud ks cluster-config <cluster_name_or_ID>
```
{: codeblock}
-
Copy the output beginning with
export
and paste it into your terminal to set theKUBECONFIG
environment variable. -
Check to see whether you already have an Ingress controller in your default namespace. {{site.data.keyword.containerlong}} supports one Ingress per namespace. If you already have one, you can update the existing Ingress configuration or use a different namespace.
kubectl get ingress
{: codeblock}
- Bind your instance of {{site.data.keyword.appid_short_notm}}. Binding creates a service key for the service instance. You can specify an existing service key by using the
-key
flag.
ibmcloud ks cluster-service-bind --cluster <cluster_name_or_ID> --namespace <namespace> --service <App_ID_instance_name> [--key <service_instance_key>]
{: codeblock}
If you do not specify a namespace, the secret is created in the default
namespace.
{: tip}
Example output:
ibmcloud ks cluster-service-bind --cluster mycluster --namespace default --service appid1
Binding service instance to namespace...
OK
Namespace: default
Secret name: binding-appid1
{: screen}
{: kube-ingress}
During cluster creation, both a private and a public IBM Kubernetes Service Application Load Balancer (ALB) are created for you. To add application protection for apps that run in your cluster, update your Ingress resource YAML.
To ensure the best performance of the integration, it is recommended that you always use the latest version of IBM Kubernetes Service Application Load Balancer (ALB). By default, auto-update is enabled for your cluster. For more information about auto-updates, see On-demand ALB update feature on {{site.data.keyword.containershort}}. {: tip}
- Get the secret that was created in your cluster namespace when you bound {{site.data.keyword.appid_short_notm}} to your cluster. Your binding will look similar to the following:
binding-<appid_instance_name>
.
kubectl get secrets --namespace=<namespace>
{: codeblock}
Example output:
NAME TYPE DATA AGE
binding-appid1 Opaque 1 1m
bluemix-default-secret kubernetes.io/dockercfg 1 1h
default-token-kf97z kubernetes.io/service-account-token 3 1h
{: screen}
This is not your Container Registry namespace. {: tip}
- Use the following example
yaml
file to create your Ingress configuration. For help with defining the rest of your deployment, check out Deploying apps with the CLI.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myingress
annotations:
ingress.bluemix.net/appid-auth: "bindSecret=<bind_secret> namespace=<namespace> requestType=<request_type> serviceName=<myservice> [idToken=false]"
spec:
tls:
- hosts:
- mydomain
secretName: mytlssecret
rules:
- host: mydomain
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 8080
{: screen}
Variable | Description |
---|---|
bindSecret |
The Kubernetes secret that was created when you bound your {{site.data.keyword.appid_short_notm}} service instance to your cluster. |
namespace |
The namespace in which your bindSecret was created. If you did not specify a namespace, the default namespace is used. |
requestType |
The type of request that you want to send to {{site.data.keyword.appid_short_notm}}. Options include: If you set the request type to |
serviceName |
Required: The name of the Kubernetes service that you created for your app. If a service name is not included, the annotation is enabled for all services. To use multiple request types in the same cluster, configure an instance of {{site.data.keyword.appid_short_notm}} to use |
idToken |
Optional: The Liberty OIDC client is unable to parse both the access and the identity token at the same time. When working with Liberty, set this value to false so that the identity token is not sent to the Liberty server. |
You can add more instance of {{site.data.keyword.appid_short_notm}} to your annotation by adding two bindSecret
lines, separated by a semicolon (;).
{: tip}
- Run the configuration file.
kubectl apply -f <file-name>.yaml
{: codeblock}
{: #kube-add-redirect}
A redirect URL is the location that your user is sent to after they successfully sign in to or out of your app. By adding the redirect URI to your whitelist, you are telling {{site.data.keyword.appid_short_notm}} that it is okay to send your users to that location. Learn more about redirect URIs.
-
Navigate to the {{site.data.keyword.cloud_notm}} GUI and open your {{site.data.keyword.appid_short_notm}} dashboard.
-
In Identity Providers > Manage, set the providers that you want to use to On. If a provider is not enabled, then users are issued an access token that provides anonymous access to your app.
-
Click Authentication Settings.
-
Click the + symbol in the Add web redirect URLs box.
-
Custom domain:
A URL that is registered with a custom domain might look like:
http://mydomain.net/myapp2path/appid_callback
. If the apps that you want to expose are within the same cluster but in different namespaces, you can use a wildcard to specify all of the apps in the cluster at once. This can be helpful during development, but you should exercise caution if you use wildcards in production. For example:https://custom_domain.net/*
-
Ingress subdomain:
If your app is registered with an IBM Ingress subdomain, your callback URL might look like:
https://mycluster.us-south.containers.appdomain.cloud/myapp1path/appid_callback
{: #kube-logout}
When you configure your application to use the Ingress Controller annotation, a session with the user's browser is established. To end the Ingress session, call the /appid_logout
endpoint and then redirect your users to a home or sign in page. Be sure that the log out code is called as a reaction to the user clicking Logout
in your app. Be sure that you add your log out URI to your whitelisted redirect URIs. Your URI will look similar to https://mycluster.us-south.containers.appdomain.cloud/myapp1path/appid_logout
.
{: #kube-next}
Now that your application is running in a Kubernetes cluster and Ingress is configured, you can try:
- Using custom attributes to set roles
- Configuring multi-factor authentication
- Customizing the Login Widget