# Policy Taxonomy

{% hint style="info" %}
This feature is part of the Enterprise plan. If it is not enabled for your organization, please contact StrongDM at the [StrongDM Help Center](https://help.strongdm.com/hc/en-us).
{% endhint %}

### Overview

This reference page provides information about the attributes supported for context-based policy.

To learn more about policy, please see the documentation:

* [Context-Based Policy](/admin/access/policies.md)
* [Policy Creation](/admin/access/policies/policy-creation.md)
* [Policy Use Cases](/admin/access/policies/policy-use-cases.md)

### Entities

Entities in Cedar are objects that represent principals, actions, or resources. They are typically annotated in the following format.

#### StrongDM Account

```cedar
StrongDM::Account::"<ACCOUNT_ID>"
```

**Supported properties**

| Property          | Description                                                                                     | Format  | Example value(s)                                                  |
| ----------------- | ----------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------- |
| `accountType`     | Type of StrongDM account (user or service account)                                              | String  | `service` or `user`                                               |
| `email`           | User email address                                                                              | String  | `alice@example.com`                                               |
| `externalId`      | External ID populated from SCIM metadata, if applicable                                         | String  | `alice`                                                           |
| `isManagedUser`   | Whether or not the user is managed by a third-party provider                                    | Boolean | `true`                                                            |
| `permissionLevel` | Permission level (such as Administrator, Auditor, Team Leader, Database Administrator, or User) | String  | `admin`, `auditor`, `multi-team-leader`, `database-admin`, `user` |
| `tags`            | Cedar record whose keys and values are strings                                                  | KVP     | `dev`                                                             |

**Example**

```cedar
// example for email
permit (
  principal,
  action,
  resource
) when {
  principal.email == "user@example.com"
};

// example for externalId
permit (
  principal,
  action,
  resource
) when {
  principal.externalId == "alice"
};

// example for isManagedUser
permit (
  principal,
  action,
  resource
) when {
  principal.isManagedUser == true
};

// example for accountType
permit (
  principal,
  action,
  resource
) when {
  principal.accountType == "service"
};

// example for permissionLevel
permit (
  principal,
  action,
  resource
) when {
  principal.permissionLevel == "admin"
};

// example for tags
permit (
  principal,
  action,
  resource
) when {
    principal.sdm.hasTag("env") && principal.sdm.getTag("foo") == "dev"
};
```

#### StrongDM Role

```cedar
StrongDM::Role::"<ROLE_ID>"
```

**Example**

```cedar
permit (
  principal in StrongDM::Role::"r-1234",
  action,
  resource
);
```

**Entity hierarchy**

StrongDM Role may be a parent of another entity, such as StrongDM Account. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `principal in StrongDM::Role::"r-1234"`).

#### StrongDM Resource

```cedar
StrongDM::Resource::"<RESOURCE_ID>"
```

**Supported properties**

| Property | Format       | Example value(s) |
| -------- | ------------ | ---------------- |
| `tags`   | Cedar record | `dev`            |

**Example**

```cedar
permit (
  principal,
  action,
  resource == StrongDM::Resource::"rs-1234"
) when {
  resource.hasTag("env") && resource.getTag("env") == "dev"
};
```

#### External Role

```cedar
External::Role::"<ROLE_NAME>"
```

External Role is populated from SCIM metadata, if applicable.

**Example**

```cedar
permit (
  principal in External::Role::"admin",
  action,
  resource
);
```

**Entity hierarchy**

External Role may be a parent of another entity, such as StrongDM Account. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `principal in External::Role::"admin"`).

#### External Group

```cedar
External::Group::"<GROUP_NAME>"
```

External Group is populated from SCIM metadata, if applicable.

**Example**

```cedar
permit (
  principal in External::Group::"dev",
  action,
  resource
);
```

**Entity hierarchy**

External Group may be a parent of another entity, such as StrongDM Account. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `principal in External::Group::"dev"`).

#### Location Continent

```cedar
Location::Continent::"<CONTINENT_CODE>"
```

Please use the appropriate [continent code](https://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_by_continent_\(data_file\)).

**Example**

```cedar
permit (
  principal,
  action,
  resource
) when {
  context.location in Location::Continent::"NA"
};
```

**Entity hierarchy**

Location Continent may be a parent of another entity, such as Location. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `context.location in Location::Continent::"NA"`).

#### Location Country

```cedar
Location::Country::"<ISO-3166-1-CODE>"
```

Please use the appropriate [ISO-3166-1 code](https://www.iso.org/obp/ui/#search).

**Example**

```cedar
permit (
  principal,
  action,
  resource
) when {
  context.location in Location::Country::"US"
};
```

**Entity hierarchy**

Location Country may be a parent of another entity, such as Location. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `context.location in Location::Country::"US"`).

#### Location Subdivision

```cedar
Location::Subdivision::"<ISO-3166-2-CODE>"
```

**Example**

```cedar
permit (
  principal,
  action,
  resource
) when {
  context.location in Location::Subdivision::"US-WA"
};
```

**Entity hierarchy**

Location Subdivision may be a parent of another entity, such as Location. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `context.location in Location::Subdivision::"US-WA"`).

