feat(db): enforce runtime RLS boundaries

This commit is contained in:
2026-03-22 22:49:47 +04:00
parent 7665af0268
commit 97b5edcc0a
24 changed files with 2054 additions and 545 deletions

View File

@@ -58,8 +58,9 @@ echo -n "<value>" | gcloud secrets versions add telegram-webhook-secret --data-f
echo -n "<value>" | gcloud secrets versions add scheduler-shared-secret --data-file=- --project <project_id>
```
If you configure optional secret IDs such as `database_url_secret_id` or
`openai_api_key_secret_id`, add versions for those secrets as well.
If you configure optional secret IDs such as `app_database_url_secret_id`,
`worker_database_url_secret_id`, or `openai_api_key_secret_id`, add versions for those secrets as
well.
If GitHub OIDC deploy access is enabled, keep `telegram_bot_token_secret_id` aligned with the
real bot token secret name so CD can read it and sync Telegram commands automatically.
@@ -84,6 +85,9 @@ Recommended approach:
`bot_assistant_rate_limit_rolling_window_ms`
- optional `bot_mini_app_allowed_origins`
- optional `alert_notification_emails`
- runtime DB URLs should stay split:
`APP_DATABASE_URL` for authenticated request flows and `WORKER_DATABASE_URL` for background
workers
## Alerting baseline
@@ -115,3 +119,4 @@ CI runs:
- Scheduler jobs default to `paused = true` and `dry_run = true` to prevent accidental sends before live reminder delivery is ready.
- Bot API is public to accept Telegram webhooks; scheduler endpoint should still verify app-level auth.
- `bot_mini_app_allowed_origins` cannot be auto-derived in Terraform because the bot and mini app Cloud Run services reference each other; set it explicitly once the mini app URL is known.
- `DATABASE_URL` is migration-only and should not be injected into the bot runtime service.

View File

@@ -30,7 +30,8 @@ locals {
runtime_secret_ids = toset(compact([
var.telegram_webhook_secret_id,
var.scheduler_shared_secret_id,
var.database_url_secret_id,
var.app_database_url_secret_id,
var.worker_database_url_secret_id,
var.telegram_bot_token_secret_id,
var.openai_api_key_secret_id
]))

View File

@@ -179,8 +179,11 @@ module "bot_api_service" {
TELEGRAM_WEBHOOK_SECRET = var.telegram_webhook_secret_id
SCHEDULER_SHARED_SECRET = var.scheduler_shared_secret_id
},
var.database_url_secret_id == null ? {} : {
DATABASE_URL = var.database_url_secret_id
var.app_database_url_secret_id == null ? {} : {
APP_DATABASE_URL = var.app_database_url_secret_id
},
var.worker_database_url_secret_id == null ? {} : {
WORKER_DATABASE_URL = var.worker_database_url_secret_id
},
var.telegram_bot_token_secret_id == null ? {} : {
TELEGRAM_BOT_TOKEN = var.telegram_bot_token_secret_id

View File

@@ -8,7 +8,8 @@ artifact_repository_id = "household-bot"
bot_api_image = "europe-west1-docker.pkg.dev/my-gcp-project/household-bot/bot:latest"
mini_app_image = "europe-west1-docker.pkg.dev/my-gcp-project/household-bot/miniapp:latest"
database_url_secret_id = "database-url"
app_database_url_secret_id = "app-database-url"
worker_database_url_secret_id = "worker-database-url"
telegram_bot_token_secret_id = "telegram-bot-token"
openai_api_key_secret_id = "openai-api-key"
bot_purchase_parser_model = "gpt-4o-mini"

View File

@@ -57,7 +57,21 @@ variable "scheduler_shared_secret_id" {
}
variable "database_url_secret_id" {
description = "Optional Secret Manager ID for DATABASE_URL"
description = "Optional Secret Manager ID for owner-only DATABASE_URL used outside runtime deploys"
type = string
default = null
nullable = true
}
variable "app_database_url_secret_id" {
description = "Optional Secret Manager ID for APP_DATABASE_URL"
type = string
default = null
nullable = true
}
variable "worker_database_url_secret_id" {
description = "Optional Secret Manager ID for WORKER_DATABASE_URL"
type = string
default = null
nullable = true