/istio-mixer-adapter

Apigee's Istio Mixer Adapter

Primary LanguageGoApache License 2.0Apache-2.0

Istio Apigee Adapter

CircleCI Go Report Card codecov.io

This is the source repository for Apigee's Istio Mixer Adapter. This allows users of Istio to incorporate Apigee Authentication, Authorization, and Analytics policies to protect and report through the Apigee UI.

To join the Apigee pre-release program for additional documentation and support, please contact: anchor-prega-support@google.com.


Installation and usage

Version note

The current release is based on Istio 0.8. The included sample files and instructions below will automatically install the correct Istio version for you onto Kubernetes. It is recommended that you install onto Kubernetes 1.9 or newer. See the Istio web page for more information.

Prerequisite: Apigee

You must have an Apigee Edge account. If you need one, you can create one here.

Download a Release

Istio Mixer Adapter releases can be found here.

Download the appropriate release package for your operating system and extract it. You should a file list similar to:

LICENSE
README.md
samples/apigee/authentication-policy.yaml
samples/apigee/definitions.yaml
samples/apigee/handler.yaml
samples/apigee/httpapispec.yaml
samples/apigee/rule.yaml
samples/istio/helloworld.yaml
samples/istio/istio-demo.yaml
samples/istio/istio-demo-auth.yaml
apigee-istio

apigee-istio (or apigee-istio.exe on Windows) is the Command Line Interface (CLI) for this project. You may add it to your PATH for quick access - or remember to specify the path for the commands below.

The yaml files in the samples/ directory contain the configuration for Istio and the adapter. We discuss these below.

Provision Apigee for Istio

The first thing you'll need to do is provision your Apigee environment to work with the Istio adapter. This will install a proxy, set up a certificate, and generate some credentials for you:

apigee-istio -u {your username} -p {your password} -o {your organization name} -e {your environment name} provision > samples/apigee/handler.yaml

Once it completes, check your samples/apigee/handler.yaml file. It should look like this (with different values):

# istio handler configuration for apigee adapter
# generated by apigee-istio provision on 2018-06-18 15:29:31
apiVersion: config.istio.io/v1alpha2
kind: apigee
metadata:
  name: apigee-handler
  namespace: istio-system
spec:
  apigee_base: https://istioservices.apigee.net/edgemicro
  customer_base: https://myorg-myenv.apigee.net/istio-auth
  org_name: myorg
  env_name: myenv
  key: 06a40b65005d03ea24c0d53de69ab795590b0c332526e97fed549471bdea00b9
  secret: 93550179f344150c6474956994e0943b3e93a3c90c64035f378dc05c98389633

Notes:

  • apigee-istio will automatically pick up the username and password from a .netrc file in your home directory if you have an entry for machine api.enterprise.apigee.com.
  • For Apigee Private Cloud (OPDK), you'll need to also specify your --managementBase in the command. In this case, the .netrc entry should match this host.

Install Istio with Apigee mixer

Be sure both your Kubernetes cluster and kubectl CLI are ready to use. Two sample Istio install files have been provided for you in the release as a convenience.

To install Istio without mutual TLS enabled between services, you can simply run:

 kubectl apply -f samples/istio/istio-demo.yaml

Or to install Istio with mutual TLS enabled, use:

kubectl apply -f samples/istio/istio-demo-auth.yaml

Note: The key difference between these files and the ones provided with Istio is simply that the pointer to the docker.io/istio/mixer docker image in the original files have been replaced with a custom build that includes the Apigee adapter.

You should soon be able to now see all the Istio components running in your Kubernetes cluster:

kubectl get pods -n istio-system

Be sure istio-pilot, istio-ingressgateway, istio-policy, istio-telemetry, and istio-citadel are running before continuing. More information on verifying the Istio installation is here.

Install a target service

Next, we'll install a simple Hello World service into the Istio mesh.

kubectl apply -f samples/istio/helloworld.yaml

You should be able to verify two instances are running:

kubectl get pods

And you should be able to access the service successfully:

curl http://${GATEWAY_URL}/hello

Note: If you don't know your GATEWAY_URL, you'll need to follow these instructions to set the INGRESS_IP and INGRESS_PORT variables. Then, your GATEWAY_URL can be set with:

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Configure Apigee Mixer in Istio

