Files
gcp-wif-test/README.md
T

103 lines
3.9 KiB
Markdown

# How to replace JSON key with X.509 WiF
This short guide provides step by step instructions how to replace a JSON key with a Workload Identity Federation (WiF) X.509 certificate.
## Prerequisites
- `openssl` 3.x
- Node.js with `npm`
- `gcloud` authenticated as an administrator of the target project
## Configuration
The scripts read the names of the resources from `env.sh`. Replace the example values with your own before running them. Run all scripts from the repository directory.
`env.sh`:
```bash
# Project
PROJECT_ID=my-project
PROJECT_NUMBER=123456789012
# Workload identity pool and provider
POOL_ID=my-pool
POOL_DISPLAY_NAME="My Pool"
PROVIDER_ID=my-x509
# Service account
SA_EMAIL="sa-test@${PROJECT_ID}.iam.gserviceaccount.com"
# Storage bucket
BUCKET=my-project-wif-test
BUCKET_LOCATION=europe-central2
```
## About the shell scripts
The `.sh` files are meant as references for copying and pasting the commands one by one, so that each step can be inspected and adapted. Running them directly with `bash` also works.
> **Note:** The scripts are not idempotent. Running a whole script with `bash` a second time may fail, because the resources created by the first run already exist, for example the workload identity pool, the provider, the service account, the bucket and the `wif-test` gcloud configuration.
## 1. Create the certificates
`make_certs.sh` performs the following steps:
1. Creates a root CA certificate and key (`ca_cert.pem`, `ca_key.pem`).
2. Creates an issuing CA certificate and key (`issuing_ca_cert.pem`, `issuing_ca_key.pem`), signed by the root CA.
3. Creates a client certificate and key (`client_cert.pem`, `client_key.pem`), signed by the issuing CA. Its subject CN (`test-client`) becomes the WiF subject.
```bash
bash make_certs.sh
```
## 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`:
```json
{
"dependencies": {
"yaml": ">=2.9.1"
}
}
```
Install the dependency and generate `trust_store.yaml`:
```bash
npm install
node make_trust_store.mjs
```
The PEM files must contain only the certificate block. A trailing newline after `-----END CERTIFICATE-----` makes gcloud fail with `Certificate is not in PEM format`, which is why the script trims it.
## 3. Create the pool, provider and credentials
`make_wif.sh` performs the following steps:
1. Creates the workload identity pool and the X.509 provider.
2. Creates a service account.
3. Allows the client certificate subject to impersonate the service account.
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.
```bash
bash make_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.
## Result
`cred.json` is a credentials configuration file that references the client certificate and private key. It contains no secret itself, but `client_key.pem` does and must be protected like a JSON key.