diff --git a/internal/promoter/image/sign.go b/internal/promoter/image/sign.go index 0e82f2a6e..3c58bfd66 100644 --- a/internal/promoter/image/sign.go +++ b/internal/promoter/image/sign.go @@ -19,11 +19,11 @@ package imagepromoter import ( "context" "fmt" - "os" credentials "cloud.google.com/go/iam/credentials/apiv1" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "golang.org/x/oauth2/google" credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1" reg "sigs.k8s.io/promo-tools/v3/legacy/dockerregistry" @@ -35,6 +35,10 @@ const ( TestSigningAccount = "" ) +type tiResponse struct { + Email string `json:"email"` +} + // ValidateStagingSignatures checks if edges (images) have a signature // applied during its staging run. If they do it verifies them and // returns an error if they are not valid. @@ -79,10 +83,10 @@ func (di *DefaultPromoterImplementation) ValidateStagingSignatures( func (di *DefaultPromoterImplementation) SignImages( opts *options.Options, sc *reg.SyncContext, edges map[reg.PromotionEdge]interface{}, ) error { - signer := sign.New(sign.Default()) - if err := os.Setenv("COSIGN_EXPERIMENTAL", "YES"); err != nil { - return errors.Wrap(err, "setting experimental env") + if err := di.EnsureWorkloadIdentity(); err != nil { + return errors.Wrap(err, "verifying the workload can has identity credentials") } + signer := sign.New(sign.Default()) for edge := range edges { imageRef := fmt.Sprintf( "%s/%s@%s", @@ -131,3 +135,42 @@ func (di *DefaultPromoterImplementation) GetIdentityToken( return resp.Token, nil } + +// EnsureWorkloadIdentity gets a token from the default application +// credentials and makes sure thers is an identity logged in. This +// function exists to ensure there is an identity starting the signing +// impersonation chain. +func (di *DefaultPromoterImplementation) EnsureWorkloadIdentity() error { + ctx := context.Background() + cred, err := google.FindDefaultCredentials(ctx) + if err != nil { + return errors.Wrap(err, "looking for default application credentials") + } + + tk, err := cred.TokenSource.Token() + if err != nil { + return errors.Wrap(err, "getting token from default credentials") + } + return errors.New("Type: " + tk.TokenType) + + /* + res, err := http.NewAgent().Get( + fmt.Sprintf( + "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=%s", + []byte(tk.AccessToken)), + ) + if err != nil { + return errors.Wrapf(err, "getting token info %s", string(cred.JSON)) + } + tinfo := tiResponse{} + if err := json.Unmarshal(res, &tinfo); err != nil { + return errors.Wrapf(err, "unmarshalling token info %s", string(res)) + } + + if tinfo.Email == "" { + return errors.New("No identity found in current application credentials") + } + logrus.Infof("Current worload identity resolves to %s", tinfo.Email) + return nil + */ +} diff --git a/internal/promoter/image/sign_test.go b/internal/promoter/image/sign_test.go index cb33d3e3c..d7054b939 100644 --- a/internal/promoter/image/sign_test.go +++ b/internal/promoter/image/sign_test.go @@ -37,3 +37,9 @@ func TestGetIdentityToken(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, tok) } + +func TestEnsureWorkloadIdentity(t *testing.T) { + di := DefaultPromoterImplementation{} + + require.NoError(t, di.EnsureWorkloadIdentity()) +}