---
layout: docs
page_title: Save random strings
description: >-
   Use password policies and the key/value v2 plugins to generate and store
   random strings in Vault.
---

# Save random strings to the key/value v2 plugin

Use [password policies](/vault/docs/concepts/password-policies) to generate
random strings and save the strings to your key/value v2 plugin.

## Before you start 

- **You must have `read`, `create`, and `update` permission for password policies.
- **You must have `create` and `update` permission for your `kv` v2 plugin**.


## Step 1: Create a password policy file

Create an HCL file with a password policy with the desired randomization and
generation rules.

For example, the following password policy requires a string 20 characters long
that includes:

- at least one lowercase character
- at least one uppercase character
- at least one number
- at least two special characters

```hcl
length=20

rule "charset" {
  charset = "abcdefghijklmnopqrstuvwxyz"
  min-chars = 1
}

rule "charset" {
  charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  min-chars = 1
}

rule "charset" {
  charset = "0123456789"
  min-chars = 1
}

rule "charset" {
  charset = "!@#$%^&*STUVWXYZ"
  min-chars = 2
}
```


## Step 2: Save the password policy

<Tabs>

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

Use `vault write` to save policies to the password policies endpoint
(`sys/policies/password/<policy_name>`):

```shell-session
$ vault write sys/policies/password/<policy_name> policy=@<policy_file>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault write sys/policies/password/randomize policy=@password-rules.hcl

Success! Data written to: sys/policies/password/randomize
```

</CodeBlockConfig>

</Tab>

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

Escape your password policy file and make a `POST` call to
[`/sys/policies/password/{policy_name}`](/vault/api-docs/system/policies-password#create-update-password-policy)
with your password creation rules:

```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/sys/policies/password/<policy_name>
```

For example:

<CodeBlockConfig hideClipboard="true">

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

</CodeBlockConfig>

`/sys/policies/password/{policy_name}` does not return data on success.

</Tab>

</Tabs>



## Step 3: Save a random string to `kv` v2

<Tabs>

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

Use `vault read` and the `generate` endpoint of the new password policy to
generate a new random string and write it to the `kv` plugin with
`vault kv put`:

```shell-session
$ vault kv put                                    \
  -mount <mount_path>                             \
  <secret_path>                                   \
  <key_name>=$(                                   \
    vault read -field password                    \
    sys/policies/password/<policy_name>/generate  \
  )
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault kv put                                \
  -mount shared                               \
  /dev/seeds                                  \
  seed1=$(                                    \
    vault read -field password                \
    sys/policies/password/randomize/generate  \
  )

==== Secret Path ====
shared/data/dev/seeds

======= Metadata =======
Key                Value
---                -----
created_time       2024-11-15T23:15:31.929717548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1
```

</CodeBlockConfig>

</Tab>

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

Use the
[`/sys/policies/password/{policy_name}/generate`](/vault/api-docs/system/policies-password#generate-password-from-password-policy)
endpoint of the new password policy to generate a random string and write it to
the `kv` plugin with a `POST` call to
[`/{plugin_mount_path}/data/{secret_path}`](/vault/api-docs/secret/kv/kv-v2#create-update-secret):

```shell-session
$ curl                                        \
    --request POST                            \
    --header "X-Vault-Token: ${VAULT_TOKEN}"  \
    --data                                    \
    "{
    \"data\": {
      \"<key_name>\": \"$(
        vault read -field password sys/policies/password/<policy_name>/generate
      )\"
      }
    }"                                        \
    ${VAULT_ADDR}/v1/<plugin_mount_path>/data/<secret_path>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ curl                                        \
    --request POST                            \
    --header "X-Vault-Token: ${VAULT_TOKEN}"  \
    --data                                    \
    "{
    \"data\": {
      \"seed1\": \"$(
        vault read -field password sys/policies/password/randomize/generate
      )\"
      }
    }"                                        \
    ${VAULT_ADDR}/v1/shared/data/dev/seeds | jq

{
  "request_id": "f9fad221-74e7-72c4-3f5a-9364944c37d9",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "created_time": "2024-11-15T23:33:08.549750507Z",
    "custom_metadata": null,
    "deletion_time": "",
    "destroyed": false,
    "version": 1
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null,
  "mount_type": "kv"
}
```

</CodeBlockConfig>

</Tab>

</Tabs>

## Step 4: Verify the data in Vault

<Tabs>

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

Use [`vault kv get`](/vault/docs/command/kv/read) with the `-field` flag to read
the randomized string from the relevant secret path:

```shell-session
$ vault kv get          \
   -mount <mount_path>  \
   -field <field_name>  \
   <secret_path>       
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault kv get -mount shared -field seed1 dev/seeds

g0bc0b6W3ii^SXa@*ie5
```

</CodeBlockConfig>

</Tab>

<Tab heading="GUI" group="gui">

@include 'gui-instructions/plugins/kv/open-overview.mdx'

- Select the **Secret** tab.

- Click the eye icon to view the desired key value.

![Partial screenshot of the Vault GUI showing the randomized string stored at the path dev/seeds.](/img/gui/kv/random-string.png)

</Tab>

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

Call the [`/{plugin_mount_path}/data/{secret_path}`](/vault/api-docs/secret/kv/kv-v2#read-secret-version)
endpoint to read all the key/value pairs at the secret path:

```shell-session
$ curl                                       \
   --request GET                             \
   --header "X-Vault-Token: ${VAULT_TOKEN}"  \
   ${VAULT_ADDR}/v1/<plugin_mount_path>/data/<secret_path>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ curl                                       \
   --request GET                             \
   --header "X-Vault-Token: ${VAULT_TOKEN}"  \
   ${VAULT_ADDR}/v1/shared/data/dev/seeds | jq

{
  "request_id": "c1202e8d-aff9-2d81-0929-4a558a193b4c",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "data": {
      "seed1": "g0bc0b6W3ii^SXa@*ie5"
    },
    "metadata": {
      "created_time": "2024-11-15T23:33:08.549750507Z",
      "custom_metadata": null,
      "deletion_time": "",
      "destroyed": false,
      "version": 1
    }
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null,
  "mount_type": "kv"
}
```

</CodeBlockConfig>

</Tab>

</Tabs>