Now that Istio is running, it's time to add Apigee policies. Apply the Apigee configuration:

    kubectl apply -f samples/apigee/definitions.yaml
    kubectl apply -f samples/apigee/handler.yaml
    kubectl apply -f samples/apigee/rule.yaml

Once done, you should no longer be able to access your helloworld service. If you curl it:

curl http://${GATEWAY_URL}/hello

You should receive a permission denied error:

PERMISSION_DENIED:apigee-handler.apigee.istio-system:missing authentication

The service is now protected by Apigee. Great! But now you've locked yourself out without a key. If only you had credentials. Let's fix that.

Configure your policies on Apigee via an API Product

Create an API Product in your Apigee organization:

  • Give the API Product definition a name (helloworld is good).
  • Select your environment(s).
  • Set the Quota to 5 requests every 1 minute.
  • Add a Path with the +Custom Resource button. Set the path to /.
  • Save

Create a Developer - use any values you wish. Be creative!

Create an App:

  • Give your App a name (helloworld is good).
  • Select the Developer you just created above.
  • Add your API Product with the +Product button.
  • Save

Still on the App page, you should now see a Credentials section. Click the Show button under the Consumer Key heading. Copy that key!

Bind your Apigee API Product to your service

Now that you have a policy, there's just one more thing your need to do: Bind it to your Istio service.

apigee-istio -o {your organization name} -e {your environment name} bindings add helloworld.default.svc.cluster.local  helloworld

You should see something like this:

product helloworld is now bound to: helloworld.default.svc.cluster.local

By the way, a handy way to see all the policies bound to your services is using the bindings list command:

apigee-istio -o {your organization name} -e {your environment name} bindings list

Access helloworld with your key

Now you should now be able to access the helloworld service in Istio by passing that key you got
from your Apigee App above. Just send it as the value of the x-api-key header:

curl http://${GATEWAY_URL}/hello -H "x-api-key: {your consumer key}"

The call should now be successful. You're back in business and your authentication policy works!

Hit your Quota

Remember that Quota you set for 5 requests per minute? Let's max it out.

Make the same request you did above just a few more times:

curl http://${GATEWAY_URL}/hello -H "x-api-key: {your consumer key}"

If you're in a Unix shell, you can just use repeat:

repeat 10 curl http://${GATEWAY_URL}/hello -H "x-api-key: {your consumer key}"

Either way, you should see some successful calls... followed by failures that look like this:

RESOURCE_EXHAUSTED:apigee-handler.apigee.istio-system:quota exceeded 

Did you see mixed successes and failures? That's OK. The Quota system is designed to have very low latency for your requests, so it uses a cache that is eventually consistent with the remote server. Client requests don't wait for the server to respond and you could have inconsistent results for a second or two, but it will be worked out quickly and no clients have to wait in the meantime.

Bonus: Use JWT authentication instead of API Keys

Update the samples/apigee/authentication-policy.yaml file to set correct URLs for your environment:

origins:
- jwt:
    issuer: https://{your organization}-{your environment}.apigee.net/istio-auth/token
    jwks_uri: https://{your organization}-{your environment}.apigee.net/istio-auth/certs

The hostname (and ports) for these URLs should mirror what you used for customer_base config above (adjust as appropriate if you're using OPDK).

Now, apply your Istio authentication policy:

kubectl apply -f samples/apigee/authentication-policy.yaml

Now calls to helloworld (with or without the API Key):

curl http://${GATEWAY_URL}/hello

Should receive an auth error similar to:

Origin authentication failed.

We need a JWT token. So have apigee-istio get you a JWT token:

apigee-istio token create -o {your organization} -e {your environment} -i {your key} -s {your secret}

Or, you can do it yourself through the API:

curl https://{your organization}-{your environment}.apigee.net/istio-auth/token -d '{ "client_id":"{your key}", "client_secret":"your secret", "grant_type":"client_credentials" }' -H "Content-Type: application/json"

Now, try again with your newly minted JWT token:

curl http://${GATEWAY_URL}/hello -H "Authorization: Bearer {your jwt token}"

This call should now be successful.

Check your analytics

Head back to the Apigee Edge UI.

Click the Analyze in the menu on the left and check out some nifty analytics information.


To join the Apigee pre-release program for additional documentation and support, please contact: anchor-prega-support@google.com.