# Impersonation

The Impersonation Filter (also known as the Access Control List (ACL) Filter) gives specified server distinguished names (DNs) the privilege to impersonate on behalf of users. The incoming headers `EXTERNAL_SYS_DN` and `SSL_CLIENT_S_DN` are validated against this list to make sure both servers wanting to impersonate a user are valid and have proper permissions to do so.

## Example Use Cases

### Limiting Access to Specific DNs

The Impersonation/ACL filter allows system administrators to specify a list of DNs which are allowed to access a service. If a DN is not in this approved list, that request is rejected with a [`403` response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403). In typical installations of Grey Matter, sidecars are set up to only accept communication from the edge and a global DN for inter-mesh communication:

```javascript
{
    "listener_key" : "listener-example-service",
    "active_http_filters" : [
        "gm.impersonation",
    ],
    "gm_impersonation" : {
        "servers": "cn=edge-egress|cn=sidecar"
    },
    ...
}
```

This ensures that services refuse any communication that does not pass through edge and is not using a valid sidecar DN.

{% hint style="info" %}
**Note:** the [`gm-inheaders` filter](https://greymatter.gitbook.io/grey-matter-documentation/1.3/reference/api/fabric-api/filters/http/gm-inheaders) needs to be set on edge nodes to ensure that users are not able to set arbitrary `USER_DN` or `EXTERNAL_SYS_DN` headers.
{% endhint %}

### Service Acting as a User

A Service may need to impersonate users in order to access user information (e.g. email addresses, phone numbers) or validate that a user exists in the system. To set this up, a User Service sidecar could have the following impersonation filter configuration:

```javascript
{
    "listener_key"  : "listener-user-service",
    "active_http_filters" : [
        "gm.impersonation",
    ],
    "gm_impersonation" : {
        "servers" : "cn=my-service|cn=edge"
    }
    ...
}
```

This will give `user-service` the ability to send any `USER_DN` to the User Service in order to access information on any user.

{% hint style="info" %}
**Note:** we also have to specify `cn=edge` in the server white list since requests coming through edge will have `SSL_CLIENT_S_DN` set to the edge certificate.
{% endhint %}

## Flow Chart

![](https://lucid.app/publicSegments/view/69d5e87c-f5e2-419f-8f17-26ffc557dfda/image.png)

## Header Definitions

**USER\_DN** - The effective (possibly impersonated) Distinguished Name of requesting application

**SSL\_CLIENT\_S\_DN** - The Distinguished Name taken from the system certificate

**EXTERNAL\_SYS\_DN** - The Distinguished Name taken from the external system certificate (originally inside s\_client\_s\_dn)

## Filter Configuration Options

| Name              | Type    | Default | Description                                                                                   |
| ----------------- | ------- | ------- | --------------------------------------------------------------------------------------------- |
| `servers`         | String  | ""      | Pipe (\|) delimited string of server DNs that will be validated against the incoming request. |
| `caseInsensitive` | Boolean | false   | If set to `true`, does not validate case for each server DN specified.                        |

### Example

```yaml
http_filters:
- name: gm.impersonation
  config:
    servers: "C=US,ST=Virginia,L=Alexandria,O=Decipher Technology Studios,OU=Engineering,CN=localhost"
    caseInsensitive: true
```