#### Location IP

```cedar
Location::IP::"<IP_ADDRESS>"
```

**Supported properties**

| Property    | Format  |
| ----------- | ------- |
| `latitude`  | Decimal |
| `longitude` | Decimal |

**Example**

```cedar
permit (
  principal,
  action,
  resource
) when {
  context.location == Location::IP::"1.2.3.4"
};

// example for latitude
permit (
  principal,
  action,
  resource
) when {
  context.location.latitude.greaterThan(decimal("49"))
};

// example for longitude
permit (
  principal,
  action,
  resource
) when {
  context.location.longitude.lessThan(decimal("-120"))
};
```

**Entity hierarchy**

Location IP may be a parent of another entity, such as Location. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `context.location == Location::IP::"1.2.3.4"`).

#### Postgres Database

```cedar
Postgres::Database::"<RESOURCE_ID>/<DATABASE_NAME>"
```

**Supported properties**

| Property   | Format |
| ---------- | ------ |
| `database` | String |

**Example**

```cedar
// example for database
permit (
  principal,
  action,
  resource == Postgres::Database::"rs-1234/prod"
) when {
  resource.database == "prod"
};
```

**Entity hierarchy**

Postgres Database may be a parent of another entity, such as Resource. Matching whether a given entity is a descendant of another entity is done through the `in` operator (for example, `resource in StrongDM::Resource::"rs-1234"`).

### Principal

```cedar
permit (
  principal == StrongDM::Account::"a-1234",
  action,
  resource
);
```

The principal referenced in StrongDM policy statements always will be a `StrongDM::Account`.

### Resource

#### StrongDM Connect

```cedar
StrongDM::Action::"connect"
```

The resource referenced in StrongDM policy statements always will be a `StrongDM::Resource`.

**Example**

```cedar
permit (
  principal,
  action == StrongDM::Action::"connect",
  resource == StrongDM::Resource::"rs-1234"
);
```

#### Postgres Action

```cedar
SQL::Action
```

```cedar
Postgres::Action
```

This always will be `Postgres::Database`.

**Example**

```cedar
permit (
  principal,
  action == SQL::Action::"select",
  resource == Postgres::Database::"rs-1234/prod"
);
```

### Action

#### All resources

* `StrongDM::Action::"connect"`

#### Postgres resources

