# Deploy a Policy for access control




This topic describes how to use F5 NGINX Ingress Controller to apply and update a Policy for access control. You can use access control policies with [VirtualServer custom resources](/nic/configuration/virtualserver-and-virtualserverroute-resources.md) or with [Ingress resources](/nic/configuration/ingress-resources/basic-configuration.md) using the `nginx.org/policies` annotation.

---

## Before you begin

You should have a [working NGINX Ingress Controller](/nic/install/helm.md) instance.

For ease of use in shell commands, set the following shell variables:

1. The public IP address for your NGINX Ingress Controller instance.

```shell
IC_IP=<ip-address>
```

2. The HTTP port of the same instance.

```shell
IC_HTTP_PORT=<port number>
```

3. The HTTPS port of the same instance (used for the [Ingress resource example](#use-access-control-with-ingress-resources)).

```shell
IC_HTTPS_PORT=<port number>
```

---

## Use access control with VirtualServer resources

### Deploy the example application

Create the file _webapp.yaml_ with the following contents:

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/custom-resources/access-control/webapp.yaml]*

Apply it using `kubectl`:

```shell
kubectl apply -f webapp.yaml
```

---

### Deploy a Policy to create a deny rule

Create a file named _access-control-policy-deny.yaml_. The highlighted _deny_ field will be used by the example application, and should be changed to the subnet of your machine.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/custom-resources/access-control/access-control-policy-deny.yaml]*

Apply the policy:

```shell
kubectl apply -f access-control-policy-deny.yaml
```

---

### Configure load balancing

Create a file named _virtual-server.yaml_ for the VirtualServer resource. The _policies_ field references the access control Policy created in the previous section.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/custom-resources/access-control/virtual-server.yaml]*

Apply the policy:

```shell
kubectl apply -f virtual-server.yaml
```

---

## Test the example application

Use `curl` to attempt to access the application:

```shell
curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP http://webapp.example.com:$IC_HTTP_PORT
```

```text
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>
```

The *403* response is expected, successfully blocking your machine.

---

### Update the Policy to create an allow rule

Update the Policy with the file _access-control-policy-allow.yaml_, setting the _allow_ field to the subnet of your machine.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/custom-resources/access-control/access-control-policy-allow.yaml]*

Apply the Policy:

```shell
kubectl apply -f access-control-policy-allow.yaml
```

----

### Verify the Policy update

Attempt to access the application again:

```shell
curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP http://webapp.example.com:$IC_HTTP_PORT
```

```text
Server address: 10.64.0.13:8080
Server name: webapp-5cbbc7bd78-wf85w
```

The successful response demonstrates that the policy has been updated.

---

## Use access control with Ingress resources

You can also apply access control policies to standard Kubernetes Ingress resources using the `nginx.org/policies` annotation. This section walks through a complete example.

### Deploy the cafe application

Create the file _cafe.yaml_ with the following contents:

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/ingress-resources/access-control/cafe.yaml]*

Apply it using `kubectl`:

```shell
kubectl apply -f cafe.yaml
```

### Configure NGINX to use the X-Real-IP header

Create the file _nginx-config.yaml_ to configure NGINX to trust the `X-Real-IP` header. This ensures the access control policy uses the client IP provided in that header.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/ingress-resources/access-control/nginx-config.yaml]*

Apply the ConfigMap:

```shell
kubectl apply -f nginx-config.yaml
```

### Deploy a Policy to create an allow rule

Create a file named _access-control-policy-allow.yaml_. The highlighted _allow_ field permits traffic from the `10.0.0.0/8` CIDR range and blocks all other addresses.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/ingress-resources/access-control/access-control-policy-allow.yaml]*

Apply the policy:

```shell
kubectl apply -f access-control-policy-allow.yaml
```

### Create the Ingress resource

Create a file named _cafe-ingress.yaml_ for the Ingress resource. The highlighted `nginx.org/policies` annotation references the access control Policy created in the previous step.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/ingress-resources/access-control/cafe-ingress.yaml]*

Apply the Ingress:

```shell
kubectl apply -f cafe-ingress.yaml
```

### Test the allow policy

1. Send a request with an IP in the allowed `10.0.0.0/8` range using the `X-Real-IP` header:

    ```shell
    curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/coffee --insecure -H "X-Real-IP: 10.0.0.1"
    ```

    ```text
    Server address: 10.244.0.6:8080
    Server name: coffee-7586895968-r26zn
    ...
    ```

    The request succeeds because `10.0.0.1` is in the allowed range.

2. Send a request with an IP outside the allowed range:

    ```shell
    curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/coffee --insecure -H "X-Real-IP: 192.168.1.1"
    ```

    ```text
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    </body>
    </html>
    ```

    The *403* response confirms that NGINX blocks clients outside the allowed range.

### Update the Policy to create a deny rule

Update the Policy with the file _access-control-policy-deny.yaml_, which denies traffic from the `10.0.0.0/8` CIDR range and allows all other addresses.

*[Code: https://raw.githubusercontent.com/nginx/kubernetes-ingress/refs/heads/main/examples/ingress-resources/access-control/access-control-policy-deny.yaml]*

Apply the updated Policy:

```shell
kubectl apply -f access-control-policy-deny.yaml
```

The Ingress resource picks up the change automatically because the policy name (`webapp-policy`) stays the same.

### Verify the deny policy

1. Send a request with an IP in the now-denied `10.0.0.0/8` range:

    ```shell
    curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/coffee --insecure -H "X-Real-IP: 10.0.0.1"
    ```

    ```text
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    </body>
    </html>
    ```

    The same IP that was previously allowed is now rejected.

2. Send a request with an IP outside the denied range:

    ```shell
    curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/coffee --insecure -H "X-Real-IP: 192.168.1.1"
    ```

    ```text
    Server address: 10.244.0.6:8080
    Server name: coffee-7586895968-r26zn
    ...
    ```

    Clients outside the denied range are now allowed through.

