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.
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.
You must have an Apigee Edge account. If you need one, you can create one here.
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.
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 formachine 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.
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.
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
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.
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 every1
minute
. - Add a Path with the
+Custom Resource
button. Set the path to/
. - Save
Create a Developer - use any values you wish. Be creative!
- 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!
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
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!
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.
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.
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.