Repository navigation
ci: read the Docker Hub credential from Secrets Manager via OIDC - #744
Conversation
The release-image, release-dev-image, promote-image, sign-image and dockerhub-description workflows now fetch the Docker Hub username and token from AWS Secrets Manager (extenddb/dockerhub-publish) through the ExtendDBDockerHubPublisher OIDC role, instead of the DOCKERHUB_USERNAME and DOCKERHUB_TOKEN GitHub Actions secrets. The role is gated to the dockerhub environment and can read only that one secret. promote-image and dockerhub-description gain id-token: write on the job that needs it.
robinnsc
left a comment
There was a problem hiding this comment.
Looks good to me. All five Docker Hub logins go through the new role, and no secrets.DOCKERHUB_* reference is left. Every job that assumes the role runs in the dockerhub environment, and with the repo's default OIDC subject that is the same repo:ExtendDB/extenddb:environment:dockerhub condition ExtendDBContainerSigningCI already relies on. In each job the signing or ECR role is assumed after the Docker Hub one. configure-aws-credentials v6.2.3 decides on OIDC from its own inputs rather than from credentials already in the environment, so the second role assumption is unaffected, and nothing after the Docker Hub role in these jobs needs other AWS credentials (promote-registry verifies against the public key file). The get-secrets pin is the v3.0.2 tag commit. It also merges cleanly with #725, so the Cassandra image picks up the same login path.
The one thing I'd check on the account side is the secret's JSON key names. With the DOCKERHUB alias and parse-json-secrets, the keys have to be username and token (any case) to come out as DOCKERHUB_USERNAME and DOCKERHUB_TOKEN; a key named password, for example, would leave the login with an empty value. Since the publish paths can't run before merge, it might be worth dispatching dockerhub-description for one image right after merge, rather than waiting for the first release. That exercises the role, the secret, the login and the Docker Hub API without spending a release approval. Once that run passes, the DOCKERHUB_TOKEN and DOCKERHUB_USERNAME secrets still in the dockerhub environment could be deleted and the token rotated then, rather than after a release.
| uses: aws-actions/aws-secretsmanager-get-secrets@2297f9a879480a9e3af9b293ed15c70caf8e1c88 # v3.0.2 | ||
| with: | ||
| secret-ids: DOCKERHUB,extenddb/dockerhub-publish | ||
| parse-json-secrets: true |
There was a problem hiding this comment.
A small one: the action exports the values to GITHUB_ENV, so DOCKERHUB_TOKEN is now in the environment of every later step in the job, not just the login. Before this, promote-image, sign-image and dockerhub-description passed the token only to their login step, and here promote-registry, skopeo and (in sign-image) the signing-role step and cosign can now read it. The values are masked in logs and the action clears them in its post step, so this isn't a blocker. If you wanted to keep it step-scoped, one option would be to read the secret inside the login step itself, e.g. aws secretsmanager get-secret-value --secret-id extenddb/dockerhub-publish --query SecretString --output text piped through jq into --password-stdin, with an ::add-mask:: for the username. The same applies to the other four workflows.
Main gained #335, #744, #751 and #752. #335 drops the continuous_backups table on every backend and moves the 0.1.x catalog to 0.0.5. On SQLite and PostgreSQL the drop is now migration 5, drop_continuous_backups, with a file body on each backend. Main's 004_drop_continuous_backups.sql, its CATALOG_VERSION constants, catalog_converge.rs and the SQLite bootstrapper test it changed stay removed, as this branch removed them. With migration 5 in the registry, docs/schema loses the table, the released SQLite catalog test expects the table gone after the upgrade and after a reconverge, the CLI migration test checks the same after init, an upgrade from 0.1.10 and a reconverge, the reconverge check in devtools/check-postgres-catalog-lock expects migration 5 to run again, the docs that name the current migration say 5, and the CONTRIBUTING example becomes migration 6. integration.yml takes #752's pinned checkout with this branch's fetch-depth: 0. The upgrade manual keeps this branch's ledger sections, gains main's catalog 0.0.5 entry and its v0.1.15 behavior change, each with a note that migration 5 makes the change from v1.0, and names Cassandra's catalog as 0.0.5. ADR-0023 counts five breaking migrations and says which catalog its v0.1.14 quote was measured on. The architecture guide and the SQLite design notes describe the ledger instead of a compiled version.
What
The five workflows that log in to Docker Hub (release-image, release-dev-image, promote-image, sign-image, dockerhub-description) now read the Docker Hub username and token at run time from AWS Secrets Manager, fetched through a GitHub OIDC role, instead of from the
DOCKERHUB_USERNAMEandDOCKERHUB_TOKENGitHub Actions secrets.Each Docker Hub login is now preceded by two steps: assume a dedicated OIDC role with
aws-actions/configure-aws-credentials(pinned to a commit SHA), then read the publishing secret withaws-actions/aws-secretsmanager-get-secrets(pinned,parse-json-secrets: true), which exportsDOCKERHUB_USERNAMEandDOCKERHUB_TOKENfor the login step that follows.The role's trust is limited to the
dockerhubGitHub environment, the same gate the existing signing role uses, and its only permission is reading that one secret.promote-imageanddockerhub-descriptiongainid-token: writeon the job that needs it; the three signing workflows already had it.Why
The Docker Hub token is a read and write credential for the primary distribution registry, and GHCR and ECR Public are mirrored from it. As a GitHub Actions secret it is a standing credential that lives outside the release pipeline's own controls. Reading it from Secrets Manager through a short-lived OIDC role takes the standing secret out of GitHub and scopes access to one environment and one secret.
No change to publishing behaviour
The login steps authenticate with the same username and token values, now sourced from Secrets Manager. Image namespaces, tags, signing, and promotion logic are unchanged.
Prerequisite (already in place)
The Secrets Manager secret and the OIDC role already exist in the release account.
Follow-up, out of band after this merges and a release verifies
DOCKERHUB_USERNAMEandDOCKERHUB_TOKENGitHub Actions secrets.Testing
yaml.safe_loadparses all five workflows, and nosecrets.DOCKERHUB_*reference remains. The publish paths cannot run without the reviewer-gateddockerhubenvironment, so the first release dispatch after merge is the functional check.