Skip to content

Commit e263d1d

Browse files
committed
Derive build_secret key_id instead of accepting user input
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent 1f5952d commit e263d1d

File tree

18 files changed

+50
-113
lines changed

18 files changed

+50
-113
lines changed

builder/build.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func getTemplate(lang string) (string, *stack.LanguageTemplate, error) {
6767

6868
// BuildImage construct Docker image from function parameters
6969
// TODO: refactor signature to a struct to simplify the length of the method header
70-
func BuildImage(image string, handler string, functionName string, language string, nocache bool, squash bool, shrinkwrap bool, buildArgMap map[string]string, buildOptions []string, tagFormat schema.BuildFormat, buildLabelMap map[string]string, quietBuild bool, copyExtraPaths []string, buildSecrets map[string]string, remoteBuilder, payloadSecretPath, builderPublicKeyPath, builderKeyID string, forcePull bool) error {
70+
func BuildImage(image string, handler string, functionName string, language string, nocache bool, squash bool, shrinkwrap bool, buildArgMap map[string]string, buildOptions []string, tagFormat schema.BuildFormat, buildLabelMap map[string]string, quietBuild bool, copyExtraPaths []string, buildSecrets map[string]string, remoteBuilder, payloadSecretPath, builderPublicKeyPath string, forcePull bool) error {
7171

7272
_, langTemplate, err := getTemplate(language)
7373
if err != nil {
@@ -138,7 +138,7 @@ func BuildImage(image string, handler string, functionName string, language stri
138138
Scheme: u.Scheme,
139139
Host: u.Host,
140140
}
141-
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, builderPublicKeyPath, builderKeyID, buildSecrets, quietBuild, functionName, imageName); err != nil {
141+
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, builderPublicKeyPath, buildSecrets, quietBuild, functionName, imageName); err != nil {
142142
return fmt.Errorf("failed to invoke builder: %w", err)
143143
}
144144

builder/publish.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
// PublishImage will publish images as multi-arch
2121
// TODO: refactor signature to a struct to simplify the length of the method header
2222
func PublishImage(image string, handler string, functionName string, language string, nocache bool, squash bool, shrinkwrap bool, buildArgMap map[string]string,
23-
buildOptions []string, tagMode schema.BuildFormat, buildLabelMap map[string]string, quietBuild bool, copyExtraPaths []string, buildSecrets map[string]string, platforms string, extraTags []string, remoteBuilder, payloadSecretPath, builderPublicKeyPath, builderKeyID string, forcePull bool) error {
23+
buildOptions []string, tagMode schema.BuildFormat, buildLabelMap map[string]string, quietBuild bool, copyExtraPaths []string, buildSecrets map[string]string, platforms string, extraTags []string, remoteBuilder, payloadSecretPath, builderPublicKeyPath string, forcePull bool) error {
2424

2525
if stack.IsValidTemplate(language) {
2626
pathToTemplateYAML := fmt.Sprintf("./template/%s/template.yml", language)
@@ -98,7 +98,7 @@ func PublishImage(image string, handler string, functionName string, language st
9898
Scheme: u.Scheme,
9999
Host: u.Host,
100100
}
101-
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, builderPublicKeyPath, builderKeyID, buildSecrets, quietBuild, functionName, imageName); err != nil {
101+
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, builderPublicKeyPath, buildSecrets, quietBuild, functionName, imageName); err != nil {
102102
return fmt.Errorf("failed to invoke builder: %w", err)
103103
}
104104

builder/remote_builder.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type remoteBuilderPublicKeyResponse struct {
2222
PublicKey string `json:"public_key"`
2323
}
2424

25-
func runRemoteBuild(builderURL *url.URL, tarPath, payloadSecretPath, builderPublicKeyPath, builderKeyID string, buildSecrets map[string]string, quietBuild bool, functionName, imageName string) error {
25+
func runRemoteBuild(builderURL *url.URL, tarPath, payloadSecretPath, builderPublicKeyPath string, buildSecrets map[string]string, quietBuild bool, functionName, imageName string) error {
2626
payloadSecret, err := os.ReadFile(payloadSecretPath)
2727
if err != nil {
2828
return fmt.Errorf("failed to read payload secret: %w", err)
@@ -34,11 +34,11 @@ func runRemoteBuild(builderURL *url.URL, tarPath, payloadSecretPath, builderPubl
3434
}
3535

3636
if len(buildSecrets) > 0 {
37-
publicKey, err := resolveRemoteBuilderPublicKey(builderURL, builderPublicKeyPath, builderKeyID)
37+
publicKey, err := resolveRemoteBuilderPublicKey(builderURL, builderPublicKeyPath)
3838
if err != nil {
3939
return err
4040
}
41-
opts = append(opts, sdkbuilder.WithBuildSecretsKey(publicKey.KeyID, []byte(publicKey.PublicKey)))
41+
opts = append(opts, sdkbuilder.WithBuildSecretsKey([]byte(publicKey.PublicKey)))
4242
}
4343

4444
b := sdkbuilder.NewFunctionBuilder(builderURL, http.DefaultClient, opts...)
@@ -57,7 +57,7 @@ func runRemoteBuild(builderURL *url.URL, tarPath, payloadSecretPath, builderPubl
5757
return consumeBuildStream(stream, quietBuild, functionName, imageName)
5858
}
5959

60-
func resolveRemoteBuilderPublicKey(builderURL *url.URL, builderPublicKeyPath, builderKeyID string) (*remoteBuilderPublicKeyResponse, error) {
60+
func resolveRemoteBuilderPublicKey(builderURL *url.URL, builderPublicKeyPath string) (*remoteBuilderPublicKeyResponse, error) {
6161
if builderPublicKeyPath == "" {
6262
return fetchRemoteBuilderPublicKey(builderURL)
6363
}
@@ -67,20 +67,7 @@ func resolveRemoteBuilderPublicKey(builderURL *url.URL, builderPublicKeyPath, bu
6767
return nil, err
6868
}
6969

70-
publicKey, err := parseRemoteBuilderPublicKey(publicKeyData)
71-
if err != nil {
72-
return nil, err
73-
}
74-
75-
if builderKeyID != "" {
76-
publicKey.KeyID = builderKeyID
77-
}
78-
79-
if publicKey.KeyID == "" {
80-
return nil, fmt.Errorf("builder key id is required when using a pinned builder public key")
81-
}
82-
83-
return publicKey, nil
70+
return parseRemoteBuilderPublicKey(publicKeyData)
8471
}
8572

8673
func readBuilderPublicKeyInput(value string) ([]byte, error) {
@@ -134,7 +121,7 @@ func fetchRemoteBuilderPublicKey(builderURL *url.URL) (*remoteBuilderPublicKeyRe
134121
algorithm = naclBoxAlgorithm
135122
}
136123
if algorithm != naclBoxAlgorithm {
137-
return nil, fmt.Errorf("unsupported encrypted build secrets algorithm: %s", publicKey.Algorithm)
124+
return nil, fmt.Errorf("unsupported build secrets algorithm: %s", publicKey.Algorithm)
138125
}
139126
if publicKey.PublicKey == "" {
140127
return nil, fmt.Errorf("builder public key response did not include a public key")
@@ -160,7 +147,7 @@ func parseRemoteBuilderPublicKey(data []byte) (*remoteBuilderPublicKeyResponse,
160147
algorithm = naclBoxAlgorithm
161148
}
162149
if algorithm != naclBoxAlgorithm {
163-
return nil, fmt.Errorf("unsupported encrypted build secrets algorithm: %s", publicKey.Algorithm)
150+
return nil, fmt.Errorf("unsupported build secrets algorithm: %s", publicKey.Algorithm)
164151
}
165152
if publicKey.PublicKey == "" {
166153
return nil, fmt.Errorf("builder public key JSON did not include a public key")

builder/remote_builder_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func TestRunRemoteBuildWithSecrets(t *testing.T) {
108108
t.Fatalf("url.Parse returned error: %v", err)
109109
}
110110

111-
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, "", "", map[string]string{
111+
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, "", map[string]string{
112112
"pip_token": "s3cr3t",
113113
}, true, "fn", "ttl.sh/test:latest"); err != nil {
114114
t.Fatalf("runRemoteBuild returned error: %v", err)
@@ -159,7 +159,7 @@ func TestRunRemoteBuildWithPinnedPublicKey(t *testing.T) {
159159
t.Fatalf("url.Parse returned error: %v", err)
160160
}
161161

162-
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, publicKeyPath, "", map[string]string{
162+
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, publicKeyPath, map[string]string{
163163
"pip_token": "s3cr3t",
164164
}, true, "fn", "ttl.sh/test:latest"); err != nil {
165165
t.Fatalf("runRemoteBuild returned error: %v", err)
@@ -197,7 +197,7 @@ func TestRunRemoteBuildWithLiteralPublicKey(t *testing.T) {
197197
t.Fatalf("url.Parse returned error: %v", err)
198198
}
199199

200-
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, string(pub), "builder-key-1", map[string]string{
200+
if err := runRemoteBuild(builderURL, tarPath, payloadSecretPath, string(pub), map[string]string{
201201
"pip_token": "s3cr3t",
202202
}, true, "fn", "ttl.sh/test:latest"); err != nil {
203203
t.Fatalf("runRemoteBuild returned error: %v", err)

commands/build.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ func runBuild(cmd *cobra.Command, args []string) error {
236236
remoteBuilder,
237237
payloadSecretPath,
238238
builderPublicKeyPath,
239-
builderKeyID,
240239
forcePull,
241240
); err != nil {
242241
return err
@@ -296,7 +295,6 @@ func build(services *stack.Services, queueDepth int, shrinkwrap, quietBuild bool
296295
remoteBuilder,
297296
payloadSecretPath,
298297
builderPublicKeyPath,
299-
builderKeyID,
300298
forcePull,
301299
)
302300

commands/priority.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const (
1414
remoteBuilderEnvironment = "OPENFAAS_REMOTE_BUILDER"
1515
payloadSecretEnvironment = "OPENFAAS_PAYLOAD_SECRET"
1616
builderPublicKeyEnvironment = "OPENFAAS_BUILDER_PUBLIC_KEY"
17-
builderKeyIDEnvironment = "OPENFAAS_BUILDER_KEY_ID"
1817
templateURLEnvironment = "OPENFAAS_TEMPLATE_URL"
1918
templateStoreURLEnvironment = "OPENFAAS_TEMPLATE_STORE_URL"
2019
defaultFunctionNamespace = ""
@@ -91,5 +90,4 @@ func applyRemoteBuilderEnvironment() {
9190
remoteBuilder = getStringValue(remoteBuilder, os.Getenv(remoteBuilderEnvironment))
9291
payloadSecretPath = getStringValue(payloadSecretPath, os.Getenv(payloadSecretEnvironment))
9392
builderPublicKeyPath = getStringValue(builderPublicKeyPath, os.Getenv(builderPublicKeyEnvironment))
94-
builderKeyID = getStringValue(builderKeyID, os.Getenv(builderKeyIDEnvironment))
9593
}

commands/priority_test.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ func TestApplyRemoteBuilderEnvironmentUsesEnvFallbacks(t *testing.T) {
66
t.Setenv(remoteBuilderEnvironment, "http://builder.example.com")
77
t.Setenv(payloadSecretEnvironment, "/var/run/secrets/payload-secret")
88
t.Setenv(builderPublicKeyEnvironment, "/var/run/secrets/builder-public-key")
9-
t.Setenv(builderKeyIDEnvironment, "builder-key-1")
109

1110
remoteBuilder = ""
1211
payloadSecretPath = ""
1312
builderPublicKeyPath = ""
14-
builderKeyID = ""
1513

1614
applyRemoteBuilderEnvironment()
1715

@@ -24,21 +22,16 @@ func TestApplyRemoteBuilderEnvironmentUsesEnvFallbacks(t *testing.T) {
2422
if builderPublicKeyPath != "/var/run/secrets/builder-public-key" {
2523
t.Fatalf("want builderPublicKeyPath from env, got %q", builderPublicKeyPath)
2624
}
27-
if builderKeyID != "builder-key-1" {
28-
t.Fatalf("want builderKeyID from env, got %q", builderKeyID)
29-
}
3025
}
3126

3227
func TestApplyRemoteBuilderEnvironmentPreservesFlags(t *testing.T) {
3328
t.Setenv(remoteBuilderEnvironment, "http://builder.example.com")
3429
t.Setenv(payloadSecretEnvironment, "/var/run/secrets/payload-secret")
3530
t.Setenv(builderPublicKeyEnvironment, "/var/run/secrets/builder-public-key")
36-
t.Setenv(builderKeyIDEnvironment, "builder-key-1")
3731

3832
remoteBuilder = "http://flag-builder.example.com"
3933
payloadSecretPath = "/tmp/payload-secret"
4034
builderPublicKeyPath = "/tmp/public-key"
41-
builderKeyID = "flag-key-id"
4235

4336
applyRemoteBuilderEnvironment()
4437

@@ -51,7 +44,4 @@ func TestApplyRemoteBuilderEnvironmentPreservesFlags(t *testing.T) {
5144
if builderPublicKeyPath != "/tmp/public-key" {
5245
t.Fatalf("want builderPublicKeyPath flag value, got %q", builderPublicKeyPath)
5346
}
54-
if builderKeyID != "flag-key-id" {
55-
t.Fatalf("want builderKeyID flag value, got %q", builderKeyID)
56-
}
5747
}

commands/publish.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ func init() {
5656
publishCmd.Flags().BoolVar(&resetQemu, "reset-qemu", false, "Runs \"docker run multiarch/qemu-user-static --reset -p yes\" to enable multi-arch builds. Compatible with AMD64 machines only.")
5757
publishCmd.Flags().StringVar(&remoteBuilder, "remote-builder", "", "URL to the builder")
5858
publishCmd.Flags().StringVar(&payloadSecretPath, "payload-secret", "", "Path to the payload secret file")
59-
publishCmd.Flags().StringVar(&builderPublicKeyPath, "builder-public-key", "", "Builder public key as a literal value, or a path to a file containing raw base64 or the JSON response from /public-key")
60-
publishCmd.Flags().StringVar(&builderKeyID, "builder-key-id", "", "Key ID for the pinned builder public key when using a raw base64 key file")
59+
publishCmd.Flags().StringVar(&builderPublicKeyPath, "builder-public-key", "", "Builder public key as a literal value, or a path to a file containing raw base64 or the JSON response from /publickey")
6160
publishCmd.Flags().BoolVar(&forcePull, "pull", false, "Force a re-pull of base images in template during build, useful for publishing images")
6261

6362
publishCmd.Flags().BoolVar(&pullDebug, "debug", false, "Enable debug output when pulling templates")
@@ -291,7 +290,6 @@ func publish(services *stack.Services, queueDepth int, shrinkwrap, quietBuild, m
291290
remoteBuilder,
292291
payloadSecretPath,
293292
builderPublicKeyPath,
294-
builderKeyID,
295293
forcePull,
296294
)
297295

commands/secret_keygen.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,14 @@ func runSecretKeygen(cmd *cobra.Command, args []string) error {
5454
return fmt.Errorf("writing public key: %w", err)
5555
}
5656

57+
keyID, err := seal.DeriveKeyID(pub)
58+
if err != nil {
59+
return fmt.Errorf("deriving key ID: %w", err)
60+
}
61+
5762
fmt.Printf("Wrote private key: %s\n", privPath)
5863
fmt.Printf("Wrote public key: %s\n", pubPath)
64+
fmt.Printf("Key ID: %s\n", keyID)
5965

6066
return nil
6167
}

commands/secret_seal.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
)
1111

1212
var (
13-
sealKeyID string
1413
sealOutput string
1514
sealFromLiteral []string
1615
sealFromFile []string
@@ -30,9 +29,8 @@ var secretSealCmd = &cobra.Command{
3029
--from-file ca.crt=./certs/ca.crt \
3130
--from-literal api_key=sk-1234
3231
33-
# Specify key ID and output path
32+
# Specify output path
3433
faas-cli secret seal key.pub \
35-
--key-id builder-key-1 \
3634
--from-literal token=s3cr3t \
3735
-o ./build/com.openfaas.secrets
3836
`,
@@ -42,7 +40,6 @@ var secretSealCmd = &cobra.Command{
4240
}
4341

4442
func init() {
45-
secretSealCmd.Flags().StringVar(&sealKeyID, "key-id", "", "Key ID for rotation tracking (optional)")
4643
secretSealCmd.Flags().StringVarP(&sealOutput, "output", "o", "com.openfaas.secrets", "Output file path")
4744
secretSealCmd.Flags().StringArrayVar(&sealFromLiteral, "from-literal", nil, "Literal secret in key=value format (can be repeated)")
4845
secretSealCmd.Flags().StringArrayVar(&sealFromFile, "from-file", nil, "Secret from file in key=path format (can be repeated)")
@@ -86,7 +83,7 @@ func runSecretSeal(cmd *cobra.Command, args []string) error {
8683
values[k] = data
8784
}
8885

89-
sealed, err := seal.Seal(pubKey, values, sealKeyID)
86+
sealed, err := seal.Seal(pubKey, values)
9087
if err != nil {
9188
return fmt.Errorf("sealing secrets: %w", err)
9289
}
@@ -95,7 +92,8 @@ func runSecretSeal(cmd *cobra.Command, args []string) error {
9592
return fmt.Errorf("writing sealed file: %w", err)
9693
}
9794

98-
fmt.Printf("Sealed %d secret(s) to %s\n", len(values), sealOutput)
95+
keyID, _ := seal.DeriveKeyID(pubKey)
96+
fmt.Printf("Sealed %d secret(s) to %s (key ID: %s)\n", len(values), sealOutput, keyID)
9997

10098
return nil
10199
}

0 commit comments

Comments
 (0)