feat: add docker credentials script
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
../modules/datalad.nix
|
../modules/datalad.nix
|
||||||
|
../modules/docker.nix
|
||||||
../modules/dropbox.nix
|
../modules/dropbox.nix
|
||||||
../modules/fonts.nix
|
../modules/fonts.nix
|
||||||
../modules/ghostty.nix
|
../modules/ghostty.nix
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
docker-credential-helpers
|
||||||
|
pass
|
||||||
|
gnupg
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -51,3 +51,8 @@ capture-hardware name:
|
|||||||
hosts:
|
hosts:
|
||||||
@./scripts/list-hosts.py
|
@./scripts/list-hosts.py
|
||||||
|
|
||||||
|
# Seed ~/.docker/config.json and (for pass) set up the GPG key + pass store.
|
||||||
|
# Override store: just docker-creds secretservice
|
||||||
|
# Unprotected key: just docker-creds pass --no-passphrase
|
||||||
|
docker-creds store='pass' flag='':
|
||||||
|
@./scripts/docker-creds.sh "{{store}}" "{{flag}}"
|
||||||
|
|||||||
Executable
+85
@@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
store="${1:-pass}"
|
||||||
|
no_passphrase=0
|
||||||
|
[ "${2:-}" = "--no-passphrase" ] && no_passphrase=1
|
||||||
|
|
||||||
|
config_dir="$HOME/.docker"
|
||||||
|
config_file="$config_dir/config.json"
|
||||||
|
|
||||||
|
# Identity used for the dedicated docker-creds GPG key. Stable so re-runs
|
||||||
|
# are idempotent (we look the key up by this uid rather than guessing).
|
||||||
|
gpg_name="Docker Credential Store"
|
||||||
|
gpg_email="${USER}@$(hostname)"
|
||||||
|
gpg_uid="$gpg_name <$gpg_email>"
|
||||||
|
|
||||||
|
# --- credsStore in config.json (merge, never clobber auths) -------------
|
||||||
|
if ! command -v "docker-credential-$store" >/dev/null 2>&1; then
|
||||||
|
echo "warning: docker-credential-$store not found in PATH" >&2
|
||||||
|
echo " is docker-credential-helpers installed and the rebuild applied?" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$config_dir"
|
||||||
|
python3 - "$config_file" "$store" <<'PY'
|
||||||
|
import json, os, sys
|
||||||
|
path, store = sys.argv[1], sys.argv[2]
|
||||||
|
config = {}
|
||||||
|
if os.path.exists(path):
|
||||||
|
with open(path) as f:
|
||||||
|
try:
|
||||||
|
config = json.load(f)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
config = {}
|
||||||
|
config["credsStore"] = store
|
||||||
|
with open(path, "w") as f:
|
||||||
|
json.dump(config, f, indent=2)
|
||||||
|
f.write("\n")
|
||||||
|
PY
|
||||||
|
chmod u+w "$config_file"
|
||||||
|
echo "Set credsStore = \"$store\" in $config_file"
|
||||||
|
|
||||||
|
# The remaining steps only apply to the pass-backed store.
|
||||||
|
[ "$store" = "pass" ] || { echo "store is '$store'; skipping GPG/pass setup."; exit 0; }
|
||||||
|
|
||||||
|
# --- GPG key (generate only if our uid doesn't already have one) --------
|
||||||
|
if gpg --list-secret-keys "$gpg_uid" >/dev/null 2>&1; then
|
||||||
|
echo "GPG key for '$gpg_uid' already exists; skipping generation."
|
||||||
|
else
|
||||||
|
echo "Generating GPG key for '$gpg_uid'..."
|
||||||
|
protection="# (passphrase-protected; pinentry will prompt)"
|
||||||
|
if [ "$no_passphrase" -eq 1 ]; then
|
||||||
|
echo "warning: creating an UNPROTECTED key (--no-passphrase)." >&2
|
||||||
|
echo " anyone who can read ~/.gnupg can decrypt your registry creds." >&2
|
||||||
|
protection="%no-protection"
|
||||||
|
fi
|
||||||
|
gpg --batch --full-generate-key <<EOF
|
||||||
|
%echo Generating docker-credential key
|
||||||
|
Key-Type: eddsa
|
||||||
|
Key-Curve: ed25519
|
||||||
|
Subkey-Type: ecdh
|
||||||
|
Subkey-Curve: cv25519
|
||||||
|
Name-Real: $gpg_name
|
||||||
|
Name-Email: $gpg_email
|
||||||
|
Expire-Date: 0
|
||||||
|
$protection
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull the fingerprint back out for pass.
|
||||||
|
fpr="$(gpg --list-secret-keys --with-colons "$gpg_uid" \
|
||||||
|
| awk -F: '/^fpr:/ {print $10; exit}')"
|
||||||
|
[ -n "$fpr" ] || { echo "error: could not determine GPG fingerprint" >&2; exit 1; }
|
||||||
|
|
||||||
|
# --- pass init (only if the store isn't already initialized) ------------
|
||||||
|
store_dir="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
|
||||||
|
if [ -f "$store_dir/.gpg-id" ]; then
|
||||||
|
echo "pass already initialized at $store_dir; skipping init."
|
||||||
|
else
|
||||||
|
pass init "$fpr"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Done. Remaining manual step: docker login"
|
||||||
Reference in New Issue
Block a user