Deploying to AWS ECS
Deploy CipherStash Proxy to AWS ECS on Fargate, covering ECR images, Secrets Manager credentials, IAM roles, task definitions, and an RDS connection.
Deploying CipherStash Proxy to AWS ECS
Prerequisites
- AWS Account: An active AWS account
- AWS CLI: Installed and configured with appropriate permissions (install guide)
- Docker: Installed if you need to push the image to ECR
- CipherStash Proxy config: Refer to the Proxy config reference
- AWS RDS instance: A PostgreSQL RDS instance in the same VPC as your ECS cluster
Set up CipherStash credentials
You need CipherStash credentials for your production Proxy deployment. Create an application client key and access key in the Dashboard — see Going to production for the full guide.
You will need:
CS_WORKSPACE_CRN— your workspace identifierCS_CLIENT_ID— application client IDCS_CLIENT_KEY— application client keyCS_CLIENT_ACCESS_KEY— access key with the member role
Note these credentials. You need them in later steps.
Prepare your Docker image
Docker images are available from:
If using Docker Hub, push the image to Amazon ECR:
# Ensure you have set these environment variables:
# export AWS_ACCOUNT_ID=111222333444
# export AWS_REGION=ap-southeast-2
set -u
aws ecr create-repository --repository-name cipherstash-proxy
aws ecr get-login-password | docker login \
--username AWS \
--password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
docker tag cipherstash/proxy:latest \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/cipherstash-proxy:latest
docker push \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/cipherstash-proxy:latestCreate secrets
Using the credentials from Step 1, create cipherstash-proxy-secrets.json:
{
"CS_WORKSPACE_ID": "...",
"CS_CLIENT_ID": "...",
"CS_DEFAULT_KEYSET_ID": "...",
"CS_CLIENT_KEY": "...",
"CS_CLIENT_ACCESS_KEY": "...",
"CS_DATABASE__PASSWORD": "..."
}The value of CS_DATABASE__PASSWORD is the password of your PostgreSQL RDS instance.
Create the secret in Secrets Manager:
aws secretsmanager create-secret \
--name cipherstash-proxy \
--secret-string file://cipherstash-proxy-secrets.jsonNote the ARN. You need it for the task definition.
Set up IAM roles and permissions
Trust policy
Create ecs-tasks-trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}Create the IAM role:
aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document file://ecs-tasks-trust-policy.jsonInline policy
Create cipherstash-proxy-ecs-policy.json, substituting the ARN of your Secrets Manager secret:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"ARN_OF_SECRETSMANAGER_SECRET"
]
}
]
}Attach the inline policy:
aws iam put-role-policy \
--role-name ecsTaskExecutionRole \
--policy-name CipherStashProxyECSPolicy \
--policy-document file://cipherstash-proxy-ecs-policy.jsonManaged policy
Attach the ECS task execution managed policy:
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicyCreate an ECS task definition
Create cipherstash-proxy-task-def.json, replacing placeholders with values from previous steps:
{
"family": "cipherstash-proxy",
"networkMode": "awsvpc",
"executionRoleArn": "ARN_OF_ROLE",
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "cipherstash-proxy",
"image": "IMAGE_FROM_STEP_2",
"essential": true,
"portMappings": [
{ "containerPort": 6432, "hostPort": 6432 },
{ "containerPort": 9930, "hostPort": 9930 }
],
"environment": [
{ "name": "CS_DATABASE__USERNAME", "value": "RDS_USERNAME" },
{ "name": "CS_DATABASE__NAME", "value": "RDS_DATABASE_NAME" },
{ "name": "CS_DATABASE__HOST", "value": "RDS_HOSTNAME" },
{ "name": "CS_DATABASE__PORT", "value": "RDS_PORT" },
{ "name": "CS_PROMETHEUS__ENABLED", "value": "true" },
{ "name": "CS_DATABASE__INSTALL_EQL", "value": "true" }
],
"secrets": [
{ "name": "CS_WORKSPACE_ID", "valueFrom": "SECRET_ARN:CS_WORKSPACE_ID::" },
{ "name": "CS_CLIENT_ID", "valueFrom": "SECRET_ARN:CS_CLIENT_ID::" },
{ "name": "CS_DEFAULT_KEYSET_ID", "valueFrom": "SECRET_ARN:CS_DEFAULT_KEYSET_ID::" },
{ "name": "CS_CLIENT_KEY", "valueFrom": "SECRET_ARN:CS_CLIENT_KEY::" },
{ "name": "CS_CLIENT_ACCESS_KEY", "valueFrom": "SECRET_ARN:CS_CLIENT_ACCESS_KEY::" },
{ "name": "CS_DATABASE__PASSWORD", "valueFrom": "SECRET_ARN:CS_DATABASE__PASSWORD::" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "cipherstash-proxy",
"awslogs-region": "AWS_REGION",
"awslogs-stream-prefix": "cipherstash-proxy"
}
}
}
],
"requiresCompatibilities": ["FARGATE"],
"runtimePlatform": {
"operatingSystemFamily": "LINUX",
"cpuArchitecture": "ARM64"
}
}Register the task definition:
aws ecs register-task-definition \
--cli-input-json file://cipherstash-proxy-task-def.jsonCreate an ECS cluster and service
Create the cluster and log group:
aws ecs create-cluster --cluster-name ecs-app
aws logs create-log-group --log-group-name cipherstash-proxyCreate an ECS service (ensure you have the subnet and security group of your RDS instance):
# Ensure you have set these environment variables:
# export SUBNETS=subnet-xxx
# export SECURITY_GROUP=sg-xxx
aws ecs create-service \
--cluster ecs-app \
--service-name CipherStashProxy \
--task-definition cipherstash-proxy \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNETS],securityGroups=[$SECURITY_GROUP],assignPublicIp=ENABLED}"Verify the deployment
Check the service and task status:
# List services running in the cluster
aws ecs list-services --cluster ecs-app
# Show details of CipherStashProxy service
aws ecs describe-services --cluster ecs-app --services CipherStashProxy
# Tail the logs
aws logs tail --since 6h --follow cipherstash-proxyNotes and considerations
- Security: Store secrets (keys and passwords) in AWS Secrets Manager or Parameter Store, not in environment variables or task definitions.
- Networking: Configure security groups and subnets so your ECS tasks can reach your RDS instance.
- Scaling: Monitor ECS service metrics and adjust
desired-countbased on load.
Testing
Test applications using @cipherstash/stack encryption with a dedicated workspace or mocked client, plus PostgreSQL integration tests and CI setup.
Troubleshooting
Diagnose @cipherstash/stack issues including client init failures, decryption and keyset errors, empty search results, native addon loading, and performance.