...

Text file src/edge-infra.dev/hack/build/rules/container/sign/container_sign.bzl

Documentation: edge-infra.dev/hack/build/rules/container/sign

     1"""Defines a rule for signing the output of a container_push rule using a cosign_key
     2"""
     3
     4load("@aspect_bazel_lib//lib:utils.bzl", "propagate_common_rule_attributes")
     5load("//hack/build/rules/container:push_info.bzl", "OCIPushInfo")
     6load("//hack/build/rules/container/sign:cosign_key.bzl", "CosignKeyInfo")
     7
     8CosignSignInfo = provider(
     9    doc = """Contains the cosign push information and executable for signing
    10a container in the artifact registry
    11""",
    12    fields = {
    13        "repo": "File containing fully qualified OCI repo that was signed",
    14    },
    15)
    16
    17def _container_sign_impl(ctx):
    18    signer = ctx.actions.declare_file("{0}.sh".format(ctx.label.name))
    19    cosign = ctx.toolchains["@rules_oci//cosign:toolchain_type"]
    20    crane = ctx.attr._crane_target.files.to_list()[0]
    21    crane_path = ctx.attr._crane_target.files.to_list()[0].short_path
    22
    23    full_repo_ref_file = ctx.attr.container_push[OCIPushInfo].ref
    24    cosign_key = ctx.attr.cosign_key[CosignKeyInfo].key_file
    25
    26    runfiles = ctx.runfiles(files = [full_repo_ref_file, cosign_key, crane])
    27    runfiles = runfiles.merge(cosign.default.default_runfiles)
    28
    29    substitutions = {
    30        "{{cosign_key}}": cosign_key.short_path,
    31        "{{cosign_path}}": cosign.cosign_info.binary.short_path,
    32        "{{crane_path}}": crane_path,
    33        "{{full_repo_ref_file}}": full_repo_ref_file.short_path,
    34        "{{skip_confirmation}}": "-y" if ctx.attr.skip_confirmation else "",
    35    }
    36
    37    ctx.actions.expand_template(
    38        template = ctx.file._sign_sh_tpl,
    39        output = signer,
    40        is_executable = True,
    41        substitutions = substitutions,
    42    )
    43
    44    return [
    45        DefaultInfo(
    46            executable = signer,
    47            runfiles = runfiles,
    48        ),
    49        CosignSignInfo(
    50            repo = full_repo_ref_file,
    51        ),
    52    ]
    53
    54_container_sign = rule(
    55    doc = """
    56        A rule for signing container_push targets using a GCP KMS signing key
    57    """,
    58    implementation = _container_sign_impl,
    59    attrs = {
    60        "container_push": attr.label(
    61            doc = "A container_push target Label",
    62            mandatory = True,
    63        ),
    64        "cosign_key": attr.label(
    65            doc = """A cosign_key label flag that can be overwritten at runtime
    66
    67To override a container_sign run/build at run/build time, pass a --key=value pair with
    68the key such as --//hack/build/rules/container/sign:gcp_kms_key and a value as a path to
    69a gcp_kms_key.
    70
    71Ex.: bazel build //hack/tools/build/apko-updater-bot:container_sign \
    72  --//hack/build/rules/container/sign:gcp_kms_key=//hack/build/rules/container/sign:sign-staging
    73
    74This will override the default "sign-dev" key with the "sign-staging" key. To use other keys,
    75add entries into the hack/build/rules/container/sign/BUILD.bazel file
    76""",
    77            default = "//hack/build/rules/container/sign:gcp_kms_key",
    78            allow_single_file = True,
    79        ),
    80        "skip_confirmation": attr.bool(
    81            doc = "Bool value to skip non-destructive actions for cosign sign - equates to `-y` option for `cosign sign`",
    82            mandatory = True,
    83        ),
    84        "_crane_target": attr.label(
    85            default = "@com_github_google_go_containerregistry//cmd/crane",
    86            allow_single_file = True,
    87        ),
    88        "_sign_sh_tpl": attr.label(
    89            default = ":sign.sh.tpl",
    90            allow_single_file = True,
    91        ),
    92    },
    93    executable = True,
    94    toolchains = [
    95        "@rules_oci//cosign:toolchain_type",
    96    ],
    97)
    98
    99def container_sign(
   100        container_push,
   101        cosign_key = None,
   102        skip_confirmation = True,
   103        name = "container_sign",
   104        **kwargs):
   105    """Creates a standardized container signing mechanism using cosign
   106
   107    It creates a container signing rule that borrows much from the rules_oci
   108    cosign_sign rule, but implements a attribute for passing signing keys
   109
   110    Args:
   111        name:               the name to pass to the container_sign rule. default: `container_sign`
   112        container_push:     a container_push Bazel Label to sign
   113        cosign_key:         a Label to a target providing the CosignKeyInfo provider.
   114                            Ex: //hack/build/rules/container:f8n-cosign-key
   115        skip_confirmation:  a flag to use to skip the confirmation step of `cosign sign` to make the the
   116                            signing non-interactive. default: True
   117        **kwargs:           additional arguments
   118    """
   119
   120    forwarded_args = propagate_common_rule_attributes(kwargs)
   121
   122    _container_sign(
   123        name = name,
   124        container_push = container_push,
   125        cosign_key = cosign_key,
   126        skip_confirmation = skip_confirmation,
   127        **forwarded_args
   128    )

View as plain text