Security, IAM & Secrets
This page describes how TLS, IAM roles and secrets are used to protect the services managed by this repository. It corresponds to the Security & Secrets diagram and focuses on the infra view rather than application logic.

The main concerns are:
- TLS termination and OIDC authentication at the Application Load Balancer
- IAM roles and policies for ECS tasks and Lambda functions
- Secrets stored in AWS Secrets Manager (and related parameters) for Kinde, databases and other external services
TLS and entry-point security (overview)
From a networking point of view (see also Networking & Entry Points):
- Cloudflare serves DNS for
rocketclub.onlineand proxies traffic towards AWS. - CloudFront distributions front the Application Load Balancer for
portal.rocketclub.onlineandpipelines.rocketclub.online. - The ALB terminates HTTPS/TLS and performs OIDC authentication with Kinde before routing traffic to ECS services for Backstage and Prefect.
TLS certificates for the ALB origin are managed via the acm-alb-origin module, and ALB resources, listeners and listener rules live under infra/modules/core/alb.
IAM roles and policies
IAM configuration for the core services is managed in the infra/modules/core/iam module and applied in infra/envs/prod.
At a high level:
- ECS tasks for Backstage and Prefect have task roles that allow them to:
- Read/write from S3 data buckets provisioned in this repo
- Read application secrets from AWS Secrets Manager
- Emit logs and metrics to CloudWatch and other AWS services as needed
- Lambda functions (such as the
.orkprocessor) have execution roles that allow them to:- Read
.orkfiles from the design files bucket - Write processed data to Neo4j Aura and Cloudinary using credentials stored in Secrets Manager
- Read
- CI/CD jobs (Terraform in CircleCI) use IAM roles with permissions scoped to manage the infrastructure resources defined in this repository.
The exact policies and role names are defined in Terraform under infra/modules/core/iam and wired into ECS and Lambda modules. This page does not attempt to document every statement; Terraform remains the source of truth.
Secrets Manager and Kinde OIDC configuration
Kinde is configured directly on the ALB using authenticate-oidc actions on HTTPS listener rules for both Backstage and Prefect:
- Listener rules live in
infra/modules/core/alb/listener_rules.tf. - The Kinde endpoints are derived from
var.kinde_domain(for exampleronaldhatcher.kinde.com). - The Kinde client ID comes from
var.kinde_client_id. - The Kinde client secret is stored in AWS Secrets Manager and referenced via
var.kinde_client_secret_arn.
In infra/envs/prod:
infra/envs/prod/variables.tfdefines:kinde_domainkinde_client_idkinde_client_secret_name(the Secrets Manager name/path)
infra/envs/prod/main.tfbuilds the fulllocal.kinde_client_secret_arnfrom that name, region and account ID and passes it into the ALB module.
The ALB module then uses data.aws_secretsmanager_secret_version.kinde_client_secret in infra/modules/core/alb/security.tf to resolve the client secret at apply time.
Other application credentials (for example database passwords, Prefect tokens, Cloudinary and Neo4j credentials) are also stored in AWS Secrets Manager and consumed by ECS tasks and Lambda functions via IAM roles defined in the iam module.
Key secrets in AWS Secrets Manager
| Secret name (prod) | Purpose | Primary consumers | Owned/defined by |
|---|---|---|---|
prod/db/admin | Aurora admin credentials | Aurora cluster module; Prefect DB URL builder | Terraform: infra/modules/core/iam, infra/modules/core/aurora |
prod/backstage/db | Backstage DB username/password | Backstage ECS task | Terraform: infra/modules/core/iam |
prod/backstage/database-url | Backstage database connection URL | Backstage ECS task | Secret container in infra/modules/core/iam |
prod/prefect/database-url | Prefect database connection URL | Prefect API ECS service | Terraform: infra/modules/apps/prefect-api |
prod/github/pat/blog_data_ci | Shared GitHub PAT | Backstage backend; Prefect deployer | External secret in AWS Secrets Manager |
prod/kinde/client-secret-* | Kinde OIDC client secret | ALB OIDC authentication | Referenced via kinde_client_secret_arn |
blog-data/neo4j/credentials | Neo4j connection credentials | Prefect flows; blog frontend | Defined in blog_data repo |
blog-data/cloudinary/credentials | Cloudinary API credentials | Prefect flows; blog frontend | Defined in blog_data repo |
This table is not exhaustive; consult Terraform modules and application-level secrets docs for additional entries.
Kinde OIDC runbook (config & rotation)
When you need to change or rotate Kinde credentials:
- Update Kinde app: In the Kinde dashboard, update or rotate the client secret for the application used by
portal.rocketclub.onlineandpipelines.rocketclub.online. - Update Secrets Manager: In AWS Secrets Manager, update the secret whose name is given by
var.kinde_client_secret_namewith the new client secret value. - Apply Terraform: Run a Terraform plan/apply for
infra/envs/prod(typically via theterraform-prodCircleCI workflow). This refreshes the ALB listener rule configuration with the new client secret. - Verify login: Hit
https://portal.rocketclub.onlineandhttps://pipelines.rocketclub.onlinein a browser and confirm Kinde login works end-to-end (no redirect loops or 403s).
If authentication starts failing in production, this section plus the ALB and Kinde logs are the starting points for debugging.