Uplink-go - object not found

This is a first time project that I’m experimenting with, so security - for the moment - isn’t something I’m looking to implement. I am currently unable to download an object from a bucket. I have 3 items that I can verify do exist in the bucket and was able to download it via uplink CLI manually. But doing it via the go lib doesn’t seem to work.

What does work:

  • getting access to the bucket
  • access grant key

What doesn’t work:

  • listing objects within the bucket
  • download from the bucket

I’m using the below code to test out whether I’m able to print what’s being received just to see that that connection is going through. But I”m hitting an object not found error that I’m not able to home in on. I double checked that I’m spelling everything correctly and that the keys match(tried regenerating them too), but I’m unfortunately not able to do a thing even with the permissions elevated to `fully.

I’m wondering if I’m supposed to do something with the satellite key? But this is purely an assumption and so I”m hoping someone might be able to provide me with the correct flow, as the tutorial shown via gh didn’t help this time around.

Below is the code I quickly hacked up to get things working. Please let me know if I’ve done something wrong here. I’m fetching the keys via a `.env file and that seems to be working just fine. Although to be sure I did verify it by using string literals.

func downloadData(ctx context.Context, env Env, data []byte) error {                                                                                          
    1                                                                                                                                                                
    2      // verification steps                                                                                                                                     
    3      project, shouldReturn, returnValue := verifyStorj(env, ctx)                                                                                               
    4      if shouldReturn {                                                                                                                                         
    5          return returnValue                                                                                                                                    
    6      }                                                                                                                                                         
    7                                                                                                                                                                
    8      download, err := project.DownloadObject(ctx, env.bucketName, env.objectKey, nil)                                                                          
    9      if err != nil {                                                                                                                                           
   10          return fmt.Errorf("could not download from bucket: %v", err)                                                                                          
   11      }                                                                                                                                                         
   12                                                                                                                                                                
   13      defer download.Close()                                                                                                                                    
   14                                                                                                                                                                
   15      receivedContents, err := ioutil.ReadAll(download)                                                                                                         
   16      if err != nil {                                                                                                                                           
   17          return fmt.Errorf("couldn't  read all download data: %v", err)                                                                                        
   18      }                                                                                                                                                         
   19                                                                                                                                                                
   20      fmt.Printf("received contents are: %v", receivedContents)                                                                                                 
   21                                                                                                                                                                
   22      if !bytes.Equal(receivedContents, data) {                                                                                                                 
   23          return fmt.Errorf("different object obtained: %q != %q", data, receivedContents)                                                                      
   24      }                                                                                                                                                         
   25      return nil                                                                                                                                                
   26  }          

Hello @StoreYourOwnKoala,
Welcome to the forum!

Usually this could mean that the prefix of the object is wrong or the encryption phrase is different from the used when you uploaded an object (prefixes are encrypted too).

Have you tried the example app from the repository?

Does it work for you?

You should provide the information in these constants for this example app:

const (
	myAccessGrant = "change-me-to-the-access-grant-created-in-satellite-gui"
	myBucket      = "mybucket"
	myObjectKey   = "foo/bar/baz"
	myData        = "one fish two fish red fish blue fish"
)

Thank you @Alexey!

Appreciate you mentioning the constraints and I have indeed set it up following the tutorial:

 type Env struct {                                                                                                      
    1      accessGrant string                                                                                                 
    2      bucketName  string                                                                                                 
    3      objectKey   string                                                                                                 
    4  }          

// and then calling it like so:

func getEnv() (env Env) {                                                                                              
    1      env = Env{                                                                                                         
    2          accessGrant: os.Getenv("ACCESS_GRANT"),                                                                        
    3          bucketName:  "bucket",                                                                                  
    4          objectKey:   "objectname.png",                                                                                 
    5      }                                                                                                                  
    6                                                                                                                         
    7      return                                                                                                             
    8  }             

Are you able to elaborate on the encryption phrase? I do understand that if I log into a bucket using a different phrase then I’ll get a different set of objects. So just wondering if that’s what you meant?

And, on that note, how do I set the encryption phrase within the code? Are these the correct steps to do so:

  • create a bucket
  • create an encryption phrase
  • create an access key
  • add access key

Is that right?

You will get only list of decryptable objects. If they are not decryptable, the list will be empty.
You will need to list it in the encrypted form then.

The encryption phrase may be just a normal phrase, not necessarily generated. You will use it to create an access grant which will be used to list objects, upload, download, delete objects.

The access key (if you mean S3 credentials) can be generated using this access grant too.

Hmmm seems like I’m not understanding the workflow then. I’ll reread the docs

In my case I’m not referencing the S3 credentials. I created it by ticking access grant and going through the generated encryption phrase step

You will:

  1. Generate either an access grant in the satellite UI or API Key if you want to create an access grant in the code instead.
  2. You may create a bucket using this access grant, upload/download/delete objects

This access grant will contain a satellite URL, derived API key (from your root API Key) and derived encryption key (from your encryption phrase) and permissions (list, get, put, delete), and scope - prefix or bucket or only one object or all.

You may inspect it:

uplink access inspect 1asdGrhtnfmutjfkfofo...

Yes! Got it! Thanks a bunch for walking me through that. Your point about inspecting the access key was it. It seems like I was using 2 different access keys for the same bucket, but may have had the passphrase incorrectly set

How I resolved:

  • Checked that I used the correct passphrase in my bucket
  • added an access key that matched the bucket with full access(first step, will restrict later) in my go project
  • Checked my CLI to make sure I was able to list the objects in the bucket I was wanting to refer to in my codebase

@Alexey thanks for pointing everything out to help me resolve this. Very much appreciated!

1 Like

You are welcome!
Please note - the encryption phrase is not tied to the bucket, it’s used to encrypt/decrypt your objects in any bucket. So you may use a different encryption phrase for each object, but to see and download it you need to use its encryption phrase used during upload.

Noted and will keep that in mind. Thanks again

1 Like