85 lines
3.5 KiB
Markdown
85 lines
3.5 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` creates a root CA, an issuing CA and a client certificate. The client certificate 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` creates the workload identity pool, the X.509 provider and a service account. It allows the client certificate subject to impersonate the service account, grants the service account read access to the project, creates a storage bucket with read and write access to its objects for the service account, enables Data Access audit logs for Cloud Storage, and writes `cred.json`. It then logs in with `cred.json` in a separate gcloud configuration, checks the access, uploads and downloads a file, makes the public folder of the bucket publicly readable, and lists the audit log of the service account operations.
|
|
|
|
```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 policy must be fetched as YAML, because a different default gcloud output format makes `set-iam-policy` reject the file.
|
|
|
|
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.
|