4.8 KiB
Requesting a client certificate from a remote Vault server with user and password authentication
This guide shows how an administrator configures the Vault userpass authentication method, and how a user logs in to a remote Vault server and gets a client certificate signed by the Vault CA.
Prerequisites
- The Vault PKI configured as described in step 1a of the main
README.md: thepki_intmount and thewif-clientrole (vault_configure.sh). - A Vault server reachable over HTTPS. The examples use
https://vault.koszewscy.waw.pl. vaultandopensslon the workstation of the administrator and of the user, and Node.js 24 or later on the workstation of the administrator.
The commands are written for bash.
1. Configure the authentication
Role: Administrator
Point the CLI at the server and authenticate with an administrator token:
export VAULT_ADDR=https://vault.koszewscy.waw.pl
export VAULT_TOKEN=<admin-token>
- Create a policy that allows signing certificate requests with the
wif-clientrole and nothing else. - Enable the userpass authentication method.
- Create the user with
vault_create_user.mjsand attach the policy. The token of the user is valid for 15 minutes and can be renewed up to 1 hour.
pki-client.hcl:
path "pki_int/sign/wif-client" {
capabilities = ["update"]
}
vault policy write pki-client pki-client.hcl
vault auth enable userpass
./vault_create_user.mjs --policy pki-client alice
vault_create_user.mjs takes the user name and one or more --policy options, one for each policy. The optional --token-ttl (default 15m) and --token-max-ttl (default 1h) options set the lifetime of the tokens of the user. It asks for the password twice without echoing it and creates the user through the Vault HTTP API with the VAULT_ADDR and VAULT_TOKEN of the administrator. The password never appears in the process list or in the shell history. It needs only Node.js 24 or later, no npm packages. When the server certificate is issued by a private CA, point Node.js at the CA certificate:
export NODE_EXTRA_CA_CERTS=/path/to/server-ca.pem
Note: The
wif-clientrole accepts any common name (allow_any_name=true). Every user with thepki-clientpolicy can therefore request a certificate with any subject CN, including the CN that other users or workloads rely on as the WiF subject. Restrict the role (allowed_domains,allow_bare_domains,enforce_hostnames) when the users must not choose their CN freely.
2. Request a certificate
Role: User
-
Set the address of the Vault server. Set
VAULT_CACERTas well when the server certificate is issued by a private CA.export VAULT_ADDR=https://vault.koszewscy.waw.pl export VAULT_CACERT=/path/to/server-ca.pem -
Unset
VAULT_TOKEN, because a token in this environment variable takes precedence over the token stored byvault loginand the CLI would keep using it. Then log in. The CLI asks for the password and stores the token in the token helper file (~/.vault-token).unset VAULT_TOKEN vault login -method=userpass username=alice -
Generate the client key and the CSR locally. The key is never sent to Vault.
openssl req \ -newkey rsa:4096 \ -keyout client_key.pem \ -noenc \ -subj "/CN=test-client" \ -out client.csr -
Sign the CSR with the Vault CA.
vault write -field=certificate pki_int/sign/wif-client \ csr=@client.csr \ common_name=test-client \ ttl=8760h > client_cert.pem -
Check the certificate.
openssl x509 -in client_cert.pem -noout -subject -issuer -dates -ext extendedKeyUsage -
Revoke the token when the work is done.
vault token revoke -self
The user token can only sign with the wif-client role. Reading the role or any other path returns permission denied.
To avoid storing the token on disk, log in with -no-store -token-only and keep the token in the environment:
export VAULT_TOKEN=$(vault login -no-store -token-only -method=userpass username=alice)
Next steps
-
Create the credentials configuration
cred.jsonforclient_cert.pemandclient_key.pem. The names come fromenv.sh.gcloud iam workload-identity-pools create-cred-config \ "projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL_ID}/providers/${PROVIDER_ID}" \ --service-account="${SA_EMAIL}" \ --credential-cert-path=client_cert.pem \ --credential-cert-private-key-path=client_key.pem \ --output-file=cred.json -
Activate the service account with
gcloud auth login --cred-file=cred.json. -
Run the WIF tests.
Example test commands are in test_wif.sh.