diff --git a/README.md b/README.md index 4d36ce6..5220a0e 100644 --- a/README.md +++ b/README.md @@ -10,60 +10,54 @@ [![GithubForks][img-github-forks]][url-github-forks] -With the App Identity and Access Adapter for Istio Mixer, you can manage authentication and access management across your service mesh. The Adapter can be configured with any OIDC or OAuth 2.0 compliant identity provider, which enables it to seamlessly control authentication and authorization policies in many heterogeneous environments, including frontend and backend applications. +By using the App Identity and Access adapter, you can centralize all of your identity management with a single instance of IBM Cloud App ID. Because enterprises use clouds from multiple providers or a combination of on and off-premise solutions, heterogenous deployment models can help you to preserve existing infrastructure and avoid vendor lock-in. The adapter can be configured to work with any OIDC compliant identity provider, which enables it to control authentication and authorization policies in all environments including frontend and backend applications. And, it does it all without any change to your code or the need to redeploy your application. -## Architecture +## Multicloud Architecture -Istio uses an Envoy proxy sidecar to mediate all inbound and outbound traffic for all services in the service mesh. By using the proxy, Istio extracts information about traffic behavior that can then be sent to the Mixer to enforce policy decisions. The App Identity and Access adapter analyzes these attributes against custom policies to control identity and access management into and across the service mesh. These access management policies are linked to particular Kubernetes services and can be finely tuned to specific service endpoints. Using the adapter, these policies can be created, updated, and deleted without redeploying applications or changing your code in any way. +A multicloud computing environment combines multiple cloud and/ or private computing environments into a single network architecture. By distributing workloads across multiple environments, you might find improved resiliency, flexibility, and greater cost-effificiency. To achieve the benefits, it's common to use a container-based applications with an orchestration layer, such as Kubernetes. -The App ID adapter provides support for two different access control flows that correspond to the frontend and backend of your apps respectively. +![App Identity and Access adapter architecture diagram](images/istio-adapter.png) +Figure. Multicloud deployment achieved with the App Identity and Access adapter. -1. [OAuth 2.0 Authorization Bearer](https://tools.ietf.org/html/rfc6750) +>> Note: Due to an Istio limitation, the App Identity and Access adapter currently stores user session information internally and does *not* persist the information across replicas or over failover configurations. When using the adapter, limit your workloads to a single replica until the limitation is addressed. -2. [Open ID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) +## Understanding Istio and the adapter -For more information about configuring OIDC and OAuth 2.0, see [Policy configuration](#Defining-a-Configuration). To see how App ID fits into the Istio architecture, check out the following diagram. +[Istio](https://istio.io) is an open source service mesh that layers transparently onto existing distributed applications that can integrate with Kubernetes. To reduce the complexity of deployments Istio provides behavioral insights and operational control over the service mesh as a whole. When App ID is combined with Istio, it becomes a scalable, integrated identity solution for multicloud architectures that does not require any custom application code changes. For more information, check out ["What is Istio?"](https://www.ibm.com/cloud/learn/istio?cm_mmc=OSocial_Youtube-_-Hybrid+Cloud_Cloud+Platform+Digital-_-WW_WW-_-IstioYTDescription&cm_mmca1=000023UA&cm_mmca2=10010608). +Istio uses an Envoy proxy sidecar to mediate all inbound and outbound traffic for all services in the service mesh. By using the proxy, Istio extracts information about traffic, also known as telemetry, that is sent to the Istio component called Mixer to enforce policy decisions. The App Identity and Access adapter extends the Mixer functionality by analyzing the telemetry (attributes) against custom policies to control identity and access management into and across the service mesh. The access management policies are linked to particular Kubernetes services and can be finely tuned to specific service endpoints. For more information about policies and telemetry, see the [Istio documentation](https://istio.io/docs/concepts/policies-and-telemetry/). -![Istio Mixer Architecture](https://istio.io/docs/concepts/policies-and-telemetry/topology-without-cache.svg "Istio Mixer Architecture") +### Protecting frontend apps -* The Envoy sidecar "proxy" sits in front of your application and calls the Mixer with telemetry before each request. -* The Mixer dispatches the telemetry to the App ID authentication/ access management Adapter. -* The Adapter evaulates the authentication and authorization policies on the request telemetry and returns response - access granted or denied. -* The proxy responds: - * When successful, the proxy forwards the request to the service or application. - * On failure, the proxy returns a failure check response to the calling client - the user or another app. +If you're using a browser based application, you can use the [Open ID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) / OAuth 2.0 `authorization_grant` flow to authenticate your users. When an unauthenticated user is detected, they are automatically redirected to the authentication page. When the authentication completes, the browser is redirected to an implicit `/oidc/callback` endpoint where the adapter intercepts the request. At this point, the adapter obtains tokens from the identity provider and then redirects the user back to their originally requested URL. - - -### API Protection - -The App ID Adapter can be used in collaboration with the OAuth 2.0 Authorization Bearer flow to protect service APIs by validating JWT Bearer tokens. The Bearer flow expects a request to contain an Authorization header with a valid access token and optionally, an identity token. The expected header structure is `Authorization=Bearer {access_token} [{id_token}]`. Unauthenticated clients are returned an HTTP 401 response status with a list of the scopes that are needed to obtain authorization. If the tokens are invalid or expired, the API strategy returns an `HTTP 401` response with an optional error component identifying the case of the error `Www-Authenticate=Bearer scope="{scope}" error="{error}"`. - - -For more information about tokens and how they're used, see the App ID documentation. For information, on configuring the OAuth 2.0 Authorization Bearer for the adapter, see [Protecting APIs](#protecting-apis). - - -### Frontend Protection - -If you're using a browser based application, you can use the OIDC / Auth 2.0 `authorization_grant` flow to authenticate your users. When an unauthenticated user is detected, they are automatically redirected to the authentication page. When the authentication completes, the browser is redirected to an implicit `/oidc/callback` endpoint where the adapter intercepts the request. At this point, the adapter obtains tokens from the identity provider and then redirects the user back to their originally requested URL. - -To view the user session information, including the session tokens, you can look in the `Authorization` header. +To view the user session information including the session tokens, you can look in the `Authorization` header. ``` Authorization: Bearer ``` +{: screen} -You can also logout authenticated users. When an authenticated user accesses any protected endpoint with `/oidc/logout` appended as shown in the following example, they are logged out from their current session. +You can also logout authenticated users. When an authenticated user accesses any protected endpoint with `oidc/logout` appended as shown in the following example, they are logged out. ``` https://myhost/path/oidc/logout ``` +{: screen} If needed, a refresh token can be used to automatically acquire new access and identity tokens without your user's needing to re-authenticate. If the configured identity provider returns a refresh token, it is persisted in the session and used to retreive new tokens when the identity token expires. -Due to a bug within Istio, the adapter currently stores user session information internally and does *not* persist the information across replicas or over failover configurations. When using the adapter, users should limit their workloads to a single replica until the bug is addressed in the next release. + +### Protecting backend apps +{: #istio-backend} + +The adapter can be used in collaboration with the OAuth 2.0 [JWT Bearer flow](https://tools.ietf.org/html/rfc6750) to protect service APIs by validating JWT Bearer tokens. The Bearer authorization flow expects a request to contain an Authorization header with a valid access token and an optional identity token. The expected header structure is `Authorization=Bearer {access_token} [{id_token}]`. Unauthenticated clients are returned an HTTP 401 response status with a list of the scopes that are needed to obtain authorization. If the tokens are invalid or expired, the API strategy returns an HTTP 401 response with an optional error component that says `Www-Authenticate=Bearer scope="{scope}" error="{error}"`. + + +For more information about tokens and how they're used, see [understanding tokens](https://cloud.ibm.com/docs/services/appid?topic=appid-tokens). + + @@ -77,26 +71,35 @@ You can install the Adapter by using the accompanying Helm chart. You can config Before you get started, be sure you have the following prerequisites installed. - [Kubernetes Cluster](https://kubernetes.io/) -- [Istio v1.1](https://istio.io/docs/setup/kubernetes/install/) - [Helm](https://helm.sh/) +- [Istio v1.1](https://istio.io/docs/setup/kubernetes/install/) + +>> You can also use the [IBM Cloud Kubernetes Service Managed Istio](https://cloud.ibm.com/docs/containers?topic=containers-istio). + -### Adapter Installation + +### Installing the Adapter To install the chart, initialize Helm in your cluster, define the options that you want to use, and then run the install command. -1. If you haven't already, install Helm in your cluster. +1. If you're working with IBM Cloud Kubeneretes service, be sure to login and set the context for your cluter. + +2. Install Helm in your cluster. + ```bash - $ helm init + helm init ``` -2. Update the [Helm chart](./helm/values.yaml) with your custom configuration. +>>You might want to configure Helm to use `--tls` mode. For help with enabling TLS, check out the [Helm repository](https://github.com/helm/helm/blob/master/docs/tiller_ssl.md). If you enable TLS, be sure to append `--tls` to every Helm command that you run. For more information about using Helm with IBM Cloud Kubernetes Service, see [Adding services by using Helm Charts](https://cloud.ibm.com/docs/docs/containers?topic=containers-helm#public_helm_install). 3. Install the chart. + ```bash - $ helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter + helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter ``` + ## Applying an authorization and authentication policy An authentication or authorization policy is a set of conditions that must be met before a request can access a resource access. By defining an identity provider's service configuration and an access policy that outlines when a particular access control flow should be used, you can control access to any resource in your service mesh. @@ -108,18 +111,6 @@ An authentication or authorization policy is a set of conditions that must be me Depending on whether you're protecting frontend or backend applications, create a policy configuration with one of the following options. -* For backend applications: The OAuth 2.0 Bearer token spec defines a pattern for protecting APIs by using [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519.html). Using the following configuration as an example, define a `JwtConfig` CRD that contains the public key resource, which is used to validate token signatures. - - ``` - apiVersion: "security.cloud.ibm.com/v1" - kind: JwtConfig - metadata: - name: samplejwtpolicy - namespace: sample-app - spec: - jwksUrl: https://us-south.appid.cloud.ibm.com/oauth/v4/oauth/v4/71b34890-a94f-4ef2-a4b6-ce094aa68092/publickeys - ``` - * For frontend applications: Browser based applications that require user authentication can be configured to use the OIDC / OAuth 2.0 authentication flow. To define an `OidcConfig` CRD containing the client used to facilitate the authentication flow with the Identity provider, use the following example as a guide. ```helmyaml @@ -146,91 +137,143 @@ Depending on whether you're protecting frontend or backend applications, create | `clientSecretRef.key` | string | yes | The field within the Kubernetes Secret that contains the `clientSecret`. | -### Register application endpoints - -Register application endpoints within a `Policy` CRD to validate incoming requests and enforce authentication rules. Each `Policy` applies exclusively to the Kubernetes namespace in which the object lives and can specify the services, paths, and methods that you want to protect. +* For backend applications: The OAuth 2.0 Bearer token spec defines a pattern for protecting APIs by using [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519.html). Using the following configuration as an example, define a `JwtConfig` CRD that contains the public key resource, which is used to validate token signatures. - ```helmyaml - kind: Policy + ``` + apiVersion: "security.cloud.ibm.com/v1" + kind: JwtConfig metadata: - name: policy-1 - namespace: sample-namespace + name: samplejwtpolicy + namespace: sample-app spec: - targets: - - service: svc-service-name-123 - paths: - - exact: /web - method: GET - policies: - - type: oidc - config: - - prefix: /api - policies: - - type: jwt - config: + jwksUrl: https://us-south.appid.cloud.ibm.com/oauth/v4/oauth/v4/71b34890-a94f-4ef2-a4b6-ce094aa68092/publickeys ``` - | Service Object | Type | Required | Description | - |----------------|:----:|:--------:| :-----------: | - | `service` | string | yes | The name of Kubernetes service in the Policy namespace that you want to protect. | - | `paths` | array | yes | A list of path objects that define the endpoints that you want to protect. If left empty, all paths are protected. | - | Path Object | Type | Required | Description | - |----------------|:----:|:--------:| :-----------: | - | `exact or prefix` | string | yes | The path that you want to apply the policies on. Options include `exact` and `prefix`. `exact` matches the provides endpoints exactly with the last `/` trimmed. `prefix` matches the endpoints that begin with the route prefix that you provide. | - | `method` | enum | no | The HTTP method protected. Valid options ALL, GET, PUT, POST, DELETE, PATCH - Defaults to ALL: | - | `policies` | array | no | The OIDC/JWT policies that you want to apply. | +### Registering application endpoints + +Register application endpoints within a `Policy` CRD to validate incoming requests and enforce authentication rules. Each `Policy` applies exclusively to the Kubernetes namespace in which the object lives and can specify the services, paths, and methods that you want to protect. + +```yaml +apiVersion: "security.cloud.ibm.com/v1" +kind: Policy +metadata: + name: samplepolicy + namespace: sample-app +spec: + targets: + - + serviceName: + paths: + - exact: /web/home + method: ALL + policies: + - policyType: oidc + config: + rules: + - claim: scope + match: ALL + source: access_token + values: + - appid_default + - openid + - claim: amr + match: ANY + source: id_token + values: + - cloud_directory + - google + + - exact: /web/user + method: GET + policies: + - policyType: oidc + config: + redirectUri: https://github.com/ibm-cloud-security/app-identity-and-access-adapter + - prefix: / + method: ALL + policies: + - + policyType: jwt + config: +``` + +| Service Object | Type | Required | Description | +|----------------|:----:|:--------:| :-----------: | +| `service` | string | yes | The name of Kubernetes service in the Policy namespace that you want to protect. | +| `paths` | array[Path Object] | yes | A list of path objects that define the endpoints that you want to protect. If left empty, all paths are protected. | + + +| Path Object | Type | Required | Description | +|----------------|:----:|:--------:| :-----------: | +| `exact or prefix` | string | yes | The path that you want to apply the policies on. Options include `exact` and `prefix`. `exact` matches the provides endpoints exactly with the last `/` trimmed. `prefix` matches the endpoints that begin with the route prefix that you provide. | +| `method` | enum | no | The HTTP method protected. Valid options ALL, GET, PUT, POST, DELETE, PATCH - Defaults to ALL: | +| `policies` | array[Policy] | no | The OIDC/JWT policies that you want to apply. | + + +| Policy Object | Type | Required | Description | +|----------------|:----:|:--------:| :-----------: | +| `policyType` | enum | yes | The type of OIDC policy. Options include: `jwt` or `oidc`. | +| `config` | string | yes | The name of the provider config that you want to use. | +| `redirectUri` | string | no | The url you want the user to be redirected after successful authentication, default: the original request url. | +| `rules` | array[Rule] | no | The set of rules the you want to use for token validation. | - | Policy Object | Type | Required | Description | - |----------------|:----:|:--------:| :-----------: | - | `type` | enum | yes | The type of OIDC policy. Options include: `jwt` or `oidc`. | - | `config` | string | yes | The name of the provider config that you want to use. | +| Rule Object | Type | Required | Description | +|----------------|:----:|:--------:| :-----------: | +| `claim` | string | yes | The claim that you want to validate. | +| `match` | enum | no | The criteria required for claim validation. Options inlcude: `ALL`, `ANY` or `NOT`. The default is set to `ALL`. | +| `source` | enum | no | The token where you want to apply the rule. Options inlcude: `access_token` or `id_token`. The default is set to `access_token`. | +| `values` | array[string] | yes | The required set of values for validation. | -## Cleanup -To remove the Adapter and all of the associated CRDs, you can delete the Helm chart and the associated signing + encrpytion keys. +## Deleting the adapter + +To remove the adapter and all of the associated CRDs, you must delete the Helm chart and the associated signing and encryption keys. ```bash -$ helm delete --purge appidentityandaccessadapter -$ kubectl delete secret appidentityandaccessadapter-keys -n istio-system +helm delete --purge appidentityandaccessadapter +kubectl delete secret appidentityandaccessadapter-keys -n istio-system ``` ## FAQ and troubleshooting -If you encounter an issue while working with the App ID Adapter, consider the following FAQ's and troubleshooting techniques. For more help, You can ask questions through a forum or open a support ticket. When you are using the forums to ask a question, tag your question so that it is seen by the App ID development team. +If you encounter an issue while working with the App Identity and Access adapter, consider the following FAQ's and troubleshooting techniques. For more help, You can ask questions through a forum or open a support ticket. When you are using the forums to ask a question, tag your question so that it is seen by the App ID development team. - * If you have technical questions about App ID, post your question on Stack Overflow External link icon and tag your question with "ibm-appid". - * For questions about the service and getting started instructions, use the dW Answers External link icon forum. Include the `appid` tag. + * If you have technical questions about App ID, post your question on [Stack Overflow](https://stackoverflow.com/) and tag your question with "ibm-appid". + * For questions about the service and getting started instructions, use the [dW Answers](https://developer.ibm.com/) forum. Include the `appid` tag. -For more information about getting support, see [how do I get the support that I need](/docs/get-support?topic=get-support-getting-customer-support#getting-customer-support). +For more information about getting support, see [how do I get the support that I need](https://cloud.ibm.com/docs/get-support?topic=get-support-getting-customer-support#getting-customer-support). ### Troubleshooting: Logging +{: #istio-logging} -By default, logs are styled as JSON and provided at an `info` visbility level to provide for ease of integration with external logging systems. To update the logging configuration, you can use the Helm chart. Supported logging levels include range [-1, 7] as shown in Zapcore. For more information about the levels, see the [Zapcore documentation](https://godoc.org/go.uber.org/zap/zapcore#Level). +By default, logs are styled as JSON and provided at an `info` visbility level to provide for ease of integration with external logging systems. To update the logging configuration, you can use the Helm chart. Supported logging levels include range `-1 - 7` as shown in Zapcore. For more information about the levels, see the [Zapcore documentation](https://godoc.org/go.uber.org/zap/zapcore#Level). ->> **Note:** When you're manually viewing JSON logs, you might want to tail the logs and "pretty print" them by using [jq](https://brewinstall.org/install-jq-on-mac-with-brew/). +>>When you're manually viewing JSON logs, you might want to tail the logs and "pretty print" them by using [jq](https://brewinstall.org/install-jq-on-mac-with-brew/). **Adapter** -To see the Adapter logs, you can use `kubectl` or access the pod from the `appidentityandaccessadapter` pod from the Kubernetes console. +To see the adapter logs, you can use `kubectl` or access the pod from the `ibmcloudappid` pod from the Kubernetes console. ```bash -$ alias adapter_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=appidentityandaccessadapter -o jsonpath='{.items[0].metadata.name}')" +$ alias adapter_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=ibmcloudappid -o jsonpath='{.items[0].metadata.name}')" $ adapter_logs | jq ``` + **Mixer** -If the Adapter does not appear to recieve requests, check the Mixer logs to ensure that it is successfully connected to the Adapter. +If the adapter does not appear to recieve requests, check the Mixer logs to ensure that it is successfully connected to the adapter. ```bash $ alias mixer_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=telemetry -o jsonpath='{.items[0].metadata.name}') -c mixer" $ mixer_logs | jq ``` + ## License This package contains code licensed under the Apache License, Version 2.0 (the "License"). You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 and may also view the License in the LICENSE file within this package. diff --git a/images/istio-adapter.png b/images/istio-adapter.png new file mode 100644 index 0000000..219b141 Binary files /dev/null and b/images/istio-adapter.png differ