> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS IAM permissions for runner deployment

export const m_runner = "Maia runner";

export const maia = "Maia";

export const RunnerMetadata = ({runnerType, platforms = []}) => {
  return <div style={{
    background: 'var(--colors-background-light, #f9fafb)',
    border: '1px solid var(--colors-border-default, #e5e7eb)',
    borderRadius: '12px',
    padding: '20px 28px',
    marginBottom: '28px',
    boxShadow: '0 1px 4px rgba(0,0,0,0.10)'
  }}>
      <table style={{
    width: '100%',
    borderCollapse: 'collapse'
  }}>
        <tbody>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    paddingBottom: '14px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle',
    width: '180px'
  }}>Runner type</td>
            <td style={{
    paddingBottom: '14px',
    verticalAlign: 'middle'
  }}>{runnerType}</td>
          </tr>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle'
  }}>Runner platform</td>
            <td style={{
    verticalAlign: 'middle'
  }}>
              <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    gap: '8px'
  }}>
                {platforms.map((platform, i) => <span key={i} style={{
    background: '#dcfce7',
    color: '#15803d',
    border: '1px solid #bbf7d0',
    borderRadius: '9999px',
    padding: '3px 12px',
    fontSize: '0.85rem',
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
                    {platform} ✅
                  </span>)}
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>;
};

<RunnerMetadata runnerType={`${maia} Hybrid`} platforms={["AWS"]} />

This guide lists the AWS IAM permissions required to deploy a {m_runner} using the CloudFormation templates Matillion provides. It covers the permissions needed by the deploying user or role—the identity that runs the CloudFormation stack—rather than the permissions the running {m_runner} itself needs, which are covered separately in [AWS IAM roles](/docs/guides/aws-iam-roles).

Always follow the principle of least privilege and assign only the minimum permissions required for the specific task.

***

## Deployer permissions

The user or role deploying the CloudFormation stack requires permissions across several AWS services, including IAM, EC2, CloudWatch Logs, Secrets Manager, and ECS.

### Coarse-grained

The following AWS managed policies cover all deployment requirements:

* AmazonECS\_FullAccess
* CloudWatchFullAccess
* SecretsManagerReadWrite
* IAMFullAccess
* AmazonS3FullAccess

### Fine-grained

If you prefer to scope permissions more tightly than the managed policies above, the following actions are required.

| AWS service | Actions |
| - | - |
| IAM | `iam:AddRoleToInstanceProfile`, `iam:PutRolePolicy`, `iam:PassRole`, `iam:GetRolePolicy`, `iam:CreateInstanceProfile`, `iam:DeleteInstanceProfile`, `iam:RemoveRoleFromInstanceProfile`, `iam:DetachRolePolicy`, `iam:AttachRolePolicy`, `iam:DeleteRolePolicy`, `iam:GetRole`, `iam:CreateRole`, `iam:DeleteRole`, `iam:TagPolicy`, `iam:UntagRole`, `iam:TagRole`, `iam:UntagPolicy`, `iam:UpdateRole`, `iam:UntagInstanceProfile`, `iam:TagInstanceProfile` |
| EC2 | `ec2:ReplaceIamInstanceProfileAssociation`, `ec2:AuthorizeSecurityGroupEgress`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:RevokeSecurityGroupEgress`, `ec2:RevokeSecurityGroupIngress`, `ec2:DescribeSecurityGroups`, `ec2:DescribeVpcs`, `ec2:DescribeSubnets`, `ec2:UpdateSecurityGroupRuleDescriptionsIngress`, `ec2:UpdateSecurityGroupRuleDescriptionsEgress`, `ec2:CreateTags`, `ec2:ModifySecurityGroupRules`, `ec2:DisassociateIamInstanceProfile`, `ec2:DeleteTags`, `ec2:CreateSecurityGroup`, `ec2:AssociateIamInstanceProfile`, `ec2:DeleteSecurityGroup` |
| Logging | `logs:PutRetentionPolicy`, `logs:CreateLogStream`, `logs:TagLogGroup`, `logs:TagResource`, `logs:CreateLogGroup`, `logs:DeleteLogStream`, `logs:UntagLogGroup`, `logs:DeleteLogGroup`, `logs:UntagResource` |
| ECS and Secrets Manager | `secretsmanager:DeleteSecret`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:TagResource`, `secretsmanager:UntagResource`, `secretsmanager:CreateSecret`, `secretsmanager:UpdateSecret`, `ecs:UpdateCluster`, `ecs:DescribeServices`, `ecs:DescribeTasks`, `ecs:DescribeClusters`, `ecs:UpdateContainerInstancesState`, `ecs:StartTask`, `ecs:CreateCapacityProvider`, `ecs:UpdateService`, `ecs:RegisterTaskDefinition`, `ecs:StopTask`, `ecs:DeregisterContainerInstance`, `ecs:DeleteTaskDefinitions`, `ecs:TagResource`, `ecs:UpdateClusterSettings`, `ecs:CreateCluster`, `ecs:DeleteService`, `ecs:DeleteCluster`, `ecs:RegisterContainerInstance`, `ecs:DeleteCapacityProvider`, `ecs:DeregisterTaskDefinition`, `ecs:CreateService`, `ecs:RunTask`, `ecs:UntagResource`, `ecs:PutClusterCapacityProviders`, `ecs:UpdateCapacityProvider`, `ecs:UpdateContainerAgent` |
| CloudFormation | `cloudformation:CreateStack` |

<Note>
  You can refer to the [IAM roles](/docs/guides/aws-iam-roles#task-role) documentation for more detailed information on the task role and task execution role that the CloudFormation stack creates.
</Note>

***

## AWS service-linked roles

Before deploying a {m_runner}, confirm the existence of a service-linked role for Amazon ECS in your AWS account. For details, read [Prerequisites](/docs/guides/aws-fargate-manual-runner-setup#prerequisites) in the AWS Fargate manual setup guide.

***

For S3 and Azure Blob Storage permissions used by pipeline components, read [Cloud provider credentials](/docs/guides/cloud-credentials#roles-and-permissions-for-cloud-storage).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.