简体   繁体   中英

Secure Service Account Credentials json key kotlin

So, I'm trying to get the Service Application Credentials on my localhost and I'm encountering some problems. I created and downloaded the json key and I want to secure them instead of letting them in plain text.

I want to know the best way to do this. I have this code:

fun getServiceAccountCredentials(
    pathToFallBackCredentialsFile: String
): ServiceAccountCredentials {
    return try {
        getApplicationDefault() as ServiceAccountCredentials
    } catch (e: IOException) {
        return ServiceAccountCredentials.fromStream(FileInputStream(pathToFallBackCredentialsFile))
    } catch (e: ClassCastException) {
        return ServiceAccountCredentials.fromStream(this::class.java.classLoader.getResourceAsStream(pathToFallBackCredentialsFile))
    }
}

The problem here is that my JSON file is exposed in plain text in my repository.

Options

  1. Encrypt them, then let the app decrypt them. However, if the decrypt key is in the same repository then you have only moved the problem to another place, albeit the someone needs someone to read/execute your code to obtain them.
  2. How is your app going to be running, eg inside a Docker container in something like Kube.netes or another app running in your data centre? If so then you pass the responsibility down the line to that app container manager to inject at startup-time the credentials (and other environment specifics), eg using some like Kube.netes Configuration Maps. We do this and keep the production config maps in a separate DevOps-only repository.
  3. There are specialist secrets management solutions for exactly this problem and your app calls out at run time to a secrets manager for the secrets it needs, eg https://www.hashicorp.com/products/vault or some custom to cloud vendor

I found a solution.

I activated the Secret Manager from GCP and I've added the JSON file there.

To take the secret in a java/kotlin application(without spring, if you have spring you can use "spring-cloud-gcp-starter-secretmanager"), I used the following piece of code.

fun accessSecretVersion(secretId: String?, versionId: String?): String {
    val googleCredentials = GoogleCredentials.getApplicationDefault() as UserCredentials
    val projectId = googleCredentials.quotaProjectId
    return getSecret(projectId, secretId, versionId)
}

fun getSecret(projectId: String?, secretId: String?, versionId: String?): String {
    SecretManagerServiceClient.create().use { client ->
        val secretVersionName = SecretVersionName.of(projectId, secretId, versionId)

        val response = client.accessSecretVersion(secretVersionName)

        return response.payload.data.toStringUtf8()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM