github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/agent/secrets/secrets.go (about) 1 package secrets 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/docker/swarmkit/agent/exec" 8 "github.com/docker/swarmkit/api" 9 "github.com/docker/swarmkit/identity" 10 ) 11 12 // secrets is a map that keeps all the currently available secrets to the agent 13 // mapped by secret ID. 14 type secrets struct { 15 mu sync.RWMutex 16 m map[string]*api.Secret 17 } 18 19 // NewManager returns a place to store secrets. 20 func NewManager() exec.SecretsManager { 21 return &secrets{ 22 m: make(map[string]*api.Secret), 23 } 24 } 25 26 // Get returns a secret by ID. If the secret doesn't exist, returns nil. 27 func (s *secrets) Get(secretID string) (*api.Secret, error) { 28 s.mu.RLock() 29 defer s.mu.RUnlock() 30 if s, ok := s.m[secretID]; ok { 31 return s, nil 32 } 33 return nil, fmt.Errorf("secret %s not found", secretID) 34 } 35 36 // Add adds one or more secrets to the secret map. 37 func (s *secrets) Add(secrets ...api.Secret) { 38 s.mu.Lock() 39 defer s.mu.Unlock() 40 for _, secret := range secrets { 41 s.m[secret.ID] = secret.Copy() 42 } 43 } 44 45 // Remove removes one or more secrets by ID from the secret map. Succeeds 46 // whether or not the given IDs are in the map. 47 func (s *secrets) Remove(secrets []string) { 48 s.mu.Lock() 49 defer s.mu.Unlock() 50 for _, secret := range secrets { 51 delete(s.m, secret) 52 } 53 } 54 55 // Reset removes all the secrets. 56 func (s *secrets) Reset() { 57 s.mu.Lock() 58 defer s.mu.Unlock() 59 s.m = make(map[string]*api.Secret) 60 } 61 62 // taskRestrictedSecretsProvider restricts the ids to the task. 63 type taskRestrictedSecretsProvider struct { 64 secrets exec.SecretGetter 65 secretIDs map[string]struct{} // allow list of secret ids 66 taskID string // ID of the task the provider restricts for 67 } 68 69 func (sp *taskRestrictedSecretsProvider) Get(secretID string) (*api.Secret, error) { 70 if _, ok := sp.secretIDs[secretID]; !ok { 71 return nil, fmt.Errorf("task not authorized to access secret %s", secretID) 72 } 73 74 // First check if the secret is available with the task specific ID, which is the concatenation 75 // of the original secret ID and the task ID with a dot in between. 76 // That is the case when a secret driver has returned DoNotReuse == true for a secret value. 77 taskSpecificID := identity.CombineTwoIDs(secretID, sp.taskID) 78 secret, err := sp.secrets.Get(taskSpecificID) 79 if err != nil { 80 // Otherwise, which is the default case, the secret is retrieved by its original ID. 81 return sp.secrets.Get(secretID) 82 } 83 // For all intents and purposes, the rest of the flow should deal with the original secret ID. 84 secret.ID = secretID 85 return secret, err 86 } 87 88 // Restrict provides a getter that only allows access to the secrets 89 // referenced by the task. 90 func Restrict(secrets exec.SecretGetter, t *api.Task) exec.SecretGetter { 91 sids := map[string]struct{}{} 92 93 container := t.Spec.GetContainer() 94 if container != nil { 95 for _, ref := range container.Secrets { 96 sids[ref.SecretID] = struct{}{} 97 } 98 } 99 100 return &taskRestrictedSecretsProvider{secrets: secrets, secretIDs: sids, taskID: t.ID} 101 }