CipherStashDocs

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

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 identifier
  • CS_CLIENT_ID — application client ID
  • CS_CLIENT_KEY — application client key
  • CS_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:latest

Create 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.json

Note 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.json

Inline 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.json

Managed 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/AmazonECSTaskExecutionRolePolicy

Create 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.json

Create 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-proxy

Create 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-proxy

Notes 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-count based on load.

On this page