@@ -6,6 +6,7 @@ package manager
66
77import (
88 "context"
9+ "crypto/sha256"
910 "encoding/base64"
1011 "encoding/json"
1112 "fmt"
@@ -39,6 +40,7 @@ import (
3940 wsk8s "github.com/gitpod-io/gitpod/common-go/kubernetes"
4041 "github.com/gitpod-io/gitpod/common-go/log"
4142 "github.com/gitpod-io/gitpod/common-go/tracing"
43+ csapi "github.com/gitpod-io/gitpod/content-service/api"
4244 "github.com/gitpod-io/gitpod/content-service/pkg/layer"
4345 regapi "github.com/gitpod-io/gitpod/registry-facade/api"
4446 wsdaemon "github.com/gitpod-io/gitpod/ws-daemon/api"
@@ -82,7 +84,6 @@ type startWorkspaceContext struct {
8284 Headless bool `json:"headless"`
8385 Class * config.WorkspaceClass `json:"class"`
8486 VolumeSnapshot * workspaceVolumeSnapshotStatus `json:"volumeSnapshot"`
85- Secrets map [string ]string `json:"secrets"`
8687}
8788
8889func (swctx * startWorkspaceContext ) ContainerConfiguration () config.ContainerConfiguration {
@@ -267,13 +268,21 @@ func (m *Manager) StartWorkspace(ctx context.Context, req *api.StartWorkspaceReq
267268 }
268269 }
269270 if createSecret {
271+ secrets , _ := buildWorkspaceSecrets (startContext .Request .Spec )
272+
273+ // This call actually modifies the initializer and removes the secrets.
274+ // Prior to the `InitWorkspace` call, we inject the secrets back into the initializer.
275+ // We do this so that no Git token is stored as annotation on the pod, but solely
276+ // remains within the Kubernetes secret.
277+ _ = csapi .ExtractAndReplaceSecretsFromInitializer (startContext .Request .Spec .Initializer )
278+
270279 secret := & corev1.Secret {
271280 ObjectMeta : metav1.ObjectMeta {
272281 Name : podName (startContext .Request ),
273282 Namespace : m .Config .Namespace ,
274283 Labels : startContext .Labels ,
275284 },
276- StringData : startContext . Secrets ,
285+ StringData : secrets ,
277286 }
278287 err = m .Clientset .Create (ctx , secret )
279288 if err != nil && ! k8serr .IsAlreadyExists (err ) {
@@ -411,6 +420,27 @@ func (m *Manager) StartWorkspace(ctx context.Context, req *api.StartWorkspaceReq
411420 return okResponse , nil
412421}
413422
423+ func buildWorkspaceSecrets (spec * api.StartWorkspaceSpec ) (secrets map [string ]string , secretsLen int ) {
424+ secrets = make (map [string ]string )
425+ for _ , env := range spec .Envvars {
426+ if env .Secret != nil {
427+ continue
428+ }
429+ if ! isProtectedEnvVar (env .Name ) {
430+ continue
431+ }
432+
433+ name := fmt .Sprintf ("%x" , sha256 .Sum256 ([]byte (env .Name )))
434+ secrets [name ] = env .Value
435+ secretsLen += len (env .Value )
436+ }
437+ for k , v := range csapi .GatherSecretsFromInitializer (spec .Initializer ) {
438+ secrets [k ] = v
439+ secretsLen += len (v )
440+ }
441+ return secrets , secretsLen
442+ }
443+
414444func (m * Manager ) restoreVolumeSnapshotFromHandle (ctx context.Context , id , handle string ) (err error ) {
415445 span , ctx := tracing .FromContext (ctx , "restoreVolumeSnapshotFromHandle" )
416446 defer tracing .FinishSpan (span , & err )
@@ -586,6 +616,10 @@ func validateStartWorkspaceRequest(req *api.StartWorkspaceRequest) error {
586616 return xerrors .Errorf ("invalid request: %w" , err )
587617 }
588618
619+ if _ , secretsLen := buildWorkspaceSecrets (req .Spec ); secretsLen > maxSecretsLength {
620+ return xerrors .Errorf ("secrets exceed maximum permitted length (%d > %d bytes): please reduce the numer or length of environment variables" , secretsLen , maxSecretsLength )
621+ }
622+
589623 rules := make ([]* validation.FieldRules , 0 )
590624 rules = append (rules , validation .Field (& req .Id , validation .Required ))
591625 rules = append (rules , validation .Field (& req .Spec , validation .Required ))
0 commit comments