Protect your APIs
Create external auth and rate limit policies to protect your APIs.
Previously, you set up a developer portal for your end users to discover your API products. Now, you protect your APIs by enforcing external auth and rate limiting policies. Together, these policies make up the usage plans for your API products. For more information, see About usage plans.
Before you begin
Complete the portal setup tutorial.
Complete the API product tutorial.
Optional: Complete the portal tutorial. You can also complete the portal tutorial after this tutorial, if you want to see the usage plans in the frontend portal.
Get the labels of your routes to use to apply policies to, such as with the example query.
kubectl get rt -n gloo-mesh-gateways -o=jsonpath='{range .items[*]}[{.metadata.name}, {.spec.http[*].name}, {.spec.http[*].labels}]{"\n"}{end}'Example output:
- The
api-example-com-rtroute table does not have any route-level labels. To apply policies, you can add labels to those routes. - The
petstore-rtroute table has ausagePlans: dev-portallabel on itspets-api,users-api, andstore-apiroutes. - The
tracks-rtroute table has ausagePlans: dev-portallabel on itstracks-apiroute.
[api-example-com-rt, , ] [petstore-rt, pets-api users-api store-api, {"usagePlans":"dev-portal"} {"usagePlans":"dev-portal"} {"usagePlans":"dev-portal"} ] [tracks-rt, tracks-api, {"usagePlans":"dev-portal"}]- The
Set up API key external auth
Require users to authenticate in requests to your API products. The following steps set up external authentication through API keys. The API keys are stored in Kubernetes secrets for simplicity. If you have a portal set up, your users can generate these API keys for themselves through the frontend portal. For more information about API keys, other backing storage options, or other external auth options such as OAuth, see the External auth for portal guide.
Step 1: Create the API key policy
To enforce external auth on the routes to your API products, create an external auth policy.
Select the external auth server to use. The example uses the default external auth server that you created when you installed Gloo Mesh Gateway.
kubectl apply -f - << EOF apiVersion: admin.gloo.solo.io/v2 kind: ExtAuthServer metadata: name: ext-auth-server namespace: gloo-mesh spec: destinationServer: ref: cluster: $CLUSTER_NAME name: ext-auth-service namespace: gloo-mesh port: name: grpc EOFCreate an API key external auth policy.
kubectl apply -f - << EOF apiVersion: security.policy.gloo.solo.io/v2 kind: ExtAuthPolicy metadata: name: api-key-auth namespace: default spec: applyToRoutes: - route: labels: usagePlans: dev-portal config: server: name: ext-auth-server namespace: gloo-mesh cluster: $CLUSTER_NAME glooAuth: configs: - apiKeyAuth: headerName: api-key k8sSecretApikeyStorage: labelSelector: extauth: apikey EOFFor more information, see the API docs.
Setting Description metadata.namespaceCreate the external auth policy in the same namespace or import it into the same Gloo workspace as the external auth server. In this example, the policy is in the default namespace. applyToRoutesApply the policy to the tracks-apiroute that you previously created in the API product’s route table. You apply policies by labels. Thetracks-apiroute has theusagePlans: dev-portallabel.config.serverSelect the external auth server that you configured in the previous step. headerNameSet the name of the header. In this example, requests must include the API key in the api-keyheader.k8sSecretApikeyStorageSelect the Kubernetes secret where the API key details are stored. This value is only required if you use local Kubernetes secrets for testing. If you configured the external auth server to use Redis as a backing database, omit this value. Verify that requests to your API now require external auth. The following request fails because you do not have the API key details stored in a local Kubernetes secret.
curl -v -H 'api-key: apikey1' --resolve api.example.com:80:${INGRESS_GW_ADDRESS} http://api.example.com/trackapi/tracksExample output:
< HTTP/1.1 401 Unauthorized < www-authenticate: API key is missing or invalid
Step 2: Verify authentication with an API key
Now that you applied an external auth policy to your routes, requests must include a valid API key in the X-Solo-Plan header. Gloo Mesh Gateway must be able to check the API keys in requests against valid API keys that are stored somewhere. In this example, you store the API key in a Kubernetes secret.
Create a Kubernetes secret with the details of your API key.
apikey1is the API key that you later include in the request header. You can choose any string value for your API key.user1is the user ID that must be included in the request metadata.user1@solo.iois the email for the user.goldis the name of a usage plan that matches the usage plans you set up as part of rate limiting.
kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: user1 namespace: default labels: extauth: apikey type: extauth.solo.io/apikey stringData: # apikey1 api-key: apikey1 # user1 user-id: user1 # user1@solo.io user-email: user1@solo.io # gold usagePlan: gold EOFVerify that the secret is created.
kubectl get secretRepeat the request with your API key details. Make sure to use the API key string value that you encoded earlier. The request now succeeds!
curl -v -H 'api-key: apikey1' --resolve api.example.com:80:${INGRESS_GW_ADDRESS} http://api.example.com/trackapi/tracksExample output:
< HTTP/1.1 200 OK ... [ { "id": "c_0", "thumbnail": "https://res.cloudinary.com/dety84pbu/image/upload/v1598465568/nebula_cat_djkt9r.jpg", "topic": "Cat-stronomy", "authorId": "cat-1", "title": "Cat-stronomy, an introduction", "description": "Curious to learn what Cat-stronomy is all about? Explore the planetary and celestial alignments and how they have affected our space missions.", "numberOfViews": 163, "createdAt": "2018-09-10T07:13:53.020Z", "length": 2377, "modulesCount": 10, "modules": [ "l_0", "l_1", "l_2", "l_3", "l_4", "l_5", "l_6", "l_7", "l_8", "l_9" ] }, ...
Set up rate limiting
Control how many requests within a time period are allowed to your API products, such as 100 requests per minute. The rate limits form a key part of the usage plan for your API products. For more information about rate limiting or for other options such as dynamic rate limiting, see the Rate limiting for portal guide.
Select the rate limiting server to use. The example uses the default rate limiting server that you created when you installed Gloo Mesh Gateway. For more information, see Rate limit server settings.
kubectl apply -f - << EOF apiVersion: admin.gloo.solo.io/v2 kind: RateLimitServerSettings metadata: name: rl-server namespace: gloo-mesh labels: portal: rate-limit spec: destinationServer: port: name: grpc ref: cluster: $CLUSTER_NAME name: rate-limiter namespace: gloo-mesh EOFSet up the rate limit client config to define the
usagePlandescriptor key and extract details from thex-solo-planheader that is set up in your matching external auth policy. The configuration varies depending on the type of external auth policy that you applied: API key or OAuth. For more information, see Rate limit client config.kubectl apply -f - <<EOF apiVersion: trafficcontrol.policy.gloo.solo.io/v2 kind: RateLimitClientConfig metadata: name: usage-plans namespace: gloo-mesh labels: portal: rate-limit spec: raw: rateLimits: - setActions: - requestHeaders: descriptorKey: usagePlan headerName: x-solo-plan - metadata: descriptorKey: userId metadataKey: key: envoy.filters.http.ext_authz path: - key: userId EOFUse the RateLimitServerConfig to define the values of the descriptors that are the usage plan names, that match the
usagePlandescriptor key that you configured in the RateLimitClientConfig. TheuserIdandusagePlandetails are extracted from the API key details in the request header that is required by the API key external auth policy. The following rate limit server config example creates three usage plans as follows:- Bronze: Requests to your APIs are limited to 1 per minute.
- Silver: Requests to your APIs are limited to 3 per minute.
- Gold: Requests to your APIs are limited to 5 per minute.
For more information, see Rate limit server config.
kubectl apply -f - << EOF apiVersion: admin.gloo.solo.io/v2 kind: RateLimitServerConfig metadata: name: usage-plans namespace: gloo-mesh labels: portal: rate-limit spec: destinationServers: - port: name: grpc ref: cluster: $CLUSTER_NAME name: rate-limiter namespace: gloo-mesh raw: setDescriptors: - simpleDescriptors: - key: userId - key: usagePlan value: bronze rateLimit: requestsPerUnit: 1 unit: MINUTE - simpleDescriptors: - key: userId - key: usagePlan value: silver rateLimit: requestsPerUnit: 3 unit: MINUTE - simpleDescriptors: - key: userId - key: usagePlan value: gold rateLimit: requestsPerUnit: 5 unit: MINUTE EOFApply the rate limit policy to the
tracks-apiroute that you previously created in the API product’s route table. You apply policies by labels. Thetracks-apiroute has theusagePlans: dev-portallabel.kubectl apply -f - << EOF apiVersion: trafficcontrol.policy.gloo.solo.io/v2 kind: RateLimitPolicy metadata: name: tracks-rate-limit namespace: default labels: portal: rate-limit spec: applyToRoutes: - route: labels: usagePlans: dev-portal config: ratelimitServerConfig: name: usage-plans namespace: gloo-mesh cluster: $CLUSTER_NAME ratelimitClientConfig: name: usage-plans namespace: gloo-mesh cluster: $CLUSTER_NAME serverSettings: name: rl-server namespace: gloo-mesh cluster: $CLUSTER_NAME phase: postAuthz: priority: 1 EOFVerify that your rate limiting is in place by repeating the following request 6 times in a row. Because your user ID is limited to the
goldusage plan’s limit of 5 requests per minute, the sixth time your request is blocked. Note that this step requires you to have set up API key external auth already.curl -v -H 'api-key: apikey1' --resolve api.example.com:80:${INGRESS_GW_ADDRESS} http://api.example.com/trackapi/tracksExample output:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true
Next steps
Good job! Now, your APIs are secured by external auth and rate limit policies. Together, you can think of these policies as the usage plan for the API products in your developer portal.
Next, Secure access to the portal by requiring users to log in through an OpenID Connect (OIDC) provider.