It's now time to get LGTM to post issues and comments as one of the "characters". To do this, LGTM's game core loop will use the GitHub API to interact with github, and to do that, it needs to be able to authenticate as a user account, which means generating a token.
Eventually, I may have several tokens being used, one for each character account. These need to be kept secure to avoid accidental exposure, and since this is an open-source project, I can't just leave them in a file (which you shouldn't do anyway).
Fortunately there are solutions to this - Secrets Management services, which are basically like password managers for code. They can be used to programatically store and retrieve secrets, and in some cases might be so automated that a human never has to see the password nor have access to it!
In the production systems I use at work, our infrastructure usually does this - when a database gets set up, a password is automatically randomly generated, and stored in a secrets management system. No human is involved in that process, so the password is never seen by human eyes. In fact it's entirely possible to configure that system to lock humans out!
Reading secrets from GCP Secrets Manager
Google Cloud has a simple secrets manager that suits our purposes. It's accessible via API/SDK and it uses the same IAM and authentication that already protects our other stuff, so it'll take very minimal setup. The Python SDK for it is google-cloud-secret-manager
and it's extremely easy to use, something like:
from google.cloud import secretmanager
secret_client = secretmanager.SecretManagerServiceClient()
def fetch_secret(secret_name: str) -> str:
secret_path = f"projects/{GCP_PROJECT_ID}/secrets/{secret_name}/versions/latest"
secret = secret_client.access_secret_version(request=dict(name=secret_path))
return secret.payload.data.decode()
Where GCP_PROJECT_ID
is the project's ID, which I'm providing from ENV already. Like most Google SDKs, this will read the service account credential from ENV, which I have set up already for firebase access.
I just need to add an additional IAM permission to the service accounts I'm using: Secret Manager Secret Accessor
Writing secrets
While it's common to programatically create these secrets, in my case, I will be creating them by hand, because unless I programatically register accounts on GitHub (something you can't do), I have to grant a script somewhere access to a GitHub account, and if I have to do that, I might as well go generate the token and save the secret manually as well.
To do that, I go into GitHub's personal access tokens page, and generate a new token with the scopes that I want:
I selected repo:status
as I need to read commits; public_repo
as these accounts will own their own forks of the repo in order to make PRs from; repo:invite
in case in the future I need characters to invite people to their repos; and notifications
which may become a key in how to hit GitHub's API less in the future (using the notifications to detect when there are replies from the player rather than polling every Issue for replies every few minutes)
Now I can go over to Secret Manager settings and register a new secret:
Now the code, whenever it is running in an environment where a valid GCP credential is stored (and I have this set up already in my local machine, as well as on Github CI, and of course in production, it can fetch these secrets, without me having to maintain a big set of env vars to do it
Top comments (0)