API keys
Authenticate requests by using an API key.
If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.
About API keys
API keys are secure, long-lived UUIDs that clients provide when they send a request to your service. You might use API keys in the following scenarios:
- You know the set of users that need access to your service. These users do not change often, or you have automation that easily generates or deletes the API key when the users do change.
- You want direct control over how the credentials are generated and expire.
When you use API keys, your services are only as secure as the API keys. Storing and rotating the API key securely is up to the user.
API keys in Gloo Mesh Enterprise
To secure your services with API keys, first provide Gloo Mesh Enterprise with your API keys in the form of Kubernetes secrets. Then in the external auth policy, you refer to the secrets in one of two ways.
- Specify a label selector that matches the label of one or more API key secrets. Labels are the more flexible, scalable approach.
- Refer to the name and namespace of each secret.
Gloo Mesh Enterprise matches a request to a route that is secured by the external auth policy. The request must have a valid API key in a header. You can configure the name of the expected header. If the header is missing, or the API key is invalid, Gloo Mesh Enterprise denies the request and returns a 401
response.
Internally, Gloo Mesh Enterprise maps API keys to user identities for all API keys in the system. The user identity for an API key is the name of the secret that has the API key. Gloo Mesh Enterprise adds the user identity to the request as a header, x-user-id
by default. Gloo Mesh Enterprise can use this header in subsequent filters. Note that for security purposes, Gloo Mesh Enterprise sanitizes the header from the response before the response leaves the gateway proxy.
Before you begin
This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started. If you have different names, make sure to update the sample configuration files in this guide.
Complete the multicluster getting started guide to set up the following testing environment.
- Three clusters along with environment variables for the clusters and their Kubernetes contexts.
- The Gloo
meshctl
CLI, along with other CLI tools such askubectl
andistioctl
. - The Gloo management server in the management cluster, and the Gloo agents in the workload clusters.
- Istio installed in the workload clusters.
- A simple Gloo workspace setup.
- Install Bookinfo and other sample apps.
Make sure that the external auth service is installed and running. If not, install the external auth service.
kubectl get pods --context $REMOTE_CONTEXT1 -A -l app=ext-auth-service
Configure an external auth policy with an API key
Create the external auth policy that uses API keys to verify identity.
You can do the following steps in a different order, depending on when you want the policy to take effect. For example, you might want the policy to always take effect as soon as the route is created. To do so, you can create the policy before you add the route to the route table.
From your API management tool such as Gloo Portal or Google Developer Portal, generate an API key to use for your app’s domain. For example, your key might be
N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy
.Store the encoded API key and any additional data as a Kubernetes secret in the workload cluster that you want to create the external auth policy in. Make sure to use a label so that you can select the secret later.
kubectl apply --context $REMOTE_CONTEXT1 -f - <<EOF apiVersion: v1 kind: Secret metadata: name: user-id-12345 namespace: bookinfo labels: extauth: apikey type: extauth.solo.io/apikey stringData: api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy user-id: user-id-12345 user-email: user12345@email.com EOF
Include any secret metadata instringData
that you want to use in additional validation checks. For example, this API key secret includes the user ID and email. Gloo Mesh Enterprise automatically forwards this metadata along with the API key in authenticated requests so that other external auth modules, such as OPA, can process them in validation checks. To find an example of combining API key and OPA to authenticate requests, see API key and OPA.Create an external auth server to use for your policy. The following example refers directly to the default Gloo Mesh Enterprise external auth service, but you can also use a virtual destination instead. For more information, see External auth server setup.
kubectl apply --context $REMOTE_CONTEXT1 -f - <<EOF apiVersion: admin.gloo.solo.io/v2 kind: ExtAuthServer metadata: name: ext-auth-server namespace: bookinfo spec: destinationServer: port: number: 8083 ref: cluster: $REMOTE_CLUSTER1 name: ext-auth-service namespace: gloo-mesh EOF
Create an external auth policy that uses the API key.
This policy currently does not support selecting VirtualDestinations as a destination.
kubectl --context $REMOTE_CONTEXT1 apply -f - <<EOF
apiVersion: security.policy.gloo.solo.io/v2
kind: ExtAuthPolicy
metadata:
name: ratings-apikey
namespace: bookinfo
spec:
applyToDestinations:
- selector:
labels:
app: ratings
config:
server:
name: ext-auth-server
namespace: bookinfo
cluster: $REMOTE_CLUSTER1
glooAuth:
configs:
- apiKeyAuth:
headerName: api-key
k8sSecretApikeyStorage:
labelSelector:
extauth: apikey
EOF
Review the following table to understand this configuration. For more information, see the API reference.
Setting | Description |
---|---|
applyToDestinations | Use labels to apply the policy to destinations. Destinations might be a Kubernetes service, VirtualDestination, or ExternalService (if supported by the policy). If you do not specify any destinations or routes, the policy applies to all destinations in the workspace by default. If you do not specify any destinations but you do specify a route, the policy applies to the route but to no destinations. |
server | The external auth server to use for the policy. |
apiKeyAuth | Configure the API key authentication details. |
headerName | The header that the Gloo Mesh Enterprise external auth server looks at to get the API key. If not set, the default api-key header name is used. |
k8sSecretApikeyStorage | The label to match the policy with valid API key secrets. Any secrets that match the label are selected and can be used to authenticate requests. The API key secrets must be in the same workspace as the external auth server. |
Verify the external auth API key policy
Send a request to the app without authorization. Now, the request is blocked with a 401 response. Create a temporary curl pod in the
bookinfo
namespace, so that you can test the app setup. You can also use this method in Kubernetes 1.23 or later, but an ephemeral container might be simpler.- Create the curl pod.
kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \ --image=curlimages/curl:7.73.0 --rm -- sh
- Send a request to the ratings app.
curl -v -H "api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy" http://ratings:9080/ratings/1
- Exit the temporary pod. The pod deletes itself.
exit
Example output:
> GET /posts/1 HTTP/1.1 > Host: foo > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 401 Unauthorized < www-authenticate: API key is missing or invalid < date: Mon, 07 Oct 2019 19:28:14 GMT < server: envoy < content-length: 0
- Create the curl pod.
Send another request to the app, this time with a header that has your API key data.
- Create the curl pod.
kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \ --image=curlimages/curl:7.73.0 --rm -- sh
- Send a request to the ratings app.
curl -v -H "api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy" http://ratings:9080/ratings/1
- Exit the temporary pod. The pod deletes itself.
exit
You can reach the ratings app again!
{"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
- Create the curl pod.
Cleanup
You can optionally remove the resources that you set up as part of this guide.
kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete Secret user-id-12345
kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete ExtAuthPolicy ratings-apikey
kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete ExtAuthServer ext-auth-server