A proof of concept to integrate Okta with Google Cloud Platform.
Used the following accounts for the POC.
Test accounts:
Terraform Cloud
GCP
Trial accounts
Google Workspace (good for 14 days)
Okta (good for 30 days)
Goals:
Okta to Google Platform Platform SSO
This involves some manual configuration as currently can’t find a way how to set required fields in Single sign-on (SSO) with third-party identity providers (IDPs) of Google Workspace using terraform
.
Checked hashicorp/googleworkspace but currently doesn’t have anything specific for setting up third-party IDPs.
Creating Okta Pre-configured GCP application
There are only 2 required fields to set in Okta Google Cloud Platform
application.
https://console.cloud.google.com
in the Default Relay State field.And the company domain.
The required fields can be manually set on Okta Admin but here’s how in terraform.
resource "okta_app_saml" "gcp" { preconfigured_app = "cloudconsole" label = "Google Cloud Platform" default_relay_state = "https://console.cloud.google.com" status = "ACTIVE" } resource "okta_app_saml_app_settings" "gcp" { app_id = okta_app_saml.gcp.id settings = jsonencode( { "domain" : "lazyluna.dev" } ) } output "okta_app_saml_gcp" { value = okta_app_saml.gcp }
Note:
We should store values of output "okta_app_saml_gcp"
e.g. certificate, SSO sign-in URL in Hashicorp vault.
These values will be used in Single sign-on (SSO) with third-party identity providers (IDPs)
on Google Workspace.
On Okta Admin after creation.
Setting up Okta as third-party IDP on Google Workspace
On https://admin.google.com/
(workspace admin required), navigate to,
Security>Authentication>SSO with third party IdP>Third-party SSO profile for your organization
Set required fields and save:
Enable
Set up SSO with third-party identity provider
Sign-in page URL
Sign-out page URL
Verification certificate (use
REPLACE CERTIFICATE
to upload)Enable
Use a domain specific issuer
Get values to use from previously created okta_app_saml.gcp
resource.
Take note that
certificate
must be in-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
form before uploading.Sign-in page URL ==
http_post_binding
Sign-out page URL == Okta domain
Sign-in via Okta
For initial sign-in, you should see the usual Okta set new password, setup security methods, etc.
Last part is google account verification then finally a successful sign-in to GCP.
Integrate Okta Roles with GCP
This integration POC does not include auto provisioning of users or Okta managing google user lifecycle and groups syncing.
This is more of a “Phase 1“ approach how to link Okta users role/s to available GCP groups using terraform.
Currently we have a couple of users_*.yaml
files where we store both users and and roles to be assigned per user. e.g. users_devops.yaml
, users_meiro.yaml
, users_firebase.yaml
, etc.
Ideally there should be a single source of truth for existing users and since Okta is a prerequisite for accessing services, user's details, like email, should just be in users_okta.yaml
.
Then we can maybe have groups_gcp.yaml
, groups_tyk.yaml
, groups_*.yaml
where roles specific details for GCP, Tyk and possibly other services we have will be stored/declared.
We can then link service specific roles to users_okta.yaml
by a unique group
naming convention.
Here’s an example in code to be clear.
In users_okta.yaml
, this should be the single source of user details including the group assignment.
users: - email: devops@lazyluna.dev first_name: DevOps last_name: Infrastructure groups: - DevOps - email: developer@lazyluna.dev first_name: Developer last_name: Programmer groups: - Developers - email: qa@lazyluna.dev first_name: QA last_name: Testing groups: - Meiro
Next is in a groups_<service>.yaml
e.g. groups_gcp.yaml
would only contain GCP specific roles per projects assigned to a GCP group.
groups: - name: DevOps projects_iam: - project: my-home-sandbox roles: - roles/editor - name: Developers projects_iam: - project: my-home-sandbox roles: - roles/viewer - roles/logging.viewer - roles/container.developer - name: Meiro projects_iam: - project: my-home-sandbox roles: - roles/viewer
Then to link Okta roles to GCP, is basically what Application
is assigned to an Okta group and GCP is just a pre-configured application that can be added in Okta.
groups: - name: DevOps description: "Group for DevOps" apps: - GCP - DevOpsSpecificApp - name: Developers description: "Group for Developers" apps: - GCP - DevelopersSpecificApp - name: Meiro description: "Group for Meiro" apps: - MeiroSpecificApp - GCP
Finally in terraform, where the actual “linking” happens.
In a shared variable, we can pre-create the groupings per application and groups.
locals { safi_okta_users = yamldecode(file("${path.module}/../_files/users_okta.yaml"))["users"] safi_okta_groups = yamldecode(file("${path.module}/../_files/groups_okta.yaml"))["groups"] safi_okta_groups_with_gcp_app = tomap({ for group in local.safi_okta_groups : group.name => group if contains(group.apps, "GCP") }) safi_okta_users_assigned_to_group_with_gcp_app = merge([for group in local.safi_okta_groups_with_gcp_app : { for user in local.safi_okta_users : user.email => user if contains(user.groups, group.name) }]...) safi_groups_gcp = yamldecode(file("${path.module}/../_files/groups_gcp.yaml"))["groups"] }
Then similar to how we currently create GCP roles assignment using the grouping per app/service.
resource "google_project_iam_member" "project" { for_each = { for item in flatten([for okta_user in local.safi_okta_users_assigned_to_group_with_gcp_app : [ # Get Okta user assigned roles from GCP groups for gcp_group in local.safi_groups_gcp : [ for gcp_project in gcp_group.projects_iam : [ for gcp_project_role in gcp_project.roles : { member = okta_user.email, project = gcp_project.project, role = gcp_project_role, group = gcp_group.name } ] ] if contains(okta_user.groups, gcp_group.name) ]]) : format("%s+%s+%s+%s", item.member, item.project, item.role, item.group) => item } project = each.value.project role = each.value.role member = format("user:%s", each.value.member) }
On Okta, after the successful provisioning.
Then on GCP.
Attachments:
image-20221114-025315.png (image/png)
image-20221114-031757.png (image/png)
image-20221114-032526.png (image/png)
image-20221114-034016.png (image/png)
image-20221114-034147.png (image/png)
image-20221114-034508.png (image/png)
image-20221114-034603.png (image/png)
image-20221114-074042.png (image/png)
image-20221114-074310.png (image/png)
image-20221114-074506.png (image/png)