# Encrypt user passwords

SnowDDL provides functionality to encrypt user passwords, secrets and other sensitive information stored in YAML config. SnowDDL uses [Fernet](https://cryptography.io/en/latest/fernet/) symmetric encryption.

### 1) How to generate a key?

Run command in terminal:

```bash
snowddl-fernet generate-key --export
```

You'll get output similar to this:

```
export SNOWFLAKE_CONFIG_FERNET_KEYS=2jVoIQgHAbtVkj04J-NZp-x69DLaXyd7KKg4pfEn6qA=
```

This is your encryption key with added "export" command for convenience. Make sure to store this encryption key securely.

Run this command in order to set environment variable `SNOWFLAKE_CONFIG_FERNET_KEYS`, which is uses by other `snowddl-fernet` and `snowddl` commands.

Also, make sure to add this environment variable to CI/CD pipelines running `snowddl`.

### 2) How to encrypt a value?

Run command in terminal:

```bash
snowddl-fernet encrypt "my_secret_value"
```

You'll get output similar to this:

```
gAAAAABmlTl8AHfqJXFfDI4jqOGiaBLZ2dDMbMCqkNyOH_EzcRYGmFxSr_fvx8mgGBWD7sOYYIFCp5AqvG8k5kGM5R5ssYZgwA==
```

This is a value encrypted by key generated earlier.

### 3) How to use encrypted value in SnowDDL config?

Add encrypted value to SnowDDL config using [custom YAML tag](/basic/yaml-tag-decrypt.md) `!decrypt`:

```yaml
john_doe:
  first_name: John
  last_name: Doe
  password: !decrypt gAAAAABmlTl8AHfqJXFfDI4jqOGiaBLZ2dDMbMCqkNyOH_EzcRYGmFxSr_fvx8mgGBWD7sOYYIFCp5AqvG8k5kGM5R5ssYZgwA
```

You may use `!decrypt` tag with any string config parameters.

As long as valid Fernet key is present in `SNOWFLAKE_CONFIG_FERNET_KEYS` environment variable, SnowDDL will automatically decrypt values with `!decrypt` tag.

### 4) How to rotate encryption key?

Normally only account administrators should know the encryption key(s). If one of administrators leaves the company, keys should be rotated and values should be encrypted again in order to prevent this administrator from being able to decrypt future passwords.

In order to perform key rotation, please do the following steps:

1. Generate new key using command: `snowddl-fernet generate-key --export --prepend`.\
   \
   Option `--prepend` means that newly generated key will be added at the beginning of key sequence stored in`SNOWFLAKE_CONFIG_FERNET_KEYS`.<br>
2. Output of previous command will look like this:\
   `export SNOWFLAKE_CONFIG_FERNET_KEYS=<new_key>,<old_key>`\
   \
   Run it in terminal to update environment variable.<br>
3. Run command to rotate keys: `snowddl-fernet config-rotate -c <path_to_config>`.\
   \
   Encrypted values in YAML files will be decrypted by old key and encrypted once again with newly generated key.\
   \
   All values with `!decrypt` tag should be changed. Review & commit these changes to Git repository.<br>
4. Update config of CI/CD pipelines with `SNOWFLAKE_CONFIG_FERNET_KEYS=<new_key>`

### Full command reference

* `snowddl-fernet generate-key` - generate new encryption key
* `snowddl-fernet encrypt <value>` - encrypt string value with first key
* `snowddl-fernet decrypt <value>` - decrypt string value with any key
* `snowddl-fernet rotate <value>` - decrypt string value with any key and encrypt it again with first key
* `snowddl-fernet config-encrypt -c <path_to_config>` - encrypt and replace all values starting with YAML custom tag `!encrypt` in config
* `snowddl-fernet config-decrypt -c <path_to_config>` - decrypt and replace all values starting with YAML custom tag `!decrypt` in config
* `snowddl-fernet config-rotate -c <path_to_config>` - rotate and replace all values starting with YAML custom tag `!decrypt` in config

### Usage notes

* Encryption keys for `snowddl` command can ONLY be specified with environment variable `SNOWFLAKE_CONFIG_FERNET_KEYS`.
* Replacing values in YAML document is difficult if we want to preserve original formatting. The current approach relies on regular expressions looking for `!encrypt` and `!decrypt` tags. Only normal single-line scalar values are supported. No literal block scalars, no folded scalars.


---

# 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.snowddl.com/guides/other-guides/encrypt-user-passwords.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.
