diff --git a/changelog/10766.txt b/changelog/10766.txt new file mode 100644 index 000000000..566add0de --- /dev/null +++ b/changelog/10766.txt @@ -0,0 +1,3 @@ +```release-note:feature +secrets/database/postgresql: Add ability to customize dynamic usernames +``` diff --git a/changelog/10767.txt b/changelog/10767.txt new file mode 100644 index 000000000..1b8fb4956 --- /dev/null +++ b/changelog/10767.txt @@ -0,0 +1,3 @@ +```release-note:feature +secrets/database/mssql: Add ability to customize dynamic usernames +``` diff --git a/changelog/10834.txt b/changelog/10834.txt new file mode 100644 index 000000000..ad2e57e5c --- /dev/null +++ b/changelog/10834.txt @@ -0,0 +1,3 @@ +```release-note:feature +secrets/database/mysql: Add ability to customize dynamic usernames +``` diff --git a/changelog/10858.txt b/changelog/10858.txt new file mode 100644 index 000000000..028831676 --- /dev/null +++ b/changelog/10858.txt @@ -0,0 +1,3 @@ +```release-note:feature +secrets/database/mongodb: Add ability to customize dynamic usernames +``` diff --git a/changelog/10906.txt b/changelog/10906.txt new file mode 100644 index 000000000..0b485056b --- /dev/null +++ b/changelog/10906.txt @@ -0,0 +1,3 @@ +```release-note:feature +secrets/database/cassandra: Add ability to customize dynamic usernames +``` diff --git a/website/content/api-docs/secret/aws.mdx b/website/content/api-docs/secret/aws.mdx index 595004389..27dba7890 100644 --- a/website/content/api-docs/secret/aws.mdx +++ b/website/content/api-docs/secret/aws.mdx @@ -336,8 +336,10 @@ Using groups: ``` Using tags: + + ```json { "credential_type": "iam_user", @@ -357,6 +359,7 @@ Using tags: } } ``` + ```bash diff --git a/website/content/api-docs/secret/databases/cassandra.mdx b/website/content/api-docs/secret/databases/cassandra.mdx index ad5f609c8..505990123 100644 --- a/website/content/api-docs/secret/databases/cassandra.mdx +++ b/website/content/api-docs/secret/databases/cassandra.mdx @@ -73,6 +73,34 @@ has a number of parameters to further configure a connection. definition](https://github.com/gocql/gocql/blob/master/frame.go#L188) for valid options. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +{{ printf "v_%s_%s_%s_%s" (.DisplayName | truncate 15) (.RoleName | truncate 15) (random 20) (unix_time) | truncate 100 | replace "-" "_" | lowercase }} +``` + +
+Example Usernames: + +| Example | | +| ------------- | ---------------------------------------------------- | +| `DisplayName` | `token` | +| `RoleName` | `myrolename` | +| Username | `v_token_myrolename_uszt1n4cyhal4m0xtgx3_1614294836` | + +| Example | | +| ------------- | ------------------------------------------------------------------- | +| `DisplayName` | `amuchlonger_dispname` | +| `RoleName` | `role-name-with-dashes` | +| Username | `v_amuchlonger_dis_role_name_with__s0t9xb0jsab9nqz7yj40_1614294836` | + +
+
+ TLS works as follows: - If `tls` is set to true, the connection will use TLS; this happens diff --git a/website/content/api-docs/secret/databases/couchbase.mdx b/website/content/api-docs/secret/databases/couchbase.mdx index 6125f0c5e..87574a6f9 100644 --- a/website/content/api-docs/secret/databases/couchbase.mdx +++ b/website/content/api-docs/secret/databases/couchbase.mdx @@ -46,6 +46,34 @@ has a number of parameters to further configure a connection. - `bucket_name` `(string: "")` - Required for Couchbase versions prior to 6.5.0. This is only used to verify vault's connection to the server. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +V_{{.DisplayName | uppercase | truncate 64}}_{{.RoleName | uppercase | truncate 64}}_{{random 20 | uppercase}}_{{unix_time}} +``` + +
+ Example Usernames: + + | Example | | + | ------------- | ---------------------------------------------------- | + | `DisplayName` | `token` | + | `RoleName` | `myrolename` | + | Username | `V_TOKEN_MYROLENAME_USZT1N4CYHAL4M0XTGX3_1614294836` | + + | Example | | + | ------------- | ------------------------------------------------------------------------------ | + | `DisplayName` | `amuchlonger_dispname` | + | `RoleName` | `role-name-with-dashes` | + | Username | `V_AMUCHLONGER_DISPNAME_ROLE-NAME-WITH-DASHES_S0T9XB0JSAB9NQZ7YJ40_1614294836` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/databases/mongodb.mdx b/website/content/api-docs/secret/databases/mongodb.mdx index a6c6f6242..618d71dfb 100644 --- a/website/content/api-docs/secret/databases/mongodb.mdx +++ b/website/content/api-docs/secret/databases/mongodb.mdx @@ -29,18 +29,51 @@ has a number of parameters to further configure a connection. connection string (URI). This field can be templated and supports passing the username and password parameters in the following format {{field_name}}. A templated connection URL is required when using root credential rotation. + - `write_concern` `(string: "")` - Specifies the MongoDB [write concern][mongodb-write-concern]. This is set for the entirety of the session, maintained for the lifecycle of the plugin process. Must be a serialized JSON object, or a base64-encoded serialized JSON object. The JSON payload values map to the values in the [Safe][mgo-safe] struct from the mgo driver. + - `username` `(string: "")` - The root credential username used in the connection URL. + - `password` `(string: "")` - The root credential password used in the connection URL. + - `tls_certificate_key` `(string: "")` - x509 certificate for connecting to the database. This must be a PEM encoded version of the private key and the certificate combined. + - `tls_ca` `(string: "")` - x509 CA file for validating the certificate presented by the MongoDB server. Must be PEM encoded. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 15) (.RoleName | truncate 15) (random 20) (unix_time) | truncate 100 }} +``` + +
+ Example Usernames: + + | Example | | + | ------------- | ---------------------------------------------------- | + | `DisplayName` | `token` | + | `RoleName` | `myrolename` | + | Username | `v-token-myrolename-jNFRlKsZZMxJEx60o66i-1614294836` | + + | Example | | + | ------------- | ------------------------------------------------------------------- | + | `DisplayName` | `amuchlonger_dispname` | + | `RoleName` | `role-name-with-dashes` | + | Username | `v-amuchlonger_dis-role-name-with--jNFRlKsZZMxJEx60o66i-1614294836` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/databases/mssql.mdx b/website/content/api-docs/secret/databases/mssql.mdx index 9dfd2f8bb..4ea6939b5 100644 --- a/website/content/api-docs/secret/databases/mssql.mdx +++ b/website/content/api-docs/secret/databases/mssql.mdx @@ -45,6 +45,34 @@ has a number of parameters to further configure a connection. - `password` `(string: "")` - The root credential password used in the connection URL. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 20) (.RoleName | truncate 20) (random 20) (unix_time) | truncate 128 }} +``` + +
+ Example Usernames: + + | Example | | + | ------------- | ---------------------------------------------------- | + | `DisplayName` | `token` | + | `RoleName` | `myrolename` | + | Username | `v-token-myrolename-jNFRlKsZZMxJEx60o66i-1614294836` | + + | Example | | + | ------------- | ----------------------------------------------------------------------------- | + | `DisplayName` | `amuchlonger_dispname` | + | `RoleName` | `role-name-with-dashes` | + | Username | `v-amuchlonger_dispname-role-name-with-dashe-LUHU9xqm6YNisikA3iCQ-1614294836` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/databases/mysql-maria.mdx b/website/content/api-docs/secret/databases/mysql-maria.mdx index 302f53e3b..c0d3d744c 100644 --- a/website/content/api-docs/secret/databases/mysql-maria.mdx +++ b/website/content/api-docs/secret/databases/mysql-maria.mdx @@ -51,6 +51,65 @@ has a number of parameters to further configure a connection. - `tls_ca` `(string: "")` - x509 CA file for validating the certificate presented by the MySQL server. Must be PEM encoded. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +**Default Username Templates:** + +
+mysql-database-plugin + +``` +{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 10) (.RoleName | truncate 10) (random 20) (unix_time) | truncate 32 }} +``` + +
+Example Usernames: + +| Example | | +| ------------- | ---------------------------------- | +| `DisplayName` | `token` | +| `RoleName` | `myrolename` | +| Username | `v-token-myrolename-jNFRlKsZZMxJE` | + +| Example | | +| ------------- | ---------------------------------- | +| `DisplayName` | `amuchlonger_dispname` | +| `RoleName` | `role-name-with-dashes` | +| Username | `v-amuchlonge-role-name--LUHU9xqm` | + +
+
+ +

