Release Manifest & Distribution
Use your BigHammer reader role to mirror entitled container images, Helm charts, and code packages into your Amazon Elastic Container Registry (ECR) and private artifact stores. Start with Step 1 — customer profile onboarding; then run the mirror workflow once per release.
BigHammer catalog artifacts may be archived or removed after a retention period. Always mirror into your ECR (and your private PyPI/npm repos if entitled) and treat those copies as your source of truth.
Step 1 — Customer profile registry (onboarding)
Before you can pull or mirror any artifact, BigHammer registers a customer profile for your organization. That profile defines who you are, what you are entitled to pull, and how your environment authenticates to the shared BigHammer release catalog.
BigHammer uses the profile to provision your dedicated IAM reader role:
arn:aws:iam::<bh-aws-account-id>:role/bh-artifact-reader-<customer-id>
You do not get a separate copy of the catalog at BigHammer. Access is scoped to entitled charts, images, and packages only.
What you submit
Send the following to your BigHammer contact. They map it to a CustomerProfile (apiVersion: bighammer.io/v1).
Organization and contacts
| Field | Example | Notes |
|---|---|---|
| Customer ID | <customer-id> | Stable kebab-case name; becomes part of the reader role |
| Display name | Example Corp | Legal or team name |
| Technical contact | devops@example.com | Handoff and entitlement changes |
AWS deployment
| Field | Example |
|---|---|
| Primary cloud | aws |
| AWS account ID | <your-aws-account-id> |
| Region(s) | <your-aws-region> |
| EKS / cluster name | <your-eks-cluster> (if known) |
Trust (AWS cross-account)
Your environment assumes the BigHammer reader role with cross-account sts:AssumeRole and a customer-specific ExternalId. This is the established AWS-to-AWS path (trust.aws_accounts in the customer profile). GitHub Actions or GitLab CI is optional — the same trust works from an EC2 bastion, operator workstation, or automation runner.
| Method | What you provide |
|---|---|
| AWS cross-account | Your AWS account ID (12 digits); BigHammer generates a unique ExternalId and returns it in the handoff pack via secure channel |
Artifact entitlements
| Field | Typical value (AWS) |
|---|---|
| Version channel | stable, rc, or lts |
| Helm charts (OCI) | bighammer, bhrabbitmq, bh-gateway (optional) |
| Chart paths | aws/bh-helm-release/<chart> (confirm with handoff) |
| Container images | Nested repos (allowlist) and/or flat repos (full_repository) as entitled |
| Code packages (optional) | Entitled PyPI / npm package names |
Target registries (your AWS account)
| Artifact | AWS format | Example name |
|---|---|---|
| Container images | ECR repository | bh-docker-public or customer-defined |
| Helm OCI charts | ECR OCI repository | bh-helm-release |
| Python packages | Private CodeArtifact / other feed | Customer-defined |
| npm packages | Private CodeArtifact / other feed | Customer-defined |
Intake example (AWS)
Reference structure — BigHammer completes and stores the profile on your behalf:
apiVersion: bighammer.io/v1
kind: CustomerProfile
metadata:
customer_id: <customer-id>
display_name: Example Corp (AWS)
deployment:
primary_cloud: aws
platform:
aws:
account_id: "<your-aws-account-id>"
region: <your-aws-region>
eks_cluster_name: <your-eks-cluster>
artifact_access:
aws_reader_role:
enabled: true
trust:
aws_accounts:
- account_id: "<your-aws-account-id>"
external_id: "<external-id-from-bighammer>"
description: customer-prod-mirror
artifact_entitlements:
version_channel: stable
helm_charts:
- name: bighammer
- name: bh-gateway
- name: bhrabbitmq
container_images:
mode: platform_release
codeartifact:
pypi_packages:
- <entitled-pypi-package>
What BigHammer returns (handoff pack)
| Item | Example |
|---|---|
| Reader role ARN | arn:aws:iam::<bh-aws-account-id>:role/bh-artifact-reader-<customer-id> |
| AWS region (catalog) | <bh-catalog-aws-region> |
| ExternalId | Delivered via secure channel (vault / encrypted ticket — not plain email) |
| Release manifest | Pinned chart versions, image tags, package versions |
| Entitlements summary | Charts, images, and packages in scope |
| Trust runbook | AWS AssumeRole + ExternalId |
| Source URIs | BigHammer ECR and CodeArtifact endpoints (mirror pull only) |
| Egress limits | Monthly direct-pull quota on the reader role |
Store ExternalId in AWS Secrets Manager (or your vault) — never commit it to Git.
Onboarding checklist
| Step | Done |
|---|---|
| Intake submitted (org, AWS account ID, entitlements) | ☐ |
| Destination ECR repos created in your account (Docker + Helm OCI) | ☐ |
| Handoff pack received (reader role ARN + ExternalId + release manifest) | ☐ |
Test assume-role (aws sts get-caller-identity) from bastion or CI | ☐ |
Only after Step 1 is complete, proceed to mirror artifacts using one of the approaches below.
Mirrored URIs (examples):
<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-docker-public/<service>:<tag>
oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/bighammer:<version>
Choose a mirror approach
| Approach | When to use |
|---|---|
| Approach 1 — CI / automation runner | You already run GitHub Actions, GitLab CI, CodeBuild, or similar |
| Approach 2 — Bastion / EC2 (no runner) | Recommended when GitHub or GitLab is not in use — mirror from an EC2 instance, bastion, or operator workstation |
Both approaches use the same trust model: AssumeRole + ExternalId → pull from BigHammer ECR → push to your ECR → install only from your ECR afterward.
End-to-end process (numbered)
| Step | Environment | Action |
|---|---|---|
| 1 | You → BigHammer | Submit customer profile intake |
| 2 | BigHammer | Provision bh-artifact-reader-<customer_id> |
| 3 | BigHammer → You | Deliver handoff pack (role ARN, ExternalId, release manifest) |
| 4 | You | Choose Approach 1 (CI) or Approach 2 (bastion / EC2) |
| 5 | Your host ↔ BH AWS | Assume reader role with ExternalId |
| 6 | Your host ← BH catalog | Pull entitled images and charts |
| 7 | Your host | Restore your AWS credentials |
| 8 | Your host → Your ECR | Push mirrored artifacts |
| 9 | Ongoing | Install and upgrade only from your ECR |
Approach 1 — CI / automation runner
Use this when a pipeline assumes the reader role, pulls from BigHammer, and pushes to your ECR.
Typical pattern: a deploy or mirror role in your AWS account calls sts:AssumeRole into the BigHammer reader role with the handoff ExternalId, then runs the pull/push steps in the job.
| Credential | Used for |
|---|---|
| BH reader role (+ ExternalId) | Pull from BH ECR and CodeArtifact |
| Your AWS credentials / role | Push to your ECR repos |
Wire the same assume-role and mirror commands from Approach 2 into your pipeline stages. Keep ExternalId in the CI secret store — never in the repository.
Approach 2 — Bastion / EC2 (no runner)
Use this when there is no GitHub Actions or GitLab runner. An EC2 instance, bastion host, or operator workstation in your AWS account performs the mirror.
Approach 2 flow (numbered)
Prerequisites
| Requirement | Notes |
|---|---|
| Host tools | AWS CLI v2, Docker, Helm 3.10+ |
| IAM on the host | Permission to sts:AssumeRole on the BH reader role; permission to push to your ECR |
| Network | Egress to BigHammer ECR (<bh-catalog-aws-region>) and to your ECR (<your-aws-region>) |
| Destination repos | Create ECR repositories in your account before the first push |
| Secrets | ExternalId stored in Secrets Manager / SSM — not in scripts checked into Git |
2.1 Assume the reader role and verify identity
Replace placeholders with values from your handoff pack.
#!/usr/bin/env bash
set -euo pipefail
# --- From BigHammer handoff pack ---
BH_READER_ROLE_ARN="arn:aws:iam::<bh-aws-account-id>:role/bh-artifact-reader-<customer-id>"
EXTERNAL_ID="<external-id-from-bighammer>"
BH_CATALOG_REGION="<bh-catalog-aws-region>"
SESSION_NAME="<customer-id>-artifact-pull"
# Start from credentials in YOUR AWS account (instance profile, SSO, or env).
CREDS=$(aws sts assume-role \
--role-arn "${BH_READER_ROLE_ARN}" \
--role-session-name "${SESSION_NAME}" \
--external-id "${EXTERNAL_ID}" \
--duration-seconds 3600 \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
--output text)
export AWS_ACCESS_KEY_ID=$(echo "${CREDS}" | awk '{print $1}')
export AWS_SECRET_ACCESS_KEY=$(echo "${CREDS}" | awk '{print $2}')
export AWS_SESSION_TOKEN=$(echo "${CREDS}" | awk '{print $3}')
export AWS_DEFAULT_REGION="${BH_CATALOG_REGION}"
aws sts get-caller-identity
# Expected: Arn contains assumed-role/bh-artifact-reader-<customer-id>/...
There is no separate username or password for the reader role. Exporting AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN from sts:AssumeRole is how you operate as that role for the session duration.
2.2 Login to BigHammer ECR (pull)
BH_ECR="<bh-aws-account-id>.dkr.ecr.<bh-catalog-aws-region>.amazonaws.com"
aws ecr get-login-password --region "${BH_CATALOG_REGION}" | \
docker login --username AWS --password-stdin "${BH_ECR}"
aws ecr get-login-password --region "${BH_CATALOG_REGION}" | \
helm registry login --username AWS --password-stdin "${BH_ECR}"
2.3 Pull entitled artifacts
Pin versions from your release manifest. Examples only — use your entitled paths and tags.
BH_HELM_PARENT="aws/bh-helm-release" # confirm in handoff
CHART_NAME="<chart-name>" # e.g. bighammer | bhrabbitmq
CHART_VERSION="<chart-version>"
IMAGE_REPO="<bh-catalog-docker-repo>/<service>" # or flat repo:client-docker-repo
IMAGE_TAG="<tag-from-release-manifest>"
# Helm OCI chart
helm pull "oci://${BH_ECR}/${BH_HELM_PARENT}/${CHART_NAME}" --version "${CHART_VERSION}"
# Container image
docker pull "${BH_ECR}/${IMAGE_REPO}:${IMAGE_TAG}"
Repeat for every entitled chart and image in the release manifest.
2.4 Switch back to your AWS credentials (push)
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
# On EC2 with an instance profile, the CLI falls back to your account role.
export AWS_DEFAULT_REGION="<your-aws-region>"
aws sts get-caller-identity
# Expected: identity in YOUR AWS account (not the BH reader role)
2.5 Login to your ECR and push mirrors
MY_ACCOUNT_ID="<your-aws-account-id>"
MY_REGION="<your-aws-region>"
MY_ECR="${MY_ACCOUNT_ID}.dkr.ecr.${MY_REGION}.amazonaws.com"
aws ecr get-login-password --region "${MY_REGION}" | \
docker login --username AWS --password-stdin "${MY_ECR}"
aws ecr get-login-password --region "${MY_REGION}" | \
helm registry login --username AWS --password-stdin "${MY_ECR}"
# Image: retag and push
MY_IMAGE_REPO="<your-image-repo-path>" # e.g. bh-docker-public/<service>
docker tag "${BH_ECR}/${IMAGE_REPO}:${IMAGE_TAG}" \
"${MY_ECR}/${MY_IMAGE_REPO}:${IMAGE_TAG}"
docker push "${MY_ECR}/${MY_IMAGE_REPO}:${IMAGE_TAG}"
# Chart: push the pulled .tgz
helm push "${CHART_NAME}-${CHART_VERSION}.tgz" "oci://${MY_ECR}/bh-helm-release"
Create destination repositories before the first push if they do not exist:
aws ecr describe-repositories --repository-names "${MY_IMAGE_REPO}" --region "${MY_REGION}" \
|| aws ecr create-repository --repository-name "${MY_IMAGE_REPO}" --region "${MY_REGION}"
aws ecr describe-repositories --repository-names "bh-helm-release/${CHART_NAME}" --region "${MY_REGION}" \
|| aws ecr create-repository --repository-name "bh-helm-release/${CHART_NAME}" --region "${MY_REGION}"
2.6 End-to-end mirror script (template)
Save as mirror-bh-artifacts.sh on the bastion. Supply versions from the release manifest; do not hard-code ExternalId in git — load it from Secrets Manager or the environment.
#!/usr/bin/env bash
# Mirror entitled BigHammer artifacts to your ECR (no CI runner required).
# Prerequisites: aws cli v2, docker, helm 3.10+, IAM as documented above.
set -euo pipefail
# --- Handoff / environment (placeholders) ---
BH_READER_ROLE_ARN="${BH_READER_ROLE_ARN:-arn:aws:iam::<bh-aws-account-id>:role/bh-artifact-reader-<customer-id>}"
EXTERNAL_ID="${EXTERNAL_ID:-}" # required — inject at runtime
BH_ACCOUNT_ID="${BH_ACCOUNT_ID:-<bh-aws-account-id>}"
BH_CATALOG_REGION="${BH_CATALOG_REGION:-<bh-catalog-aws-region>}"
BH_HELM_PARENT="${BH_HELM_PARENT:-aws/bh-helm-release}"
MY_ACCOUNT_ID="${MY_ACCOUNT_ID:-<your-aws-account-id>}"
MY_REGION="${MY_REGION:-<your-aws-region>}"
CHART_NAME="${1:-}" # e.g. bhrabbitmq
CHART_VERSION="${2:-}" # e.g. 16.0.18
IMAGE_SRC="${3:-}" # e.g. bh-docker-public/bh-rabbitmq OR client-docker-repo
IMAGE_TAG="${4:-}" # e.g. 4.3.6-2-rc
IMAGE_DST="${5:-${IMAGE_SRC}}"
if [[ -z "${EXTERNAL_ID}" || -z "${CHART_NAME}" || -z "${CHART_VERSION}" || -z "${IMAGE_SRC}" || -z "${IMAGE_TAG}" ]]; then
echo "Usage: EXTERNAL_ID=... $0 <chart-name> <chart-version> <bh-image-repo> <image-tag> [dest-image-repo]"
exit 1
fi
BH_ECR="${BH_ACCOUNT_ID}.dkr.ecr.${BH_CATALOG_REGION}.amazonaws.com"
MY_ECR="${MY_ACCOUNT_ID}.dkr.ecr.${MY_REGION}.amazonaws.com"
assume_bh_role() {
local creds
creds=$(aws sts assume-role \
--role-arn "${BH_READER_ROLE_ARN}" \
--role-session-name "mirror-${CHART_NAME}" \
--external-id "${EXTERNAL_ID}" \
--duration-seconds 3600 \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
--output text)
export AWS_ACCESS_KEY_ID=$(echo "${creds}" | awk '{print $1}')
export AWS_SECRET_ACCESS_KEY=$(echo "${creds}" | awk '{print $2}')
export AWS_SESSION_TOKEN=$(echo "${creds}" | awk '{print $3}')
export AWS_DEFAULT_REGION="${BH_CATALOG_REGION}"
}
clear_assumed_creds() {
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
export AWS_DEFAULT_REGION="${MY_REGION}"
}
echo "==> Assuming BigHammer reader role"
assume_bh_role
aws sts get-caller-identity
echo "==> Login + pull from BigHammer ECR"
aws ecr get-login-password --region "${BH_CATALOG_REGION}" | \
docker login --username AWS --password-stdin "${BH_ECR}"
aws ecr get-login-password --region "${BH_CATALOG_REGION}" | \
helm registry login --username AWS --password-stdin "${BH_ECR}"
helm pull "oci://${BH_ECR}/${BH_HELM_PARENT}/${CHART_NAME}" --version "${CHART_VERSION}"
docker pull "${BH_ECR}/${IMAGE_SRC}:${IMAGE_TAG}"
echo "==> Restoring your account credentials"
clear_assumed_creds
aws sts get-caller-identity
echo "==> Login + push to your ECR"
aws ecr get-login-password --region "${MY_REGION}" | \
docker login --username AWS --password-stdin "${MY_ECR}"
aws ecr get-login-password --region "${MY_REGION}" | \
helm registry login --username AWS --password-stdin "${MY_ECR}"
docker tag "${BH_ECR}/${IMAGE_SRC}:${IMAGE_TAG}" \
"${MY_ECR}/${IMAGE_DST}:${IMAGE_TAG}"
docker push "${MY_ECR}/${IMAGE_DST}:${IMAGE_TAG}"
helm push "${CHART_NAME}-${CHART_VERSION}.tgz" "oci://${MY_ECR}/bh-helm-release"
echo "==> Mirror complete"
echo " Chart: oci://${MY_ECR}/bh-helm-release/${CHART_NAME}:${CHART_VERSION}"
echo " Image: ${MY_ECR}/${IMAGE_DST}:${IMAGE_TAG}"
Example invocation (placeholders only):
export EXTERNAL_ID="<external-id-from-bighammer>"
export BH_READER_ROLE_ARN="arn:aws:iam::<bh-aws-account-id>:role/bh-artifact-reader-<customer-id>"
export BH_ACCOUNT_ID="<bh-aws-account-id>"
export BH_CATALOG_REGION="<bh-catalog-aws-region>"
export MY_ACCOUNT_ID="<your-aws-account-id>"
export MY_REGION="<your-aws-region>"
./mirror-bh-artifacts.sh \
bhrabbitmq "<chart-version>" \
"bh-docker-public/bh-rabbitmq" "<image-tag>"
Run once per release when BigHammer publishes a new manifest. After mirroring, day-2 installs use only your ECR (no BigHammer role required).
Entitled Helm chart paths (AWS)
After mirror, install from your ECR, not BigHammer ECR:
| Chart | BigHammer source (mirror from) | Your ECR OCI path |
|---|---|---|
| Platform | oci://<bh-aws-account-id>.dkr.ecr.<bh-catalog-aws-region>.amazonaws.com/aws/bh-helm-release/bighammer | oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/bighammer |
| RabbitMQ | .../aws/bh-helm-release/bhrabbitmq | oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/bhrabbitmq |
| Gateway (optional) | .../aws/bh-helm-release/bh-gateway | oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/bh-gateway |
Confirm the exact BH parent path (aws/bh-helm-release or another catalog path) in your handoff pack. Pin versions from the release manifest BigHammer sends per upgrade.
Initial AWS catalog chart: bighammer 1.0.12 — release notes. RabbitMQ chart notes: RabbitMQ Broker.
Release manifest
BigHammer sends a release manifest per upgrade. Pin every version in your mirror process — do not use floating tags.
# release-manifest.yaml (your repo)
release: "2026-06"
channel: stable
charts:
bighammer: "1.0.12" # initial AWS catalog — see helm-releases/v1.0.12
bhrabbitmq: "16.0.18" # see rabbitmq-broker release notes
bh-gateway: "<chart-version>"
images:
bh-ui: "<tag-from-release-manifest>"
bh-catalog-api: "<tag-from-release-manifest>"
bh-audit-api: "<tag-from-release-manifest>"
bh-keycloak: "<tag-from-release-manifest>"
bh-ai-agent: "<tag-from-release-manifest>"
Update global.image.repository and per-service image.tag in values-<env>.yaml to match mirrored tags.
Mirror container images (reference)
Source (BH):
<bh-aws-account-id>.dkr.ecr.<bh-catalog-aws-region>.amazonaws.com/<bh-catalog-docker-repo>/<service>:<tag>
Target (your ECR):
<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-docker-public/<service>:<tag>
For flat repositories (tag follows the repo name directly), the source path has no service segment — for example <bh-catalog-docker-repo>:<tag>. Use the layout documented in your handoff pack.
Mirror Helm charts (reference)
Source (BH):
oci://<bh-aws-account-id>.dkr.ecr.<bh-catalog-aws-region>.amazonaws.com/aws/bh-helm-release/<chart>:<version>
Target (your ECR):
oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/<chart>:<version>
Mirror code packages (PyPI / npm)
If your contract includes CodeArtifact entitlements, mirror entitled packages the same way as images and charts (assume reader role → download → publish to your private feed with your account credentials).
| Type | BigHammer source (pull only) |
|---|---|
| PyPI | https://bighammer-<bh-aws-account-id>.d.codeartifact.<bh-catalog-aws-region>.amazonaws.com/pypi/<bh-catalog-pypi-repo>/simple/ |
| npm | https://bighammer-<bh-aws-account-id>.d.codeartifact.<bh-catalog-aws-region>.amazonaws.com/npm/<bh-catalog-npm-repo>/ |
Domain: <bh-codeartifact-domain> · Account: <bh-aws-account-id> · Region: <bh-catalog-aws-region>
Only package names in your entitlement list can be downloaded with the reader role.
Deploy from mirrored ECR
After Approach 1 or Approach 2 succeeds, install from your registry only:
aws ecr get-login-password --region <your-aws-region> | \
helm registry login --username AWS --password-stdin \
<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com
helm pull oci://<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-helm-release/bighammer \
--version <CHART_VERSION>
tar -xzf bighammer-<CHART_VERSION>.tgz
cp bighammer/values.yaml values.yaml
cp bighammer/values-release.yaml values-<env>.yaml # edit all placeholders
helm upgrade --install bighammer ./bighammer \
-f values.yaml \
-f values-<env>.yaml \
-n bh-control-plane \
--create-namespace
Set global.image.repository to your mirrored ECR prefix, for example:
<your-aws-account-id>.dkr.ecr.<your-aws-region>.amazonaws.com/bh-docker-public/
Full deploy steps: Platform Deployment.
Testing access (onboarding validation)
Once the customer profile is registered and the reader role is granted:
- Assume the BH reader role with ExternalId →
aws sts get-caller-identity. - Pull one entitled image and one Helm chart from BigHammer ECR.
- Push both to your ECR; deploy a smoke-test release from mirrored artifacts only.
- Confirm day-2 install does not require the BigHammer role.
Document results in your runbook before production cutover.
Related
| Topic | Link |
|---|---|
| Platform deploy | Platform Deployment |
| Prerequisites | Prerequisites |
| RabbitMQ broker (including custom image mirror) | RabbitMQ Broker |
| Secrets Manager (initial list) | Secrets Manager Secrets |
Helm release notes (bighammer) | v1.0.12 Release |
| Azure mirror (same BH reader role pattern) | Azure Release Manifest |
| GCP mirror (same BH reader role pattern) | GCP Release Manifest |