Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make authservice config as a Helm package. #148

Merged
merged 7 commits into from
Aug 16, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bookinfo-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
key.pem
cert.pem
81 changes: 62 additions & 19 deletions bookinfo-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,85 @@ This doc shows how to integrate Authservice into an Istio system deployed on Kub

This demo uses the [Istio Bookinfo sample application](https://istio.io/docs/examples/bookinfo/).

This demo takes advantage of an Istio feature set that gives the ability to inject http filters on
Sidecars. This feature set was released in Istio 1.3.0.
This demo takes relies on Istio [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/), released since 1.9.

Things needed before starting:

- A Kubernetes cluster that is compatible with Istio 1.3 or newer
- An OIDC provider configured to support Authorization Code grant type. The urls and credentials for this
provider will be needed to configure Authservice.

### Pre-requisites:

1. Download Istio 1.9 or greater. For example:
1. Prepare your OIDC provider configuration. In our example, we use Google as identity provider.
Follow [instructions](https://developers.google.com/identity/protocols/oauth2/openid-connect) to
create one.

[`scripts/download-istio-1.4.sh`](scripts/download-istio-1.4.sh)
```shell
export OIDC_CLIENT_ID="<your-client-id>"
export OIDC_CLIENT_SECRET="<your-client-secret>"
```

1. Install Istio and enable sidecar injection for the namespace where services will be deployed. For example,
one could install the Istio demo like this:
1. Install Istio 1.9 or later.

[`scripts/install-istio.sh`](scripts/install-istio.sh)

1. If certs signed by a known CA cannot be obtained, generate self signed certs for the ingress gateway. For example:
```shell
istioctl install -y
kubectl label namespace default istio-injection=enabled --overwrite
```

[`scripts/generate-self-signed-certs-for-ingress-gateway.sh`](scripts/generate-self-signed-certs-for-ingress-gateway.sh)
1. In our example, we use a self signed certificate at localhost for easy setup.
This is used to terminate HTTPS at the ingress gateway since OIDC requires client callback
URI to be hosted on a protected endpoint.

1. Configure the Istio mesh config with an [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/) as `sample-ext-authz-grpc`.
```shell
bash ./scripts/generate-self-signed-certs-for-ingress-gateway.sh
```

1. Configure the Istio mesh config with an [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/).

```shell
kubectl edit cm -n istio-system
```

Change the mesh config with the config below.

```yaml
data:
mesh: |-
extensionProviders:
- name: "sample-ext-authz-grpc"
- name: "authservice-grpc"
envoyExtAuthzGrpc:
service: ext.authz.local
service: authservice.default.svc.cluster.local
port: "10003"
```

1. Install authservice via Helm.

```shell
helm template authservice \
--set oidc.clientID=${OIDC_CLIENT_ID} \
--set oidc.clientSecret=${OIDC_CLIENT_SECRET} \
| kubectl apply -f -
```

1. Access product page via port-forwarding at local host.

```shell
kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
```

At your browser visit the page at https://localhost:8443/productpage.

### Further Protect via RequestAuthentication and Authorization Policy

Istio native RequestAuthentication and Authorization policy can be used configure which end user
can access specific apps, at specific paths. For example, you can apply the sample configuration
to only allow authenticated request to access productpage service.

```shell
kubectl apply -f ./config/productpage-authn-authz.yaml
```

## Configure OIDC flow at Ingress Gateway

TODO(incfly): write it up with sample config and setup.

## :warning: The REST documnetation needs updates.

## Deploy Bookinfo Using the Authservice for Token Acquisition (Sidecar integration)

The goal of these steps is the protect the `productpage` service with OIDC authentication provided by the mesh.
Expand Down
211 changes: 211 additions & 0 deletions bookinfo-example/auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
# Source: authservice/templates/config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: authservice
data:
config.json: |
{
"listen_address": "127.0.0.1",
"listen_port": "10003",
"log_level": "trace",
"threads": 8,
"chains": [
{
"name": "idp_filter_chain",
"filters": [
{
"oidc":
{
"authorization_uri": "https://accounts.google.com/o/oauth2/v2/auth",
"token_uri": "https://oauth2.googleapis.com/token ",
"callback_uri": "https://localhost:8443/productpage/oauth/callback",
"jwks": "{ \"keys\": [ { \"use\": \"sig\", \"alg\": \"RS256\", \"n\": \"7qnlkR2Ysvik__jqELu5__2Ib4_Pix6NEmEYKY80NyIGBhUQ0QDtijFypOk3cN3aRgb1f3741vQu7PQGMr79J8jM4-sA1A6UQNmfjl-thB5JpdfQrS1n3EpsrPMUvf5w-uBMQnxmiM3hrHgjA107-UxLF_xBG8Vp_EXmZI7y6IfUwTHrNotSpLLBSNH77C8ncFcm9ADsdl-Bav2CjOaef6CpGISCscx2T4LZS6DIafU1M_xYcx3aLET9TojymjZJi2hfZDyF9x_qssrlnxqfgrI71warY8HiXsiZzOTNB6s81Fu9AaxV7YckfLHyvXwOX8lQN53c2IiAuk-T7nf69w\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"kid\": \"0fcc014f22934e47480daf107a340c22bd262b6c\" }, { \"alg\": \"RS256\", \"e\": \"AQAB\", \"kid\": \"462949174f1eedf4f9f9434877be483b324140f5\", \"kty\": \"RSA\", \"n\": \"2BHFUUq8NqZ3pxxi_RJcSIMG5nJoZQ8Nbvf-lW5o7hJ9CmLA4SeUmDL2IVK6CSuskTPj_ohAp_gtOg3PCJvn33grPoJQu38MoMB8kDqA4U-u3A86GGEjWtk6LPo7dEkojZNQkzhZCnEMTuRMtBZXsLWNGJpY3UADA3rxnHnBP1wrSt27iXIE0C6-1N5z00R13r3L0aWC0MuAUgjI2H4dGMr8B3niJ-NjOVPCwG7xSWsCwsSitAuhPGHaDtenB23ZsFJjbuTuiguoSJ9A1qo9kzBOg32xda4derbWasu7Tk8p53PFxXDJGR_h7dM-nsJHl7lAUDqL8zOrf9XXlPTjwQ\", \"use\": \"sig\" } ] }",
"client_id": "159575789034-27l81afqk927eg7urur2etntg91rv8on.apps.googleusercontent.com",
"client_secret": "5GHnk4Fs94x13Oif4hKhYV2d",
incfly marked this conversation as resolved.
Show resolved Hide resolved
"scopes": [],
"cookie_name_prefix": "productpage",
"id_token": {
"preamble": "Bearer",
"header": "Authorization"
},
"logout": {
"path": "/authservice_logout",
"redirect_uri": "https://localhost:8443/some/logout/path"
}
}
}
]
}
]
}
---
# Source: authservice/templates/deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: authservice
# namespace: istio-system
labels:
app: authservice
spec:
ports:
- port: 10003
name: grpc
selector:
app: authservice
---
# Source: authservice/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: authservice
# TODO(incfly): change to istio-system when the config map is also updated to that namespace.
# namespace: istio-system
labels:
app: authservice
spec:
replicas: 1 # you can scale up productpage as long as session affinity is enabled via a DestinationRule (see ./config/bookinfo-gateway.yaml)
selector:
matchLabels:
app: authservice
template:
metadata:
labels:
app: authservice
spec:
volumes:
- name: authservice-config # declare the volume containing the authservice ConfigMap
configMap:
name: authservice
containers:
- name: authservice # authservice needs to be deployed in the sample Pod as the productpage
# TODO(incfly): change to a proper project wide container registry.
image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870)
imagePullPolicy: Always
ports:
- containerPort: 10003
volumeMounts:
- name: authservice-config # mount the volume containing the authservice ConfigMap
mountPath: /etc/authservice
---
# Source: authservice/templates/config.yaml
#
# A ConfigMap which contains the configuration of the authservice.
# In bookinfo-with-authservice-template.yaml the authservice container is created
# with this ConfigMap volume mounted inside the container at /etc/authservice, which
# is the location where the authservice expects the file to exist.
#
---
# Source: authservice/templates/gateway.yaml
#
# A simple example of a gateway for the bookinfo app.
#
---
# Source: authservice/templates/ext-authz.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ext-authz
spec:
selector:
matchLabels:
app: productpage
action: CUSTOM
provider:
# The provider name must match the extension provider defined in the mesh config.
name: authservice.default.svc.cluster.local
rules:
- to:
- operation:
notPaths: ["/public"] # enable all except /public paths.
---
# Source: authservice/templates/gateway.yaml
# Add a DestinationRule to enable session affinity, which ensures that the requests from the same user-agent reach
# the same instance of productpage, and hence, the same instance of Sidecar and Authservice. This is required when you
# deploy multiple instances of productpage because Authservice currently only supports in-memory session storage.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo-dest-rule
spec:
host: productpage.default.svc.cluster.local
trafficPolicy:
loadBalancer:
consistentHash:
httpCookie:
name: bookinfo-session-affinity-cookie
ttl: 0s
---
# Source: authservice/templates/gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https-443
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
credentialName: ingress-tls-cert
---
# Source: authservice/templates/ext-authz.yaml
# TODO(incfly): enable if else check for including this only for sidecar mode.
# Istio requires the external authz provider to be available in the service registry.
# See https://github.com/istio/istio/issues/34622.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: authz-svc
spec:
hosts:
- ext.authz.local # not used
ports:
- number: 10003
name: grpc-ext
protocol: grpc
resolution: STATIC
endpoints:
- address: 127.0.0.1
---
# Source: authservice/templates/gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
# Allow the Authentication Request Callback to get routed to productpage so it can be intercepted by the authservice
prefix: /productpage/oauth
- uri:
# Allow the authservice logout request to get routed to productpage so it can be intercepted by the authservice
exact: /authservice_logout
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/
route:
- destination:
host: productpage
port:
number: 9080
23 changes: 23 additions & 0 deletions bookinfo-example/authservice/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
24 changes: 24 additions & 0 deletions bookinfo-example/authservice/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: authservice
description: A Helm chart for Istio Authservice.

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.4.1"
Loading