Setting a secret in JSON format

Hi there,

I’m trying to set the following secret for my app, which is a JSON token:

GCP_AUTH={
  "auth_provider_x509_cert_url"="https://www.googleapis.com/oauth2/v1/certs",
  "auth_uri"="https://accounts.google.com/o/oauth2/auth",
  "client_email"="xxx@xxx",
  "client_id"="xxx",
  "client_x509_cert_url"="https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxxxx",
  "private_key"="-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
  "private_key_id"="xxxxxxxxxxxxx",
  "project_id"="xxx",
  "token_uri"="https://oauth2.googleapis.com/token",
  "type"="service_account"
}

Two questions:

  • How should I format it: escape special characters, remove newlines? It seems like the hash of secrets is different if I do SOME_SECRET=abcd or SOME_SECRET="abcd".
  • Should I set this with fly secrets set GCP_AUTH=... or fly secrets import?

Thanks!

Edit: I’ve tried to escape it with single quotes and got a (Jason.DecodeError) unexpected byte at position 33: 0x3D ("=")... error:

({application_start_failure,goth,{{shutdown,{failed_to_start_child,'Elixir.Goth.Config',{#{'__exception__' => true,'__struct__' => 'Elixir.Jason.DecodeError',data => <<"{\n  \"auth_provider_x509_cert_url\"=\"https://www.googleapis.com/oauth2/v1/certs\",\n  \"auth_uri\"=\"https://accounts.google.com/o/oauth2/auth\",\n  \"client_email\"=\"xxx\",\n  \"client_id\"=\"xxxxxx\",\n
...

Hey @fdeage, I typically run the GCP credentials json file through base64 before setting it as a secret and in my application, I’ll decode it as base64 before using it.

I think the CLI also has a flag for setting a secret from a file.

2 Likes

Thanks @JP_Phillips ! By creating a JSON file I also realized I was using = instead of : in my file :slight_smile:

Same.

First I download the service account JSON from Google Cloud.

Then convert it to base64 in the terminal with:

base64 ./credentials.json > credentials.base64

Add the base64 string to the .env file or Fly secrets.

Then in Node:

const buffer = Buffer.from(process.env.BASE_64, 'base64');

const storage = new Storage({
	credentials: JSON.parse(buffer.toString('ascii'))
});
3 Likes

Thanks, this worked great for me. Is there any consideration when using this method vs using the various methods in the Google docs?

Not sure what Google Docs you’re looking at, but most of what I’ve seen is when running stuff on Google Cloud. When running on Fly (or any other provider) you’re basically on your own.

When running on GC their SDKs look for an en var to automatically add the credentials. Took me a while to figure out you can manually pass a JSON string.

I mean I like your solution just wondering. I found the Google Docs somewhat overwhelming with the amount of differnent ways to authenticate, so I didn’t really understand best practice when not on GCP.