Skip to content

Commit 88c9b50

Browse files
committed
fix security concerns and address comments
1 parent b332900 commit 88c9b50

11 files changed

Lines changed: 99 additions & 42 deletions

File tree

aws/examples/simple/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@ To get the NLB DNS name:
134134
terraform output -json | jq -r .nlb_dns_name.value
135135
```
136136

137-
Connect using psql with the default service account credentials:
137+
Connect using psql with the superuser credentials:
138138
```bash
139139
# Get the password (use jq -r to decode JSON-escaped characters)
140-
terraform output -json mz_instance_service_account_credentials | jq -r '.password'
140+
terraform output -json mz_instance_superuser_credentials | jq -r '.password'
141141

142-
psql -h <NLB_DNS> -p 6875 -U default
142+
psql -h <NLB_DNS> -p 6875 -U <username>
143143
```
144144

145145
**If using a private (internal) NLB:**

aws/examples/simple/main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ module "materialize_instance" {
378378
# The password for the external login to the Materialize instance
379379
external_login_password_mz_system = random_password.external_login_password_mz_system.result
380380
authenticator_kind = "Password"
381+
superuser_credentials = {
382+
username = "materialize_admin"
383+
}
381384

382385
# AWS IAM role annotation for service account
383386
service_account_annotations = {

aws/examples/simple/outputs.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ output "nlb_dns_name" {
111111
value = module.materialize_nlb.nlb_dns_name
112112
}
113113

114-
output "mz_instance_service_account_credentials" {
115-
description = "Credentials for the default service account with superuser privileges, Login to materialize using these credentials"
116-
value = module.materialize_instance.service_account_credentials
114+
output "mz_instance_superuser_credentials" {
115+
description = "Credentials for the superuser, Login to materialize using these credentials"
116+
value = module.materialize_instance.superuser_credentials
117117
sensitive = true
118118
}
119119

azure/examples/simple/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ To get the Load Balancer IP:
160160
kubectl get svc -n materialize-environment -o jsonpath='{.items[?(@.spec.type=="LoadBalancer")].status.loadBalancer.ingress[0].ip}'
161161
```
162162

163-
Connect using psql with the default service account credentials:
163+
Connect using psql with the superuser credentials:
164164
```bash
165165
# Get the password (use jq -r to decode JSON-escaped characters)
166-
terraform output -json mz_instance_service_account_credentials | jq -r '.password'
166+
terraform output -json mz_instance_superuser_credentials | jq -r '.password'
167167

168-
psql -h <LoadBalancerIP> -p 6875 -U default
168+
psql -h <LoadBalancerIP> -p 6875 -U <username>
169169
```
170170

171171
**If using a private (internal) Load Balancer:**

azure/examples/simple/outputs.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ output "resource_group_name" {
153153
value = azurerm_resource_group.materialize.name
154154
}
155155

