Basic external auth policy

Authenticate requests with a basic dictionary of usernames and passwords.

Basic authentication sends encoded user credentials in a standard header within the request. Then, Gloo Gateway authenticates the request against a dictionary of usernames and passwords that are written in the external auth policy. If the credentials in the request header match the policy, the request is sent to the destination. If not, Gloo Gateway returns a 401 response.

You might use basic auth for testing environments, such as when you release a new API method or version to a small number of known users.

If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.

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 you have the following CLI tools, or something comparable:

    • htpasswd to generate hashed, salted passwords.
    • base64 to encode strings.
  5. 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
    

Configure basic external auth policies

You can apply a basic external auth policy at the route or destination level. For more information, see Applying policies.

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.

  1. Generate a salt and hashed password for your user credentials. The following example uses the htpasswd tool for a user named user.
    htpasswd -nbm user password
    

    Example output:

    user:$apr1$TYiryv0/$8BvzLUO9IfGPGGsPnAgSu1
    
  2. Retrieve the salt and hashed password from the output of the previous step.
    • Salt: TYiryv0/
    • Hashed password: 8BvzLUO9IfGPGGsPnAgSu1
  3. Review the following sample configuration file.
    apiVersion: security.policy.gloo.solo.io/v2
    kind: ExtAuthPolicy
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: basic-auth
      namespace: bookinfo
    spec:
      applyToRoutes:
      - {}
      - route:
          labels:
            route: ratings
      config:
        glooAuth:
          configs:
          - basicAuth:
              apr:
                users:
                  user:
                    hashedPassword: 8BvzLUO9IfGPGGsPnAgSu1
                    salt: TYiryv0/
        server:
          name: default-server
      

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

Setting Description
spec.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.
spec.config.glooAuth.configs.basicAuth Configure the basic auth credentials to use to authenticate requests. The example sets up user credentials for a user named user in the required APR1 format. For more information, see the API reference.
spec.config.glooAuth.configs.basicAuthapr.users.user.hashedPassword The hashed password that you generated in the previous step. The example sets 8BvzLUO9IfGPGGsPnAgSu1.
spec.config.glooAuth.configs.basicAuthapr.users.user.salt The salt, or random data that hashes the password, that you generated in the previous step. The example sets TYiryv0/.
server The ExtAuthServer resource that represents the server for the policy to use. In this example, only the name is specified. Gloo attempts to find the resource in the same namespace and cluster as the policy, or you can add namespace and cluster fields. To create an ExtAuthServer resource, see Set up the Gloo Gateway external auth server.

Apply external auth to external services

The following example is for an external auth policy that applies to an external service. Note that this policy requires different routing table and external auth server resources, as well as an external service.

apiVersion: security.policy.gloo.solo.io/v2
kind: ExtAuthPolicy
metadata:
  annotations:
    cluster.solo.io/cluster: ""
  name: httpbin-basic-auth
  namespace: bookinfo
spec:
  applyToRoutes:
  - route:
      labels:
        route: external-service
  config:
    glooAuth:
      configs:
      - basicAuth:
          apr:
            users:
              user:
                hashedPassword: 8BvzLUO9IfGPGGsPnAgSu1
                salt: TYiryv0/
    server:
      name: default-server
apiVersion: admin.gloo.solo.io/v2
kind: ExtAuthServer
metadata:
  annotations:
    cluster.solo.io/cluster: ""
  name: default-server
  namespace: bookinfo
spec:
  destinationServer:
    port:
      number: 8083
    ref:
      cluster: cluster-1
      name: ext-auth-service
      namespace: gloo-mesh-addons
apiVersion: networking.gloo.solo.io/v2
kind: ExternalService
metadata:
  annotations:
    cluster.solo.io/cluster: ""
  name: external-service
  namespace: bookinfo
spec:
  hosts:
  - httpbin.solo
  ports:
  - name: http
    number: 8080
    protocol: HTTP
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
  annotations:
    cluster.solo.io/cluster: ""
  name: external-service-northsouth
  namespace: bookinfo
spec:
  defaultDestination:
    kind: EXTERNAL_SERVICE
    port:
      number: 8080
    ref:
      name: external-service
      namespace: bookinfo
  hosts:
  - www.example.com
  http:
  - forwardTo: {}
    labels:
      "no": auth
    matchers:
    - headers:
      - name: noauth
        value: "true"
    name: external-service-no-auth
  - forwardTo: {}
    labels:
      route: external-service
    name: external-service-northsouth
  virtualGateways:
  - name: istio-ingressgateway

Verify basic external auth policies

  1. Apply the example basic external auth policy and server in the workload cluster.

    kubectl apply -f - << EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: ExtAuthPolicy
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: basic-auth
      namespace: bookinfo
    spec:
      applyToRoutes:
      - {}
      - route:
          labels:
            route: ratings
      config:
        glooAuth:
          configs:
          - basicAuth:
              apr:
                users:
                  user:
                    hashedPassword: 8BvzLUO9IfGPGGsPnAgSu1
                    salt: TYiryv0/
        server:
          name: default-server
    ---
    apiVersion: admin.gloo.solo.io/v2
    kind: ExtAuthServer
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: default-server
      namespace: bookinfo
    spec:
      destinationServer:
        port:
          number: 8083
        ref:
          cluster: cluster-1
          name: ext-auth-service
          namespace: gloo-mesh-addons
    EOF
       

  2. Send an unauthenticated request to the ratings app.

    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: Notice that the request is denied with a 401 Unauthorized response.

    HTTP/2 401
    
  3. Encode the expected user credentials in base64 format.

    echo -n "user:password" | base64
    

    Example output:

    dXNlcjpwYXNzd29yZA==
    
  4. Repeat the request to the ratings app, including the authorization header with the user credentials. This time, the request succeeds.

    curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1 -H "Authorization: basic dXNlcjpwYXNzd29yZA=="
    
    curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1 -H "Authorization: basic dXNlcjpwYXNzd29yZA=="
    

    Example output:

    HTTP/2 200
    
  5. Optional: Clean up the resources that you created.

    kubectl -n bookinfo delete ExtAuthPolicy basic-auth
    kubectl -n bookinfo delete ExtAuthServer default-server