Skip to content

Add GCP okta-conditional-access addon#223

Open
robbiet480 wants to merge 4 commits intofleetdm:mainfrom
CampusTech:gcp-okta-conditional-access
Open

Add GCP okta-conditional-access addon#223
robbiet480 wants to merge 4 commits intofleetdm:mainfrom
CampusTech:gcp-okta-conditional-access

Conversation

@robbiet480
Copy link
Copy Markdown

@robbiet480 robbiet480 commented Apr 16, 2026

Summary

  • Adds addons/gcp/okta-conditional-access/ — a GCP-native equivalent of the existing AWS okta-conditional-access addon
  • Updates gcp/byo-project with three new optional inputs: server_tls_policy, backend_custom_request_headers, and okta_subdomain

Architecture

GCP's ServerTLSPolicy applies at the HTTPS proxy level — attaching it to the main proxy enforces mTLS on the Fleet UI too. To avoid that, this addon provisions a dedicated second proxy and global IP for okta.<fleet_domain>, leaving the main Fleet UI proxy untouched and mTLS-free.

fleet.example.com      →  1.2.3.4  →  fleet-lb-https-proxy       (no mTLS)       →  Cloud Run
okta.fleet.example.com →  5.6.7.8  →  fleet-okta-https-proxy  (mTLS enforced)  →  Cloud Run
                                                 ↑
                                      ServerTLSPolicy (REJECT_INVALID)
                                      TrustConfig (Fleet SCEP CA)

Both proxies share the same URL map and backend service. The mTLS proxy forwards the client cert serial to Fleet via X-Client-Cert-Serial.

When okta_subdomain is set, gcp/byo-project automatically:

  1. Provisions a dedicated global IP (fleet-okta-ip)
  2. Creates a managed SSL cert for okta.<fleet_domain> only
  3. Creates a second HTTPS proxy with the ServerTLSPolicy attached
  4. Creates a forwarding rule on the new IP → okta proxy
  5. Adds a URL map host rule redirecting /api/fleet/conditional_access/idp/sso to the okta subdomain
  6. Creates a DNS A record for okta.<fleet_domain> pointing to the new IP

Differences from AWS Addon

Concern AWS GCP
CA cert storage S3 bucket Inline in TrustConfig (no object storage needed)
mTLS termination Separate ALB Dedicated proxy on existing LB
Cert revocation Supported Not supported by GCP LB (Fleet still enforces it)
Serial header ALB-native Custom request header {client_cert_serial_number}
Extra infrastructure cost Second ALB + global IP Second global IP only

Disclosure

This module was written with Claude (Anthropic) as a coding assistant. I reviewed the implementation, tested it end-to-end, and have been running it in production at CampusGroup with Okta conditional access enabled on our Fleet deployment since April 2026.

Test plan

  • terraform validate passes
  • Deploy addon against an existing gcp/byo-project Fleet stack
  • Confirm main Fleet UI is accessible without a client cert prompt
  • Confirm fleet-okta-https-proxy has ServerTLSPolicy attached
  • Confirm X-Client-Cert-Serial header is forwarded to Fleet on mTLS connections on the okta subdomain
  • Confirm non-mTLS connections are rejected at the LB for the okta.* subdomain
  • Confirm Okta SSO redirect path (/api/fleet/conditional_access/idp/sso) routes correctly

🤖 Generated with Claude Code, reviewed and deployed by @robbiet480

robbiet480 and others added 2 commits April 15, 2026 20:34
Creates addons/gcp/okta-conditional-access/ — a GCP-native equivalent of
the existing AWS okta-conditional-access addon. Uses ServerTLSPolicy +
TrustConfig to enable mTLS on the existing Application Load Balancer
(no separate LB needed). Updates gcp/byo-project to accept optional
server_tls_policy, backend_custom_request_headers, and okta_subdomain inputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@robbiet480 robbiet480 requested review from a team and ddribeiro as code owners April 16, 2026 00:39
@robbiet480 robbiet480 force-pushed the gcp-okta-conditional-access branch from 7cbb1fd to e84505f Compare April 16, 2026 04:31
@robbiet480 robbiet480 marked this pull request as draft April 16, 2026 04:32
@robbiet480 robbiet480 force-pushed the gcp-okta-conditional-access branch from e84505f to 826ff2c Compare April 16, 2026 04:35
@robbiet480 robbiet480 marked this pull request as ready for review April 16, 2026 21:43
- ignore_changes on client_validation_trust_config: GCP returns project
  number instead of ID in state, causing unnecessary destroy/recreate
- ignore_changes on terracurl_request headers: bearer token rotates each
  apply, was forcing replacement of the migration job trigger every time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant