Added guides for requesting certificates remotely using
username-password or Entra ID authentication.
This commit is contained in:
1 parent
b60d3080a9
commit
947abfc97c
4 files changed
+255
No files matched your search
@@ -11,3 +11,4 @@ vault-data/
|
|||||||
vault-init.txt
|
vault-init.txt
|
||||||
vault.hcl
|
vault.hcl
|
||||||
*.csr
|
*.csr
|
||||||
|
editor.json
|
||||||
@@ -142,6 +142,8 @@ bash vault_gcp_update.sh
|
|||||||
|
|
||||||
For a new setup, continue with step 2 instead.
|
For a new setup, continue with step 2 instead.
|
||||||
|
|
||||||
|
Requesting the client certificate from a remote Vault server with a user account is described in `docs/vault-userpass.md` (user and password) and `docs/vault-entra-id.md` (Microsoft Entra ID).
|
||||||
|
|
||||||
## 2. Create the trust store
|
## 2. Create the trust store
|
||||||
|
|
||||||
`make_trust_store.mjs` creates `trust_store.yaml`, a YAML file that holds the root CA as the trust anchor and the issuing CA as an intermediate CA. It uses the `yaml` npm package, declared in `package.json`:
|
`make_trust_store.mjs` creates `trust_store.yaml`, a YAML file that holds the root CA as the trust anchor and the issuing CA as an intermediate CA. It uses the `yaml` npm package, declared in `package.json`:
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
# Requesting a client certificate from a remote Vault server with Microsoft Entra ID authentication
|
||||||
|
|
||||||
|
This guide shows how an administrator configures the Vault OIDC authentication method with Microsoft Entra ID as the identity provider, and how a user logs in with the Entra ID account 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`: the `pki_int` mount and the `wif-client` role (`vault_configure.sh`).
|
||||||
|
- A Vault server reachable over HTTPS. The examples use `https://vault.example.com:8200`.
|
||||||
|
- Permissions to register applications in the Entra ID tenant.
|
||||||
|
- `vault` and `openssl` on the workstation of the administrator and of the user, and a web browser on the workstation of the user.
|
||||||
|
|
||||||
|
The commands are written for bash.
|
||||||
|
|
||||||
|
## 1. Register the application in Entra ID
|
||||||
|
|
||||||
|
Role: **Administrator**
|
||||||
|
|
||||||
|
1. Register an application for Vault in the tenant.
|
||||||
|
2. Add the redirect URIs of the type "Web":
|
||||||
|
|
||||||
|
- `http://localhost:8250/oidc/callback` for the CLI login.
|
||||||
|
- `https://vault.example.com:8200/ui/vault/auth/oidc/oidc/callback` for the Vault UI login.
|
||||||
|
|
||||||
|
3. Record the **Application (client) ID** and the **Directory (tenant) ID**.
|
||||||
|
4. Under **Certificates & secrets**, create a client secret and record its value.
|
||||||
|
5. Under **Token configuration**, add a groups claim and select the ID token.
|
||||||
|
6. Create a security group of the users who may request certificates, add the users to it, and record the **Object ID** of the group.
|
||||||
|
7. Under **API permissions**, add the Microsoft Graph delegated permission `User.Read` and grant the admin consent. Entra ID omits the groups from the token of users who are members of more than 200 groups, and Vault then reads them through Graph.
|
||||||
|
|
||||||
|
## 2. Configure Vault
|
||||||
|
|
||||||
|
Role: **Administrator**
|
||||||
|
|
||||||
|
Point the CLI at the server and authenticate with an administrator token:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_ADDR=https://vault.example.com:8200
|
||||||
|
export VAULT_TOKEN=<admin-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Create a policy that allows signing certificate requests with the `wif-client` role and nothing else.
|
||||||
|
2. Enable the OIDC authentication method and configure Entra ID as the provider.
|
||||||
|
3. Create a role that accepts only members of the group and attaches the policy. The token is valid for 15 minutes and can be renewed up to 1 hour.
|
||||||
|
|
||||||
|
`pki-client.hcl`:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
path "pki_int/sign/wif-client" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault policy write pki-client pki-client.hcl
|
||||||
|
|
||||||
|
vault auth enable oidc
|
||||||
|
|
||||||
|
vault write auth/oidc/config - <<'EOF'
|
||||||
|
{
|
||||||
|
"oidc_discovery_url": "https://login.microsoftonline.com/<tenant-id>/v2.0",
|
||||||
|
"oidc_client_id": "<client-id>",
|
||||||
|
"oidc_client_secret": "<client-secret>",
|
||||||
|
"default_role": "entra-pki",
|
||||||
|
"provider_config": {
|
||||||
|
"provider": "azure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
vault write auth/oidc/role/entra-pki - <<'EOF'
|
||||||
|
{
|
||||||
|
"role_type": "oidc",
|
||||||
|
"user_claim": "sub",
|
||||||
|
"allowed_redirect_uris": [
|
||||||
|
"http://localhost:8250/oidc/callback",
|
||||||
|
"https://vault.example.com:8200/ui/vault/auth/oidc/oidc/callback"
|
||||||
|
],
|
||||||
|
"groups_claim": "groups",
|
||||||
|
"oidc_scopes": ["profile"],
|
||||||
|
"bound_claims": {"groups": ["<group-object-id>"]},
|
||||||
|
"token_policies": ["pki-client"],
|
||||||
|
"token_ttl": "15m",
|
||||||
|
"token_max_ttl": "1h"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
The redirect URIs in the role must match the ones registered in Entra ID exactly, including the scheme, the port and the trailing path. The `bound_claims` entry limits the login to the members of the group, the other Entra ID users get an error at login.
|
||||||
|
|
||||||
|
The commands above pass JSON on standard input, because the CLI cannot express the `bound_claims` map as `key=value` arguments.
|
||||||
|
|
||||||
|
> **Note:** The `wif-client` role accepts any common name (`allow_any_name=true`). Every member of the group 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.
|
||||||
|
|
||||||
|
## 3. Request a certificate
|
||||||
|
|
||||||
|
Role: **User**
|
||||||
|
|
||||||
|
1. Set the address of the Vault server. Set `VAULT_CACERT` as well when the server certificate is issued by a private CA.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_ADDR=https://vault.example.com:8200
|
||||||
|
export VAULT_CACERT=/path/to/server-ca.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in with the Entra ID account. The CLI starts a listener on `localhost:8250` and opens the browser with the Entra ID sign-in page. After the sign-in the CLI stores the token in the token helper file (`~/.vault-token`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault login -method=oidc role=entra-pki
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Generate the client key and the CSR locally. The key is never sent to Vault.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl req \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-keyout client_key.pem \
|
||||||
|
-noenc \
|
||||||
|
-subj "/CN=test-client" \
|
||||||
|
-out client.csr
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Sign the CSR with the Vault CA.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault write -field=certificate pki_int/sign/wif-client \
|
||||||
|
csr=@client.csr \
|
||||||
|
common_name=test-client \
|
||||||
|
ttl=8760h > client_cert.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Check the certificate.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl x509 -in client_cert.pem -noout -subject -issuer -dates -ext extendedKeyUsage
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Revoke the token when the work is done.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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`.
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
# 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`: the `pki_int` mount and the `wif-client` role (`vault_configure.sh`).
|
||||||
|
- A Vault server reachable over HTTPS. The examples use `https://vault.example.com:8200`.
|
||||||
|
- `vault` and `openssl` on the workstation of the administrator and of the user.
|
||||||
|
|
||||||
|
The commands are written for bash.
|
||||||
|
|
||||||
|
## 1. Configure the authentication
|
||||||
|
|
||||||
|
Role: **Administrator**
|
||||||
|
|
||||||
|
Point the CLI at the server and authenticate with an administrator token:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_ADDR=https://vault.example.com:8200
|
||||||
|
export VAULT_TOKEN=<admin-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Create a policy that allows signing certificate requests with the `wif-client` role and nothing else.
|
||||||
|
2. Enable the userpass authentication method.
|
||||||
|
3. Create the user and attach the policy. The token of the user is valid for 15 minutes and can be renewed up to 1 hour.
|
||||||
|
|
||||||
|
`pki-client.hcl`:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
path "pki_int/sign/wif-client" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault policy write pki-client pki-client.hcl
|
||||||
|
|
||||||
|
vault auth enable userpass
|
||||||
|
|
||||||
|
read -r -s -p "Password: " PASSWORD; echo
|
||||||
|
printf '%s' "${PASSWORD}" | vault write auth/userpass/users/alice \
|
||||||
|
password=- \
|
||||||
|
token_policies=pki-client \
|
||||||
|
token_ttl=15m \
|
||||||
|
token_max_ttl=1h
|
||||||
|
unset PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
`password=-` makes the CLI read the password from standard input, so it does not appear in the process list or in the shell history.
|
||||||
|
|
||||||
|
> **Note:** The `wif-client` role accepts any common name (`allow_any_name=true`). Every user with the `pki-client` policy 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**
|
||||||
|
|
||||||
|
1. Set the address of the Vault server. Set `VAULT_CACERT` as well when the server certificate is issued by a private CA.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_ADDR=https://vault.example.com:8200
|
||||||
|
export VAULT_CACERT=/path/to/server-ca.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in. The CLI asks for the password and stores the token in the token helper file (`~/.vault-token`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault login -method=userpass username=alice
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Generate the client key and the CSR locally. The key is never sent to Vault.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl req \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-keyout client_key.pem \
|
||||||
|
-noenc \
|
||||||
|
-subj "/CN=test-client" \
|
||||||
|
-out client.csr
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Sign the CSR with the Vault CA.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vault write -field=certificate pki_int/sign/wif-client \
|
||||||
|
csr=@client.csr \
|
||||||
|
common_name=test-client \
|
||||||
|
ttl=8760h > client_cert.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Check the certificate.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl x509 -in client_cert.pem -noout -subject -issuer -dates -ext extendedKeyUsage
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Revoke the token when the work is done.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_TOKEN=$(vault login -no-store -token-only -method=userpass username=alice)
|
||||||
|
```
|
||||||
Reference in new issue
Block a user