use sops for secret management

This commit is contained in:
Seaswimmer 2024-12-02 20:50:24 -05:00
parent 6eeea660f0
commit cd820411c4
Signed by: cswimr
GPG key ID: 0EC431A8DA8F8087
9 changed files with 95 additions and 25 deletions

9
.sops.yaml Normal file
View file

@ -0,0 +1,9 @@
keys:
- &cswimr age1q9f9zhkfjn2c3a8qtmfqh0rtls3542jukqpt7t93jca6hc947f3sm9ujhx
- &eclipse age184ude6fyak8z4nnndq4nzcpe2d89zxf3r4paty7j2tenkwa6zgtqrz60lq
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- age:
- *cswimr
- *eclipse

View file

@ -1,7 +0,0 @@
keys:
- $eclipse age1q9f9zhkfjn2c3a8qtmfqh0rtls3542jukqpt7t93jca6hc947f3sm9ujhx
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini|sops)$
key_groups:
- age:
- *eclipse

View file

@ -532,9 +532,30 @@
"nixpkgs": "nixpkgs_3",
"nixvim": "nixvim",
"plasma-manager": "plasma-manager",
"sops-nix": "sops-nix",
"zen-browser": "zen-browser"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1733128155,
"narHash": "sha256-m6/qwJAJYcidGMEdLqjKzRIjapK4nUfMq7rDCTmZajc=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "c6134b6fff6bda95a1ac872a2a9d5f32e3c37856",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,

View file

@ -11,6 +11,10 @@
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-flatpak.url = "github:gmodena/nix-flatpak";
nixvim = {
url = "github:nix-community/nixvim";
@ -44,6 +48,7 @@
inherit pkgs;
system = system;
hostname = "eclipse";
user = user;
};
modules = [
# imports
@ -60,6 +65,7 @@
./nixos/nvim.nix
./nixos/pkg.nix
./nixos/shell.nix
./nixos/sops.nix
./nixos/sudo.nix
./nixos/symlinks.nix
./nixos/tailscale.nix
@ -69,6 +75,7 @@
hardware.bluetooth.enable = true;
}
inputs.sops-nix.nixosModules.sops
inputs.nixvim.nixosModules.nixvim
inputs.nix-flatpak.nixosModules.nix-flatpak

13
nixos/sops.nix Normal file
View file

@ -0,0 +1,13 @@
{ user, ... }:
{
sops = {
defaultSopsFile = ../secrets/secrets.yaml;
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
secrets = {
"zipline" = {
owner = user;
path = "/home/${user}/.secrets/zipline";
};
};
};
}

View file

