diff --git a/README.md b/README.md
index d1469d72..06c90806 100644
--- a/README.md
+++ b/README.md
@@ -83,12 +83,13 @@ The following config options are supported:
| Environment Variable | Sigstore
Prefix | Default | Description |
| ---------------------------- | ------------------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GITSIGN_CREDENTIAL_CACHE | | | Optional path to [gitsign-credential-cache](cmd/gitsign-credential-cache/README.md) socket. |
-| GITSIGN_CONNECTOR_ID | ✅ | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
-| GITSIGN_TOKEN_PROVIDER | ✅ | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` |
-| GITSIGN_FULCIO_URL | ✅ | https://fulcio.sigstore.dev | Address of Fulcio server |
-| GITSIGN_LOG | ❌ | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
-| GITSIGN_OIDC_CLIENT_ID | ✅ | sigstore | OIDC client ID for application |
-| GITSIGN_OIDC_ISSUER | ✅ | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
+| GITSIGN_CONNECTOR_ID | ✅ | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
+| GITSIGN_TOKEN_PROVIDER | ✅ | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` |
+| GITSIGN_FULCIO_URL | ✅ | https://fulcio.sigstore.dev | Address of Fulcio server |
+| GITSIGN_LOG | ❌ | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
+| GITSIGN_OIDC_CLIENT_ID | ✅ | sigstore | OIDC client ID for application
+| GITSIGN_OIDC_CLIENT_SECRET_FILE | ✅ | | Path to the file containing the OIDC client secret for the application. | |
+| GITSIGN_OIDC_ISSUER | ✅ | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
| GITSIGN_OIDC_REDIRECT_URL | ✅ | | OIDC Redirect URL |
| GITSIGN_REKOR_URL | ✅ | https://rekor.sigstore.dev | Address of Rekor server |
| GITSIGN_TIMESTAMP_SERVER_URL | ✅ | | Address of timestamping authority. If set, a trusted timestamp will be included in the signature. |
diff --git a/internal/config/config.go b/internal/config/config.go
index 62d81028..2ee62b70 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -24,6 +24,7 @@ import (
"os/exec"
"strconv"
"strings"
+ "unicode/utf8"
)
type RekorVerificationMode int
@@ -57,6 +58,9 @@ type Config struct {
// OIDC client ID for application
ClientID string
+ // File containing the OIDC Client Secret
+ clientSecretFile string
+
// OIDC Redirect URL
RedirectURL string
// OIDC provider to be used to issue ID token
@@ -89,6 +93,23 @@ type Config struct {
AutocloseTimeout int
}
+// CLientSecret retrieves the OIDC client secret from the file provided
+func (o *Config) ClientSecret() (string, error) {
+ if o.clientSecretFile != "" {
+ clientSecretBytes, err := os.ReadFile(o.clientSecretFile)
+ if err != nil {
+ return "", fmt.Errorf("reading OIDC client secret: %w", err)
+ }
+ if !utf8.Valid(clientSecretBytes) {
+ return "", fmt.Errorf("OIDC client secret in file %s not valid utf8", o.clientSecretFile)
+ }
+ clientSecretString := string(clientSecretBytes)
+ clientSecretString = strings.TrimSpace(clientSecretString)
+ return clientSecretString, nil
+ }
+ return "", nil
+}
+
// Get fetches the gitsign config options for the repo in the current working
// directory.
func Get() (*Config, error) {
@@ -127,6 +148,7 @@ func Get() (*Config, error) {
out.FulcioRoot = envOrValue(fmt.Sprintf("%s_FULCIO_ROOT", prefix), out.FulcioRoot)
out.Rekor = envOrValue(fmt.Sprintf("%s_REKOR_URL", prefix), out.Rekor)
out.ClientID = envOrValue(fmt.Sprintf("%s_OIDC_CLIENT_ID", prefix), out.ClientID)
+ out.clientSecretFile = envOrValue(fmt.Sprintf("%s_OIDC_CLIENT_SECRET_FILE", prefix), out.clientSecretFile)
out.RedirectURL = envOrValue(fmt.Sprintf("%s_OIDC_REDIRECT_URL", prefix), out.RedirectURL)
out.Issuer = envOrValue(fmt.Sprintf("%s_OIDC_ISSUER", prefix), out.Issuer)
out.ConnectorID = envOrValue(fmt.Sprintf("%s_CONNECTOR_ID", prefix), out.ConnectorID)
@@ -198,6 +220,8 @@ func applyGitOptions(out *Config, cfg map[string]string) {
out.RekorMode = v
case strings.EqualFold(k, "gitsign.clientID"):
out.ClientID = v
+ case strings.EqualFold(k, "gitsign.clientSecretFile"):
+ out.clientSecretFile = v
case strings.EqualFold(k, "gitsign.redirectURL"):
out.RedirectURL = v
case strings.EqualFold(k, "gitsign.issuer"):
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index b63bcaca..f0e3c2c8 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -99,7 +99,7 @@ func TestGet(t *testing.T) {
t.Fatal(err)
}
- if diff := cmp.Diff(want, got); diff != "" {
+ if diff := cmp.Diff(want, got, cmp.AllowUnexported(Config{})); diff != "" {
t.Error(diff)
}
}
diff --git a/internal/fulcio/identity.go b/internal/fulcio/identity.go
index fbc901b7..79748c87 100644
--- a/internal/fulcio/identity.go
+++ b/internal/fulcio/identity.go
@@ -195,6 +195,12 @@ func NewIdentityFactory(in io.Reader, out io.Writer) *IdentityFactory {
func (f *IdentityFactory) NewIdentity(ctx context.Context, cfg *config.Config) (*Identity, error) {
clientID := cfg.ClientID
+ clientSecret, err := cfg.ClientSecret()
+
+ if err != nil {
+ return nil, err
+ }
+
// Autoclose only works if we don't go through the identity selection page
// (otherwise it'll show a countdown timer that doesn't work)
if cfg.ConnectorID == "" {
@@ -247,10 +253,11 @@ func (f *IdentityFactory) NewIdentity(ctx context.Context, cfg *config.Config) (
client, err := fulcio.NewClient(cfg.Fulcio,
fulcio.OIDCOptions{
- Issuer: cfg.Issuer,
- ClientID: clientID,
- RedirectURL: cfg.RedirectURL,
- TokenGetter: authFlow,
+ Issuer: cfg.Issuer,
+ ClientID: clientID,
+ ClientSecret: clientSecret,
+ RedirectURL: cfg.RedirectURL,
+ TokenGetter: authFlow,
})
if err != nil {
return nil, fmt.Errorf("error creating Fulcio client: %w", err)