# Field-level and column-level security

|     |     |
| --- | --- |
|  | This documentation is for<br>an as-yet unreleased<br>version of Cerbos PDP. Choose 0.53.0 from the version picker at the top right or navigate to [https://docs.cerbos.dev](https://docs.cerbos.dev/) for the latest version. |

Applications often need to control access not just at the resource level but at the field level. For example, an HR system might allow all employees to view a colleague’s name and department, but restrict salary information to HR staff and managers.

## Pattern 1: Actions as field operations

Model each field-action combination as a distinct action using the hierarchical action naming convention (`:` delimiter).

Resource policy with field-level actions

```yaml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  resource: "employee_record"
  version: "default"
  rules:
    - actions: ["name:view", "department:view", "title:view"]
      effect: EFFECT_ALLOW
      roles: ["employee"]

- actions: ["salary:*"]
      effect: EFFECT_ALLOW
      roles: ["hr_admin"]

- actions: ["salary:view"]
      effect: EFFECT_ALLOW
      derivedRoles:
        - direct_manager
```

Check multiple field-level actions in a single request:

Request

```json
{
  "principal": {
    "id": "alice",
    "roles": ["employee"]
  },
  "resources": [
    {
      "resource": {
        "kind": "employee_record",
        "id": "emp-001"
      },
      "actions": ["name:view", "department:view", "salary:view"]
    }
  ]
}
```

Response

```json
{
  "results": [
    {
      "resource": { "id": "emp-001", "kind": "employee_record" },
      "actions": {
        "name:view": "EFFECT_ALLOW",
        "department:view": "EFFECT_ALLOW",
        "salary:view": "EFFECT_DENY"
      }
    }
  ]
}
```

Alice can view name and department but not salary.

|     |     |
| --- | --- |
|  | Wildcards respect the `:` delimiter. A rule with `actions: ["salary:*"]` matches both `salary:view` and `salary:edit`. |

## Pattern 2: Output expressions for permitted fields

Use [output expressions](https://docs.cerbos.dev/cerbos/prerelease/policies/outputs) to return the set of fields a user can access, so your application can dynamically build responses.

Resource policy with output expressions

```yaml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  resource: "employee_record"
  version: "default"
  rules:
    - name: base-fields
      actions: ["view"]
      effect: EFFECT_ALLOW
      roles: ["employee"]
      output:
        when:
          ruleActivated: |-
            {"viewable_fields": ["name", "department", "title"]}

- name: sensitive-fields
      actions: ["view"]
      effect: EFFECT_ALLOW
      roles: ["hr_admin"]
      output:
        when:
          ruleActivated: |-
            {"viewable_fields": ["name", "department", "title", "salary", "ssn"]}
```

The response `outputs` array contains the field lists from all matched rules. Your application merges these to determine the full set of accessible fields.

Response outputs

```json
{
  "outputs": [
    {
      "src": "resource.employee_record.vdefault#base-fields",
      "val": {
        "viewable_fields": ["name", "department", "title"]
      }
    }
  ]
}
```

## Choosing a pattern

Actions as field operations

Best when you need yes/no decisions per field and want to leverage Cerbos wildcard matching. Works well with [PlanResources](https://docs.cerbos.dev/cerbos/prerelease/api/#resources-query-plan) for query-level filtering.

Output expressions

Best when you want to return a dynamic set of permitted fields from a single action check. More flexible but requires application-side logic to process the output.

These patterns can be combined — for example, use action-based checks for write operations and output expressions for read operations.
