Skip to content

Registry authentication #6

Closed
Closed

Description

@crazy-max
No description provided.

Activity

  1. crazy-max commented on Aug 21, 2025

    @crazy-max
    MemberAuthor

    GHCR

    Login to the registry by using the ephemeral builtin GITHUB_TOKEN passed to the reusable workflow through the login-password secret input. Seems the only way to authenticate from their docs.

    Need to test if this is possible to directly consume ${{ github.token }} in the reusable workflow without passing it from downstream but that would defeat the purpose of the reusable workflow for other registries.

    Docker Hub

    For personal accounts, upstream repo need to pass secrets.

    OIDC can be used only for organization atm. It's currently C0 and can be tested with an internal action.

    AWS or Google Cloud

    OIDC can be used so no need to have secrets: https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

    Although it’s recommended to have the AWS_ACCOUNT_ID as secret!

    Example with AWS:

    permissions:
      id-token: write
      contents: read
    
    env:
      AWS_REGION: us-east-1
      AWS_ACCOUNT_ID: foo
      AWS_ROLE_NAME: bar
    
    jobs:
      build-ecr:
        runs-on: ubuntu-latest
        steps:
          - name: Configure AWS Credentials (OIDC)
            uses: aws-actions/configure-aws-credentials@v4
            with:
              role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/${{ env.AWS_ROLE_NAME }}
              aws-region: ${{ env.AWS_REGION }}
    
          - name: Login to Amazon ECR
            uses: aws-actions/amazon-ecr-login@v2
          # or our login-action
          - name: Login to Amazon ECR
            uses: docker/login-action@v3
            with:
              registry: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com
          
    
          - name: Build and push image to ECR
            uses: docker/build-push-action@v5
              with:
                push: true
                tags: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/my-image:latest

    No auth

    We could avoid any authentication in the reusable workflow and pass the build artifact to the upstream repo through Actions Artifacts: https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/storing-and-sharing-data-from-a-workflow

    In the reusable workflow we would:

    • Push the image to a local registry so cosign can sign the attestations.
    • Consolidate both the image manifest and signature manifest in an archived OCI layout.
    • Push as Action Artifact

    Then on upstream repo people would need to:

    • Download the artifact
    • Use buildx imagetools to push the manifest from OCI tarball.
  2. crazy-max commented on Aug 21, 2025

    @crazy-max
    MemberAuthor

    Push the image to a local registry so cosign can sign the attestations.

    We need to check if oci-layout is supported by cosign.

    Push as Action Artifact

    No known size limitation from their documentation but people talk about 5GB size limit due to a bug when chunking: actions/upload-artifact#9

    Download the artifact

    This is one of the trade off of "No auth". Uploading and downloading back the artifact can be slow depending on its size.

  3. crazy-max commented on Aug 21, 2025

    @crazy-max
    MemberAuthor

    Had a deeper look at OIDC. When I tried to pass the OIDC token as output in the reusable workflow: https://github.com/docker/github-builder-test/actions/runs/17119508786/workflow#L38-L71

      docker-oidc:
        runs-on: ubuntu-latest
        permissions:
          contents: read
          id-token: write
        outputs:
          token: ${{ steps.docker_oidc.outputs.token }}
        steps:
          -
            uses: docker/configure-credentials-action-internal@main
            id: docker_oidc
            with:
              connection_id: cdeb5882-30b7-4076-be92-bfdceb258e9c # https://app-stage.docker.com/accounts/docker/admin/oidc-connections/cdeb5882-30b7-4076-be92-bfdceb258e9c
              env: stage
    
      build-dockerhub:
        uses: docker/github-builder-experimental/.github/workflows/build.yml@build-reusable-workflow
        needs:
          - docker-oidc
        permissions:
          contents: read
          packages: write
          id-token: write
        with:
          push: ${{ github.event_name != 'pull_request' }}
          meta-image: registry-1-stage.docker.io/docker/github-builder-test
          meta-tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=sha
          login-registry: registry-1-stage.docker.io
          login-username: docker
        secrets:
          login-password: ${{ needs.docker-oidc.outputs.token }}

    It doesn't set it because it is not possible to pass a secret or masked variable between jobs in GitHub Actions using outputs.

    Also tried passing docker config as secret in 869656d so we can also support authentication with multiple registries but same, the output is not set.

    For example with GHCR when logging in and outputting the Docker config: https://github.com/docker/github-builder-test/actions/runs/17120615481/job/48560373886#step:2:9

    image

    The runner skips setting the output as it may contain secret: https://github.com/docker/github-builder-test/actions/runs/17120615481

    image

    So it seems necessary to use login-action within the reusable workflow.

    This is more problematic for OIDC that needs specific actions to retrieve the OIDC token. We would need to add steps in our reusable workflows for each providers like AWS with aws-actions/configure-aws-credentials action or Docker Hub with docker/oidc-action. Same with Google, etc...

    Although with Docker Hub we we could make changes in our login-action to support OIDC directly so we don't need docker/oidc-action and we could just do:

          -
            name: Login to Docker Hub
            uses: docker/login-action@v3
            with:
              username: <username>:<connection-id>

    But that would just work for us and not other providers.

  4. tonistiigi commented on Aug 21, 2025

    @tonistiigi
    Member

    For OIDC, the token should not be resolved in user's repo scope but by the reusable workflow itself. Permissions should be limited so reusable workflow repo needs to be the builder URL and app repo the source URL.

    The runner skips setting the output as it may contain secret:

    For passing docker config for non-oidc case (we discussed potentially just passing config instead of separate login-* options) I guess we need to encode it (eg base64) so it is not detected. I don't get it though because we are passing it as a list of secrets: , so why is it complaining the value can't contain a potentially secret value? I would get it if we would pass it as regular input to the workflow.

  5. crazy-max commented on Aug 21, 2025

    @crazy-max
    MemberAuthor

    I guess we need to encode it (eg base64) so it is not detected.

    That would work and output would be set but anyone with access to the logs can copy the base64 encoded secret and base64 decode it. The only secure way to transfer secrets between jobs is with a "secret store" as described in the GitHub docs: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#example-masking-and-passing-a-secret-between-jobs-or-workflows.

    I don't get it though because we are passing it as a list of secrets: , so why is it complaining the value can't contain a potentially secret value?

    I think this just limited for a secret created by a job but for one created in repo settings it looks good.

  6. tonistiigi commented on Aug 21, 2025

    @tonistiigi
    Member

    logs can copy the base64 encoded secret

    I don't get what the point of the secrets option is if the values you pass there get logged out.

    If the outputs get logged, then the output can be a path to the file containing the actual value.

  7. crazy-max commented on Aug 21, 2025

    @crazy-max
    MemberAuthor

    Not related but for the attestation manifest: https://explore.ggcr.dev/?image=registry-1-stage.docker.io/docker/github-builder-test@sha256:6318026a1837b0c591a4c21ebb889ea73ece1c1932cd4b1605d204fe2d9b4966&mt=application%2Fvnd.oci.image.manifest.v1%2Bjson&size=914

    Signing using referrers seems to work on Docker Hub stage:

    See https://explore.ggcr.dev/?image=registry-1-stage.docker.io%2Fdocker%2Fgithub-builder-test%40sha256%3A389c6bbc319fe80b5de92b48632b04f61b6cec585c9cc8cb2f7665225212ec78

    Referrers for the attestation manifest: https://oci.dag.dev/?referrers=registry-1-stage.docker.io/docker/github-builder-test@sha256:6318026a1837b0c591a4c21ebb889ea73ece1c1932cd4b1605d204fe2d9b4966

    Verification step fails though: https://github.com/docker/github-builder-test/actions/runs/17123004125/job/48568088146#step:10:132

    Referrers result looks empty: https://github.com/docker/github-builder-test/actions/runs/17123004125/job/48568088146#step:10:118

      2025/08/21 09:33:57 <-- 200 https://registry-1-stage.docker.io/v2/docker/github-builder-test/referrers/sha256:6318026a1837b0c591a4c21ebb889ea73ece1c1932cd4b1605d204fe2d9b4966 (87.807718ms)
      2025/08/21 09:33:57 HTTP/2.0 200 OK
      Content-Length: 89
      Content-Type: application/vnd.oci.image.index.v1+json
      Date: Thu, 21 Aug 2025 09:33:57 GMT
      Docker-Distribution-Api-Version: registry/2.0
      Strict-Transport-Security: max-age=31536000
      
      {"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[]}
    

    After waiting ~5 minutes, I can see the signatures in https://oci.dag.dev/?referrers=registry-1-stage.docker.io/docker/github-builder-test@sha256:6318026a1837b0c591a4c21ebb889ea73ece1c1932cd4b1605d204fe2d9b4966

    There might be some cache going on on Docker Hub compared to GHCR?

  8. crazy-max commented on Sep 8, 2025

    @crazy-max
    MemberAuthor

    follow-up #8 (comment)

    I will check if we can instead pass as secret a list of credentials like:

      build-dockerhub:
        uses: docker/github-builder-experimental/.github/workflows/build.yml@build-reusable-workflow
        needs:
          - docker-oidc
        permissions:
          contents: read
          packages: write
          id-token: write
        with:
          push: ${{ github.event_name != 'pull_request' }}
          meta-image: |
            registry-1-stage.docker.io/docker/github-builder-test
            ghcr.io/docker/github-builder-test
          meta-tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=sha
        secrets:
          login-config: |
            - registry: registry-1-stage.docker.io
              username: docker:cdeb5882-30b7-4076-be92-bfdceb258e9c
            - registry: ghcr.io
              username: ${{ github.actor }}
              password: ${{ secrets.GITHUB_TOKEN }}

    Made some changes in our login-action: https://github.com/docker/login-action/compare/multi-login?expand=1

    Run: https://github.com/docker/login-action/actions/runs/17550563584/job/49841820472#step:3:18

    Image

    Not yet sure about add as input name. Maybe logins would be better?

  9. crazy-max commented on Sep 8, 2025

    @crazy-max
    MemberAuthor

    Not yet sure about add as input name. Maybe logins would be better?

    Renamed it logins: https://github.com/docker/login-action/compare/multi-login?expand=1

    And tested within our reusable workflow: d3ccc93

    So we now have a single registry-auths secret that accepts YAML objects to authenticate to registries.

    Tested in https://github.com/docker/github-builder-test/commit/3997b04c6da55d4f6ff193ca5152de798bf8b240

    See this run: https://github.com/docker/github-builder-test/actions/runs/17554592398

  10. crazy-max commented on Oct 1, 2025

    @crazy-max
    MemberAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions