Skip to content

Commit 642cfb8

Browse files
committed
Add SSM parameter for the user-bot Slack token
1 parent 5b43117 commit 642cfb8

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

‎terraform/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Resources created by this code repository.
5454
| [aws_s3_bucket_public_access_block.tf_backend_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
5555
| [aws_s3_bucket_server_side_encryption_configuration.management_events](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
5656
| [aws_s3_bucket_server_side_encryption_configuration.tf_backend_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
57+
| [aws_ssm_parameter.user_bot_slack_token](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource |
5758
| [archive_file.user_bot_placeholder](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
5859
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
5960
## Inputs

‎terraform/user-bot.tf‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,54 @@ resource "aws_lambda_function" "user_bot" {
110110
filename = data.archive_file.user_bot_placeholder.output_path
111111
source_code_hash = data.archive_file.user_bot_placeholder.output_base64sha256
112112

113+
// The name, not the token. The function reads and decrypts the value at cold start.
114+
environment {
115+
variables = {
116+
SLACK_TOKEN_PARAMETER = aws_ssm_parameter.user_bot_slack_token.name
117+
}
118+
}
119+
113120
depends_on = [aws_cloudwatch_log_group.user_bot]
114121

115122
lifecycle {
116123
ignore_changes = [filename, source_code_hash]
117124
}
118125
}
119126

127+
// ---------------------------------------------------------------------------
128+
// Slack bot token
129+
// ---------------------------------------------------------------------------
130+
131+
// The Slack app's bot token (xoxb-...). Terraform creates the parameter with a
132+
// placeholder; the real token is set by hand with `aws ssm put-parameter --overwrite`
133+
// (see lambda/user-bot/README.md), so it never appears in git or in Terraform state.
134+
// See hackforla/devops-security#212.
135+
//
136+
// value_wo rather than value is what keeps the token out of state. With `value`, the
137+
// provider reads the decrypted parameter back into state on every refresh. With the
138+
// write-only value_wo, its read sets `value` to null, and the value is only ever
139+
// written when value_wo_version changes.
140+
//
141+
// Two traps, both because the real value lives outside Terraform:
142+
// - Never change value_wo_version. That writes the placeholder over the real token,
143+
// and the bot refuses to send until the token is set again.
144+
// - Do not change other arguments, such as description, in place. The provider then
145+
// sends an empty value and the apply fails.
146+
resource "aws_ssm_parameter" "user_bot_slack_token" {
147+
region = local.user_bot_region
148+
149+
name = "/user-bot/slack-bot-token"
150+
description = "Slack bot token for the user-bot Lambda. Set by hand; see lambda/user-bot/README.md in hackforla/devops-security."
151+
type = "SecureString"
152+
153+
value_wo = "placeholder-set-by-hand"
154+
value_wo_version = 1
155+
156+
lifecycle {
157+
prevent_destroy = true
158+
}
159+
}
160+
120161
// ---------------------------------------------------------------------------
121162
// Execution role
122163
// ---------------------------------------------------------------------------
@@ -165,6 +206,14 @@ resource "aws_iam_role_policy" "user_bot" {
165206
}
166207
}
167208
},
209+
// No kms:Decrypt statement: the parameter uses the AWS-managed aws/ssm key, whose
210+
// key policy already allows decryption through SSM for principals in the account.
211+
{
212+
Sid = "ReadSlackToken"
213+
Effect = "Allow"
214+
Action = "ssm:GetParameter"
215+
Resource = aws_ssm_parameter.user_bot_slack_token.arn
216+
},
168217
{
169218
Sid = "WriteOwnLogs"
170219
Effect = "Allow"

0 commit comments

Comments
 (0)