> ## Documentation Index
> Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Impersonation

Impersonation lets users act on behalf of others—like support reps accessing customer accounts—by temporarily inheriting a subset of their permissions through a combination of impersonation facts and policy rules.

## Implementation

There are two main components to impersonation:

1. A fact that indicates whether a user is impersonating another user.
2. A policy that grants permissions to users who are impersonating another user.

In our example, members with a "support" role need to impersonate admins.

```polar theme={null}
actor User {
  permissions = ["impersonate"];

  "impersonate" if global "support";
}

global {
  roles = ["support"];
}

resource Organization {
  roles = ["admin", "member"];
  permissions = ["read", "write"];

  "member" if "admin";

  "read" if "member";
  "write" if "admin";
}

# a user can do anything some other user can do
# if they are allowed to impersonate that user and
# are currently impersonating them
allow(user: User, action: String, resource: Resource) if
  other_user matches User and
  has_permission(user, "impersonate", other_user) and
  is_impersonating(user, other_user) and
  has_permission(other_user, action, resource);

# we need to specify the default allow rule here
# because we added our own custom one above
allow(user: User, action: String, resource: Resource) if
  has_permission(user, action, resource);

test "global support users can read user organizations via impersonation" {
  setup {
    has_role(User{"alice"}, "support");
    has_role(User{"bob"}, "admin", Organization{"acme"});
    has_role(User{"charlie"}, "member", Organization{"bar"});
    is_impersonating(User{"alice"}, User{"bob"});
  }

  # bob can read as a member
  assert allow(User{"bob"}, "read", Organization{"acme"});

  # alice can impersonate bob
  assert allow(User{"alice"}, "impersonate", User{"bob"});

  # alice can read via Bob by impersonating bob
  assert allow(User{"alice"}, "read", Organization{"acme"});

  # charlie can read as a member
  assert allow(User{"charlie"}, "read", Organization{"bar"});

  # alice cannot read because alice is not impersonating charlie
  assert_not allow(User{"alice"}, "read", Organization{"bar"});
}
```

In our test case:

1. Alice is a customer support rep and is impersonating Bob.
2. Bob is an admin of the acme organization.
3. And so Alice can see anything Bob can.

## Common scenarios

There are several ways to define who has permission to impersonate another user. Common ones include:

From a relationship with the user:

```polar theme={null}
actor User {
  permissions = ["impersonate"];
  relations = { manager: User };

  "impersonate" if "manager";
}
```

Or from a role on the organization:

```polar theme={null}
actor User {
  permissions = ["impersonate"];
}

resource Organization {
  roles = ["member", "admin"];
}

# Organization admins can impersonate members
has_permission(user: User, "impersonate", other_user: User) if
  org matches Organization and
  has_role(user, "admin", org) and
  has_role(other_user, "member", org);
```

The `is_impersonating` fact can be included as an ephemeral context fact or more durably synced to Oso Cloud.

* If included as a [context fact](/develop/facts/context-facts), when a user "ends" an impersonation session, the application stops sending the impersonation context fact.
* If stored in Oso Cloud, you need to delete the persisted fact to end the impersonation.

Use context facts to scope impersonation to a single application or service, and persisted facts to share impersonation sessions across multiple services.
