question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide access keys used for a SSL connection

See original GitHub issue

I would like to use a ssl protected db with my application, which is deployed on Zeit Now. I am not sure how to get my p12 and my .pem file into the serverless function though.

I fount this issue: https://github.com/zeit/now/issues/749 , but I think it’s not possible that way, since we can’t combine env vars

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

14reactions
danhollickcommented, Jun 21, 2020

Just posting here to bump this back up the priority level.

This was quite a pain to hack around and will be a problem for almost anyone needing to use Prisma in production with a serverless environment.

I am using CloudSQL with SSL from Google Cloud for my database and Vercel (like OP) for my deployment provider. This is how I hacked around it for now:

I store both the server-ca.pem and client-identity.p12 in ENV variables (this gets tricky with the .p12 file and requires some base64 encoding) and then before the Prisma client is initialised I write them to the /tmp folder which is available to vercel deployments:

import { tmpdir } from 'os'
import fs from 'fs'

    fs.writeFile(
      `${tmpdir()}/server-ca.pem`,
      process.env.CLIENT_CERTIFICATE,
      err => {
        if (err) return console.log(err)
      }
    )

  fs.writeFile(
      `${tmpdir()}/client-identity.p12`,
      process.env.CLIENT_IDENTITY,
      //important to re-encode it correctly
      'base64',
      err => {
        if (err) return console.log(err)
      }
    )
...
global.prisma = new PrismaClient()

Then my database url for production looks like :

postgresql://USER:XXX@DBCONNECTION?&sslmode=require&sslaccept=accept_invalid_certs&sslidentity=/tmp/client-identity.p12&sslpassword=XXX&sslcert=/tmp/server-ca.pem

NOTE: Once you have encoded the client-identity.p12 into base64 it will exceed the size limit for ENVs in Vercel so you need to follow the guide mentioned here to encrypt it and then decrypt it before writing the file to disk.

For completeness here is my context.js where I initialise the Prisma client:

import { PrismaClient } from '@prisma/client'
import { tmpdir } from 'os'
import fs from 'fs'
import crypto from 'crypto'
// nextjs dev server reloads files on page navigation, so new Prisma Clients were being spawned everytime
let prisma

if (!global.prisma) {
  if (process.env.NODE_ENV !== 'development') {
    fs.writeFile(
      `${tmpdir()}/server-ca.pem`,
      process.env.CLIENT_CERTIFICATE,
      err => {
        if (err) return console.log(err)
      }
    )

    const algorithm = 'aes-128-cbc'
    const decipher = crypto.createDecipheriv(
      algorithm,
      process.env.CLIENT_IDENTITY_KEY,
      process.env.CLIENT_IDENTITY_IV
    )

    const getDecryptedSecret = () => {
      let decrypted = decipher.update(
        process.env.ENCRYPTED_CLIENT_IDENTITY,
        'base64',
        'utf8'
      )
      decrypted += decipher.final('utf8')
      return decrypted
    }

    fs.writeFile(
      `${tmpdir()}/client-identity.p12`,
      getDecryptedSecret(),
      'base64',
      err => {
        if (err) return console.log(err)
      }
    )
  }
  global.prisma = new PrismaClient({})
}

prisma = global.prisma

export default prisma
4reactions
matthewmuellercommented, Jan 11, 2021

Composing your .env is doable now. We didn’t implement it in the schema, but instead support .env template expansion: https://www.prisma.io/docs/concepts/components/prisma-schema#accessing-environment-variables-from-the-schema

So in your .env file:

SSL_CA="./path/to/ca.crt"
DATABASE_URL="postgresql://user:xxx@host?&sslmode=require&sslcert=${SERVER_CA}"

Then in production you can load a different .env or do it programmatically as @pantharshit00 suggested.


For the other part of the issue of accepting a certificate’s content as an environment variable. We probably won’t support this workflow directly, but recommend using the workaround @danhollick suggested. The main reason is that it’s easy enough to create a library in userland for handling this and environment variables have size limits.

If we get burned by /tmp not being writable in some serverless environment or enough people want this feature, we may revisit.


Closing, but happy to re-open if this workflow doesn’t work for you. Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How an SSL connection is established - IBM
An SSL connection is established though a handshake (a series of communications exchanges) between the client and the server.
Read more >
Private And Public Keys - SSL.com
The SSL/TLS protocol uses a pair of keys – one private, one public – to authenticate, secure and manage secure connections. These keys...
Read more >
What you need to know about Private Key in SSL and Code ...
Your private key is the single most important component of your SSL certificate. It's what gives you the power to authenticate your website...
Read more >
What is an RSA key used for? - SSL Certificates - Namecheap
RSA key is a private key based on RSA algorithm. Private Key is used for authentication and a symmetric key exchange during establishment...
Read more >
SSL and SSL Certificates Explained For Beginners
Secure Sockets Layer (SSL) and Transport Layer security (TLS ) are protocols that provide secure communications over a computer network or ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found