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