with one click
ecr-image-source-repo-via-provenance
// Recover the source GitHub repository and workflow metadata for an AWS ECR image by reading OCI attestation/provenance manifests via boto3 when the source repo is not otherwise obvious.
// Recover the source GitHub repository and workflow metadata for an AWS ECR image by reading OCI attestation/provenance manifests via boto3 when the source repo is not otherwise obvious.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | ecr-image-source-repo-via-provenance |
| description | Recover the source GitHub repository and workflow metadata for an AWS ECR image by reading OCI attestation/provenance manifests via boto3 when the source repo is not otherwise obvious. |
| version | 1.0.0 |
| author | Hermes Agent |
| license | MIT |
| metadata | {"hermes":{"tags":["aws","ecr","provenance","slsa","github","containers","debugging"]}} |
Use this when:
Modern ECR images may include OCI attestation manifests with SLSA provenance. These often reveal:
team/repo)This is often enough to identify the real source repo even when:
git clone is impossibleStart from ECS task definition or image tag
ecs.describe_task_definition()702197142747.dkr.ecr.ap-northeast-2.amazonaws.com/segment-publisher:segment-publisher-<sha>Get the ECR image index/manifest
ecr.batch_get_image()Inspect attestation manifest(s)
vnd.docker.reference.type = attestation-manifestbatch_get_image()application/vnd.in-toto+jsonDownload the attestation layer
ecr.get_download_url_for_layer() on the in-toto layer digestExtract repository metadata
predicate.buildDefinition.internalParameters.github_repositorypredicate.buildDefinition.internalParameters.github_refpredicate.buildDefinition.internalParameters.github_workflowpredicate.buildDefinition.github_event_payload.repository.full_namesubject[] image names and tagsState the source clearly
segment-publisher:<tag> was built from GitHub repo team-michael/notifly-event.github/workflows/ecs_build.ymlrefs/heads/mainpython - <<'PY'
import boto3, os, json, urllib.request
session = boto3.Session(
aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY'),
aws_session_token=os.environ.get('AWS_SESSION_TOKEN'),
region_name=os.environ.get('AWS_DEFAULT_REGION', 'ap-northeast-2'),
)
ecr = session.client('ecr')
repo = 'segment-publisher'
tag = 'segment-publisher-<tag>'
resp = ecr.batch_get_image(
registryId='702197142747',
repositoryName=repo,
imageIds=[{'imageTag': tag}],
acceptedMediaTypes=['application/vnd.oci.image.index.v1+json']
)
index_manifest = json.loads(resp['images'][0]['imageManifest'])
attestation_digest = next(
m['digest'] for m in index_manifest['manifests']
if m.get('annotations', {}).get('vnd.docker.reference.type') == 'attestation-manifest'
)
resp = ecr.batch_get_image(
registryId='702197142747',
repositoryName=repo,
imageIds=[{'imageDigest': attestation_digest}],
acceptedMediaTypes=['application/vnd.oci.image.manifest.v1+json']
)
att_manifest = json.loads(resp['images'][0]['imageManifest'])
layer_digest = att_manifest['layers'][0]['digest']
url = ecr.get_download_url_for_layer(
registryId='702197142747',
repositoryName=repo,
layerDigest=layer_digest,
)['downloadUrl']
with urllib.request.urlopen(url, timeout=30) as r:
provenance = json.load(r)
print(json.dumps({
'github_repository': provenance['predicate']['buildDefinition']['internalParameters'].get('github_repository'),
'github_ref': provenance['predicate']['buildDefinition']['internalParameters'].get('github_ref'),
'github_workflow': provenance['predicate']['buildDefinition']['internalParameters'].get('github_workflow'),
}, indent=2))
PY
For Notifly ECS images, the ECR attestation revealed:
team-michael/notifly-event.github/workflows/ecs_build.ymlrefs/heads/mainThis was crucial because the repo was private and the available GitHub token authenticated as another user without access, so provenance was the only reliable way to identify the correct source repository.
batch_get_image() may first return an OCI index, not the final image manifest.