Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested edits for identity doc updates #29339

Open
wants to merge 6 commits into
base: docs/identity-deduplication
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,363 @@
---
layout: docs
page_title: Resolve deduplication impact on ACL policy templates
description: >-
Resolve templated ACL behavior for deduplicated entities and groups.
---

# Resolve deduplication impact on ACL policy templates

Fix templated ACL policy behavior for entities and groups renamed during
identity deduplication.

<Tip title="Assumptions">

- You have [identified the duplicate entity and group names](/vault/docs/upgrading/identity-deduplication).
- You have admin permission on the relevant Vault server or cluster.

</Tip>


## How renaming affect ACL policies

Operators use
[policy templating](/vault/docs/concepts/policies#templated-policies) to specify
permissions that dynamically resolve based on specific properties of an
authenticated entity. During deduplication, Vault renames entities or groups
with duplicate identities by appending a universally unique identifier (UUID) to
all but one of the entities to avoid future duplication.

If a templated ACL policy relies on an entity or group name, renaming duplicate
identities could inadvertently change the meaning of the policy. In practice,
identity deduplication is unlikely to grant unintended access to an existing
resource since the renamed identity contains a UUID that should
not collide with other resource paths. But the rename might **remove** access to
existing resources after deduplication if the associated resource policy
references the old entity or group name.

For example, assume you have the following templated ACL policy that grants
users access to a `kv` plugin:

```hcl
path "kv/users/{{identity.entity.name}}/*" {
capabilities = ["read", "create", "update"]
}
```

The policy grants a user entity named `janine` permission to read and write
key-value pairs to the `kv` plugin on the path `kv/users/janine/`. If there are
duplicate entities named `janine`, Vault renames all but one of entities
to `janine-<UUID>` during deduplication.

The ACL policy now gives the renamed entity permission to read and write
While the renamed entity can still access the `kv` plugin, the change in
no longer grants access to path `kv/users/janine/`. As a result, the user can no
longer access their data stored under `kv/users/janine/`.


## Find affected ACL policies

Deduplication has the potential to break templated ACL policies that rely on
entity or group name keys:

Template key | Description
------------------------------------------------------------- | ----------------
`identity.entity.name` | Entity name
`identity.entity.aliases.<mount accessor>.name` | Entity alias name for the given mount
`identity.groups.ids.<group id>.name` | Group name for the given group ID
`identity.groups.names.<group name>.id` | Group ID for the given group name
`identity.groups.names.<group name>.metadata.<metadata key>` | Metadata for the given group name and key

You can use the following `bash` script to check for templated policies using
entity or group names:

<Tabs>

<Tab heading="CLI" group="cli">

```bash
policy_list=$(vault policy list)

for policy in ${policy_list} ; do

# Get the policy details
policy_details=$(vault policy read ${policy})

# Check for a name based template key
if echo "${policy_details}" | grep -q "\.name" ; then
echo ""
echo "Policy name: ${policy}"
fi
echo "${policy_details}" |
tr -s ' ' '\n' |
grep "\.name" --label=" template key" -H
done
```

</Tab>

<Tab heading="API" group="api">

```bash
policy_list=$(
curl \
--silent \
--request GET \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy \
| jq .data.policies | jq -c '.[]' | tr -d '"'
)

for policy in ${policy_list} ; do

# Get the policy details
policy_details=$(
curl \
--silent \
--request GET \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/${policy} \
| jq '.data.rules' | sed 's/\\"/"/g' | sed 's/\\n/ /g'
)

# Check for a name based template key
if echo "${policy_details}" | grep -q "\.name" ; then
echo ""
echo "Policy name: ${policy}"
fi
echo "${policy_details}" |
tr -s ' ' '\n' |
grep "\.name" --label=" template key" -H
done
```

</Tab>

</Tabs>

Compare the returned list of policies and template keys against the list of
deduplication targets identified in your system logs to determine if the policy
will break after duplication.

If you identify policies that may break during deduplication, consult with
the relevant teams to determine if the policies are still used and if you should
address the renaming problem before or after deduplication.

If you find policies that need remediation, there are two ways to fix user
access:

1. Update relevant templated ACL policies.
1. Move the affected resource.


## Solution 1: Update relevant templated ACL policies

The easiest way to deal with broken ACL policy templates due to deduplication is
to define new policies or add rules to existing policies that explicitly grants
access to previous resources for the affected entities.

If you have a large number of duplicate identities, it may be easier to
pre-populate a custom metadata field (e.g., `prev_name`) for the renamed
entities. Then create a single policy that uses the custom metadata field
instead of the entity name and attach that policy to the renamed entities.

<Tabs>

<Tab heading="CLI" group="cli">

Assume you have a file called `duplicate-names.txt` with a list of entity names
currently attached to a templated ACL policy, which will no longer work after
deduplication.

1. Use `vault write` and the
[`{namespace}/identity/entity/name/{name}`](/vault/api-docs/secret/identity/entity#create-update-entity-by-name)
endpoint to update your target entries with a custom metadata field called
`old_name` set to the **current** entity name:

```bash
while read entity_name; do

if [[ "" = "${entity_name}" ]] ; then continue ; fi

# Create a payload file with the new metadata field
echo -n '{"metadata": { "old_name": "'${entity_name}'"}}' > ./metadata.json

# Save the metadata to the entity
vault write /identity/entity/name/${entity_name} @metadata.json

done < duplicate-names.txt
```

1. Create a new templatized ACL policy file that replaces the entity name
reference with a reference to the metadata field. For example:

```hcl
path "kv/users/{{identity.entity.metadata.old_name}}/*" {
capabilities = ["read", "create", "update"]
}
```

1. Use `vault policy write` to create a new ACL policy with the policy
definition file:

```shell-session
$ vault policy write <policy_name> <path_to_policy_file>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault policy write "kv-access-preservation" ./dedupe-policy.hcl
```

</CodeBlockConfig>

1. Use `vault read` with the
[`{namespace}/identity/entity/name/{name}`](/vault/api-docs/secret/identity/entity#create-update-entity-by-name)
path to read in the existing policy assignments and add the new policy to the
target entities. For example:

```bash
policy_name="<policy_name>"
while read entity_name; do

if [[ "" = "${entity_name}" ]] ; then continue ; fi

# Create a payload file with new policy added to any existing policy
# assignments
vault read \
-field policies \
-format json \
/identity/entity/name/${entity_name} \
| jq ". + [\"${policy_name}\"] | {policies: .}" > policy_update.json

# Update the policy assignment for the entity
vault write /identity/entity/name/${entity_name} @policy_update.json

done < duplicate-names.txt
```

</Tab>

<Tab heading="API" group="api">

Assume you have a file called `duplicate-names.txt` with a list of entity names
currently attached to a templated ACL policy, which will no longer work after
deduplication.

1. Use the
[`{namespace}/identity/entity/name/{name}`](/vault/api-docs/secret/identity/entity#create-update-entity-by-name)
endpoint to update your target entries with a custom metadata field called
`old_name` set to the **current** entity name:

```bash
while read entity_name; do

if [[ "" = "${entity_name}" ]] ; then continu ; fi

# Create a payload file with the new metadata
echo -n '{"metadata": { "old_name": "'${entity_name}'"}}' > ./metadata.json

# Save the metadata to the entity
curl \
--request POST \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
--data @./metadata.json \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name}

done < duplicate-names.txt
```

1. Create a new templatized ACL policy file that replaces the entity name
reference with a reference to the metadata field. For example:

```hcl
path "kv/users/{{identity.entity.metadata.old_name}}/*" {
capabilities = ["read", "create", "update"]
}
```

1. Escape your policy file and make a `POST` call to the
[`{namespace}/sys/policy/{policy_name}`](/vault/api-docs/system/policy#create-update-policy)
with your policy details:

```shell-session
$ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' <path_to_policy_file> |
curl \
--request POST \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
"$(</dev/stdin)" \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/<policy_name>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' ./dedupe-policy.hcl |
curl \
--request POST \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
--data "$(</dev/stdin)" \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/sys/policy/kv-access-preservation
```
</CodeBlockConfig>

`/sys/mounts/{plugin_mount_path}` does not return data on success.


1. Make a `GET` call to the
[`{namespace}/identity/entity/name/{name}`](/vault/api-docs/secret/identity/entity#create-update-entity-by-name)
endpoint to read in the existing policy assignments and add the new policy to the
target entities. For example:

```bash
policy_name="<policy_name>"
while read entity_name; do

if [[ "" = "${entity_name}" ]] ; then continue ; fi

# Create a payload file with new policy added to any existing policy assignments
curl \
--request GET \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name} \
| jq ".data.policies + [\"${policy_name}\"] | {policies: .}" > policy_update.json

# Update the policy assignment for the entity
curl \
--request POST \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
--data @policy_update.json \
${VAULT_ADDR}/v1/${VAULT_NAMESPACE}/identity/entity/name/${entity_name}

done < duplicate-names.txt
```

</Tab>

</Tabs>


## Solution 2: Move the affected resource

Some resources are immovable and others are difficult to move. If you decide you
can, and want, to move resources affected by the renaming:

1. Inventory the relevant resources and the associated mount paths.
1. Determine which resources you will migrate before activating the
deduplication flag.
- Resources migrating **before** deduplication will be unavailable on the
old and new paths until **deduplication** completes.
- Resources migrating **after** deduplication will be unavailable until
**migration** completes.
1. Move any resources flagged for migration before deduplication and alert the
relevant users that the paths will remain unavailable until deduplication
completes.
1. [Enable the deduplication option for Vault](/vault/docs/upgrading/deduplication#dedupe-flag)
1. Move any resources flagged for migration after deduplication and alert the
relevant users that the paths will remain unavailable until migration
completes and the changes fully propagate.
Loading