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

# Migrate Access Policies

> Moving Access Policy calls from v0 to v1: kebab-case paths, grants named by entitlement ID, what to remove from a read before an update, lowercase status values, and conditions checked on save.

Access Policies have the same structure in v1, except for how a policy names what it grants. This guide
covers that change and what it means for updates. The changes every endpoint shares are in
[What changes in v1](https://docs.lumos.com/reference/v1/migrate/what-changes.md).

## Routes

| v0 | v1 |
| - | - |
| `GET /access_policies` | `GET /v1/access-policies` |
| `POST /access_policies` | `POST /v1/access-policies` |
| `GET /access_policies/{access_policy_id}` | `GET /v1/access-policies/{access_policy_id}` |
| `PUT /access_policies/{access_policy_id}` | `PUT /v1/access-policies/{access_policy_id}` |
| — | `PATCH /v1/access-policies/{access_policy_id}` |
| `DELETE /access_policies/{access_policy_id}` | `DELETE /v1/access-policies/{access_policy_id}` |

## Grants

An app's grants move from `permissions`, identified by requestable-permission ID, to
`entitlements`, identified by entitlement ID. A v1 body looks like this:

```json v1 body theme={null}
{
  "name": "Company-wide GitHub access",
  "business_justification": "Everyone at the company reviews code on GitHub.",
  "is_everyone_condition": true,
  "apps": [
    {
      "id": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "is_preapproved": true,
      "entitlements": [{ "id": "4d5e6f70-8192-4a3b-8c4d-5e6f70819203" }]
    }
  ]
}
```

Requestable-permission IDs stored from v0 don't work in `entitlements`.
[Migrate requestable permissions to entitlements](https://docs.lumos.com/reference/v1/migrate/permissions-to-entitlements.md)
covers the change from requestable-permission IDs to entitlement IDs.
[Grants](https://docs.lumos.com/reference/v1/objects/access-policy.md#grants) covers app-level grants and the checks Lumos
runs on each ID.

## Updating a policy

Send only the fields that a write body takes. To send a read back in
[Update Access Policy](https://docs.lumos.com/api-reference/v1/access-policies/update-access-policy.md), first remove the
policy's `id`, and the `label` on each app and entitlement. v1 returns `400` for a field that a
write body doesn't take. v0 ignored those fields.

## Status values

`status` takes lowercase values, in responses and in request bodies. A v0 value returns `400`.

| v0 `status` | v1 `status` |
| - | - |
| `DRAFT` | `draft` |
| `PUBLISHED` | `published` |

[Drafts, publishing, and enabling](https://docs.lumos.com/reference/v1/objects/access-policy.md#drafts-publishing-and-enabling)
covers what each status allows.

## Conditions

v0 saves any condition. v1 checks each condition when you save it, and returns `400` for one it
can't evaluate, such as a misspelled attribute or a date without a time zone.
[What Lumos rejects](https://docs.lumos.com/reference/v1/guides/conditions.md#what-lumos-rejects) has the list. A policy
whose stored condition names a deleted custom attribute fails the same check. To change anything
else on that policy, send
[Patch Access Policy](https://docs.lumos.com/api-reference/v1/access-policies/patch-access-policy.md) without
`access_condition`.

v0 ignores `access_condition` when `is_everyone_condition` is `true`. v1 returns `400`, unless
`access_condition` is the everyone condition a read returns.
[Conditions](https://docs.lumos.com/reference/v1/objects/access-policy.md#conditions) on the Access Policy object covers both
fields.

## Terraform

In version 1.x of the Lumos Terraform provider, `lumos_access_policy` names grants by entitlement ID
and takes lowercase `status` values, as v1 does.
[Migrating from 0.x to 1.x](https://registry.terraform.io/providers/teamlumos/lumos/latest/docs/guides/migrating-from-0x)
maps each attribute.
