0

I'm trying to setup the Azure Face recognition container, but wondering how to use a k8 secret as a Docker command "argument."

This works, but I need to replace the ApiKey with my k8 secret.

{
  "kind": "Deployment",
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "name": "azure-face",
            "args": [
              "Eula=accept",
              "Billing=https://microsoft.com",
              "ApiKey=123"
            ]
          }
        ]
      }
    }
  }
}

Create secret like this:

kubectl create secret generic azure-api-key --from-literal=azure-api-key="123"

Tried changing the container args like this but it doesn't work - arugment is not passed as expected: (also tried other variations like ApiKey=${AZURE_API_KEY})

    "containers": [
      {
        "args": [
          "Eula=accept",
          "Billing=https://microsoft.com",
          "ApiKey=$AZURE_API_KEY"
        ],
        "env": [
          {
            "name": "AZURE_API_KEY",
            "valueFrom": {
              "secretKeyRef": {
                "name": "azure-api-key",
                "key": "azure-api-key"
              }
            }
          }
        ]
      }
    ]

Also did docker exec and from inside container verified that:

$ echo $AZURE_API_KEY
$ 123
Charlie
  • 2,004
  • 6
  • 20
  • 40
  • This works as expected right? You pass the API key as an environment variable, which is then passed as an arg to your program. This is also suggested in the Kubernetes docs (see: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#use-environment-variables-to-define-arguments) – Blokje5 May 24 '19 at 14:46
  • Replacing the env var does not work - updated the question to try and clarify – Charlie May 24 '19 at 15:21

2 Answers2

1

Looks like this was the issue thanks to @Blokje5:

Note: The environment variable appears in parentheses, "$(VAR)". This is required for the variable to be expanded in the command or args field.

I had tried ${VAR} not $(VAR).

Charlie
  • 2,004
  • 6
  • 20
  • 40
0

Using an environment variable for sensitive information like an API key is not necessarily the best practice. It's an open argue what is better, but I personally believe using files is better mainly because it's common to collect env vars for logging purposes etc.

So instead, I would mount the secret as file and read it in the command line, something like API_KEY=$(cat api_key.txt). I think this should work but need verification. Usually, there is support for configuration files in most images provided those days - so I would first look into this, e.g. if Azure Face recognition supports a configuration file.

Final note, if you're looking to read more about Kubernetes secrets and how to manage them on Git, check out this blog post (full disclosure: I'm the author) which covers all the different options to manage Kubernetes secrets securely.

Omer Levi Hevroni
  • 1,935
  • 1
  • 15
  • 33
  • Doesn't really matter where you store the password when it's being used on the command line – Matt May 27 '19 at 06:54
  • It's an open debate - it's still an environment variable. And it might be even worse when running a container you don't know what it does or if it log env vars... – Omer Levi Hevroni May 27 '19 at 17:01
  • Storing sensitive data in a file or an env var for the application to read from is debatable. Writing sensitive data to the process command line leaks the information on most linux systems (that aren't hardened against it). MS shouldn't set up the ApiKey argument like this. – Matt May 27 '19 at 23:39
  • Sorry, misread you :) I guess this also debatable - how can you leak this argument? If it required access to the host - well, a compromised Kubernetes node is a very serious situation and your container has compromised no matter what :) – Omer Levi Hevroni May 28 '19 at 05:04
  • Command line arguments are written world readable to to the `/proc` file system. The proc ps tools make this easily browsable. Not everyone maintains systems where the only users are root users. Monitoring systems also like to trawl this information. – Matt May 29 '19 at 23:12
  • Yep, but my point is - if someone can read /proc (assuming this requires root), that person can (probably) read any other file on the machine - so you can't really protect from this threat. – Omer Levi Hevroni May 30 '19 at 05:24
  • 1
    It doesn't require root access, the `cmdline` files are world readable (without the additional hardening on /proc) – Matt May 30 '19 at 05:32
  • Oh, that worst than what I was thinking :( Thanks, I've learned something new. – Omer Levi Hevroni Jun 03 '19 at 08:53