Introduction
Username templating is a feature of various Vault secrets engines that allows operators to control how dynamic usernames are produced. The customization capability makes use of the Go template language, and some of the secrets engines that produce dynamic users for external systems allow Vault operators to customize how those usernames are generated. The format is defined by the username templates, which include static text, secret engine metadata, system information, and randomized values.
Scenarios:
In this section, we will look at a few real-world requirements where a unique username is required, as well as how to modify the username template to achieve them.
Scenario 1:
Customer logs into Vault from a Kubernetes Cluster that has an additional security layer of spiffe to access the database secret engine for cassandra plugin to produce dynamic credential with a specific username format
Below are the display name and required username
Display Name | Required UserName |
widp-spiffe://cmdb.hashicorp.net/kube_system | kube_system_random(8 characters) |
To achieve this, the below username template can be used which will generate the username kube_system_ appended with 8 random characters as seen below:
root@vaults0:/home/vagrant# vault write database/config/my-cassandra-database plugin_name="cassandra-database-plugin" hosts=192.168.50.40 protocol_version=4 username=vault password=vault allowed_roles=* username_template='{{.DisplayName | replace "widp-spiffe://cmdb.hashicorp.net/" ""}}_{{random 8}}'
#Success! Data written to: database/config/my-cassandra-database
root@vaults0:/home/vagrant# vault write database/roles/cas-role db_name=my-cassandra-database creation_statements="CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER;" default_ttl="10m" max_ttl="1h
#Success! Data written to: database/roles/cas-role
root@vaults0:/home/vagrant# vault read database/creds/cas-role
#Key Value
#--- -----
#lease_id database/creds/cas-role/DHT1nVmB7nbORrbysvVQQPSo
#lease_duration 10m
#lease_renewable true
#password Q90cP4HR-HWNuWJAE59M
#username kube_system_blPM9Bhx
Scenario 2:
The client has LDAP Auth configured on Vault and would like to append uppercase V to the username specified in the DisplayName, with unix_time appended towards the end. The generated username must be all uppercase.
Below are the display name and required username
Display Name | Required UserName |
oracle_auth_poc-auth-ldap-ashish | V_ASHISH_1694674885 |
The below username template will generate the username V_ASHISH_ appended with unix_time:
root@vaults0:/home/vagrant# vault write database/config/my-oracle-database plugin_name=oracle-database-plugin connection_url="{{username}}/{{password}}@localhost:1521/OraDoc.localhost" allowed_roles="*" username="vault_admin" password="myreallysecurepassword" username_template='V_{{.DisplayName | replace "oracle_auth_poc-auth-ldap-" "" | uppercase}}_{{unix_time}}'
#Success! Data written to: database/config/my-oracle-database
root@vaults0:/home/vagrant# vault write database/roles/oracle-role db_name=my-oracle-database creation_statements='CREATE USER {{username}} IDENTIFIED BY "{{password}}"; GRANT CONNECT TO {{username}}; GRANT CREATE SESSION TO {{username}};' default_ttl="1h" max_ttl="24h"
#Success! Data written to: database/roles/oracle-role
root@vaults0:/home/vagrant# vault read database/creds/oracle-role
#Key Value
#--- -----
#lease_id database/creds/oracle-role/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6
#lease_duration 1h
#lease_renewable true
#password yRUSyd-vPYDg5NkU9kDg
#username V_ASHISH_1694674885
Scenario 3:
The client has OIDC auth enabled on Vault and would like to remove the special character @ , companyname.com and oidc string from the display name. The requirement is just to keep the username and replace the (.) with underscore (_) appended by unix time in milliseconds.
Below are the display name and required username
Display Name | Required UserName |
oidc-ashish.garg@hashicorp.com | ashish_garg_1696688775000 |
The below username template will generate the username ashish_garg and will replace the period(.) with underscore(_):
root@vaults0:/home/vagrant# vault write database/config/my-postgresql-database plugin_name="postgresql-database-plugin" allowed_roles="*" connection_url="postgresql://{{username}}:{{password}}@localhost:5432/database-name" username="vaultroot" password="vaultpass" username_template='{{.DisplayName | replace "@hashicorp.com" "" | replace "oidc-" "" | replace "." "-"}}_{{unix_time_millis}}'
#Success! Data written to: database/config/my-postgresql-database
root@vaults0:/home/vagrant# vault write database/roles/postgres-role db_name="my-postgresql-database"creation_statements="CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";"default_ttl="1h"max_ttl="24h"
#Success! Data written to: database/roles/postgres-role
root@vaults0:/home/vagrant# vault read database/creds/postgres-role
#Key Value
#--- -----
#lease_id database/creds/postgres-role/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6
#lease_duration 1h
#lease_renewable true
#password SsnoaA-8Tv4t34f41baD
#username ashish_garg_1696688791000
Scenario 4:
The client has OIDC auth enabled on Vault and the username has cutoff the role name because of the character limit. The username created will be vault-OIDCAuthName-EntityAlias-RoleNamexxxxx and due to the long username the role name cuts off or not displayed at all. The requirement is to display the complete role name and cut off the username to accommodate the role name.
Below are the display name and required username:
Display Name | Required UserName |
vault-oidc-google-oauth2_106598944214391708799-myaws-new-testing | vault-oidc-google-oauth2-myaws-new-testing-role-1708973570-xRi2X |
The below command for configuring AWS auth method uses a username template which will cutoff the username at 18 characters and therefore will allow the role name to be displayed. This number can be changed as per the requirement.
vault write aws/config/root \
access_key=XXXXXXXXXX \
secret_key=XXXXXXXXXX \
region=us-east-1 \
username_template='{{ printf "vault-%s-%s-%s" (printf "%s-%s" (.DisplayName | truncate 18) (.PolicyName | truncate 42)) (unix_time) (random 20) | truncate 64 }}'
References: