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.

API keys in Gloo Mesh Gateway

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

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

Internally, Gloo Mesh 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 Mesh Gateway adds the user identity to the request as a header, x-user-id by default. Gloo Mesh Gateway can use this header in subsequent filters. Note that for security purposes, Gloo Mesh Gateway sanitizes the header from the response before the response leaves the gateway proxy.

Before you begin

  1. Set up Gloo Mesh Gateway in a single cluster.
  2. Install Bookinfo and other 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.

      kubectl get pods -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.

  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. 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
      
  3. Create an external auth server to use for your policy. The following example refers directly to the default Gloo Mesh Gateway external auth service, but you can also use a virtual destination instead. For more information, see External auth server setup.

      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
    EOF
      
  4. Create an external auth policy that uses the API key.

      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.

    SettingDescription
    applyToRoutesUse 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.
    serverThe external auth server to use for the policy.
    apiKeyAuthConfigure the API key authentication details.
    headerNameThe header that the Gloo Mesh Gateway external auth server looks at to get the API key. If not set, the default api-key header name is used.
    k8sSecretApikeyStorageThe 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 app without authorization. Now, the request is blocked with a 401 response.

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

    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 another request to the app, this time with a header that has your API key data.

    • HTTP:
        curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1 -H "api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy"
        
    • HTTPS:
        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}}
      

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl  -n bookinfo delete Secret user-id-12345
kubectl  -n bookinfo delete ExtAuthPolicy ratings-apikey
kubectl  -n bookinfo delete ExtAuthServer ext-auth-server