+ +
+ + mysql-aurora-database-plugin, mysql-rds-database-plugin, mysql-legacy-database-plugin + + +``` +{{ printf "v-%s-%s-%s" (.RoleName | truncate 4) (random 20) | truncate 16 }} +``` + +
+ Example Usernames: + + | Example | | + | ------------- | ------------------ | + | `DisplayName` | `token` | + | `RoleName` | `myrolename` | + | Username | `v-myro-jNFRlKsZZ` | + + | Example | | + | ------------- | ----------------------- | + | `DisplayName` | `amuchlonger_dispname` | + | `RoleName` | `role-name-with-dashes` | + | Username | `v-role-b9ODeKsfl` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/databases/oracle.mdx b/website/content/api-docs/secret/databases/oracle.mdx index 4c5d13341..93a862b7b 100644 --- a/website/content/api-docs/secret/databases/oracle.mdx +++ b/website/content/api-docs/secret/databases/oracle.mdx @@ -42,6 +42,34 @@ has a number of parameters to further configure a connection. - `password` `(string: "")` - The root credential password used in the connection URL. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +{{ printf "V_%s_%s_%s_%s" (.DisplayName | truncate 8) (.RoleName | truncate 8) (random 20) (unix_time) | truncate 30 | uppercase | replace "-" "_" | replace "." "_" }} +``` + +
+Example Usernames: + +| Example | | +| ------------- | -------------------------------- | +| `DisplayName` | `token` | +| `RoleName` | `myrolename` | +| Username | `V_TOKEN_MYROLENA_JNFRLKSZZMXJE` | + +| Example | | +| ------------- | -------------------------------- | +| `DisplayName` | `amuchlonger_dispname` | +| `RoleName` | `role-name-with-dashes` | +| Username | `V_AMUCHLON_ROLE_NAM_LUHU9XQM6Y` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/databases/postgresql.mdx b/website/content/api-docs/secret/databases/postgresql.mdx index e42c1e52b..66d5da968 100644 --- a/website/content/api-docs/secret/databases/postgresql.mdx +++ b/website/content/api-docs/secret/databases/postgresql.mdx @@ -45,6 +45,34 @@ has a number of parameters to further configure a connection. - `password` `(string: "")` - The root credential password used in the connection URL. +- `username_template` `(string)` - [Template](/docs/concepts/username-templating) describing how + dynamic usernames are generated. + +
+Default Username Template + +``` +{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 8) (.RoleName | truncate 8) (random 20) (unix_time) | truncate 63 }} +``` + +
+Example Usernames: + +| Example | | +| ------------- | -------------------------------------------------- | +| `DisplayName` | `token` | +| `RoleName` | `myrolename` | +| Username | `v-token-myrolena-jNFRlKsZZMxJEx60o66i-1614294836` | + +| Example | | +| ------------- | ----------------------------------------------------- | +| `DisplayName` | `amuchlonger_dispname` | +| `RoleName` | `role-name-with-dashes` | +| Username | `v-amuchlon-role-nam-LUHU9xqm6YNisikA3iCQ-1614294836` | + +
+
+ ### Sample Payload ```json diff --git a/website/content/api-docs/secret/openldap.mdx b/website/content/api-docs/secret/openldap.mdx index bb8fc59da..0e25e0a45 100644 --- a/website/content/api-docs/secret/openldap.mdx +++ b/website/content/api-docs/secret/openldap.mdx @@ -296,7 +296,32 @@ entries. All LDIF entries are performed in order. If Vault encounters an error w as a base64 encoded string. `username_template` `(string)` - A template used to generate a dynamic username. This will be used to fill in the -`.Username` field within the `creation_ldif` string. See appendix for available template functions. +`.Username` field within the `creation_ldif` string. + +
+Default Username Template + +``` +v_{{.DisplayName}}_{{.RoleName}}_{{random 10}}_{{unix_time}} +``` + +
+Example Usernames: + +| Example | | +| ------------- | ------------------------------------------ | +| `DisplayName` | `token` | +| `RoleName` | `myrolename` | +| Username | `v_token_myrolename_uszt1n4cyh_1614294836` | + +| Example | | +| ------------- | -------------------------------------------------------------------- | +| `DisplayName` | `amuchlonger_dispname` | +| `RoleName` | `role-name-with-dashes` | +| Username | `v_amuchlonger_dispname_role-name-with-dashes_s0t9xb0jsa_1614294836` | + +
+
`default_ttl` `(string/int)` - Specifies the TTL for the leases associated with this role. Accepts time suffixed strings ("1h") or an integer number of seconds. Defaults to system/engine default TTL time. The @@ -307,6 +332,10 @@ strings ("1h") or an integer number of seconds. Defaults to system/mount default be less than the mount max TTL (or, if not set, the system max TTL), but it is not allowed to be longer. The [available units](https://golang.org/pkg/time/#ParseDuration) are: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. +The `creation_ldif`, `deletion_ldif`, `rollback_ldif`, and `username_template` fields are all templated fields. See +[Username Templating](/docs/concepts/username-templating) for details on how to use templating. Also see +[Templates](#templates) for specifics on what data is available for each template. + #### Sample Payload Sample LDIF files: diff --git a/website/content/docs/concepts/username-templating.mdx b/website/content/docs/concepts/username-templating.mdx new file mode 100644 index 000000000..3e694bf50 --- /dev/null +++ b/website/content/docs/concepts/username-templating.mdx @@ -0,0 +1,143 @@ +--- +layout: docs +page_title: Username Templating +sidebar_title: Username Templating +description: >- + Username templating are used in some secret engines to allow operators to define + how dynamic usernames are generated. +--- + +# Username Templating + +Some of the secrets engines that generate dynamic users for external systems provide the ability for Vault operators +to customize how usernames are generated for said external systems. This customization feature uses the +[Go template language](https://golang.org/pkg/text/template/). This page describes the basics of using these templates +for username generation but does not go into great depth of using the templating language for more advanced usages. +See the API documentation for the given secret engine to determine if it supports username templating and for more +details on using it with that engine. + +~> When customizing how usernames are generated, take care to ensure you have enough randomness to ensure uniqueness + otherwise multiple calls to create the credentials may interfere with each other. + +In addition to the functionality built into the Go template language, a number of additional functions are available: + +## Available Functions + +### String/Character Manipulation + +`lowercase` - Lowercases the input value.
+**Example**: `{{.FieldName | lowercase}}` + +`replace` - Find/replace on the input value.
+**Example**: `{{.FieldName | replace - _}}` + +`truncate` - truncates the input value to the specified number of characters.
+**Example**: `{{.FieldName | truncate 10}}` + +`truncate_sha256` - Truncates the input value to the specified number of characters. The last 8 characters of the +new value will be replace by the first 8 characters of the SHA256 hash of the truncated characters.
+**Example**: `{{.FieldName | truncate_sha256 20}}`. If `FieldName` is `abcdefghijklmnopqrstuvwxyz`, all characters after +the 12th (`l`) are removed and SHA256 hashed (`872808ffbf...1886ca6f20`). +The first 8 characters of the hash (`872808ff`) are then appended to the end of the first 12 characters from the +original value: `abcdefghijkl872808ff`. + +`uppercase` - Uppercases the input value.
+**Example**: `{{.FieldName | uppercase}}` + +### Generating Values + +`random` - Generates a random string from lowercase letters, uppercase letters, and numbers. Must include a +number indicating how many characters to generate.
+**Example**: `{{random 20}}` generates 20 random characters + +`timestamp` - The current time. Must provide a formatting string based on Go’s [time package](https://golang.org/pkg/time/).
+**Example**: `{{timestamp "2006-01-02T15:04:05Z"}}` + +`unix_time` - The current unix timestamp (number of seconds since Jan 1 1970).
+**Example**: `{{unix_time}}` + +`unix_time_millis` - The current unix timestamp in milliseconds.
+**Example**: `{{unix_time_millis}}` + +`uuid` - Generates a random UUID.
+**Example**: `{{uuid}}` + +### Hashing + +`base64` - Base64 encodes the input value.
+**Example**: `{{.FieldName | base64}}` + +`sha256` - SHA256 hashes the input value.
+**Example**: `{{.FieldName | sha256}}` + +## Examples + +Each secret engine provides a different set of data to the template. Please see the associated secret engine's +documentation for details on what values are provided to the template. The examples below are modeled after the +[Database engine's](/docs/secrets/databases) data, however the specific fields that are provided from a given engine +may differ from these examples. Additionally, the time is assumed to be 2009-02-13 11:31:30PM GMT +(unix timestamp: 1234567890) and random characters are the ordered english alphabet: `abcdefghijklmnopqrstuvwxyz`. + +-> Note: The space between `{{`/`}}` and the values/functions are optional. + For instance: `{{.DisplayName}}` is equivalent to `{{ .DisplayName }}` + +| Field name | Value | +| ------------- | ----- | +| `DisplayName` | `token-with-display-name` | +| `RoleName` | `my_custom_database_role` | + +To reference either of these fields, a `.` must be put in front of the field name: `{{.DisplayName}}`. Custom functions +do not include a `.` in front of them: `{{random 20}}`. + +### Basic Example + +**Template**: +``` +{{.DisplayName}}_{{.RoleName}} +``` +**Username**: +``` +token-with-display-name_my_custom_database_role +``` + +This is a basic example that references the two fields that are provided to the template. In simplest terms, this is +a simple string substitution. + +~> This example does not have any randomness and should not be used when generating dynamic usernames. The purpose is to + demonstrate referencing data within the Go template language. + +### Custom Functions + +**Template**: +``` +FOO_{{.DisplayName | replace "-" "_" | uppercase}}_{{.RoleName | replace "-" "_" | uppercase}}_{{timestamp "2006_01_02T15_04_05Z" | replace "-" "_"}} +``` +**Username**: +``` +FOO_TOKEN_WITH_DISPLAY_NAME_MY_CUSTOM_DATABASE_ROLE_2009_02_13T11_31_30Z_0700 +``` + +`{{.DisplayName | replace "-" "_" | uppercase}}` - Replaces all dashes with underscores and then uppercases the display name.
+`{{.RoleName | replace "-" "_" | uppercase}}` - Replaces all dashes with underscores and then uppercases the role name.
+`{{timestamp "2006_01_02T15_04_05Z" | replace "-" "_"}}` - Generates the current timestamp using the provided format and +replaces all dashes with underscores. + +### Truncating to Maximum Length + +**Template**: +``` +{{printf "v_%s_%s_%s_%s" (.DisplayName | truncate 8) (.RoleName | truncate 8) (random 20) (unix_time) | truncate 45}} +``` +**Username**: +``` +v_token-wi_my_custo_abcdefghijklmnopqrst_1234 +``` + +`.DisplayName | truncate 8` truncates the display name to 8 characters (`token-wi`).
+`.RoleName | truncate 8` truncates the role name to 8 characters (`my_custo`).
+`random 20` generates 20 random characters `abcdefghijklmnopqrst`.
+`unix_time` generates the current timestamp as the number of seconds since January 1, 1970 (`1234567890`).
+ +Each of these values are passed to `printf "v_%s_%s_%s_%s"` which prepends them with `v_` and puts an underscore between +each field. This results in `v_token-wi_my_custo_abcdefghijklmnopqrst_1234567890`. This value is then passed to +`truncate 45` where the last 6 characters are removed which results in `v_token-wi_my_custo_abcdefghijklmnopqrst_1234`. diff --git a/website/data/docs-navigation.js b/website/data/docs-navigation.js index 06f9f6539..dbaf24508 100644 --- a/website/data/docs-navigation.js +++ b/website/data/docs-navigation.js @@ -33,13 +33,14 @@ export default [ 'response-wrapping', 'policies', 'password-policies', + 'username-templating', 'ha', 'integrated-storage', 'pgp-gpg-keybase', 'recovery-mode', 'resource-quotas', 'client-count', - 'transform', + 'transform' ], }, {