> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/cka/10_ingress_basic_auth.md).

# Ingress: Basic Auth

We can secure our ingres setup by adding basic auth.

## Create Basic Auth Secret

First we need to create basic auth file using `htpasswd`. It will ask for a password and confirmation password, then write the credential to file `auth`.

```bash
➜ htpasswd -c auth admin
New password: 
Re-type new password: 
Adding password for user admin
```

Then we create a `secret` to store the basic auth credential. This command below will read the `auth` file and create a secret named `ingress-auth`.

```bash
➜ kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
```

We can see and validate the secret we just create using this command below.

```bash
➜ kubectl get secret ingress-auth -o yaml
```

That will output a yaml format for our `ingress-auth` secret.

```yaml
apiVersion: v1
data:
  auth: YWRtaW46JGFwcjEkNXo0b1kvY2wkSEVlRFhaam1jSWkvSkF1V0o1L25BMQo=
kind: Secret
metadata:
  creationTimestamp: "2025-02-02T09:36:06Z"
  name: ingress-auth
  namespace: default
  resourceVersion: "933788"
  uid: 09bf23ec-625a-434b-b39a-4dc528a57b2b
type: Opaque
```

## Configure Ingress

Now with the secret ready we need to configure our ingress. Add this annotations below.

```yaml
nginx.ingress.kubernetes.io/auth-type: "basic"
nginx.ingress.kubernetes.io/auth-secret: "ingress-auth"
nginx.ingress.kubernetes.io/auth-realm: "Restricted Area"
```

`nginx.ingress.kubernetes.io/auth-type`: type of authentication, either `basic` or `digest`.

`nginx.ingress.kubernetes.io/auth-secret`: the name of secret object that contains username and password that we just created. This annotations also support secret reference in other namespace `"namespace/secret_name"`.

`nginx.ingress.kubernetes.io/auth-realm`: message to display with an appropriate context why the authentication is required.

Lets apply the changes and test using `curl`. First test without any username password.

```bash
curl --resolve "simple-go.mine:443:127.0.0.1" -i -k https://simple-go.mine
```

```html
HTTP/2 401 
date: Sun, 02 Feb 2025 09:52:43 GMT
content-type: text/html
content-length: 172
www-authenticate: Basic realm="Restricted Area"

<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
```

We got error `401 Authorization Required` for any request without basic auth credentials. We can also see the realm message in the response header.

Next lets test with added basic auth using `-u admin`. The curl command will ask for password, put the correct password and we should see the ok response.

```bash
curl --resolve "simple-go.mine:443:127.0.0.1" -i -k -u admin https://simple-go.mine
Enter host password for user 'admin':
```

```json
HTTP/2 200 
date: Sun, 02 Feb 2025 09:53:06 GMT
content-type: text/plain; charset=utf-8
content-length: 65

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
```

You can try what happened if you put wrong password.

## References

* <https://kubernetes.github.io/ingress-nginx/examples/auth/basic/>
* <https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#authentication>
* <https://httpd.apache.org/docs/2.4/programs/htpasswd.html>
