Least-Privilege AWS Account Setup for Harness in a SaaS Environment
Contents
When deploying a SaaS service on AWS and connecting Harness for CI/CD, one of the first questions is how Harness should access the AWS account.
The easiest option is to create an Access Key and attach AdministratorAccess, but that creates an unnecessarily large blast radius if the credential is ever compromised.
This post describes a setup that allows Harness to deploy AWS resources while granting only the permissions it actually needs.
Assumption: an AWS Connector is configured through Harness Delegate or Harness Platform, and a restricted IAM Role is provided in the target SaaS deployment account.
The short answer
Use the following approach where possible.
- Do not use an IAM User Access Key as the default authentication method.
- Prefer IAM Role + STS AssumeRole for Harness access to AWS.
- When the external Harness SaaS assumes the role, include an External ID in the trust policy.
- Separate roles by deployment environment.
harness-dev-deploy-roleharness-stg-deploy-roleharness-prod-deploy-role
- Do not try to produce a perfect least-privilege policy immediately. Start small, observe Access Analyzer and CloudTrail, then refine the policy.
AWS recommends temporary credentials and roles over long-lived IAM user Access Keys. IAM policies should also follow the least-privilege principle by allowing only the actions required for the workload.
Recommended architecture
| |
Why use a role?
An Access Key is a long-lived credential that remains usable until it is revoked. STS authentication through an IAM Role issues temporary credentials with a limited session duration.
The target account can also separate two concerns:
- the trust policy controls who can assume the role
- the permission policy controls what the assumed role can do
Harness AWS Connector supports a cross-account role ARN and External ID. The connector’s base credential assumes a role in the target account, and that assumed role receives only the permissions required for services such as S3, ECS, EC2, or EKS.
Account and role design
For a SaaS environment, I prefer at least the following separation.
| Environment | Purpose | Harness permissions |
|---|---|---|
shared | ECR, shared artifacts, CI infrastructure | Image push/pull and artifact read/write |
dev | Development deployments | Can be broader, but avoid administrator access |
stg | Pre-production validation | Restricted similarly to production |
prod | Live customer traffic | Narrowest permissions and mandatory approval |
Even before adopting AWS Organizations, keep the dev, staging, and production roles separate by name and policy. This reduces migration cost later when accounts are split or Control Tower is introduced.
Trust policy example
A role assumed by Harness from outside the target account can begin with a trust policy like this.
| |
Two points matter here.
- Restrict
Principalto a specific AWS account and role whenever possible. - Use
sts:ExternalIdto reduce the confused deputy risk.
An External ID is not a secret like a password. It is an additional control that helps distinguish whether an AssumeRole request made by a third-party service is intended for this specific customer account.
Permission policy example: ECS deployment
For an ECS/Fargate deployment, the Harness deployment role can start with permissions similar to the following.
| |
In production, reduce Resource: "*" wherever possible. Some actions, such as ECR GetAuthorizationToken, cannot be restricted to a repository resource. A practical approach is to verify the deployment first and then narrow repository, cluster, and service ARNs incrementally.
Permission policy example: Terraform and IaC
When Harness uses Terraform to create VPC, ECS, RDS, and other infrastructure, the required permission scope becomes much larger. Do not place every permission into one role. Split the responsibilities instead.
| Role | Responsibility |
|---|---|
harness-iac-plan-role | Read-oriented permissions for terraform plan |
harness-iac-apply-role | Permissions for terraform apply, used only after approval |
harness-app-deploy-role | Application image and service deployment |
Avoid granting broad permissions such as iam:*, organizations:*, account:*, or kms:* from the beginning. When they are required, constrain them with specific paths, prefixes, resources, and tag conditions.
Harness Connector setup
- Create
harness-prod-deploy-rolein the target AWS account. - Add the Harness-side principal and External ID to the role trust policy.
- Attach a least-privilege permission policy for the deployment type, such as ECS, EKS, Lambda, or Terraform.
- Create an AWS Connector in Harness.
- Select a cross-account role ARN or a Delegate-based AssumeRole authentication method.
- Enter the External ID.
- Run Test connection.
- Review only the failed actions in CloudTrail or Harness logs and add permissions as needed.
Harness documentation notes that the AWS Connector connection test may require ec2:DescribeRegions. When the test fails even though the actual deployment permissions look correct, check whether this action is missing.
Operations checklist
- Enable MFA for the root account
- Define expiration and rotation rules for any long-lived Access Key used by Harness
- Allow only deployment-related actions in the production role
- Restrict
iam:PassRoleto specific task and task execution roles - Use an External ID
- Enable CloudTrail
- Use IAM Access Analyzer to inspect external access and unused permissions
- Add Harness approval or Change Management stages to production pipelines
- Separate connectors for dev, staging, and production
- Keep the break-glass administrator account separate and unused during normal operations
The rules I use
CI/CD permissions for a SaaS service need to balance deployment convenience with a small blast radius. I start with these rules.
- Do not give Harness administrator access.
- Separate human identities from automation roles.
- Separate deployment roles by environment.
- Treat
PassRoleand KMS permissions conservatively. - First make the deployment work, then immediately reduce permissions using Access Analyzer and CloudTrail evidence.