Google Cloud Armor security policy rules that filter based on an IP address
typically use the caller's client IP. When your services are behind an
intermediary, such as a third-party content delivery network (CDN), the client
IP in the `origin.ip` field is the IP address of the last intermediary, not the
original client.

The user IP feature lets you configure an alternate field, `origin.user_ip`, to
resolve from a header that the upstream provider populates. You can then use the
`origin.user_ip` field in your security policy rules to specify the IP address
used in those features. You can configure the `userIpRequestHeaders[]` option
in the security policy's `advancedOptionsConfig` field when using
`origin.user_ip`.

## How user IP addresses work

You configure Cloud Armor to extract the end user's IP address from a
specific request header. This value populates the `origin.user_ip` field, which
you can then use in your security policy rules.

If the headers specified in `userIpRequestHeaders[]` don't exist, or if their
values are not valid IP addresses, then Cloud Armor falls back to the
client IP address (`origin.ip`) instead. The following example shows a direct comparison for the default case.

```
origin.ip != origin.user_ip
```

The following examples show how to use `origin.user_ip` in the rules language,
with Google Threat Intelligence, and in address groups.

### `inIpRange`

```
inIpRange(origin.user_ip, '9.9.9.0/24')
```

For more information about using `inIpRange` with `origin.user_ip`, see [Attributes](https://docs.cloud.google.com/armor/docs/create-security-policy-rules#attributes).

### Google Threat Intelligence

```
evaluateThreatIntelligence('iplist-known-malicious-ips', origin.user_ip)
```

For more information, see [Apply Google Threat Intelligence](https://docs.cloud.google.com/armor/docs/threat-intelligence).

### Address groups

```
evaluateAddressGroup('example-address-group', origin.user_ip)
```

For more information, see [Configure address groups](https://docs.cloud.google.com/armor/docs/address-groups-using).

### Organization-scoped address groups

```
evaluateOrganizationAddressGroup('example-org-address-group', origin.user_ip)
```

For more information, see [Use organization-scoped address groups](https://docs.cloud.google.com/armor/docs/address-groups-using#use-org-scoped).

## Best practices

Because `origin.user_ip` resolves from a request header, which an untrusted
client can manipulate, you must validate that traffic originates from a trusted
upstream source.

To validate the upstream source, create a security policy with at least two
rules. The first rule, with a higher priority, checks that the immediate client
IP (`origin.ip`) belongs to your trusted upstream provider. The second rule,
with a lower priority, applies your intended logic using the `origin.user_ip`
field.

For example, you can create a policy with the following two rules:

- Rule 1: `evaluateThreatIntelligence('iplist-public-clouds', origin.ip)`
- Rule 2: `inIpRange(origin.user_ip, '9.9.9.0/24')`

## What's next

- [Create and view security policy rules](https://docs.cloud.google.com/armor/docs/create-security-policy-rules)
- [Apply Google Threat Intelligence](https://docs.cloud.google.com/armor/docs/threat-intelligence)
- [Configure address groups](https://docs.cloud.google.com/armor/docs/address-groups-using)
- [Use organization-scoped address groups](https://docs.cloud.google.com/armor/docs/address-groups-using#use-org-scoped)