Skip to content

Commit 3ee5fc4

Browse files
Adding support for WIF based auth to Webhook Datasource module (#21)
* Adding support for WIF based auth to Webhook Datasource module Change summary: ----------------- To add auth support for validating cloud ingestion resources :- - Adding the support for creating WIF resources with AWS provider. - Allowing external trusted identity to be able to impersonate the SA and use temporary service tokens for authentication. This is to allow Sysdig backend to be able to talk to GCP to access and read the cloud resources. - Using assumed role attribute as the signature for trusted identity. - Creating and binding a custom role to the SA, with just the right set of permissions to read data ingestion cloud resources. - Updating the module outputs with the fields to pass in as metadata to Sysdig backend to do the auth. * Fix fmt * Fix sysdig provider version in tests * Restrict the WIF identity signtaure to use external_id within the assumed role * Fix org installs for webhook datasource with org-level permissions * Add README and tests * Add comment for randomly generated suffix
1 parent 6224133 commit 3ee5fc4

File tree

10 files changed

+234
-6
lines changed

10 files changed

+234
-6
lines changed

modules/services/webhook-datasource/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,22 @@ The following resources will be created in each instrumented account:
88
- A `PubSub` ingestion topic that will hold all the AuditLogs coming from the specified project
99
- A `Push` Subscription that will POST the AuditLogs collected from the project towards Sysdig's backend
1010
- All the necessary `Service Accounts` and `Policies` to enable the `AuditLogs` publishing operation
11+
- A `Workload Identity Pool`, `Provider` and added custom role permissions to the `Service Account`, to allow Sysdig to authenticate to GCP on your behalf to validate resources.
1112

1213
## Requirements
1314

1415
| Name | Version |
1516
|------|---------|
1617
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
1718
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.21.0 |
19+
| <a name="requirement_sysdig"></a> [sysdig](#requirement\_sysdig) | >= 1.19.0 |
1820

1921
## Providers
2022

2123
| Name | Version |
2224
|------|---------|
2325
| <a name="provider_google"></a> [google](#provider\_google) | 5.0.0 |
26+
| <a name="provider_random"></a> [random](#provider\_random) | >= 3.1 |
2427

2528
## Modules
2629

@@ -41,6 +44,16 @@ No modules.
4144
| [google_service_account.push_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
4245
| [google_service_account_iam_binding.push_auth_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_binding) | resource |
4346
| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source |
47+
| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source |
48+
| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source |
49+
| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
50+
| [google_iam_workload_identity_pool.ingestion_auth_pool](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource |
51+
| [google_iam_workload_identity_pool_provider.ingestion_auth_pool_provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource |
52+
| [google_project_iam_custom_role.custom_ingestion_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_custom_role) | resource |
53+
| [google_project_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member) | resource |
54+
| [google_service_account_iam_member.custom_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member) | resource |
55+
| [google_organization_iam_custom_role.custom_ingestion_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam_custom_role) | resource |
56+
| [google_organization_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam#google_organization_iam_member) | resource |
4457

4558
## Inputs
4659

@@ -56,6 +69,9 @@ No modules.
5669
| <a name="input_organization_domain"></a> [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no |
5770
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes |
5871
| <a name="input_push_endpoint"></a> [push\_endpoint](#input\_push\_endpoint) | (Required) Final endpoint towards which audit logs POST calls will be directed | `string` | n/a | yes |
72+
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data ingestion resources | `string` | `"SysdigIngestionAuthRole"` | no |
73+
| <a name="input_external_id"></a> [external\_id](#input\_external\_id) | (Optional) Random string generated unique to a customer | `string` | `""` | no |
74+
| <a name="input_suffix"></a> [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no |
5975

6076
## Outputs
6177

@@ -65,3 +81,7 @@ No modules.
6581
| <a name="output_ingestion_pubsub_topic_name"></a> [ingestion\_pubsub\_topic\_name](#output\_ingestion\_pubsub\_topic\_name) | PubSub ingestion topic that will hold all the AuditLogs coming from the specified project |
6682
| <a name="output_ingestion_sink_name"></a> [ingestion\_sink\_name](#output\_ingestion\_sink\_name) | Project/Organization sink to direct the AuditLogs towards a dedicated PubSub topic |
6783
| <a name="output_ingestion_push_subscription_name"></a> [ingestion\_push\_subscription\_name](#output\_ingestion\_push\_subscription\_name) | Push Subscription that will POST the AuditLogs collected from the project towards Sysdig's backend |
84+
| <a name="output_workload_identity_pool_id"></a> [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access data ingestion resources |
85+
| <a name="output_workload_identity_pool_provider_id"></a> [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access data ingestion resources |
86+
| <a name="output_workload_identity_project_number"></a> [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number |
87+
| <a name="output_service_account_email"></a> [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created |

modules/services/webhook-datasource/main.tf

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,88 @@ resource "google_pubsub_subscription" "ingestion_topic_push_subscription" {
141141
}
142142
}
143143

144+
#------------------------------------------------------------------#
145+
# Fetch and compute required data for Workload Identity Federation #
146+
#------------------------------------------------------------------#
147+
148+
data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
149+
cloud_provider = "gcp"
150+
}
151+
152+
data "google_project" "project" {
153+
project_id = var.project_id
154+
}
155+
156+
locals {
157+
suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix
158+
}
159+
160+
// suffix to uniquely identify WIF pool and provider during multiple installs. If suffix value is not provided, this will generate a random value.
161+
resource "random_id" "suffix" {
162+
count = var.suffix == null ? 1 : 0
163+
byte_length = 3
164+
}
165+
166+
#------------------------------------------------------------#
167+
# Configure Workload Identity Federation for auth #
168+
# See https://cloud.google.com/iam/docs/access-resources-aws #
169+
#------------------------------------------------------------#
170+
171+
resource "google_iam_workload_identity_pool" "ingestion_auth_pool" {
172+
project = var.project_id
173+
workload_identity_pool_id = "sysdig-ingestion-${local.suffix}"
174+
}
175+
176+
resource "google_iam_workload_identity_pool_provider" "ingestion_auth_pool_provider" {
177+
project = var.project_id
178+
workload_identity_pool_id = google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id
179+
workload_identity_pool_provider_id = "sysdig-ingestion-${local.suffix}"
180+
display_name = "Sysdigcloud ingestion auth"
181+
description = "AWS identity pool provider for Sysdig Secure Data Ingestion resources"
182+
disabled = false
183+
184+
attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}\""
185+
186+
attribute_mapping = {
187+
"google.subject" = "assertion.arn",
188+
"attribute.aws_role" = "assertion.arn"
189+
}
190+
191+
aws {
192+
account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id
193+
}
194+
}
195+
196+
# creating custom role with project-level permissions to access data ingestion resources
197+
resource "google_project_iam_custom_role" "custom_ingestion_auth_role" {
198+
count = var.is_organizational ? 0 : 1
199+
200+
project = var.project_id
201+
role_id = var.role_name
202+
title = "Sysdigcloud Ingestion Auth Role"
203+
description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion"
204+
permissions = [
205+
"pubsub.topics.get",
206+
"pubsub.topics.list",
207+
"pubsub.subscriptions.get",
208+
"pubsub.subscriptions.list",
209+
"logging.sinks.get",
210+
"logging.sinks.list",
211+
]
212+
}
213+
214+
# adding custom role with project-level permissions to the service account for auth
215+
resource "google_project_iam_member" "custom" {
216+
count = var.is_organizational ? 0 : 1
217+
218+
project = var.project_id
219+
role = google_project_iam_custom_role.custom_ingestion_auth_role[0].id
220+
member = "serviceAccount:${google_service_account.push_auth.email}"
221+
}
222+
223+
# attaching WIF as a member to the service account for auth
224+
resource "google_service_account_iam_member" "custom_auth" {
225+
service_account_id = google_service_account.push_auth.name
226+
role = "roles/iam.workloadIdentityUser"
227+
member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}"
228+
}

modules/services/webhook-datasource/organizational.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,30 @@ resource "google_logging_organization_sink" "ingestion_sink" {
4848
# even from potential sub-organizations
4949
include_children = true
5050
}
51+
52+
# creating custom role with organization-level permissions to access data ingestion resources
53+
resource "google_organization_iam_custom_role" "custom_ingestion_auth_role" {
54+
count = var.is_organizational ? 1 : 0
55+
56+
org_id = data.google_organization.org[0].org_id
57+
role_id = var.role_name
58+
title = "Sysdigcloud Ingestion Auth Role"
59+
description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion"
60+
permissions = [
61+
"pubsub.topics.get",
62+
"pubsub.topics.list",
63+
"pubsub.subscriptions.get",
64+
"pubsub.subscriptions.list",
65+
"logging.sinks.get",
66+
"logging.sinks.list",
67+
]
68+
}
69+
70+
# adding custom role with organization-level permissions to the service account for auth
71+
resource "google_organization_iam_member" "custom" {
72+
count = var.is_organizational ? 1 : 0
73+
74+
org_id = data.google_organization.org[0].org_id
75+
role = google_organization_iam_custom_role.custom_ingestion_auth_role[0].id
76+
member = "serviceAccount:${google_service_account.push_auth.email}"
77+
}

modules/services/webhook-datasource/outputs.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,23 @@ output "ingestion_push_subscription_name" {
1717
value = google_pubsub_subscription.ingestion_topic_push_subscription.name
1818
description = "Push Subscription that will POST the AuditLogs collected from the project towards Sysdig's backend"
1919
}
20+
21+
output "workload_identity_pool_id" {
22+
value = google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id
23+
description = "Id of Workload Identity Pool for authenticating to GCP to access data ingestion resources"
24+
}
25+
26+
output "workload_identity_pool_provider_id" {
27+
value = google_iam_workload_identity_pool_provider.ingestion_auth_pool_provider.workload_identity_pool_provider_id
28+
description = "Id of Workload Identity Pool Provider for authenticating to GCP to access data ingestion resources"
29+
}
30+
31+
output "workload_identity_project_number" {
32+
value = data.google_project.project.number
33+
description = "GCP project number"
34+
}
35+
36+
output "service_account_email" {
37+
value = google_service_account.push_auth.email
38+
description = "email of the Service Account created"
39+
}

modules/services/webhook-datasource/variables.tf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,21 @@ variable "organization_domain" {
5757
description = "(Optional) Organization domain. e.g. sysdig.com"
5858
default = ""
5959
}
60+
61+
variable "role_name" {
62+
type = string
63+
description = "Name for the Ingestion auth Role on the Customer infrastructure"
64+
default = "SysdigIngestionAuthRole"
65+
}
66+
67+
variable "external_id" {
68+
type = string
69+
description = "Random string generated unique to a customer"
70+
default = ""
71+
}
72+
73+
variable "suffix" {
74+
type = string
75+
description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated"
76+
default = null
77+
}

modules/services/webhook-datasource/versions.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ terraform {
66
source = "hashicorp/google"
77
version = ">= 4.21.0"
88
}
9+
sysdig = {
10+
source = "sysdiglabs/sysdig"
11+
version = "~> 1.19.0"
12+
}
13+
random = {
14+
source = "hashicorp/random"
15+
version = ">= 3.1, < 4.0"
16+
}
917
}
1018
}

test/examples/secure_config_posture_identity_access/organization/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ terraform {
1616
required_providers {
1717
sysdig = {
1818
source = "sysdiglabs/sysdig"
19-
version = "~> 1.18.2"
19+
version = "~> 1.19.0"
2020
}
2121
}
2222
}

test/examples/secure_config_posture_identity_access/single/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ terraform {
1414
required_providers {
1515
sysdig = {
1616
source = "sysdiglabs/sysdig"
17-
version = "~> 1.18.2"
17+
version = "~> 1.19.0"
1818
}
1919
}
2020
}

test/examples/secure_threat_detection/organization/main.tf

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module "organization-threat-detection" {
99
push_endpoint = "test_sysdig_secure_cloudingestion_endpoint"
1010
is_organizational = true
1111
organization_domain = "mytestorg.com"
12+
external_id = "external_id"
1213
}
1314

1415
module "organization-posture" {
@@ -24,7 +25,7 @@ terraform {
2425
required_providers {
2526
sysdig = {
2627
source = "sysdiglabs/sysdig"
27-
version = "~> 1.18.2"
28+
version = "~> 1.19.0"
2829
}
2930
}
3031
}
@@ -43,12 +44,36 @@ resource "sysdig_secure_cloud_auth_account" "gcp_project_mytestproject" {
4344

4445
secure_threat_detection {
4546
enabled = true
46-
components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"]
47+
components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime", "COMPONENT_SERVICE_PRINCIPAL/secure-runtime"]
4748
}
4849
}
4950
component {
5051
type = "COMPONENT_WEBHOOK_DATASOURCE"
5152
instance = "secure-runtime"
53+
webhook_datasource_metadata = jsonencode({
54+
gcp = {
55+
webhook_datasource = {
56+
pubsub_topic_name = module.organization-threat-detection.ingestion_pubsub_topic_name
57+
sink_name = module.organization-threat-detection.ingestion_sink_name
58+
push_subscription_name = module.organization-threat-detection.ingestion_push_subscription_name
59+
push_endpoint = module.organization-threat-detection.push_endpoint
60+
}
61+
}
62+
})
63+
}
64+
component {
65+
type = "COMPONENT_SERVICE_PRINCIPAL"
66+
instance = "secure-runtime"
67+
service_principal_metadata = jsonencode({
68+
gcp = {
69+
workload_identity_federation = {
70+
pool_id = module.organization-threat-detection.workload_identity_pool_id
71+
pool_provider_id = module.organization-threat-detection.workload_identity_pool_provider_id
72+
project_number = module.organization-threat-detection.workload_identity_project_number
73+
}
74+
email = module.organization-threat-detection.service_account_email
75+
}
76+
})
5277
}
5378
component {
5479
type = "COMPONENT_SERVICE_PRINCIPAL"

test/examples/secure_threat_detection/single/main.tf

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ module "single-project-threat-detection" {
77
source = "../../../..//modules/services/webhook-datasource"
88
project_id = "mytestproject"
99
push_endpoint = "test_sysdig_secure_cloudingestion_endpoint"
10+
external_id = "external_id"
1011
}
1112

1213
terraform {
1314

1415
required_providers {
1516
sysdig = {
1617
source = "sysdiglabs/sysdig"
17-
version = "~> 1.18.2"
18+
version = "~> 1.19.0"
1819
}
1920
}
2021
}
@@ -33,12 +34,36 @@ resource "sysdig_secure_cloud_auth_account" "gcp_project_mytestproject" {
3334

3435
secure_threat_detection {
3536
enabled = true
36-
components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"]
37+
components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime", "COMPONENT_SERVICE_PRINCIPAL/secure-runtime"]
3738
}
3839
}
3940
component {
4041
type = "COMPONENT_WEBHOOK_DATASOURCE"
4142
instance = "secure-runtime"
43+
webhook_datasource_metadata = jsonencode({
44+
gcp = {
45+
webhook_datasource = {
46+
pubsub_topic_name = module.single-project-threat-detection.ingestion_pubsub_topic_name
47+
sink_name = module.single-project-threat-detection.ingestion_sink_name
48+
push_subscription_name = module.single-project-threat-detection.ingestion_push_subscription_name
49+
push_endpoint = module.single-project-threat-detection.push_endpoint
50+
}
51+
}
52+
})
53+
}
54+
component {
55+
type = "COMPONENT_SERVICE_PRINCIPAL"
56+
instance = "secure-runtime"
57+
service_principal_metadata = jsonencode({
58+
gcp = {
59+
workload_identity_federation = {
60+
pool_id = module.single-project-threat-detection.workload_identity_pool_id
61+
pool_provider_id = module.single-project-threat-detection.workload_identity_pool_provider_id
62+
project_number = module.single-project-threat-detection. workload_identity_project_number
63+
}
64+
email = module.single-project-threat-detection.service_account_email
65+
}
66+
})
4267
}
4368
}
4469

0 commit comments

Comments
 (0)