title: Google Cloud Storage JSON API with JWT Token
body: <p>I'm trying to use the JSON API for Google Cloud Storage to retrieve a file from Google Cloud Storage. I am not allowed to use the SDKs. Is it possible to create a JWT from a ServiceAccount.json file and use the JWT to access files from Google Cloud Storage? I have a script in node.js that generates a JWT from the service account, but i'm not sure if the audience is right</p>
  
  <pre><code>const jwt = require('jsonwebtoken');
  const serviceAccount = require('./serviceAccount.json');
  const issuedAt = Math.floor(Date.now() / 1000);
  
  const TOKEN_DURATION_IN_SECONDS = 3600;
  
  let params = {
      'iss': serviceAccount.client_email,
      'sub': serviceAccount.client_email,
      'aud': serviceAccount.project_id,
      'iat': issuedAt,
      'exp': issuedAt + TOKEN_DURATION_IN_SECONDS,
  };
  
  let options = {
      algorithm: 'RS256',
      header: {
          'kid': serviceAccount.private_key_id,
          'typ': 'JWT',
          'alg': 'RS256',
      },
  };
  
  let token = jwt.sign(params, serviceAccount.private_key, options);
  console.log(token);
  </code></pre>
  
  <p>I then use that JWT to call the Google Cloud Storage JSON API:</p>
  
  <p><code>https://www.googleapis.com/storage/v1/b/test</code></p>
  
  <p>Using the header: <code>Authorization Bearer {token}</code></p>
  
  <p>That simply resulted in a <code>Invalid Credentials</code> response.</p>
  
  <p>A few questions:</p>
  
  <ul>
  <li>I'm not sure what the 'aud' should be when creating the JWT. I've seen examples where it's a url and also where it's the projectId. Neither work for me.</li>
  <li>One of the JSON API examples said the Authorization token should be an oauth token. Can I use a JWT instead or do I need to make a call using the JWT to get an access token?</li>
  <li>Is my bucket path correct? Is the base folder for the bucket path your projectId? Should my path be <code>/{projectId}/test</code>. I've tried both and neither work.</li>
  </ul>
  
  <p><strong>Recap</strong></p>
  
  <p>This is an IoT project and I need embedded devices to download files from Google Cloud Storage. I need to create a web portal to upload files to (using Firebase Functions) and pass to the device either a bucket path or a private/signed URL that. The bottom line being I need to access a Google Cloud Storage bucket using a service account key. If there is an embedded SDK - great, but I couldn't find one for C. My only thought was to use the JSON API. If there is a way I can sign a URL which can only be accessed using a service account - that works too.</p>
  
  <p>Thanks!</p>