Skip to content

Commit

Permalink
feat: agentless workload controller WIF (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
mms2409 authored Mar 5, 2024
1 parent c983a90 commit 6224133
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ Co-authored-by: Fede Barcelona <[email protected]>
Co-authored-by: Miguel Angel Baztán <[email protected]>
Co-authored-by: Rubén Eguiluz <[email protected]>
Co-authored-by: Iru <[email protected]>
Co-authored-by: Mitul Sheth <[email protected]>
Co-authored-by: Hayk Kocharyan <[email protected]>
Co-authored-by: David González Diez <[email protected]>
123 changes: 123 additions & 0 deletions modules/services/workload-scan/controller.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
resource "google_service_account" "controller" {
project = var.project_id
account_id = "sysdig-ws-${local.suffix}"
display_name = "Sysdig Agentless Workload Scanning"
}

resource "google_project_iam_custom_role" "controller" {
project = var.project_id
role_id = "${var.role_name}WorkloadController${title(local.suffix)}"
title = "Role for Sysdig Agentless Workload Controller"
permissions = [
# artifact registry reader permissions
"artifactregistry.repositories.downloadArtifacts",
"artifactregistry.repositories.get",
"artifactregistry.repositories.list",
"artifactregistry.dockerimages.get",
"artifactregistry.dockerimages.list",

# workload identity federation
"iam.serviceAccounts.getAccessToken",
]
}

resource "google_project_iam_binding" "controller_custom" {
project = var.project_id
role = google_project_iam_custom_role.controller.id

members = [
"serviceAccount:${google_service_account.controller.email}",
]
}

resource "google_iam_workload_identity_pool" "agentless" {
workload_identity_pool_id = "sysdig-wl-${local.suffix}"
}

resource "google_iam_workload_identity_pool_provider" "agentless" {
count = var.sysdig_backend != null ? 1 : 0

lifecycle {
precondition {
condition = (var.sysdig_backend != null && var.sysdig_account_id == null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}

workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
workload_identity_pool_provider_id = "sysdig-wl-${local.suffix}"
display_name = "Sysdig Workload Controller"
description = "AWS identity pool provider for Sysdig Secure Agentless Workload Scanning"
disabled = false

attribute_condition = "attribute.aws_account==\"${var.sysdig_backend}\""

attribute_mapping = {
"google.subject" = "assertion.arn"
"attribute.aws_account" = "assertion.account"
"attribute.role" = "assertion.arn.extract(\"/assumed-role/{role}/\")"
"attribute.session" = "assertion.arn.extract(\"/assumed-role/{role_and_session}/\").extract(\"/{session}\")"
}

aws {
account_id = var.sysdig_backend
}
}

resource "google_service_account_iam_member" "controller_custom" {
count = var.sysdig_backend != null ? 1 : 0

lifecycle {
precondition {
condition = (var.sysdig_backend != null && var.sysdig_account_id == null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}

service_account_id = google_service_account.controller.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.agentless.name}/attribute.aws_account/${var.sysdig_backend}"
}

resource "google_iam_workload_identity_pool_provider" "agentless_gcp" {
count = var.sysdig_account_id != null ? 1 : 0

lifecycle {
precondition {
condition = (var.sysdig_backend == null && var.sysdig_account_id != null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}

workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
workload_identity_pool_provider_id = "sysdig-ws-${local.suffix}-gcp"
display_name = "Sysdig Agentless Workload Controller"
description = "GCP identity pool provider for Sysdig Secure Agentless Workload Scanning"
disabled = false

attribute_condition = "google.subject == \"${var.sysdig_account_id}\""

attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.sa_id" = "assertion.sub"
}

oidc {
issuer_uri = "https://accounts.google.com"
}
}

resource "google_service_account_iam_member" "controller_custom_gcp" {
count = var.sysdig_account_id != null ? 1 : 0

lifecycle {
precondition {
condition = (var.sysdig_backend == null && var.sysdig_account_id != null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}

service_account_id = google_service_account.controller.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.agentless.name}/attribute.sa_id/${var.sysdig_account_id}"
}
3 changes: 3 additions & 0 deletions modules/services/workload-scan/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "google_project" "project" {
project_id = var.project_id
}
8 changes: 8 additions & 0 deletions modules/services/workload-scan/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
locals {
suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix
}

resource "random_id" "suffix" {
count = var.suffix == null ? 1 : 0
byte_length = 3
}
32 changes: 32 additions & 0 deletions modules/services/workload-scan/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
output "project_id" {
value = var.project_id
}

output "project_number" {
value = data.google_project.project.number
}

output "controller_service_account" {
value = google_service_account.controller.email
}

output "workload_identity_pool_provider" {
value = var.sysdig_backend != null ? google_iam_workload_identity_pool_provider.agentless[0].name : var.sysdig_account_id != null ? google_iam_workload_identity_pool_provider.agentless_gcp[0].name : null
precondition {
condition = (var.sysdig_backend != null && var.sysdig_account_id == null) || (var.sysdig_backend == null && var.sysdig_account_id != null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}

output "json_payload" {
value = jsonencode({
"projectId" = var.project_id
"projectNumber" = data.google_project.project.number
"serviceAccount" = google_service_account.controller.email
"identityProvider" = var.sysdig_backend != null ? google_iam_workload_identity_pool_provider.agentless[0].name : var.sysdig_account_id != null ? google_iam_workload_identity_pool_provider.agentless_gcp[0].name : null
})
precondition {
condition = (var.sysdig_backend != null && var.sysdig_account_id == null) || (var.sysdig_backend == null && var.sysdig_account_id != null)
error_message = "Cannot provide both sysdig_backend or sysdig_account_id"
}
}
14 changes: 14 additions & 0 deletions modules/services/workload-scan/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
terraform {
required_version = ">=1.0"

required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.1, < 5.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.1, < 4.0"
}
}
}
29 changes: 29 additions & 0 deletions modules/services/workload-scan/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
variable "project_id" {
type = string
description = "GCP Project ID"
}

variable "sysdig_backend" {
type = string
description = "Sysdig provided AWS Account designated for the workload scan.<br/>One of `sysdig_backend` or `sysdig_account_id`must be provided"
default = null
}

variable "sysdig_account_id" {
type = string
description = "Sysdig provided GCP Account designated for the workload scan.<br/>One of `sysdig_backend` or `sysdig_account_id`must be provided"
default = null
}

# optionals
variable "role_name" {
type = string
description = "Name for the Worker Role on the Customer infrastructure"
default = "SysdigAgentlessWorkloadRole"
}

variable "suffix" {
type = string
description = "By default a random value will be autogenerated.<br/>Suffix word to enable multiple deployments with different naming<br/>(Workload Identity Pool and Providers have a soft deletion on Google Platform that will disallow name re-utilization)"
default = null
}

0 comments on commit 6224133

Please sign in to comment.