Skip to content

Commit

Permalink
Make authservice config as a Helm package. (#148)
Browse files Browse the repository at this point in the history
* Update authservice using external authz.

Signed-off-by: Jianfei Hu <[email protected]>

* revert envoyfilter change.

Signed-off-by: Jianfei Hu <[email protected]>

* remove push.

Signed-off-by: Jianfei Hu <[email protected]>

* example of beta authn,authz and separate service.

Signed-off-by: Jianfei Hu <[email protected]>

* Helm-ize authservice config.

Clarified some expectations on identity provider config and settings.
Setup instructions are simplified because of Helm.
Also provide config sample as standalone authservice.
The in-pod-container mode can be added later.

Signed-off-by: Jianfei Hu <[email protected]>
Signed-off-by: Jianfei Hu <[email protected]>

* remove auth.yaml and update readme.md

Signed-off-by: Jianfei Hu <[email protected]>
  • Loading branch information
Jianfei Hu authored Aug 16, 2021
1 parent 1bc4289 commit 2931c4c
Show file tree
Hide file tree
Showing 13 changed files with 435 additions and 24 deletions.
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
83 changes: 63 additions & 20 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
port: "10003"
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
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"
48 changes: 48 additions & 0 deletions bookinfo-example/authservice/templates/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# 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.
#

---
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": "{{ .Values.oidc.authorizationURI }}",
"token_uri": "{{ .Values.oidc.tokenURI }} ",
"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": "{{ .Values.oidc.clientID }}",
"client_secret": "{{ .Values.oidc.clientSecret }}",
"scopes": [],
"cookie_name_prefix": "productpage",
"id_token": {
"preamble": "Bearer",
"header": "Authorization"
},
"logout": {
"path": "/authservice_logout",
"redirect_uri": "https://localhost:8443/some/logout/path"
}
}
}
]
}
]
}
45 changes: 45 additions & 0 deletions bookinfo-example/authservice/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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
image: {{ .Values.authservice.image }}
imagePullPolicy: Always
ports:
- containerPort: 10003
volumeMounts:
- name: authservice-config # mount the volume containing the authservice ConfigMap
mountPath: /etc/authservice
---
apiVersion: v1
kind: Service
metadata:
name: authservice
# namespace: istio-system
labels:
app: authservice
spec:
ports:
- port: 10003
name: grpc
selector:
app: authservice
34 changes: 34 additions & 0 deletions bookinfo-example/authservice/templates/ext-authz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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-grpc
rules:
- to:
- operation:
notPaths: ["/public"] # enable all except /public paths.
---
# 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
71 changes: 71 additions & 0 deletions bookinfo-example/authservice/templates/gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# A simple example of a gateway for the bookinfo app.
#

---
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
---
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
---
# 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
13 changes: 13 additions & 0 deletions bookinfo-example/authservice/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
authservice:
# TODO(incfly): change to a proper project wide container registry.
image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1

oidc:
idpURL: https://account.google.com
authorizationURI: "https://accounts.google.com/o/oauth2/v2/auth"
tokenURI: "https://oauth2.googleapis.com/token"
clientID: your-client-id
clientSecret: your-client-secret
# JSON string containing the identity provider's public key for validating id token.
# jwks: "<>"

Loading

0 comments on commit 2931c4c

Please sign in to comment.