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

  • 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 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. The extauth plugin that handles the API key flow is part of the AuthNStage stage. All filters after this stage have access to the user identity header. For example, this functionality is used in Gloo Gateway’s rate limiting API to provide different rate limits for anonymous vs. authorized users. Note that for security purposes, Gloo Gateway sanitizes the header from the response before the response leaves the gateway proxy.

Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. Get the external address of the gateway and save it in an environment variable.

Setup

  1. From your API management tool such as Gloo Portal, generate an API key to use for your app’s domain. For example, your key might be N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy.

  2. Create a Kubernetes secret to store your API key.

  3. Verify that the secret is created. Note that the data.api-key value is base64 encoded.

      kubectl get secret infra-apikey -n httpbin -oyaml
      

    Example output:

      apiVersion: v1
    kind: Secret
    metadata:
      name: infra-apikey
      namespace: httpbin
      labels:
        team: infrastructure
    type: extauth.solo.io/apikey
    data:
      api-key: TjJZd01ESXhaVEV0TkdVek5TMWpOemd6TFRSa1lqQXRZakUyWXpSa1pHVm1OamN5
      
  4. Create an AuthConfig resource and add your external authentication rules. The following example configures API key authentication. When a request comes in for a route that is secured by this AuthConfig, Gloo Gateway extracts the API key from the api-key request header. Then, it uses the Kubernetes secret with the label team: infrastructure to check if the API key in that Kubernetes secret matches the API key from the request.

      kubectl apply -f- <<EOF
    apiVersion: enterprise.gloo.solo.io/v1
    kind: AuthConfig
    metadata:
      name: apikey-auth
      namespace: httpbin
    spec:
      configs:
        - apiKeyAuth:
            # The request header name that holds the API key.
            # This field is optional and defaults to api-key if not present.
            headerName: api-key
            labelSelector:
              team: infrastructure
    EOF
      
  5. Create a RouteOption resource and reference the AuthConfig resource that you just created.

      kubectl apply -f- <<EOF
    apiVersion: gateway.solo.io/v1
    kind: RouteOption
    metadata:
      name: apikey-auth
      namespace: httpbin
    spec:
      options:
        extauth:
          configRef:
            name: apikey-auth
            namespace: httpbin
    EOF
      
  6. Create an HTTPRoute resource for the httpbin app that requires authentication for requests on the extauth.example domain.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: httpbin-apikey-auth
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: gloo-system
      hostnames:
        - extauth.example
      rules:
        - filters:
            - type: ExtensionRef
              extensionRef:
                group: gateway.solo.io
                kind: RouteOption
                name: apikey-auth
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
      
  7. Send a request to the httpbin app on the extauth.example domain without any API key. Verify that your request is denied and that you get back a 401 HTTP response code.

    Example output:

      * Mark bundle as not supporting multiuse
    < HTTP/1.1 401 Unauthorized
    < www-authenticate: Basic realm="gloo"
    < date: Fri, 19 Apr 2024 17:41:01 GMT
    < server: envoy
    < content-length: 0
      
  8. Send another request to the httpbin app. This time, you include the API key in the api-key header. Verify that the request succeeds and that you get back a 200 HTTP response code.

    Example output:

      * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < access-control-allow-credentials: true
    < access-control-allow-origin: *
    < date: Fri, 19 Apr 2024 17:44:06 GMT
    < content-length: 0
    < x-envoy-upstream-service-time: 0
    < server: envoy
      

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl delete authconfig apikey-auth -n httpbin
kubectl delete routeoption apikey-auth -n httpbin
kubectl delete httproute httpbin-apikey-auth -n httpbin
kubectl delete secret infra-apikey -n httpbin