#Payload Cloud + plugin-cloud-storage - How to use env vars without exposing them publicly?

1 messages · Page 1 of 1 (latest)

elder sapphire
#

I'm trying to setup the cloud-storage plugin with the GCS adapter in my Payload Cloud project.

It seems like the only way for me to pass my GCS credentials to payload is by using the PAYLOAD_PUBLIC_ prefix for my variables.
Isn't this bad though given that my credentials contain a private key and all? 🤔

Is there any other way to do it?

undone star
#

Have you seen the code in the dev folder of the repo here? https://github.com/payloadcms/plugin-cloud-storage/blob/master/dev/src/payload.config.ts#L47-L53

The PAYLOAD_PUBLIC_ prefix is only for environment variables you want to show up in the frontend, which, like you said, is not what you want.

GitHub

The official cloud storage plugin for Payload. Contribute to payloadcms/plugin-cloud-storage development by creating an account on GitHub.

elder sapphire
#

My apologies, I'm not super familiar with GCS and to make things even harder I have to ask colleagues with the proper access to generate keys and accounts and all when it comes to GC stuff, so that makes troubleshooting a bit tricky... All that to say, thank you for bearing with me. 😅

I was currently trying to use the options.crendentials like so:

options: {
  credentials: JSON.parse(process.env.GCS_CREDENTIALS)
}

passing it the stringified json key from my GCS service account, which look like this:

{
  "type": "service_account",
  "project_id": "xxxxxx",
  "private_key_id": "xxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----xxxxxx",
  "client_id": "xxxxxx",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxx"
}

but looking at the snippet you just shared, it doesn't look like this is how you're supposed to do it?

I'm a bit confused though because the plugin's readme example doesn't mention the apiEndpoint or projectId options that are being used in there. Did I miss something in the docs about that? Is that enough for authentication? 🤔

undone star
#

I think because our dev example works against a docker-compatible GCS implementation, there may be more things you'll need to pass.

#

If you open up that configuration body, it should give you some help

#

That being said, I don't see why what you're trying wouldn't work.

elder sapphire
elder sapphire
undone star
#

Yes, it should

#

PAYLOAD_PUBLIC_ only needed if you need the env var in the admin bundle

elder sapphire
#

Doesn't it need to be in the admin bundle in order for Payload to be able to use the gcs adapter in the cloud-storage plugin? 🤔
Sorry if I'm being dumb, I feel like I'm missing a major piece of the puzzle here. 😅

ornate orchid
#

Are you calling dotenv in this file?

elder sapphire
#

I... don't think so? 🤔
It's literally just the blank Payload template to which I've added a Media collection and the cloudStorage plugin:

import { buildConfig } from 'payload/config';
import path from 'path';
import Users from './collections/Users';
import { payloadCloud } from '@payloadcms/plugin-cloud';
import { gcsAdapter } from '@payloadcms/plugin-cloud-storage/gcs';
import { cloudStorage } from '@payloadcms/plugin-cloud-storage';
import Media from './collections/Media';

const adapter = gcsAdapter({
  options: {
    credentials: JSON.parse(process.env.GCS_CREDENTIALS)
  },
  bucket: process.env.GCS_BUCKET,
});

export default buildConfig({
  admin: {
    user: Users.slug,
  },
  collections: [
    Users,
    Media,
  ],
  typescript: {
    outputFile: path.resolve(__dirname, 'payload-types.ts'),
  },
  graphQL: {
    schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
  },
  plugins: [
    payloadCloud(),
    cloudStorage({
      collections: {
        'media': {
          adapter: adapter,
          disablePayloadAccessControl: true,
          prefix: 'media',
        },
      },
    }),
  ]
});
#

Uh, so it seem to be as simple as just checking whether the env var exists?

const adapter = gcsAdapter({
  options: {
    credentials: process.env.GCS_CREDENTIALS ? JSON.parse(process.env.GCS_CREDENTIALS) : null
  },
  bucket: process.env.GCS_BUCKET,
});

Which I guess kinda makes sense, it still runs on the server where the var exists, but prevent it from crashing in the client where it doesn't? 🤷‍♂️

elder sapphire
#

I wonder if we should update the examples in the plugin's readme? 🤔

undone star
#

Sure, we can do that. Did you get yours working?