A partial archive of https://discourse-mediawiki.wmflabs.org as of Saturday May 21, 2022.

Setting PHP environment variables in Kubernetes on Toolforge

Smith609

I’m working on a bot that runs as a webservice on Toolforge, using Kubernetes in order to access php5.6.

The bot’s PHP code looks to environment variables for secrets (such as oAuth and API keys).

As I’m not familiar with this setup, I wonder whether anyone could recommend the best way to set environment variables within the webservice such that I do not inadvertently expose the raw text?

Thanks.

Smith609

What I’ve tried so far:

Kubernetes is configured using ~/.kube/config, which is a read-only file. chmod o+w .kube/config returns Operation not permitted.

kubectl set env TEST=value returns a help message indicating that set env is not an available command.

Setting the env var KUBECONFIG=.kube.config.file before launching kube, or within the kube environment, seems to have no effect on env vars, or on the output of kubectl config view. (.kube.config.file contains:

{
    "env": [
        {
            "name": "TEST",
            "value": "Working"
        }
    ]
}

kubectl config set current-context .kube.config.file gives
open /data/project/citations-dev/.kube/config: operation not permitted

I’ve created a .bashrc file, following https://askubuntu.com/questions/58814/how-do-i-add-environment-variables, to no avail.

I eventually added .profile as a symbolic link to .bashrc, which adds environment variables to a shell session, but not, it seems, to the live webserver (which I restarted by running webservice stopwebservice start) by which users access the bot interface.

Chicocvenancio

Hey @Smith609, I believe we talked a bit about this in IRC.

In theory, the full kubernetes API is available and you could in fact set environment variables (see https://wikitech.wikimedia.org/wiki/Help:Toolforge/Kubernetes#Kubernetes_continuous_jobs ) , however this is not the easiest path to achieve your goal in my view.

The more traditional approach to handling secrets is to leave them in a configuration file in a standard format (json, yaml, ini, etc) and use application code to load it when needed. Then the config file can be kept secure by file permissions and the secrets be left out of the code.

I don’t usually code in php, so I’ll leave for a more experienced PHP developer to provide an example.

Smith609

Thanks @Chicocvenancio. The reason I came to a dead end with the configuration file approach is that I couldn’t work out how to make such a file available to Travis CI servers without making it publicly readable. Environment variables seemed to be the answer to this issue.

LucasWerkmeisterWMDE

Do you really need to give Travis CI the real secrets of your bot? That sounds like a bad idea to me (but I’m not familiar with what your bot does).

Smith609

Travis gets given its own special secrets, logging it in to separate accounts that are linked to Travis IPs and are restricted to what’s needed for testing, to minimize damage caused if they are exposed.

Without using secrets it’s not possible to access the APIs that drive the bot (which adds missing data to citations on Wikipedia by consulting external databases such as CrossRef).

bd808

One thing you could try is a pattern that I have used in the Wikimania Scholarships application:

  • main application PHP code expects to get data from environment variables
  • application entry point also looks for local configuration file(s) and loads the settings they contain into the environment

This gives a bit of a best of both worlds approach for 12-factor style applications. The core application stays decoupled from the configuration mechanism. The entry point helps handle differences between runtime environments (dev, test, prod).

Example: