func()

in pkg/berglas/grant.go [143:215]


func (c *Client) storageGrant(ctx context.Context, i *StorageGrantRequest) error {
	bucket := i.Bucket
	if bucket == "" {
		return fmt.Errorf("missing bucket name")
	}

	object := i.Object
	if object == "" {
		return fmt.Errorf("missing object name")
	}

	members := i.Members
	if len(members) == 0 {
		return nil
	}
	sort.Strings(members)

	logger := logging.FromContext(ctx).With(
		"bucket", bucket,
		"object", object,
		"members", members,
	)

	logger.DebugContext(ctx, "grant.start")
	defer logger.DebugContext(ctx, "grant.finish")

	// Get attributes to find the KMS key
	logger.DebugContext(ctx, "finding storage object")

	objHandle := c.storageClient.Bucket(bucket).Object(object)
	attrs, err := objHandle.Attrs(ctx)
	if errors.Is(err, storage.ErrObjectNotExist) {
		return errSecretDoesNotExist
	}
	if err != nil {
		return fmt.Errorf("failed to read secret metadata: %w", err)
	}
	if attrs.Metadata == nil || attrs.Metadata[MetadataKMSKey] == "" {
		return fmt.Errorf("missing kms key in secret metadata")
	}
	key := attrs.Metadata[MetadataKMSKey]

	logger = logger.With("key", key)
	logger.DebugContext(ctx, "found kms key")

	// Grant access to storage
	logger.DebugContext(ctx, "granting access to storage")

	storageHandle := c.storageIAM(bucket, object)
	if err := updateIAMPolicy(ctx, storageHandle, func(p *iam.Policy) *iam.Policy {
		for _, m := range members {
			p.Add(m, iamObjectReader)
		}
		return p
	}); err != nil {
		return fmt.Errorf("failed to update Storage IAM policy for %s: %w", object, err)
	}

	// Grant access to KMS
	logger.DebugContext(ctx, "granting access to kms")

	kmsHandle := c.kmsClient.ResourceIAM(key)
	if err := updateIAMPolicy(ctx, kmsHandle, func(p *iam.Policy) *iam.Policy {
		for _, m := range members {
			p.Add(m, iamKMSDecrypt)
		}
		return p
	}); err != nil {
		return fmt.Errorf("failed to update KMS IAM policy for %s: %w", key, err)
	}

	return nil
}