-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow flexible options for github app secret and metrics (#412)
feat: allow flexible options for github app secret and metrics allows for the GitHub app secret to be loaded from GCPKMS as the default, but also now allows envvars and files to be utilized. Vaulting mechanisms are used in our case, however they're loaded a bit differently. allows for the metrics specific to chainguard to be optionally disabled. the default is to allow the chainguard default metrics. --------- Signed-off-by: Karl Haworth <[email protected]> Co-authored-by: Billy Lynch <[email protected]>
- Loading branch information
1 parent
11cf87b
commit 4a23eac
Showing
7 changed files
with
412 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2024 Chainguard, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package envconfig | ||
|
||
import ( | ||
"errors" | ||
|
||
"github.com/kelseyhightower/envconfig" | ||
) | ||
|
||
type EnvConfig struct { | ||
Port int `envconfig:"PORT" required:"true"` | ||
Domain string `envconfig:"STS_DOMAIN" required:"true"` | ||
KMSKey string `envconfig:"KMS_KEY" required:"false"` | ||
AppID int64 `envconfig:"GITHUB_APP_ID" required:"true"` | ||
EventingIngress string `envconfig:"EVENT_INGRESS_URI" required:"true"` | ||
AppSecretCertificateFile string `envconfig:"APP_SECRET_CERTIFICATE_FILE" required:"false"` | ||
AppSecretCertificateEnvVar string `envconfig:"APP_SECRET_CERTIFICATE_ENV_VAR" required:"false"` | ||
Metrics bool `envconfig:"METRICS" required:"false" default:"true"` | ||
} | ||
|
||
func Process() (*EnvConfig, error) { | ||
cfg := new(EnvConfig) | ||
var err error | ||
if err = envconfig.Process("", cfg); err != nil { | ||
return nil, err | ||
} | ||
|
||
kmsSet := false | ||
for _, v := range []string{cfg.KMSKey, cfg.AppSecretCertificateFile, cfg.AppSecretCertificateEnvVar} { | ||
if v != "" { | ||
if kmsSet { | ||
return nil, errors.New("only one of KMS_KEY, APP_SECRET_CERTIFICATE_FILE, APP_SECRET_CERTIFICATE_ENV_VAR may be set") | ||
} | ||
kmsSet = true | ||
} | ||
} | ||
|
||
return cfg, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2024 Chainguard, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package envconfig | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestProcess(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
envVars map[string]string | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "No environment variables set", | ||
envVars: map[string]string{ | ||
"PORT": "8080", | ||
"STS_DOMAIN": "", | ||
"GITHUB_APP_ID": "1234", | ||
"EVENT_INGRESS_URI": "", | ||
"KMS_KEY": "", | ||
"APP_SECRET_CERTIFICATE_FILE": "", | ||
"APP_SECRET_CERTIFICATE_ENVVAR": "", | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Only KMS_KEY set", | ||
envVars: map[string]string{ | ||
"PORT": "8080", | ||
"STS_DOMAIN": "", | ||
"GITHUB_APP_ID": "1234", | ||
"EVENT_INGRESS_URI": "", | ||
"KMS_KEY": "some-kms-key", | ||
"APP_SECRET_CERTIFICATE_FILE": "", | ||
"APP_SECRET_CERTIFICATE_ENVVAR": "", | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Only APP_SECRET_CERTIFICATE_FILE set", | ||
envVars: map[string]string{ | ||
"PORT": "8080", | ||
"STS_DOMAIN": "", | ||
"GITHUB_APP_ID": "1234", | ||
"EVENT_INGRESS_URI": "", | ||
"KMS_KEY": "", | ||
"APP_SECRET_CERTIFICATE_FILE": "some-file-path", | ||
"APP_SECRET_CERTIFICATE_ENVVAR": "", | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Only APP_SECRET_CERTIFICATE_ENVVAR set", | ||
envVars: map[string]string{ | ||
"PORT": "8080", | ||
"STS_DOMAIN": "", | ||
"GITHUB_APP_ID": "1234", | ||
"EVENT_INGRESS_URI": "", | ||
"KMS_KEY": "", | ||
"APP_SECRET_CERTIFICATE_FILE": "", | ||
"APP_SECRET_CERTIFICATE_ENVVAR": "some-env-var", | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Multiple variables set", | ||
envVars: map[string]string{ | ||
"PORT": "8080", | ||
"STS_DOMAIN": "", | ||
"GITHUB_APP_ID": "1234", | ||
"EVENT_INGRESS_URI": "", | ||
"KMS_KEY": "some-kms-key", | ||
"APP_SECRET_CERTIFICATE_FILE": "some-file-path", | ||
"APP_SECRET_CERTIFICATE_ENVVAR": "", | ||
}, | ||
wantErr: true, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
for key, value := range tt.envVars { | ||
t.Setenv(key, value) | ||
} | ||
|
||
cfg, err := Process() | ||
|
||
if tt.wantErr { | ||
assert.Error(t, err) | ||
assert.Nil(t, cfg) | ||
} else { | ||
assert.NoError(t, err) | ||
assert.NotNil(t, cfg) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2024 Chainguard, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package ghtransport | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
|
||
kms "cloud.google.com/go/kms/apiv1" | ||
"github.com/bradleyfalzon/ghinstallation/v2" | ||
envConfig "github.com/octo-sts/app/pkg/envconfig" | ||
"github.com/octo-sts/app/pkg/gcpkms" | ||
) | ||
|
||
func New(ctx context.Context, env *envConfig.EnvConfig, kmsClient *kms.KeyManagementClient) (*ghinstallation.AppsTransport, error) { | ||
switch { | ||
case env.AppSecretCertificateEnvVar != "": | ||
atr, err := ghinstallation.NewAppsTransport(http.DefaultTransport, env.AppID, []byte(env.AppSecretCertificateEnvVar)) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
return atr, nil | ||
|
||
case env.AppSecretCertificateFile != "": | ||
atr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, env.AppID, env.AppSecretCertificateFile) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
return atr, nil | ||
default: | ||
if env.KMSKey == "" { | ||
return nil, fmt.Errorf("failed to process env var: %q", env.KMSKey) | ||
} | ||
|
||
signer, err := gcpkms.New(ctx, kmsClient, env.KMSKey) | ||
if err != nil { | ||
return nil, fmt.Errorf("error creating signer: %w", err) | ||
} | ||
|
||
atr, err := ghinstallation.NewAppsTransportWithOptions(http.DefaultTransport, env.AppID, ghinstallation.WithSigner(signer)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return atr, nil | ||
} | ||
} |
Oops, something went wrong.