Standalone (no-dependencies beyond Python) script fetches SSH keys of GitHub repository contributors and generates SOPS-compatible SSH key files.
Project description
github-to-sops integrates SOPS with github team/user identities. Use sops + github instead of having to operate Hashicorp Vault, AWS Secret Manager or just stuffing everything into github action secrets, or fighting with GPG.
Why?
I think SOPS is the simplest way to manage secrets for team and individual projects, especially when combined with github as a key distribution mechanism.
This script 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
Installation
This tool has two parts that need to be installed: github-to-sops
itself, and sops
.
Step 1: Install github-to-sops
The preferred way to install github-to-sops
is with uv
, a fast Python package installer:
uv pip install github-to-sops
As an alternative to installing, uv
can also run github-to-sops
directly. For example:
uv run github-to-sops -- import-keys > .sops.yaml
Step 2: Install sops
After installing github-to-sops
, you need to install sops
.
On Mac or Linux, github-to-sops
provides a helper command to install sops
for you:
github-to-sops install
For other platforms or for manual installation, please see the official sops installation guide.
Development Setup
For development on a local checkout, use uv
to create a virtual environment and install in editable mode.
This avoids externally-managed-environment
errors on modern OSes.
Create and activate a virtual environment:
uv venv
source .venv/bin/activate
Then install in editable mode:
uv pip install -e .
Alternative: pip Installation
If you prefer not to use uv
, you can install github-to-sops
using pip
:
pip install github-to-sops
Implementation
github-to-sops generates and maintains .sops.yaml file with comments indicating where the keys came from. Has refresh-secrets command to pull new secrets and re-encrypt files.
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.
Env vars:
- GITHUB_TOKEN: optional github token which helps avoid rate limiting.
I tried to make the code work without github tokens, but github requires them for private repos and does aggressive rate-limiting without them. See github docs on how to obtain GITHUB_TOKEN https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
Example workflow for secrets with github
Import all public keys for contributors from an existing github project
github-to-sops import-keys > .sops.yaml
of if your repo isn't published to github or you aren't working inside a git checkout
github-to-sops import-keys --github-url https://github.com/tarasglek/chatcraft.org
lets see
cat .sops.yaml
creation_rules:
- key_groups:
- age:
# Generated by `github-to-sops import-keys` https://github.com/tarasglek/github-to-sops
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG... user1@host # user1
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ... user2@host # user2
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!
sops -i secrets.enc.yaml
is useful for interactive editing.
Bulk-updating secrets+keys when someone is added/removed from project
github-to-sops refresh-secrets
Usage:
github-to-sops -h
usage: github-to-sops [-h] [--version] [--github-users GITHUB_USERS]
{install,refresh-secrets,import-keys} ...
Manage GitHub SSH keys and generate SOPS-compatible SSH key files.
options:
-h, --help show this help message and exit
--version show program's version number and exit
--github-users GITHUB_USERS
Comma-separated list of GitHub usernames to fetch keys
for. This is a global option that can be used with
import-keys and refresh-secrets.
Commands:
{install,refresh-secrets,import-keys}
install Install sops binary for supported platforms (Linux and
Mac).
refresh-secrets Find all .sops.yaml files in the repo that are
managed by git and run `import-keys --inplace-edit
.sops.yaml` on them. Can be combined with
--github-users.
import-keys Import SSH keys of GitHub repository contributors or
specified github users and output that info into a
useful format like sops or ssh authorized_keys
Example invocations:
- `github-to-sops import-keys --github-url https://github.com/tarasglek/chatcraft.org --key-types ssh-ed25519 --format sops`
- `github-to-sops import-keys --github-url https://github.com/tarasglek/chatcraft.org --format authorized_keys`
- `github-to-sops import-keys --local-github-checkout . --format sops --key-types ssh-ed25519`
- `github-to-sops refresh-secrets`
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
File details
Details for the file github_to_sops-2.0.0.tar.gz
.
File metadata
- Download URL: github_to_sops-2.0.0.tar.gz
- Upload date:
- Size: 13.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
b4a8ae3fd53ec925c351b6b96d278576f46991b9a180c858ba505d15e05e7f8c
|
|
MD5 |
35e7501fcaf3eba0a2b372b3c736602b
|
|
BLAKE2b-256 |
cd1e244f12ce31f616545f1b9050c9b4547a71a4af9a26662e5d1376bc31bf72
|
Provenance
The following attestation bundles were made for github_to_sops-2.0.0.tar.gz
:
Publisher:
publish.yml
on tarasglek/github-to-sops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
github_to_sops-2.0.0.tar.gz
-
Subject digest:
b4a8ae3fd53ec925c351b6b96d278576f46991b9a180c858ba505d15e05e7f8c
- Sigstore transparency entry: 264353610
- Sigstore integration time:
-
Permalink:
tarasglek/github-to-sops@b366e95a813e8444b5fd591e5e9a5d16bf8ac665
-
Branch / Tag:
refs/heads/main
- Owner: https://github.com/tarasglek
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@b366e95a813e8444b5fd591e5e9a5d16bf8ac665
-
Trigger Event:
push
-
Statement type:
File details
Details for the file github_to_sops-2.0.0-py3-none-any.whl
.
File metadata
- Download URL: github_to_sops-2.0.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
71b8ff17b2d065a0a0a80cdc0e6dcff12e1bc0341b6681542b8ca6baa12695c0
|
|
MD5 |
0f9309cf673390015b8f305570941ec6
|
|
BLAKE2b-256 |
670fafa0a248d8d37236ee2583a6329863ba82d2f0eb17740599010d87ba5614
|
Provenance
The following attestation bundles were made for github_to_sops-2.0.0-py3-none-any.whl
:
Publisher:
publish.yml
on tarasglek/github-to-sops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
github_to_sops-2.0.0-py3-none-any.whl
-
Subject digest:
71b8ff17b2d065a0a0a80cdc0e6dcff12e1bc0341b6681542b8ca6baa12695c0
- Sigstore transparency entry: 264353611
- Sigstore integration time:
-
Permalink:
tarasglek/github-to-sops@b366e95a813e8444b5fd591e5e9a5d16bf8ac665
-
Branch / Tag:
refs/heads/main
- Owner: https://github.com/tarasglek
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@b366e95a813e8444b5fd591e5e9a5d16bf8ac665
-
Trigger Event:
push
-
Statement type: