Added a variant of the test that uses HashiCorp Vault to manage te
Certificate Authorities.
This commit is contained in:
1 parent
7f07e47138
commit
777b86ce33
7 files changed
+236
-48
No files matched your search
@@ -5,6 +5,7 @@ This short guide provides step by step instructions how to replace a JSON key wi
|
||||
## Prerequisites
|
||||
|
||||
- `openssl` 3.x
|
||||
- `vault` (only for the Vault based CA in step 1a)
|
||||
- Node.js with `npm`
|
||||
- `gcloud` authenticated as an administrator of the target project
|
||||
|
||||
@@ -50,6 +51,97 @@ The `.sh` files are meant as references for copying and pasting the commands one
|
||||
bash make_certs.sh
|
||||
```
|
||||
|
||||
## 1a. Alternative: create the certificates with Vault
|
||||
|
||||
HashiCorp Vault Community Edition can replace the OpenSSL based CA. The PKI secrets engine hosts the root CA and the issuing CA, and a role issues the client certificate. The commands below produce the same files as `make_certs.sh`: `ca_cert.pem`, `issuing_ca_cert.pem`, `client_key.pem` and `client_cert.pem`. Continue with step 2 afterwards.
|
||||
|
||||
Prerequisites: the `vault` command installed on the workstation.
|
||||
|
||||
### Start a local Vault server
|
||||
|
||||
Vault dev mode keeps all data in memory, and a dev server cannot be restarted on existing file storage. The local server therefore runs in normal mode with file storage in the gitignored `vault-data` directory.
|
||||
|
||||
Create `vault.hcl`, replacing the path with the absolute path of the `vault-data` directory:
|
||||
|
||||
```hcl
|
||||
storage "file" {
|
||||
path = "/path/to/repository/vault-data"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "127.0.0.1:8200"
|
||||
tls_disable = true
|
||||
}
|
||||
|
||||
api_addr = "http://127.0.0.1:8200"
|
||||
disable_mlock = true
|
||||
ui = true
|
||||
```
|
||||
|
||||
Start the server in a separate terminal:
|
||||
|
||||
```bash
|
||||
vault server -config=vault.hcl
|
||||
```
|
||||
|
||||
The web UI is available at `http://127.0.0.1:8200/ui`.
|
||||
|
||||
Initialize the server once with a single unseal key, unseal it, and set `VAULT_TOKEN` to the generated root token. Replace `<initial-root-token>` with the initial root token printed in `vault-init.txt`:
|
||||
|
||||
```bash
|
||||
export VAULT_ADDR=http://127.0.0.1:8200
|
||||
vault operator init -key-shares=1 -key-threshold=1 > vault-init.txt
|
||||
vault operator unseal
|
||||
export VAULT_TOKEN=<initial-root-token>
|
||||
vault status
|
||||
```
|
||||
|
||||
`vault operator unseal` asks for the unseal key from `vault-init.txt`. After every server restart, run `vault operator unseal` again and set `VAULT_ADDR` and `VAULT_TOKEN` in new terminals. The data is kept in `vault-data`.
|
||||
|
||||
> **Note:** The unseal key and the root token stored in a file are suitable only for a local, disposable server.
|
||||
|
||||
### Configure the CA hierarchy
|
||||
|
||||
`vault_configure.sh` performs the following steps in the terminal where `VAULT_ADDR` and `VAULT_TOKEN` are set:
|
||||
|
||||
1. Enables the PKI secrets engine for the root CA and for the issuing CA, and sets the maximum TTLs.
|
||||
2. Generates the root CA inside Vault.
|
||||
3. Generates the issuing CA key and CSR, signs it with the root CA, and installs the signed certificate.
|
||||
4. Creates a role that issues client authentication certificates.
|
||||
5. Exports the root CA and the issuing CA certificates (`ca_cert.pem`, `issuing_ca_cert.pem`).
|
||||
|
||||
```bash
|
||||
bash vault_configure.sh
|
||||
```
|
||||
|
||||
### Create the client certificate
|
||||
|
||||
`vault_make_client_cert.sh` performs the following steps in the same terminal:
|
||||
|
||||
1. Generates the client key and CSR locally with `openssl`. The key is never sent to Vault.
|
||||
2. Signs the client CSR with the issuing CA. The certificate subject CN (`test-client`) becomes the WiF subject.
|
||||
|
||||
```bash
|
||||
bash vault_make_client_cert.sh
|
||||
```
|
||||
|
||||
The client certificate is valid for 365 days, has the Digital Signature and Key Encipherment key usages, and the TLS Web Client Authentication extended key usage. Unlike the certificate from `make_certs.sh`, it has no `basicConstraints` extension.
|
||||
|
||||
### Update a WiF provider created with the OpenSSL CA
|
||||
|
||||
If the provider was already created by `make_wif.sh` with the OpenSSL based CA, `vault_gcp_update.sh` switches it to the Vault CA. The client certificate keeps the subject CN `test-client`, so the service account binding and `cred.json` stay valid. The script performs the following steps:
|
||||
|
||||
1. Generates `trust_store.yaml` from the Vault CA certificates with `make_trust_store.mjs`.
|
||||
2. Replaces the trust store of the existing X.509 provider.
|
||||
3. Shows the provider configuration.
|
||||
4. Tests the federation with the client certificate issued by Vault.
|
||||
|
||||
```bash
|
||||
bash vault_gcp_update.sh
|
||||
```
|
||||
|
||||
For a new setup, continue with step 2 instead.
|
||||
|
||||
## 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`:
|
||||
@@ -81,18 +173,27 @@ The PEM files must contain only the certificate block. A trailing newline after
|
||||
4. Grants the service account read access to the project.
|
||||
5. Writes `cred.json`.
|
||||
6. Creates a storage bucket and grants the service account read and write access to its objects.
|
||||
7. Enables Data Access audit logs for Cloud Storage.
|
||||
8. Creates a separate gcloud configuration and logs in with `cred.json`.
|
||||
9. Checks the access to the project and the bucket, including an upload and a download of a file.
|
||||
10. Switches back to the original gcloud configuration.
|
||||
11. Makes the `public/` managed folder of the bucket publicly readable.
|
||||
12. Lists the audit log of the service account operations.
|
||||
13. Optionally switches back to the service account configuration.
|
||||
7. Makes the `public/` managed folder of the bucket publicly readable.
|
||||
8. Enables Data Access audit logs for Cloud Storage.
|
||||
|
||||
```bash
|
||||
bash make_wif.sh
|
||||
```
|
||||
|
||||
## 4. Test the federation
|
||||
|
||||
`test_wif.sh` performs the following steps:
|
||||
|
||||
1. Creates a separate gcloud configuration and logs in with `cred.json`.
|
||||
2. Checks the access to the project and the bucket, including an upload and a download of a file.
|
||||
3. Switches back to the original gcloud configuration.
|
||||
4. Lists the audit log of the service account operations.
|
||||
5. Optionally switches back to the service account configuration.
|
||||
|
||||
```bash
|
||||
bash test_wif.sh
|
||||
```
|
||||
|
||||
Data Access audit logs are enabled for the whole project, not per bucket, by editing the project IAM policy. `add_audit_config.mjs` adds the `auditConfigs` section to the policy file fetched by gcloud.
|
||||
|
||||
The audit log lists only Cloud Storage operations of the service account. Resource Manager calls such as `projects describe` are not covered by the Data Access configuration.
|
||||
|
||||
Reference in new issue
Block a user