Policy can be enacted for over 180 [Postgres database actions](https://www.postgresql.org/docs/16/sql-commands.html), such as the following examples.

Examples of Postgres actions:

* `Postgres::Action::"callFunction"`
* `Postgres::Action::"executeUnknown"`
* `Postgres::Action::"parse"`
* `SQL::Action::"select"`
* `SQL::Action::"insert"`
* `SQL::Action::"update"`

**Supported Postgres resource types**

Postgres/SQL actions are supported on all of the Postgres resource types, including:

* Aurora PostgreSQL
* Aurora PostgreSQL (IAM)
* Azure Database for PostgreSQL
* Azure PostgreSQL (Managed Identity)
* Citus
* CockroachDB
* Greenplum
* PostgreSQL
* PostgreSQL (mTLS)
* RDS PostgreSQL (IAM)
* Redshift

### Context

#### All resources

**Supported context properties for all resources**

| Property                | Description                                                                                                                                                                                                                                   | Format     | Example value(s)                                                                                                                     |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `location`              | Geographical location; may not be present if a location cannot be determined from the client IP address                                                                                                                                       | Entity UID | `Location::IP`                                                                                                                       |
| `network.clientIp`      | IP address associated with the client, as determined by the StrongDM control plane; always a public IP address                                                                                                                                | IPAddr     | `ip("1.2.3.0")`                                                                                                                      |
| `network.destinationIp` | IP address of the destination resource, as determined after connecting to the resource; may not be present for policy authorization requests such as `StrongDM::Action::"connect"` performed prior to establishing a connection to a resource | IPAddr     | `1.2.3.0`                                                                                                                            |
| `network.requestIp`     | IP address associated with the request, as determined at the point of ingest (either a StrongDM gateway or StrongDM control plane, depending on the type of request); may be either a public or private (VPN) IP address                      | IPAddr     | `ip("1.2.3.0")`                                                                                                                      |
| `trust.ok`              | Device Trust status; `true` value indicates "good" or "exempt" status; `false` value indicates "bad" or "unknown" status                                                                                                                      | Boolean    | `true`                                                                                                                               |
| `trust.status`          | Device Trust context; `bad` for low trust; `exempt` for exempt; `good` for high trust; `unknown` for unknown                                                                                                                                  | String     | `"bad"`, `"exempt"`, `"good"`, `"unknown"`                                                                                           |
| `utcNow.day`            | Day of month, starting with 1                                                                                                                                                                                                                 | Long       | `30`                                                                                                                                 |
| `utcNow.dayOfWeek`      | Day of week, where Sunday is 1 and Saturday is 7                                                                                                                                                                                              | Long       | `3`                                                                                                                                  |
| `utcNow.month`          | Month of year, where January is 1 and December is 12                                                                                                                                                                                          | Long       | `1`                                                                                                                                  |
| `utcNow.timestamp`      | Cedar datetime (UTC)                                                                                                                                                                                                                          | String     | `YYYY-MM-DD`, `YYYY-MM-DDThh:mm:ssZ`, `YYYY-MM-DDThh:mm:ss.SSSZ`, `YYYY-MM-DDThh:mm:ss(+/-)hhmm`, `YYYY-MM-DDThh:mm:ss.SSS(+/-)hhmm` |
| `utcNow.year`           | Four-digit year                                                                                                                                                                                                                               | Long       | `2024`                                                                                                                               |

**Example**

```cedar
permit (
  principal,
  action,
  resource
) when {
  context.location in Location::Country::"US"
};

// example for network.clientIp
permit (
  principal,
  action,
  resource
) when {
  context.network.clientIp.isInRange(ip("1.2.3.0/24"))
};

// example for network.requestIp
permit (
  principal,
  action,
  resource
) when {
  context.network.requestIp.isInRange(ip("1.2.3.0/24"))
};

// example for trust.ok
permit (
  principal,
  action,
  resource
) when {
  context.trust.ok == true
};

// example for trust.status
permit (
  principal,
  action,
  resource
) when {
  context.trust.status == "good"
};

// example for utcNow
permit (
  principal,
  action,
  resource
) when {
  context.utcNow.dayOfWeek == 3 &&
  context.utcNow.day == 31 &&
  context.utcNow.month == 12 &&
  context.utcNow.year == 2024 &&
  context.utcNow.timestamp.toTime().toHours() >= 2
};
```

#### Postgres resources

**Supported context properties for all Postgres resources**

| Property                   | Format         | Example value(s)                                         |
| -------------------------- | -------------- | -------------------------------------------------------- |
| `sql.tables`               | Set of strings | `["users", "groups"]` or `["prod.users", "prod.groups"]` |
| `sql.writeTables`          | Set of strings |                                                          |
| `sql.qualifiedTables`      | Set of strings |                                                          |
| `sql.qualifiedWriteTables` | Set of strings |                                                          |

**Example**

```cedar
permit(principal, action, resource) when {
  context.location in Location::Country::"US" ||
  context.network.clientIp.isInRange(ip("1.2.3.0/24")) ||
  context.network.destinationIp.isInRange(ip("1.2.3.0/24")) ||
  context.network.requestIp.isInRange(ip("1.2.3.0/24")) ||
  context.trust.ok == true ||
  context.trust.status == "good" ||
};

permit(principal, action == SQL::Action::"update", resource) when {
  context.sql.tables.contains("secrets") ||
  context.sql.writeTables.contains("secrets") ||
  context.sql.qualifiedTables.contains("prod.secrets") ||
  context.sql.qualifiedWriteTables.contains("prod.secrets")
};
```

```cedar
// example for location
permit (
  principal,
  action,
  resource
) when {
  context.location in Location::Country::"US"
};

// example for network.clientIp
permit (
  principal,
  action,
  resource
) when {
  context.network.clientIp.isInRange(ip("1.2.3.0/24"))
};

// example for network.destinationIp
permit (
  principal,
  action,
  resource
) when {
  context.network.destinationIp.isInRange(ip("1.2.3.0/24"))
};

// example for network.requestIp
permit (
  principal,
  action,
  resource
) when {
  context.network.requestIp.isInRange(ip("1.2.3.0/24"))
};

// example for trust.ok
permit (
  principal,
  action,
  resource
) when {
  context.trust.ok == true
};

// example for trust.status
permit (
  principal,
  action,
  resource
) when {
  context.trust.status == "good"
};

// example for sql.tables
permit (
  principal,
  action == SQL::Action::"update",
  resource
) when {
  context.sql.tables.contains("secrets")
};

// example for sql.writeTables
permit (
  principal,
  action == SQL::Action::"update",
  resource
) when {
  context.sql.writeTables.contains("secrets")
};

// example for sql.qualifiedTables
permit (
  principal,
  action == SQL::Action::"update",
  resource
) when {
  context.sql.qualifiedTables.contains("prod.secrets")
};

// example for sql.qualifiedWriteTables
permit (
  principal,
  action == SQL::Action::"update",
  resource
) when {
  context.sql.qualifiedWriteTables.contains("prod.secrets")
};
```

### Annotations

| Annotation                  | Format of value |
| --------------------------- | --------------- |
| `@approve("<WORKFLOW_ID>")` | String          |
| `@disconnect("true")`       | Truthy value    |
| `@error("<REASON>")`        | String          |
| `@justify("<PROMPT>")`      | String          |
| `@logout("<REASON>")`       | String          |
| `@mfa("<PROMPT>")`          | String          |
| `@maxrows("<NUMBER>")`      | String          |

#### Example

```cedar
@approve("af-1234")
@credential("rs-1234")
@email("user@example.com")
@justify("Enter a reason")
@mfa("MFA required")
@maxrows("1234")
@notify("You have access!")
@disconnect("true")
@error("denied!")
@logout("unauthorized access")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.strongdm.com/admin/access/policies/policy-taxonomy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
