Standalone (no-dependencies beyond Python) script fetches SSH keys of GitHub repository contributors and generates SOPS-compatible SSH key files.
Project description
This script enables one to use github as a trusted public key distribution mechanism. SOPS enables git as a secret vault.
Why?
I needed github-to-sops to make SOPS easier to use for my https://deepstructure.io and https://chatcraft.org projects.
This makes it easy to setup SOPS as a lightweight gitops alternative to AWS Secrets Manager, AWS KMS, Hashicorp Vault.
SOPS is helpful to avoid the push-and-pray (https://dagger.io/ came up with this term and solution for it) pattern where all secrets for github actions are stored in Github Secrets such that nobody can repro stuff locally. With sops one can give github actions a single age private key and share all the development keys with rest of team on equal footing with CI/CD env.
Requirements
- Python3
- pip
- https://github.com/Mic92/ssh-to-age/ (until the SOPS ssh backend lands).
Installation
The latest version of github-to-sops can be cloned locally or installed using pip:
pip install github-to-sops
Implementation
This generates a nice .sops.yaml file with comments indicating where the keys came from to make key rotation easier.
Idea for this originated in https://github.com/tarasglek/chatcraft.org/pull/319 after I got sick of devising a secure secret distribution scheme for every small project.
Contributions Welcome
- Tests
- Binary build for python-less environments
- Would be nice to add is ACLs and an integrity check to keys being used.
Examples:
I wrote an indepth explanation and screencasts on my blog post introducing github-to-sops.
Example workflow for secrets with github
generate keys
./github-to-sops --github-url https://github.com/tarasglek/chatcraft.org --key-types ssh-ed25519 --format sops > .sops.yaml
lets see
cat .sops.yaml
creation_rules:
- key_groups:
- age:
- age19j4d6v9j7rx5fs629fu387qz4zmlpsqjexa4s08tkfrrmfdl5cwqjlaupd # humphd
- age13runq29jhy9kfpaegczrzttykerswh0qprq59msgd754yermtfmsa3hwg2 # tarasglek
Put a sample secret in yaml
echo -e "secrets:\n SECRET_KEY: dontlook" | sops --input-type yaml --output-type yaml -e /dev/stdin > secrets.enc.yaml
Lets take a peek
head -n 9 secrets.enc.yaml
secrets:
SECRET_KEY: ENC[AES256_GCM,data:MKKR6B0h1iA=,iv:KegjC62NQxich1dtodVF3aVnchf/fB+KQbtETh+4CaY=,tag:2+5mk4YMKKxLqaCOpZVNSA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age19j4d6v9j7rx5fs629fu387qz4zmlpsqjexa4s08tkfrrmfdl5cwqjlaupd
^ is safe to commit!
Decrypting secrets using ssh keys
export SOPS_AGE_KEY=$(ssh-to-age -private-key < ~/.ssh/id_ed25519)
Lets extract our secret in a way that's useful for automation
sops --extract '["secrets"]["SECRET_KEY"]' -d secrets.env.yaml
dontlook
sops -i secrets.env.yaml
is useful for interactive editing.
Bulk-updating secrets+keys when someone is added/removed from project
First command pulls the latest set of keys from people in github, the second re-encrypts. Note you need to be able to decrypt keys yourself using sops -d
command above as a prereq.
fdfind -H .sops.yaml$|xargs -n1 github-to-sops --local-github-checkout . --key-types ssh-ed25519 --inplace-edit
fdfind enc.yaml|xargs -n1 sops updatekeys -y
Misc Examples
Generate keys from a local github checkout and add ssh hosts to it:
# note you can also make a "custom" known_hosts with ssh-keyscan 192.168.1.1 > /tmp/known_hosts
./github-to-sops --local-github-checkout . --format sops --known-hosts ~/.ssh/known_hosts --key-types ssh-ed25519
creation_rules:
- key_groups:
- age:
- age13runq29jhy9kfpaegczrzttykerswh0qprq59msgd754yermtfmsa3hwg2 # tarasglek
- age120ld5rvtsuavnlexa2kc7eahrg8egf4gwg22t0q44rcu2z3xegrq4364t4 # 192.168.1.1
For generating ssh authorized_keys:
./github-to-sops --github-url https://github.com/tarasglek/chatcraft.org --format authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIedvn21UgBc1VcasThd+/U84Xfkrw+Ox5RIxufs5tJP humphd
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDzJmAWAOp6fQGs/+v1PT+0dgzG7XHwhJnvF+tL5TwJx tarasglek
Usage:
./github-to-sops -h
usage: github-to-sops [-h] [--github-url GITHUB_URL | --local-github-checkout LOCAL_GITHUB_CHECKOUT] [--known-hosts KNOWN_HOSTS] [--github-users GITHUB_USERS] [--key-types KEY_TYPES] [--format {authorized_keys,ssh-to-age,sops}]
Fetch SSH keys of GitHub repository contributors or specified github users and output that info into a useful format like sops or ssh authorized_keys
options:
-h, --help show this help message and exit
--github-url GITHUB_URL
GitHub repository URL.
--local-github-checkout LOCAL_GITHUB_CHECKOUT
Path to local Git repository.
--known-hosts KNOWN_HOSTS
Path to ssh known hosts to also fetch keys from
--github-users GITHUB_USERS
Comma-separated list of GitHub usernames to fetch keys for.
--key-types KEY_TYPES
Comma-separated types of SSH keys to fetch (e.g., ssh-ed25519,ssh-rsa). Pass no value for all types.
--format {authorized_keys,ssh-to-age,sops,json}
Output/convert keys using the specified format. Supported formats: authorized_keys, ssh-to-age, sops. For example, use '--format ssh-to-age' to convert SSH keys to age keys.
Example invocations: `./github-to-sops --github-url https://github.com/tarasglek/chatcraft.org --key-types ssh-ed25519 --format sops` `./github-to-sops --github-url https://github.com/tarasglek/chatcraft.org --format authorized_keys` `./github-to-sops --local-github-
checkout . --format sops --known-hosts ~/.ssh/known_hosts --key-types ssh-ed25519`
Env vars:
- GITHUB_TOKEN: optional github token which helps avoid rate limiting.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for github_to_sops-1.1.7-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 73a2084dd2f9f187ed23ec1263e398b11ffa41d5b22603cc0b1bb71cae8388c3 |
|
MD5 | 8cbdc13c2fbaec0289476bcf77192823 |
|
BLAKE2b-256 | 2e88676d05ee74910e821e95ac0e4eec3715818d968e7de91757525e5f889b72 |