Skip to content
This repository has been archived by the owner on Jul 28, 2021. It is now read-only.

Commit

Permalink
Dev --> Master (#22)
Browse files Browse the repository at this point in the history
* Update integration test (#19)

* update integration test

* update README (#20)

* update README

* spelling errors

* remove {: screen}

* add coveralls

* new helm chart (#21)

* new chart

* update to version 0.4.0

* remove version 0.1.0

* readme updates

* add flag info

* update name

* fix integration test

* update state param parsing
  • Loading branch information
ishangulhane authored Jul 12, 2019
1 parent 2a4e807 commit 5706774
Show file tree
Hide file tree
Showing 22 changed files with 168 additions and 101 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ main
node_modules
.DS_Store
coverage.out
profile.out
profile.out
samples/testcrds/
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ script:
# Run coverage on unit tests
- go test -coverprofile=coverage.out ./adapter/... || travis_terminate 1;
# Run all integration tests
- go test -v -race ./tests/integration/...
- go test -v ./tests/integration/... || travis_terminate 1;

after_success:
- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=coverage.out
Expand Down
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![IBM Cloud powered][img-ibmcloud-powered]][url-ibmcloud]
[![Travis][img-travis-master]][url-travis-master]
[![Coverage Status](https://coveralls.io/repos/github/ibm-cloud-security/app-identity-and-access-adapter/badge.svg?branch=master)](https://coveralls.io/github/ibm-cloud-security/app-identity-and-access-adapter?branch=master)

[![GithubWatch][img-github-watchers]][url-github-watchers]
[![GithubStars][img-github-stars]][url-github-stars]
Expand All @@ -13,7 +14,7 @@ By using the App Identity and Access adapter, you can centralize all of your ide

## Multicloud Architecture

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.
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-efficiency. To achieve the benefits, it's common to use a container-based applications with an orchestration layer, such as Kubernetes.

![App Identity and Access adapter architecture diagram](images/istio-adapter.png)
Figure. Multicloud deployment achieved with the App Identity and Access adapter.
Expand All @@ -24,7 +25,7 @@ Figure. Multicloud deployment achieved with the App Identity and Access adapter.

[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 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/).

### Protecting frontend apps

Expand All @@ -35,20 +36,17 @@ To view the user session information including the session tokens, you can look
```
Authorization: Bearer <access_token> <id_token>
```
{: 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.

```
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.
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 retrieve new tokens when the identity token expires.


### 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}"`.

Expand All @@ -70,7 +68,7 @@ Before you get started, be sure you have the following prerequisites installed.

- [Kubernetes Cluster](https://kubernetes.io/)
- [Helm](https://helm.sh/)
- [Istio v1.1](https://istio.io/docs/setup/kubernetes/install/)
- [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).
Expand All @@ -81,7 +79,7 @@ Before you get started, be sure you have the following prerequisites installed.

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're working with IBM Cloud Kubeneretes service, be sure to login and set the context for your cluter.
1. If you're working with IBM Cloud Kubeneretes service, be sure to login and set the context for your cluster.

2. Install Helm in your cluster.

Expand All @@ -94,9 +92,13 @@ To install the chart, initialize Helm in your cluster, define the options that y
3. Install the chart.

```bash
helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter
$ helm repo add appidentityandaccessadapter https://raw.githubusercontent.com/ibm-cloud-security/app-identity-and-access-adapter/master/helm/appidentityandaccessadapter
$ helm install --name appidentityandaccessadapter appidentityandaccessadapter/appidentityandaccessadapter
```

>>Helm lets you specify an image tag during installation with the set image.tag flag. For example, `helm install --name appidentityandaccessadapter appidentityandaccessadapter/appidentityandaccessadapter --set image.tag=0.4.0`

>>The chart can also be installed locally. First clone this repo by `git clone [email protected]:ibm-cloud-security/app-identity-and-access-adapter.git`, then install the chart `helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter`.

## Applying an authorization and authentication policy

Expand Down Expand Up @@ -220,8 +222,8 @@ spec:
| 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`. |
| `match` | enum | no | The criteria required for claim validation. Options include: `ALL`, `ANY` or `NOT`. The default is set to `ALL`. |
| `source` | enum | no | The token where you want to apply the rule. Options include: `access_token` or `id_token`. The default is set to `access_token`. |
| `values` | array[string] | yes | The required set of values for validation. |
Expand All @@ -246,25 +248,24 @@ For more information about getting support, see [how do I get the support that I


### 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` visibility 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).

>>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 `ibmcloudappid` pod from the Kubernetes console.
To see the adapter logs, you can use `kubectl` or access the pod from the `appidentityandaccessadapter` pod from the Kubernetes console.
```bash
$ alias adapter_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=ibmcloudappid -o jsonpath='{.items[0].metadata.name}')"
$ alias adapter_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=appidentityandaccessadapter -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 receive 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"
Expand Down
10 changes: 6 additions & 4 deletions adapter/authserver/authserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package authserver

import (
"errors"
"github.com/ibm-cloud-security/app-identity-and-access-adapter/adapter/authserver/keyset"
"github.com/ibm-cloud-security/app-identity-and-access-adapter/adapter/networking"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ibm-cloud-security/app-identity-and-access-adapter/adapter/authserver/keyset"
"github.com/ibm-cloud-security/app-identity-and-access-adapter/adapter/networking"
)

const (
Expand Down
6 changes: 4 additions & 2 deletions adapter/client/client_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package client

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/ibm-cloud-security/app-identity-and-access-adapter/adapter/pkg/apis/policies/v1"
"github.com/ibm-cloud-security/app-identity-and-access-adapter/tests/fake"
"github.com/stretchr/testify/assert"
"testing"
)

func TestClientNew(t *testing.T) {
Expand Down
11 changes: 4 additions & 7 deletions bin/ibmcloud_login.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
#

## Cluster Information
region="us-south"
dataCenter="dal10"
clusterName="appid-istio-dev-dal10"

# Adapter information
adapterName="appidentityandaccessadapter"
Expand All @@ -39,18 +36,18 @@ function checkEnv() {

function configureCluster() {
echo "Logging into IBM Cloud."
ibmcloud login -r ${region} --apikey ${IBM_CLOUD_API_KEY}
ibmcloud login -r ${REGION} --apikey ${IBM_CLOUD_API_KEY}


ibmcloud ks cluster-config --cluster ${clusterName}
ibmcloud ks cluster-config --cluster ${CLUSTER_NAME}

local homeDir="home"
if [[ -z ${TRAVIS+x} ]]; then
homeDir="Users"
fi

echo "Exporting KUBECONFIG=/${homeDir}/${USER}/.bluemix/plugins/container-service/clusters/${clusterName}/kube-config-${dataCenter}-${clusterName}.yml"
export KUBECONFIG=/${homeDir}/${USER}/.bluemix/plugins/container-service/clusters/${clusterName}/kube-config-${dataCenter}-${clusterName}.yml
echo "Exporting KUBECONFIG=/${homeDir}/${USER}/.bluemix/plugins/container-service/clusters/${CLUSTER_NAME}/kube-config-${DATA_CENTER}-${CLUSTER_NAME}.yml"
export KUBECONFIG=/${homeDir}/${USER}/.bluemix/plugins/container-service/clusters/${CLUSTER_NAME}/kube-config-${DATA_CENTER}-${CLUSTER_NAME}.yml
}

# Execute
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ require (
istio.io/api v0.0.0-20190515205759-982e5c3888c6
istio.io/istio v0.0.0-20190516081059-beb17827e164
k8s.io/api v0.0.0-20190612125737-db0771252981
k8s.io/apiextensions-apiserver v0.0.0-20190221221350-bfb440be4b87
k8s.io/apimachinery v0.0.0-20190612125636-6a5db36e93ad
k8s.io/client-go v10.0.0+incompatible
k8s.io/code-generator v0.0.0-20190612125529-c522cb6c26aa
Expand Down
3 changes: 1 addition & 2 deletions helm/appidentityandaccessadapter/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
apiVersion: v1
name: appidentityandaccessadapter
namespace: istio-system
version: 0.1.0
version: 0.4.0
description: A Helm chart for the App Identity and Access Adapter
appVersion: "1.0"
Binary file not shown.
12 changes: 12 additions & 0 deletions helm/appidentityandaccessadapter/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
entries:
appidentityandaccessadapter:
- apiVersion: v1
created: "2019-07-11T11:20:28.607495-05:00"
description: A Helm chart for the App Identity and Access Adapter
digest: e01cbc4df68ce945fcfbd382a931a987e4c24a588a8ac63a816719d68ea9b5d3
name: appidentityandaccessadapter
urls:
- appidentityandaccessadapter-0.4.0.tgz
version: 0.4.0
generated: "2019-07-11T11:20:28.600058-05:00"
6 changes: 5 additions & 1 deletion samples/app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
## Configure and Deploy

1. Enure your kubectl environment to use your second cluster 
```bash
$ kubectl label namespace sample-app istio-injection=enabled
```

2. Inject the Istio sidecar into your deployment

```
```bash
$ istioctl kube-inject -f ./sample-app.yaml | kubectl apply -f -
```
1 change: 1 addition & 0 deletions samples/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ app.get('/', (req, res) => {
routes: [
"/web/home",
"/web/home/:id",
"/web/user",
"/api/headers",
"/api/headers/:id",
]
Expand Down
4 changes: 2 additions & 2 deletions samples/app/cicd.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
APP_NAME=demo
APP_NAME=app-identity-and-access-adapter-sample-app
APP_VERSION=latest
IMAGE_REGISTRY_NAMESPACE=ishangulhane
IMAGE_REGISTRY_NAMESPACE=ibmcloudsecurity
IMAGE_TAG=${IMAGE_REGISTRY_NAMESPACE}/${APP_NAME}:${APP_VERSION}

IMAGE_TAG=${IMAGE_REGISTRY_NAMESPACE}/${APP_NAME}:${APP_VERSION}
Expand Down
2 changes: 1 addition & 1 deletion samples/app/sample-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ spec:
spec:
containers:
- name: sample-app
image: ishangulhane/demo:latest
image: ibmcloudsecurity/app-identity-and-access-adapter-sample-app:latest
imagePullPolicy: Always
ports:
- containerPort: 8000
Expand Down
28 changes: 15 additions & 13 deletions tests/framework/appid.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ const (
applicationFormEncoded = "application/x-www-form-urlencoded"
contentType = "Content-Type"
setCookie = "set-cookie"
facebookStateID = "#facebook_state"
samlStateID = "#SAML_State"
widgetURLID = "#widgetUrl"
stateID = "#cd_form .form-group"
)

// AppIDManager models the authorization server
Expand Down Expand Up @@ -135,17 +134,16 @@ func (m *AppIDManager) ROP(username string, password string) error {
return nil
}

///
/// App ID utility request functions to handle OIDC flow without UI
/// Redirect cannot be used as cookies will not be automatically set
///
//
// App ID utility request functions to handle OIDC flow without UI
// Redirect cannot be used as cookies will not be automatically set
//

func (m *AppIDManager) initialRequestToFrontend(t *testing.T, path string) (adapterState *http.Cookie, appIDState string, widgetURL string) {

// Make request to the frontend
req, err := http.NewRequest("GET", path, nil)
require.NoError(t, err)

res, err := m.client.Do(req)
require.NoError(t, err)

Expand All @@ -162,7 +160,6 @@ func (m *AppIDManager) initialRequestToFrontend(t *testing.T, path string) (adap

url2, err := res.Location()
require.NoError(t, err)

// Follow the redirect to the authorization server
redirectRes, err := http.DefaultClient.Get(url2.String()) // Use default to allow redirect
require.NoError(t, err)
Expand All @@ -174,12 +171,17 @@ func (m *AppIDManager) initialRequestToFrontend(t *testing.T, path string) (adap

// Parse login page
doc, err := goquery.NewDocumentFromReader(redirectRes.Body)
state, ok := doc.Find(facebookStateID).Attr("value")
if !ok || state == "" {
state, ok = doc.Find(samlStateID).Attr("value")
}
var state string
doc.Find(stateID).Each(func(i int, s *goquery.Selection) {
_ = s.Find("input").Each(func(i int, q *goquery.Selection) {
name, _ := q.Attr("name")
value,_ := q.Attr("value")
if name == "state" {
state = value
}
})
})
widgetUrl, okW := doc.Find(widgetURLID).Attr("value")
require.True(t, ok)
require.True(t, okW)
return stateCookie, state, widgetUrl
}
Expand Down
3 changes: 2 additions & 1 deletion tests/framework/crd_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package framework

import (
"fmt"
"github.com/ibm-cloud-security/app-identity-and-access-adapter/tests/framework/utils"
"math/rand"
"os"
"strings"
"text/template"

"github.com/ibm-cloud-security/app-identity-and-access-adapter/tests/framework/utils"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion tests/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (s *Suite) run() (errLevel int) {
fmt.Printf("Cleanup failed %v\n", err)
}

return 0
return errLevel
}

func (s *Suite) runModifierFns(ctx *Context, fns []ModifierFn) (err error) {
Expand Down
Loading

0 comments on commit 5706774

Please sign in to comment.