@ -13,6 +13,8 @@ def notify(
icon: Path | None = None,
desktop_entry: str | None = None,
) -> None:
if not which("notify-send"):
raise FileNotFoundError("notify-send is not installed.")
args = ["notify-send", "-a", application_name, "-u", urgency]
if category:
args.append("-c")
@ -21,6 +23,8 @@ def notify(
args.append("-i")
args.append(str(icon))
if desktop_entry:
if not does_desktop_entry_exist(desktop_entry=desktop_entry):
raise FileNotFoundError("Desktop entry does not exist.")
args.append("-h")
args.append(f"string:desktop-entry:{desktop_entry}")
args.append(title)
@ -29,12 +33,15 @@ def notify(
subprocess.run(args)
def read_secret_file(secret: str) -> str:
path = f"/var/secrets/{secret}"
def read_secret_file(secret: str, home: bool = False) -> str:
if home:
path = os.path.expanduser(f"~/.secrets/{secret}")
else:
path = f"/var/secrets/{secret}"
if not os.path.exists(path):
raise FileNotFoundError(f"Secret file {path} does not exist or cannot be read.")
with open(f"/var/secrets/{secret}", "r") as f:
secret = f.read().strip()
with open(file=path, mode="r") as secret_file:
secret = secret_file.read().strip()
if not secret:
raise ValueError(f"Secret file {path} is empty.")
return secret

View file

@ -60,7 +60,7 @@ def spectacle_screenshot(
try:
opts = [
"zipline.py",
"/etc/nixos/scripts/py/zipline.py",
file_path,
"--application-name",
"Spectacle",

View file

@ -5,12 +5,10 @@ import argparse
import mimetypes
import os
from pathlib import Path
from shutil import which
from typing import Any
import requests # type: ignore
from common.common import ( # type: ignore
does_desktop_entry_exist,
notify,
read_secret_file,
)
@ -23,19 +21,11 @@ def zipline(
application_name: str | None = None,
desktop_entry: str | None = None,
) -> Any:
token = read_secret_file("zipline")
token = read_secret_file(secret="zipline", home=True)
if not os.path.isfile(file_path):
raise FileNotFoundError(f"File at {file_path} does not exist.")
use_notify_send = False
if application_name and desktop_entry:
if not does_desktop_entry_exist(desktop_entry=desktop_entry):
raise FileNotFoundError("Desktop entry does not exist.")
if not which("notify-send"):
raise FileNotFoundError("notify-send is not installed.")
use_notify_send = True
content_type = mimetypes.guess_type(file_path)[0] or "application/octet-stream"
try:
@ -55,7 +45,7 @@ def zipline(
copy(text=link)
print(f"Link copied to clipboard: {link}")
if use_notify_send:
if application_name and desktop_entry:
notify(
application_name=application_name,
title="Upload Successful",
@ -71,7 +61,7 @@ def zipline(
raise Exception(error_message)
except BaseException as e:
if use_notify_send:
if application_name and desktop_entry:
notify(
application_name=application_name,
title="Upload Failed",

30
secrets/secrets.yaml Normal file
View file

@ -0,0 +1,30 @@
zipline: ENC[AES256_GCM,data:YQMdw1cJy9wFnJsX6fPWBXK0rPEnuJJwJysVh0vggcnySFjl5Dmolaqxhw==,iv:RKB+rNz76ZxqzmyATLcpHmaap1f6aWWm7smBTieMZ8M=,tag:GN967VhwqZwMA6uzshKBmQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1q9f9zhkfjn2c3a8qtmfqh0rtls3542jukqpt7t93jca6hc947f3sm9ujhx
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBabXF4b2dBelo1THZHOG9u
UWxNaEMwTlErTU1ZYmhISnVubXBBY3JaZkFjClFpblNFeWtwN0hrOGVTdThaQzFE
R0lqS2lYcDBWck9Pb3dmTk1yRS9rNFUKLS0tIFRUaUx2QlRmb0NFRlV3RndYbUpn
RHlURzRGL0grRFRDVGlVMTNpMlU5eUkKWzoCPqrcJBqM0H+Ap0v5Jsf69y7xV9gA
d9ubH84yMrOjLPs/K2FmLm+0zr7/epGE02nceiGzgWDHczQGp7qhzA==
-----END AGE ENCRYPTED FILE-----
- recipient: age184ude6fyak8z4nnndq4nzcpe2d89zxf3r4paty7j2tenkwa6zgtqrz60lq
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1ZVdIRkMzMjErTjRpSC82
Rk04SmxVM3FiUys1VVViUmhQTkJKTW1MSjNNClg2KzA1M3lXTjVqVm52aXlxNDE1
cHl0VDB1MCtpdnVabStZRkoxQjlHQmcKLS0tIGs5WTZMUFNKcU5qQXVqUjFNTGVF
b1JvNi9YODZPN1FObWpOVHN3aU85NFEK1dN5pV8g3nG3D2l482z1JCRzmJ/9m495
YEobjXbEqQDhvA47ueWojoMjvQ3CgrPyiL6v+DLj7VfI5cyuo+89IQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-12-03T01:29:28Z"
mac: ENC[AES256_GCM,data:NzE6V3kb9hiA9WAs7GFK5GqFoOUP5U/EOskWq0qdCo6GMewkK8TqrY+lFgjkEhY39PobgVTICBT8MGhY9eiEINYdBl7DuQGb3cR/puV+iCPEgUemzVcmcGkd24ktzUO2DsWet1EFC84oOu50XzYfR9VqW3z7+7UbpzWuOxIdvAA=,iv:pxNCxKPevqg8QxsIfL6+2pEB5cUmKhmLhmdiO+nB/Ac=,tag:uFA84z0XjzNgp3NLBu8AfQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1