156-
output "mz_instance_service_account_credentials" {
157-
description = "Credentials for the default service account with superuser privileges, Login to materialize using these credentials"
158-
value = module.materialize_instance.service_account_credentials
156+
output "mz_instance_superuser_credentials" {
157+
description = "Credentials for the superuser, Login to materialize using these credentials"
158+
value = module.materialize_instance.superuser_credentials
159159
sensitive = true
160160
}
161161

gcp/examples/simple/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ To get the Load Balancer IP:
160160
kubectl get svc -n materialize-environment -o jsonpath='{.items[?(@.spec.type=="LoadBalancer")].status.loadBalancer.ingress[0].ip}'
161161
```
162162

163-
Connect using psql with the default service account credentials:
163+
Connect using psql with the superuser credentials:
164164
```bash
165165
# Get the password (use jq -r to decode JSON-escaped characters)
166-
terraform output -json mz_instance_service_account_credentials | jq -r '.password'
166+
terraform output -json mz_instance_superuser_credentials | jq -r '.password'
167167

168-
psql -h <LoadBalancerIP> -p 6875 -U default
168+
psql -h <LoadBalancerIP> -p 6875 -U <username>
169169
```
170170

171171
**If using a private (internal) Load Balancer:**

gcp/examples/simple/main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ module "materialize_instance" {
330330
# The password for the external login to the Materialize instance
331331
external_login_password_mz_system = random_password.external_login_password_mz_system.result
332332
authenticator_kind = "Password"
333+
superuser_credentials = {
334+
username = "materialize_admin"
335+
}
333336

334337
# GCP workload identity annotation for service account
335338
# TODO: this needs a fix in Environmentd Client. KSA based access to storage doesn't work end to end

gcp/examples/simple/outputs.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ output "balancerd_load_balancer_ip" {
147147
value = module.load_balancers.balancerd_load_balancer_ip
148148
}
149149

150-
output "mz_instance_service_account_credentials" {
151-
description = "Credentials for the default service account with superuser privileges, Login to materialize using these credentials"
152-
value = module.materialize_instance.service_account_credentials
150+
output "mz_instance_superuser_credentials" {
151+
description = "Credentials for the superuser, Login to materialize using these credentials"
152+
value = module.materialize_instance.superuser_credentials
153153
sensitive = true
154154
}
155155

kubernetes/modules/materialize-instance/main.tf

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,47 @@
11
locals {
2-
secret_name = "${var.instance_name}-materialize-backend"
3-
mz_resource_id = data.kubernetes_resource.materialize_instance.object.status.resourceId
4-
service_account_name = "default"
2+
secret_name = "${var.instance_name}-materialize-backend"
3+
mz_resource_id = data.kubernetes_resource.materialize_instance.object.status.resourceId
4+
create_superuser = contains(["Password", "Sasl"], var.authenticator_kind) && var.superuser_credentials != null
55

6-
# Hash of password - job only recreates when password changes
7-
service_account_password_hash = contains(["Password", "Sasl"], var.authenticator_kind) ? substr(sha256(random_password.service_account_password[0].result), 0, 8) : ""
6+
use_provided_password = trimspace(try(var.superuser_credentials.password, "")) != ""
7+
superuser_password = local.create_superuser ? (local.use_provided_password ? var.superuser_credentials.password : random_password.superuser_password[0].result) : ""
88
}
99

10-
resource "random_password" "service_account_password" {
11-
count = contains(["Password", "Sasl"], var.authenticator_kind) ? 1 : 0
10+
resource "random_password" "superuser_password" {
11+
count = local.create_superuser ? 1 : 0
1212
length = 16
1313
special = true
1414
override_special = "!#$%&*()-_=+[]{}<>:?"
1515
}
1616

17-
# Create a job to create the default service account with superuser privileges
18-
# https://materialize.com/docs/security/self-managed/access-control/manage-roles/#create-individual-userservice-account-roles
19-
resource "kubernetes_job" "create_service_account" {
20-
count = contains(["Password", "Sasl"], var.authenticator_kind) ? 1 : 0
17+
# Secret to store superuser credentials (avoids exposing password in pod spec)
18+
resource "kubernetes_secret" "superuser_credentials" {
19+
count = local.create_superuser ? 1 : 0
20+
2121
metadata {
22-
# Hash in name ensures job only recreates when password changes
23-
name = "${var.instance_name}-create-role-${local.service_account_password_hash}"
22+
name = "${var.instance_name}-superuser-credentials"
2423
namespace = var.instance_namespace
2524
}
2625

26+
data = {
27+
username = var.superuser_credentials.username
28+
password = local.superuser_password
29+
}
30+
31+
}
32+
33+
# Create a job to create the user with superuser privileges
34+
# https://materialize.com/docs/security/self-managed/access-control/manage-roles/#create-individual-userservice-account-roles
35+
resource "kubernetes_job" "create_superuser" {
36+
count = local.create_superuser ? 1 : 0
37+
metadata {
38+
generate_name = "${var.instance_name}-create-superuser-"
39+
namespace = var.instance_namespace
40+
}
41+
2742
spec {
28-
# No TTL - job stays so Terraform doesn't see drift and recreate on every apply
29-
backoff_limit = 3
43+
ttl_seconds_after_finished = 600
44+
backoff_limit = 3
3045

3146
template {
3247
metadata {
@@ -40,18 +55,18 @@ resource "kubernetes_job" "create_service_account" {
4055

4156
container {
4257
name = "psql"
43-
image = "postgres:16-alpine"
58+
image = "postgres:18-alpine"
4459

4560
command = [
4661
"sh", "-c",
4762
<<-EOT
48-
ROLE_EXISTS=$(PGPASSWORD=$MZ_PASSWORD psql -h $MZ_HOST -p 6875 -U mz_system -d materialize -tAc "SELECT 1 FROM mz_roles WHERE name = '${local.service_account_name}';")
63+
ROLE_EXISTS=$(PGPASSWORD=$MZ_PASSWORD psql -h $MZ_HOST -p 6875 -U mz_system -d materialize -tAc "SELECT 1 FROM mz_roles WHERE name = '$SUPERUSER_USERNAME';")
4964
if [ -z "$ROLE_EXISTS" ]; then
5065
PGPASSWORD=$MZ_PASSWORD psql -h $MZ_HOST -p 6875 -U mz_system -d materialize \
51-
-c "CREATE ROLE ${local.service_account_name} WITH SUPERUSER LOGIN PASSWORD '${random_password.service_account_password[0].result}';"
66+
-c "CREATE ROLE $SUPERUSER_USERNAME WITH SUPERUSER LOGIN PASSWORD '$SUPERUSER_PASSWORD';"
5267
else
5368
PGPASSWORD=$MZ_PASSWORD psql -h $MZ_HOST -p 6875 -U mz_system -d materialize \
54-
-c "ALTER ROLE ${local.service_account_name} PASSWORD '${random_password.service_account_password[0].result}';"
69+
-c "ALTER ROLE $SUPERUSER_USERNAME PASSWORD '$SUPERUSER_PASSWORD';"
5570
fi
5671
EOT
5772
]
@@ -70,6 +85,26 @@ resource "kubernetes_job" "create_service_account" {
7085
}
7186
}
7287
}
88+
89+
env {
90+
name = "SUPERUSER_USERNAME"
91+
value_from {
92+
secret_key_ref {
93+
name = kubernetes_secret.superuser_credentials[0].metadata[0].name
94+
key = "username"
95+
}
96+
}
97+
}
98+
99+
env {
100+
name = "SUPERUSER_PASSWORD"
101+
value_from {
102+
secret_key_ref {
103+
name = kubernetes_secret.superuser_credentials[0].metadata[0].name
104+
key = "password"
105+
}
106+
}
107+
}
73108
}
74109
}
75110
}
@@ -79,6 +114,7 @@ resource "kubernetes_job" "create_service_account" {
79114

80115
timeouts {
81116
create = "5m"
117+
update = "5m"
82118
}
83119

84120
depends_on = [

kubernetes/modules/materialize-instance/outputs.tf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ output "mz_system_credentials" {
3232
sensitive = true
3333
}
3434

35-
output "service_account_credentials" {
36-
description = "Credentials for the default service account with superuser privileges, Login to materialize using these credentials"
37-
value = contains(["Password", "Sasl"], var.authenticator_kind) ? {
38-
username = local.service_account_name
39-
password = random_password.service_account_password[0].result
35+
output "superuser_credentials" {
36+
description = "Credentials for the superuser, Login to materialize using these credentials"
37+
value = local.create_superuser ? {
38+
username = var.superuser_credentials.username
39+
password = local.superuser_password
4040
} : {}
4141
sensitive = true
4242
}

0 commit comments

Comments
 (0)