AWS ECR
ECR is the registry where IAM, regions, and cross-account access dominate the setup. The registry hostname encodes both the AWS account and the region — <account-id>.dkr.ecr.<region>.amazonaws.com — and a single connection scans one account in one region.
Auth options
| Method | When to use | Required HarborGuard fields |
|---|---|---|
| IAM access key + secret | Cloud scan from outside AWS, or quick proof-of-concept | Access Key ID + Secret Access Key |
| IAM role on the sensor host | Sensor runs on EC2/ECS/EKS in the same account or one that can sts:AssumeRole | None — the sensor uses the instance / pod IAM role |
| Cross-account assume-role | Sensor runs in account A, scans ECR in account B | The sensor's role must be allowed by B's repository policy |
ECR is the only provider whose wizard asks for Access Key ID / Secret Access Key rather than Username / Password. The provider is auto-detected when the URL matches *.dkr.ecr.*.amazonaws.com.
Add the registry
- Registries → Connect Registry.
- Registry URL —
123456789012.dkr.ecr.us-east-1.amazonaws.com. The wizard parses out account + region. - The wizard shows
AWS ECR Detectedand the credential form switches to AWS fields. - Cloud mode: paste the access key + secret of an IAM user with the policy below. Sensor mode: skip credentials; the sensor uses the host's role.
- Save. The first sync calls
ecr:DescribeRepositoriesfollowed byecr:DescribeImagesper repo.
Required IAM permissions
Minimum policy for HarborGuard to enumerate and scan an ECR registry:
ecr:GetAuthorizationToken is special — it must be granted on *, not on a repository ARN. Forgetting this is the most common cause of a registry that lists its repos but cannot pull any layers.
Cross-account access
When the sensor's role lives in account A (111111111111) and the ECR registry is in account B (222222222222):
- In account
A, the sensor's role gets the policy above (with<account-id>set to222222222222). - In account
B, attach a repository policy to each scanned repository:
Push-event sync
ECR emits PutImage events on the EventBridge default bus. To wire up on_push:
- Create an EventBridge rule matching
aws.ecr/ detail-typeECR Image Action/action-type = PUSH. - Target an API Destination that POSTs to
https://<your-harborguard-host>/api/webhooks/ecr. - Set the registry's schedule to
on_push.
A scan is queued within seconds of the push and a private-network sensor handles the actual pull, so the image never leaves your VPC.
Common pitfalls
- Wrong region. ECR is regional.
123456789012.dkr.ecr.us-east-1.amazonaws.comand123456789012.dkr.ecr.us-west-2.amazonaws.comare two separate registries. Add a connection per region. ecr:GetAuthorizationTokenresource scope. Granting it on a repository ARN silently fails token exchange. It must beResource: "*".- Public ECR.
public.ecr.awsis a different service with a different API. It is not yet supported as a typed provider — use Custom / OCI if you must. - Image immutability. If a tag has been pushed to an immutable repository, re-pushing the same tag fails — but HarborGuard still rescans on the new digest if you re-tag.
- Lifecycle policies that race the scan. A lifecycle policy that prunes untagged images can delete an image between catalog sync and scan dispatch. The scan job will report "manifest not found"; reduce the policy's untagged window to ≥ scan interval.
Troubleshooting
| Symptom | Likely cause |
|---|---|
Repos enumerate, but scans fail with denied | Missing ecr:BatchGetImage / ecr:GetDownloadUrlForLayer |
| Test connection succeeds, sync produces zero repos | The IAM principal has access in a different region than the URL |
| "InvalidSignatureException" | Clock drift on the sensor host > 5 minutes |
| Cross-account: list works, pull fails | Repository policy missing on the target account |
| Sensor mode authenticates but eventually 401s | Role-chain credentials expired and the sensor isn't refreshing — confirm AWS_ROLE_ARN and IRSA / IMDSv2 access |