AWS permissions per service
What each profile needs in AWS, read and write, for discovery, preflight and each kind of move.
Each profile acts in its own account: the source profile reads, the destination profile writes. Grant each one what its side of the move needs.
Reads for discovery and checks
| Service | Actions |
|---|---|
| STS | GetCallerIdentity |
| S3 | ListBuckets, GetBucketLocation |
| ECR | DescribeRepositories, DescribeImages, BatchGetImage (also covers ListImageReferrers) |
| CodeCommit | BatchGetRepositories, on both sides, before any Git operation |
| IAM Identity Center | sso:GetRoleCredentials, sso:ListAccounts, sso:ListAccountRoles; sso-oidc:RegisterClient, StartDeviceAuthorization, CreateToken; sts:AssumeRole only for a role chained after SSO |
Optional reads for preflight
s3:GetEncryptionConfiguration on both buckets, ecr:DescribeRepositories on
the mapped repositories and kms:DescribeKey on the keys they name. Douklar
calls kms:DescribeKey directly, so do not put it under a kms:ViaService
condition. Without these reads, the encryption posture shows "unknown" and the
run is not blocked.
Per service
| Move | Source profile | Destination profile |
|---|---|---|
| S3, worker relay | s3:ListBucket, s3:GetObject on the selected scope | s3:ListBucket, s3:PutObject on the destination scope |
| S3, server-side copy | One copy identity reads the source and writes the destination: the same S3 actions on both buckets | |
| DynamoDB | dynamodb:DescribeTable, DescribeTimeToLive, Scan | dynamodb:DescribeTable, DescribeTimeToLive, PutItem |
| ECR | Pull of the selected image and its referrers | Push and tag in the destination repository |
| CodeCommit | Git pull of the repository | Git push to the existing repository |
Copying an object's own metadata needs no version, tag, ACL or KMS-control
permission. DynamoDB needs no UpdateTimeToLive.
S3 Batch Operations
In the destination account, after you confirm Prepare: s3:CreateBucket for
the operations bucket, iam:CreateRole and iam:PutRolePolicy for the Batch
role, then s3:PutObject for the manifest, s3control:CreateJob and
s3control:UpdateJobStatus (Cancel, and Start for a held job). Set
S3_BATCH_ROLE_NAME to use a role you already manage instead.
Keys
The writing profile needs kms:GenerateDataKey and kms:Decrypt on the
destination key; the reading profile needs kms:Decrypt on the source key. A
key in another account also needs a key-policy statement there. Examples:
Hand a change to the other account's admin.
Log delivery
To deliver audit and run logs to S3: s3:PutObject on the configured bucket
and prefix only, plus kms:GenerateDataKey when that bucket uses a customer
managed key.