Step 2: Deploy the Key Access Server
The Key Access Server (KAS) is the core of DCS Level 3. It decides whether to release a Data Encryption Key based on the requesting user's attributes and the data's policy. We'll run the OpenTDF platform as a single ECS Fargate task with a public IP in your account's default VPC, no custom networking, no load balancer.
Create the RDS database
OpenTDF needs PostgreSQL for storing attribute definitions, subject mappings, and audit logs. We'll use a small single-AZ instance in the default VPC.
- Go to RDS Console: https://console.aws.amazon.com/rds
- Click Create database
- Engine: PostgreSQL
- Templates: Free tier
- DB instance identifier:
dcs-level3-opentdf - Master username:
opentdf - Master password: Choose a password and save it
- Instance configuration: db.t3.micro
- Connectivity:
- VPC: Default VPC
- Public access: No
- VPC security group: Create new >
dcs-level3-rds-sg
- Database name (under Additional configuration):
opentdf - Click Create database (takes 5-10 minutes)
While the database creates...
Continue with the ECS setup below. Come back to verify the database is available before starting the ECS service.
Update the RDS security group
The auto-created security group needs to allow connections from ECS tasks.
- Go to EC2 > Security Groups > find
dcs-level3-rds-sg - Edit Inbound rules
- Add: Type: PostgreSQL, Port: 5432, Source: the default VPC's CIDR (e.g.,
172.31.0.0/16) - Click Save rules
Default VPC
Every AWS account has a default VPC with public subnets in each AZ. We're using it to avoid creating any custom networking. The RDS instance and ECS task will both run here.
Create the ECS cluster
- Go to ECS Console: https://console.aws.amazon.com/ecs
- Click Create cluster
- Cluster name:
dcs-level3 - Infrastructure: AWS Fargate
- Click Create
Create the ECS task execution role
- Go to IAM > Roles > Create role
- Trusted entity: AWS service > Elastic Container Service > Elastic Container Service Task
- Attach policy:
AmazonECSTaskExecutionRolePolicy - Role name:
dcs-level3-ecs-execution-role - Click Create role
Create the ECS task role (for KMS access)
- Create another role: AWS service > Elastic Container Service > Elastic Container Service Task
- Role name:
dcs-level3-kas-task-role - Click Create role
- Add an inline policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:YOUR-REGION:YOUR-ACCOUNT:key/YOUR-KMS-KEY-ID"
}
]
}
Update the KMS key ARN
Replace the Resource with your actual KMS key ARN from Step 1.
Update the KMS key policy
Add the task role to the key's usage permissions:
- Open your
dcs-level3-kas-kekkey in the KMS console - Click Key policy > Edit
- Add a statement:
{
"Sid": "AllowKASTaskRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::YOUR-ACCOUNT:role/dcs-level3-kas-task-role"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "*"
}
Create the ECS task definition
This is where we configure the OpenTDF platform. We point the auth issuer at your Cognito user pool from Lab 2 and set entity resolution to claims mode so the platform reads user attributes directly from the JWT.
- Go to ECS > Task definitions > Create new task definition
- Family:
dcs-level3-opentdf - Launch type: Fargate
- CPU: 0.5 vCPU
- Memory: 1 GB
- Task role:
dcs-level3-kas-task-role - Task execution role:
dcs-level3-ecs-execution-role - Container:
- Name:
opentdf - Image:
ghcr.io/opentdf/platform:latest - Port mappings: 8080 TCP
- Environment variables:
- Name:
| Variable | Value |
|---|---|
OPENTDF_DB_HOST |
Your RDS endpoint (e.g., dcs-level3-opentdf.abc123.eu-west-2.rds.amazonaws.com) |
OPENTDF_DB_PORT |
5432 |
OPENTDF_DB_DATABASE |
opentdf |
OPENTDF_DB_USER |
opentdf |
OPENTDF_DB_PASSWORD |
Your database password |
OPENTDF_SERVER_PORT |
8080 |
OPENTDF_SERVER_AUTH_ISSUER |
https://cognito-idp.YOUR-REGION.amazonaws.com/YOUR-UK-POOL-ID |
OPENTDF_SERVER_AUTH_AUDIENCE |
http://localhost:8080 |
OPENTDF_SERVICES_ENTITYRESOLUTION_MODE |
claims |
- Click Create
Finding your Cognito issuer URL
The issuer URL follows the pattern https://cognito-idp.{region}.amazonaws.com/{userPoolId}. Use the UK user pool ID from Lab 2. Verify it by opening https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration in a browser.
Why claims mode?
The OpenTDF platform has three entity resolution modes: keycloak (calls back to Keycloak's admin API), claims (reads attributes directly from the JWT), and multi-strategy (preview). Since Cognito includes custom attributes in its OIDC tokens, claims mode is all we need. No extra identity infrastructure.
Run the ECS task with a public IP
Instead of setting up a load balancer, we'll run the task directly in a public subnet with a public IP assigned. This is the simplest way to make the KAS reachable.
- Go to your ECS cluster
dcs-level3> Tasks tab > Run new task - Launch type: Fargate
- Task definition:
dcs-level3-opentdf - Networking:
- VPC: Default VPC
- Subnets: Pick any one of the default public subnets
- Security group: Create new >
dcs-level3-ecs-sg- Inbound: Custom TCP, Port 8080, Source 0.0.0.0/0
- Public IP: ENABLED (this is the key setting)
- Click Run task (or Create depending on your console version)
Find the public IP
- Click on the running task
- In the Configuration section, find the Public IP (e.g.,
3.10.45.123) - Note this IP, you'll use it as your KAS endpoint
Test it:
You should get a 200 response.
The IP changes if the task restarts
Since we're not using a load balancer or Elastic IP, the public IP is dynamic. If the task stops and restarts, you'll get a new IP. For a demo this is fine, just note the new one. In production you'd put a load balancer or DNS in front.
Troubleshooting
If the task keeps stopping, check CloudWatch logs (the task definition creates a log group automatically). Common issues:
- Database connection refused: Check that the RDS security group allows inbound from the default VPC CIDR
- Wrong DB credentials: Double-check the environment variables
- Image pull failure: The task needs outbound internet access (default VPC public subnets have this via the internet gateway)
- Auth issuer unreachable: Verify the Cognito issuer URL is correct