API keys

Authenticate requests by using an API key.

This feature is available with a Gloo Gateway license only.

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:

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.

How API keys work with Gloo Gateway

To secure your services with API keys, first provide Gloo Gateway 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.

Gloo Gateway 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 Gateway denies the request and returns a 401 response.

Internally, Gloo Gateway 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 Gateway adds the user identity to the request as a header, x-user-id by default. Gloo Gateway can use this header in subsequent filters. For security purposes, Gloo Gateway 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, and that your Kubernetes context is set to the cluster you store your Gloo config in (typically the management cluster). If you have different names, make sure to update the sample configuration files in this guide.

Follow the getting started instructions to:

  1. Set up Gloo Gateway in a single cluster.

  2. Deploy sample apps.

  3. Configure an HTTP listener on your gateway and set up basic routing for the sample apps.

  4. Make sure that the external auth service is installed and running. If not, install the external auth service in your single or multicluster environment.

    kubectl get pods -A -l app=ext-auth-service
    
  5. Make sure that you have the following CLI tools, or something comparable:

    • base64 to encode strings.

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.
  1. 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.

  2. Encode the API key value so that you can store the API key in a Kubernetes secret. You can optionally encode other details that you want to pass in with the API key, such as a user ID and email address.

    echo -n N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy | base64
    echo -n user-id-12345 | base64
    echo -n user12345@email.com | base64
    

    Example output:

    TjJZd01ESXhaVEV0TkdVek5TMWpOemd6TFRSa1lqQXRZakUyWXpSa1pHVm1OamN5
    dXNlci1pZC0xMjM0NQ==
    dXNlcjEyMzQ1QGVtYWlsLmNvbQ==
    
  3. 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 -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: user-id-12345
      namespace: bookinfo
      labels:
        extauth: apikey
    type: extauth.solo.io/apikey
    data:
      api-key: TjJZd01ESXhaVEV0TkdVek5TMWpOemd6TFRSa1lqQXRZakUyWXpSa1pHVm1OamN5
      user-id: dXNlci1pZC0xMjM0NQ==
      user-email: dXNlcjEyMzQ1QGVtYWlsLmNvbQ==
    EOF
    
  4. Create an external auth server to use for your policy.

    kubectl apply -f - <<EOF
    apiVersion: admin.gloo.solo.io/v2
    kind: ExtAuthServer
    metadata:
      name: ext-auth-server
      namespace: bookinfo
    spec:
      destinationServer:
        port:
          number: 8083
        ref:
          cluster: $CLUSTER_NAME
          name: ext-auth-service
          namespace: gloo-mesh-addons
    EOF
    
  5. Create an external auth policy that uses the API key.

    When you create the policy with a destination selector, only Kubernetes services can be specified in the applyToDestination section. Gloo virtual destinations or Gloo external services are not supported.

    kubectl apply -f - <<EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: ExtAuthPolicy
    metadata:
      name: ratings-apikey
      namespace: bookinfo
      labels:
        route: ratings
    spec:
      applyToRoutes:
      - route:
          labels:
            route: ratings
      config:
        server:
          name: ext-auth-server
          namespace: bookinfo
          cluster: $CLUSTER_NAME
        glooAuth:
          configs:
          - apiKeyAuth:
              headerName: api-key
              headersFromMetadataEntry:
                x-user-email: 
                  name: user-email
              k8sSecretApikeyStorage:
                labelSelector:
                  extauth: apikey
    EOF
       

Review the following table to understand this configuration. For more information, see the API reference.

Setting Description
applyToRoutes Use labels to configure which routes to apply the policy to. This example label matches the app and route from the example route table that you apply separately. If omitted and you do not have another selector such as applyToDestinations, the policy applies to all routes in the workspace.
server The external auth server to use for the policy.
apiKeyAuth Configure the API key authentication details.
headerName The header that the Gloo Gateway external auth server looks at to get the API key. If not set, the default api-key header name is used.
headersFromMetadataEntry Additional headers from the secret metadata to add to the authenticated requests so that other external auth modules can perform additional validation checks. For example, you might configure the API key secret to include extra data such as the user email. The key in this field is the name of the header to add to the request. The value in this field is the key in the secret data field. That key's value is injected as the header value. In this example, Gloo Gateway adds an x-user-email header into authenticated requests, with the value of the user-email from the user-id-12345 secret (dXNlcjEyMzQ1QGVtYWlsLmNvbQ==) that other external auth modules can process, such as OPA. To find an example of combining API key and OPA to authenticate requests, see API key and OPA.
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

  1. Send a request to the ratings app without authorization. Now, the request is blocked with a 401 response.

    curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1
    
    curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1
    

    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
       
  2. Send the request again, this time with a header that contains your API key data.

    curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1 -H "api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy"
    
    curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1 -H "api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy"
    

    You can reach the ratings app again!

    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
    
  3. Optional: Clean up the resources that you created.

    kubectl -n bookinfo delete Secret user-id-12345
    kubectl -n bookinfo delete ExtAuthPolicy ratings-apikey
    kubectl -n bookinfo delete ExtAuthServer ext-auth-server