Skip to content

Commit 0f7097d

Browse files
committed
LOG-9171: Add GCP WIF support
1 parent b2e58e8 commit 0f7097d

11 files changed

Lines changed: 888 additions & 278 deletions

File tree

Cargo.lock

Lines changed: 473 additions & 79 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,10 @@ prost = { workspace = true, optional = true }
331331
prost-reflect = { workspace = true, optional = true }
332332
prost-types = { workspace = true, optional = true }
333333

334-
# GCP
335-
goauth = { version = "0.16.0", optional = true }
336-
smpl_jwt = { version = "0.8.0", default-features = false, optional = true }
334+
# GCP - using official googleapis/google-cloud-rust authentication library
335+
# Supports service accounts, external accounts (workload identity), and ADC
336+
# Version 1.6 required for full external account support
337+
google-cloud-auth = { version = "1.6", optional = true }
337338

338339
# AMQP
339340
lapin = { version = "2.5.3", default-features = false, features = ["native-tls"], optional = true }
@@ -640,7 +641,7 @@ aws-core = [
640641
# Anything that requires Protocol Buffers.
641642
protobuf-build = ["dep:tonic-build", "dep:prost-build"]
642643

643-
gcp = ["dep:base64", "dep:goauth", "dep:smpl_jwt"]
644+
gcp = ["dep:base64", "dep:google-cloud-auth"]
644645

645646
# Enrichment Tables
646647
enrichment-tables = ["enrichment-tables-geoip", "enrichment-tables-mmdb", "enrichment-tables-memory"]
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# Google Cloud Platform Workload Identity Federation Support
2+
## Vector v0.54 Enhancement
3+
4+
---
5+
6+
## Summary
7+
8+
Implement Google Cloud Platform (GCP) Workload Identity Federation (WIF) support in /viaq/vector v0.54, enabling **keyless authentication** for all GCP integrations.
9+
10+
This enhancement eliminates the operational burden and security risks of managing service account keys while maintaining full backwards compatibility with existing deployments.
11+
12+
### Key Features
13+
- ✅ Full WIF support across all GCP sinks and sources
14+
- ✅ Backward compatible with existing authentication methods
15+
- ✅ Production-ready and tested implementation
16+
17+
---
18+
19+
### Industry
20+
Google Cloud **recommends** Workload Identity Federation as the preferred authentication method for workloads running outside GCP, particularly in OpenShift environments. This is becoming a **requirement** for security-conscious enterprises and is mandated by many compliance frameworks.
21+
22+
---
23+
24+
### Auth Comparison
25+
26+
**Traditional Auth (Static Keys - INSECURE):**
27+
```
28+
Collector Pod → Service Account Key (NEVER EXPIRES) → GCP APIs
29+
30+
[Stored as secret]
31+
[Can be copied anywhere]
32+
[Persists in images/logs]
33+
[Indefinite access if stolen]
34+
```
35+
36+
**Workload Identity Federation (Dynamic Tokens - SECURE):**
37+
```
38+
Collector Pod → OpenShift Pod Token → GCP Token Exchange → Short-lived Token (1hr) → GCP APIs
39+
↑ ↓ ↓
40+
[Bound to pod identity] [Logged & audited] [Auto-refreshed]
41+
[Cannot be copied] [Traceable] [Auto-expires]
42+
[Terminates with pod] [Revocable] [Scoped access]
43+
```
44+
45+
### Security Enhancement
46+
47+
With WIF, there are **no long-lived credentials to protect**. Even if an attacker compromises a pod, they only gain access for the current token's remaining lifetime (maximum 1 hour). Additionally, the token is cryptographically bound to that specific OpenShift workload identity, making it useless elsewhere.
48+
49+
---
50+
51+
### Implementation Details
52+
53+
**Core Authentication Module** (`src/gcp.rs`)
54+
- Complete rewrite using official Google authentication library
55+
- Support for multiple OAuth scopes
56+
- Automatic token refresh handling
57+
- Thread-safe credential management
58+
59+
**GCP Sinks** (Data Destinations)
60+
- `gcp_cloud_storage` - Cloud Storage bucket output
61+
- `gcp_pubsub` - Pub/Sub topic publishing
62+
- `gcp_stackdriver_logs` - Cloud Logging
63+
- `gcp_stackdriver_metrics` - Cloud Monitoring
64+
- `gcp_chronicle` - Chronicle Security
65+
66+
### Cargo
67+
```toml
68+
# Before
69+
goauth = "0.16.0"
70+
smpl_jwt = "0.8.0"
71+
72+
# After
73+
google-cloud-auth = "1.6" # Official Google library with full WIF support woot!
74+
```
75+
76+
77+
78+
### New "type" of Credentials File
79+
```json
80+
{
81+
"type": "external_account",
82+
"audience": "//iam.googleapis.com/projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL/providers/PROVIDER",
83+
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
84+
"token_url": "https://sts.googleapis.com/v1/token",
85+
"credential_source": {
86+
"file": "/var/run/ocp-collector/serviceaccount/token"
87+
},
88+
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA@PROJECT.iam.gserviceaccount.com:generateAccessToken"
89+
}
90+
```
91+
92+
---
93+
94+
### Benefits
95+
96+
-**Zero Key Management:** No rotation schedules, no distribution pipelines, no key tracking
97+
- Eliminates entire category of operational incidents
98+
- No "emergency key rotation" fire drills
99+
- No secret management infrastructure needed
100+
101+
-**Least Privilege Access:** Tokens are scoped to specific GCP APIs and resources
102+
- Fine-grained IAM policies per workload
103+
- No over-privileged "one key for everything" scenarios
104+
105+
-**Complete Audit Trail:** Every authentication is logged and traceable
106+
- GCP Cloud Audit Logs show which OpenShift pod accessed which resource
107+
- Token exchange events provide forensic evidence
108+
- Real-time detection of unauthorized access attempts
109+
110+
-**Multi-Cloud Support:** Works with AWS, Azure, and other identity providers
111+
-**Industry Best Practice:** Aligns with Google Cloud's **required** approach for modern workloads
112+
113+
-**Risk Reduction:** Eliminates entire class of credential leakage incidents
114+
- No more "key accidentally committed to GitHub" incidents
115+
- No credential exposure via container image scanning
116+
- Protection against supply chain attacks targeting secrets
117+
118+
---
119+
### Testing
120+
121+
**Unit Tests**
122+
```bash
123+
✓ gcp::tests::skip_authentication
124+
✓ gcp::tests::uses_api_key
125+
✓ gcp::tests::fails_bad_api_key
126+
```
127+
128+
**Build Verification**
129+
```bash
130+
✓ Compiles with all GCP features
131+
✓ Rust 1.92 compatibility verified
132+
✓ No clippy warnings or errors
133+
```
134+
135+
**Integration Testing**
136+
- GCP integration test suite available (`cargo vdev int test gcp`)
137+
- Tested with service account credentials
138+
- Verified with external account credentials (WIF)
139+
140+
---
141+
142+
## Authentication Priority
143+
144+
Vector searches for credentials in this order:
145+
146+
1. `api_key` (if configured)
147+
2. `credentials_path` (if configured) - supports both Service Account and External Account (WIF) files
148+
3. **Application Default Credentials (ADC)** - automatic fallback
149+
150+
ADC searches: `GOOGLE_APPLICATION_CREDENTIALS` env var → gcloud CLI → GCE/GKE metadata server
151+
152+
**Behavior Change**: When no explicit credentials are configured, Vector now attempts ADC instead of failing immediately. Tests renamed from `fails_missing_creds` to `falls_back_to_adc` to reflect this improvement.
153+
154+
---
155+
156+
## Steps
157+
158+
**Step 1:** Create a GCP service account to be used by the ClusterLogForwarder:
159+
```bash
160+
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
161+
--display-name="OpenShift Logging Admin" \
162+
--project=PROJECT_ID
163+
```
164+
165+
**Step 2:** Bind Permissions to your Collector Service Account
166+
```bash
167+
# Allow OpenShift service account to impersonate GCP service account
168+
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_NAME@project.iam.gserviceaccount.com \
169+
--role=roles/iam.workloadIdentityUser \
170+
--member="principal://iam.googleapis.com/projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL/subject/system:serviceaccount:NAMESPACE:MY_COLLECTOR_SERVICE_ACCOUNT"
171+
```
172+
173+
**Step 3:** Generate a Configuration file for the External Account (Google Service Account)
174+
```bash
175+
gcloud iam workload-identity-pools create-cred-config \
176+
projects/PROJECT_NUM/locations/global/workloadIdentityPools/POOL/providers/PROVIDER \
177+
--service-account=SA@PROJECT.iam.gserviceaccount.com \
178+
--output-file=external-account.json \
179+
--credential-source-file=/var/run/ocp-collector/serviceaccount/token
180+
```
181+
182+
**Step 4:** Create secret and configure ClusterLogForwarder
183+
184+
```bash
185+
# Create secret in openshift-logging namespace
186+
oc create secret generic gcp-wif-credentials \
187+
--from-file=credentials.json=external-account.json \
188+
-n openshift-logging
189+
```
190+
191+
**ClusterLogForwarder Configuration**:
192+
```yaml
193+
apiVersion: observability.openshift.io/v1
194+
kind: ClusterLogForwarder
195+
metadata:
196+
name: instance
197+
namespace: openshift-logging
198+
spec:
199+
outputs:
200+
- name: gcp-wif-logging
201+
type: googleCloudLogging
202+
googleCloudLogging:
203+
id:
204+
type: project
205+
value: my-project123
206+
logId: my-logs123
207+
authentication:
208+
credentials:
209+
secretName: gcp-wif-credentials
210+
key: external-account.json
211+
...
212+
# The external-account.json contains external account config (WIF)
213+
# Vector detects the credential type and uses appropriate auth flow
214+
```
215+
216+
## References
217+
218+
- **Google Cloud Documentation:** [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation)
219+
- **google-cloud-auth Library:** [Official Rust SDK](https://github.com/googleapis/google-cloud-rust)
220+
- **Vector Documentation:** [GCP Authentication](https://vector.dev/docs/reference/configuration/sinks/gcp_stackdriver_logs/#authentication)
221+
- **Ticket:** RH OpenShift LOG-9171
222+
- **Branch:** `v0.54.0-rh-gcp-wif`

0 commit comments

Comments
 (0)