Sign inSign up

docker/sbx-kit-git-ssh-sign:1.0.0

Multi-platform
Manifest digest

sha256:79c6aaca0f08003913a68539c2105a0c4d7109b740aa2cbcadfa103b80336445

Last pushed

9 days by cdupuis

Type

Sandbox Kit

Manifest digest

sha256:79c6aaca0f08003913a68539c2105a0c4d7109b740aa2cbcadfa103b80336445

yaml
schemaVersion: "3"
displayName: Git SSH Commit Signing
description: Configures git to sign commits using the SSH key forwarded from the host's SSH agent.
version: 1.0.0
kind: mixin
requires:
    - deb/openssh-client
capabilities:
    - type: com.docker.sandbox/network-policy@1
      config:
        runtime:
            allow:
                - api.github.com
    - type: com.docker.sandbox/lifecycle@1
      config:
        install:
            - command: |
                set -e

                # Signing *machinery* stays machine-wide: it is inert unless something
                # asks for a signature, and keeping it here means `git commit -S` works
                # in any repository in the sandbox.
                git config --system gpg.format ssh
                # The key command is invoked through /bin/sh rather than executed
                # directly. Files shipped under a kit's files/home/ tree land mode
                # 0644 when the kit is installed from its OCI artifact -- per-file
                # executable bits are not representable in a v2 layer (spec/OCI-v2.md)
                # -- and git execs this value itself, so a bare path would die with
                # "cannot exec: Permission denied" before a single one of the script's
                # own diagnostics could run.
                git config --system gpg.ssh.defaultKeyCommand '/bin/sh /home/agent/.config/git/ssh-signing-key-command'
                git config --system gpg.ssh.allowedSignersFile /home/agent/.config/git/allowed_signers

                # user.signingKey MUST stay unset: git only runs
                # gpg.ssh.defaultKeyCommand when it is empty. Setting it to any value
                # (even a placeholder) disables dynamic key resolution entirely.
                git config --system --unset-all user.signingKey || true

                # Signing *policy* is scoped, not machine-wide. Setting
                # commit.gpgSign=true in /etc/gitconfig makes every `git commit` in the
                # sandbox depend on a live SSH agent — including throwaway repositories
                # created by test suites that have nothing to do with the user's work.
                # When the forwarded agent goes away, those all fail too.
                mkdir -p /etc/git
                cat > /etc/git/signing-enabled.inc <<'INC'
                # Included by /etc/gitconfig for repositories with a remote.
                # See the git-ssh-sign kit.
                [commit]
                	gpgSign = true
                [tag]
                	gpgSign = true
                INC
                chmod 0644 /etc/git/signing-enabled.inc

                # Clear anything an older version of this kit left machine-wide, so a
                # re-install converges rather than layering.
                git config --system --unset-all commit.gpgSign || true
                git config --system --unset-all tag.gpgSign || true
                git config --system --unset-all 'includeIf.hasconfig:remote.*.url:**.path' || true

                # `includeIf "hasconfig:remote.*.url:**"` needs git >= 2.36. Probe for
                # it rather than parsing a version string: build a throwaway repo with
                # a remote and see whether the include actually fires. Note that `**`
                # is only a cross-slash wildcard when it is a whole path component --
                # `[email protected]:**` does NOT match `[email protected]:org/repo.git`, so
                # a bare `**` ("has any remote at all") is the pattern to use here.
                probe=$(mktemp -d)
                git init -q "$probe"
                git -C "$probe" remote add origin https://example.invalid/probe.git
                printf '[commit]\n\tgpgSign = true\n' > "$probe/inc"
                printf '[includeIf "hasconfig:remote.*.url:**"]\n\tpath = %s/inc\n' "$probe" > "$probe/sys"
                supported=$(GIT_CONFIG_SYSTEM="$probe/sys" GIT_CONFIG_GLOBAL=/dev/null \
                    git -C "$probe" config --get commit.gpgSign 2>/dev/null || true)
                rm -rf "$probe"

                if [ "$supported" = "true" ]; then
                    git config --system 'includeIf.hasconfig:remote.*.url:**.path' /etc/git/signing-enabled.inc
                else
                    # Old git: an unrecognised includeIf keyword evaluates false, which
                    # would silently disable signing. Fail closed (sign everywhere)
                    # rather than fail open (sign nothing).
                    echo "[git-ssh-sign] git $(git --version | awk '{print $3}') lacks includeIf hasconfig; enabling signing machine-wide" >&2
                    git config --system commit.gpgSign true
                    git config --system tag.gpgSign true
                fi

                if [ "$(git config --system --get core.hooksPath || true)" = "/home/agent/.config/git/hooks" ]; then
                    git config --system --unset-all core.hooksPath
                fi
              description: Configure SSH commit signing, scoped to repositories with a remote
              user: "0"
    - type: com.docker.sandbox/agent-context@1
      config:
        contentFile: /usr/share/sandbox/kit/git-ssh-sign/git-ssh-sign-context.md