Skip to content

Instantly share code, notes, and snippets.

@wshayes
Created April 14, 2020 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wshayes/9a8fa6e928c00f15da6f26b9688c7092 to your computer and use it in GitHub Desktop.
Save wshayes/9a8fa6e928c00f15da6f26b9688c7092 to your computer and use it in GitHub Desktop.
[Github Actions Secrets Mgmt] Update github secrets for all repos in a github org
token: <Github Personal Access token with github actions/secrets scopes>
username: <github username>
globals:
- name: <secret_name>
value: <value>
description: <description>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import yaml
from typing import List
import httpx
import base64
import nacl.public
import nacl.encoding
SECRETS_FN = "/Users/william/.config/github/biodati_secrets.yaml"
GITHUB_ROOT = "https://api.github.com"
ORG = "biodati"
with open(SECRETS_FN, "r") as f:
SECRETS = yaml.load(f, Loader=yaml.SafeLoader)
client = httpx.Client(auth=(SECRETS["username"], SECRETS["token"]))
def get_repos(org: str) -> List[str]:
"""Get repositories for org"""
r = client.get(f"{GITHUB_ROOT}/orgs/{org}/repos")
results = r.json()
repos = [repo["name"] for repo in results]
return repos
def get_public_key(org: str, repo: str) -> str:
"""Get Public key needed to encrypt secrets"""
r = client.get(f"{GITHUB_ROOT}/repos/{org}/{repo}/actions/secrets/public-key")
results = r.json()
return {"key": results["key"], "id": results["key_id"]}
def encrypt(public_key: str, secret_value: str) -> str:
"""Encrypt a Unicode string using the public key."""
public_key = nacl.public.PublicKey(public_key.encode("utf-8"), nacl.encoding.Base64Encoder())
sealed_box = nacl.public.SealedBox(public_key)
encrypted = sealed_box.encrypt(secret_value.encode("utf-8"))
return base64.b64encode(encrypted).decode("utf-8")
def update_globals(org):
repos = get_repos(org)
public_keys = {}
for repo in repos:
public_keys[repo] = get_public_key(org, repo)
for repo in repos:
public_key = public_keys[repo]["key"]
public_key_id = public_keys[repo]["id"]
for secret in SECRETS["globals"]:
name = secret["name"]
encrypted = encrypt(public_key, secret["value"])
payload = {"encrypted_value": encrypted, "key_id": public_key_id}
r = client.put(f"{GITHUB_ROOT}/repos/{org}/{repo}/actions/secrets/{name}", json=payload)
print(f"Status: {r.status_code} Repo: {repo} Name: {name}")
if r.status_code != 200:
print(r.text)
def main():
update_globals(ORG)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment