sops: prioritize SOPS_AGE_KEY_FILE over local key
... instead of loading both keys and raise an error This is important for testing when one wants to override SOPS_AGE_KEY_FILE New prio: `SOPS_AGE_KEY` > `SOPS_AGE_KEY_FILE` > `~/.config/sops/age/keys.txt`
This commit is contained in:
@@ -20,7 +20,7 @@ log = logging.getLogger(__name__)
|
|||||||
def generate_key() -> sops.SopsKey:
|
def generate_key() -> sops.SopsKey:
|
||||||
key = maybe_get_admin_public_key()
|
key = maybe_get_admin_public_key()
|
||||||
if key is not None:
|
if key is not None:
|
||||||
print(f"{key.key_type.name} key {key.pubkey} is already set")
|
print(f"{key.key_type.name} key {key.pubkey} is already set", file=sys.stderr)
|
||||||
return key
|
return key
|
||||||
|
|
||||||
path = default_admin_private_key_path()
|
path = default_admin_private_key_path()
|
||||||
@@ -34,8 +34,11 @@ def generate_key() -> sops.SopsKey:
|
|||||||
def generate_command(args: argparse.Namespace) -> None:
|
def generate_command(args: argparse.Namespace) -> None:
|
||||||
key = generate_key()
|
key = generate_key()
|
||||||
key_type = key.key_type.name.lower()
|
key_type = key.key_type.name.lower()
|
||||||
print(f"Add your {key_type} public key to the repository with:")
|
print(f"Add your {key_type} public key to the repository with:", file=sys.stderr)
|
||||||
print(f"clan secrets users add <username> --{key_type}-key {key.pubkey}")
|
print(
|
||||||
|
f"clan secrets users add <username> --{key_type}-key {key.pubkey}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def show_command(args: argparse.Namespace) -> None:
|
def show_command(args: argparse.Namespace) -> None:
|
||||||
|
|||||||
@@ -50,17 +50,6 @@ class KeyType(enum.Enum):
|
|||||||
keyring: list[str] = []
|
keyring: list[str] = []
|
||||||
|
|
||||||
if self == self.AGE:
|
if self == self.AGE:
|
||||||
if keys := os.environ.get("SOPS_AGE_KEY"):
|
|
||||||
# SOPS_AGE_KEY is fed into age.ParseIdentities by Sops, and
|
|
||||||
# reads identities line by line. See age/keysource.go in
|
|
||||||
# Sops, and age/parse.go in Age.
|
|
||||||
for private_key in keys.strip().splitlines():
|
|
||||||
public_key = get_public_age_key(private_key)
|
|
||||||
log.info(
|
|
||||||
f"Found age public key from a private key "
|
|
||||||
f"in the environment (SOPS_AGE_KEY): {public_key}"
|
|
||||||
)
|
|
||||||
keyring.append(public_key)
|
|
||||||
|
|
||||||
def maybe_read_from_path(key_path: Path) -> None:
|
def maybe_read_from_path(key_path: Path) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -78,10 +67,23 @@ class KeyType(enum.Enum):
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
log.warning(f"Could not read age keys from {key_path}", exc_info=ex)
|
log.warning(f"Could not read age keys from {key_path}", exc_info=ex)
|
||||||
|
|
||||||
|
if keys := os.environ.get("SOPS_AGE_KEY"):
|
||||||
|
# SOPS_AGE_KEY is fed into age.ParseIdentities by Sops, and
|
||||||
|
# reads identities line by line. See age/keysource.go in
|
||||||
|
# Sops, and age/parse.go in Age.
|
||||||
|
for private_key in keys.strip().splitlines():
|
||||||
|
public_key = get_public_age_key(private_key)
|
||||||
|
log.info(
|
||||||
|
f"Found age public key from a private key "
|
||||||
|
f"in the environment (SOPS_AGE_KEY): {public_key}"
|
||||||
|
)
|
||||||
|
keyring.append(public_key)
|
||||||
|
|
||||||
# Sops will try every location, see age/keysource.go
|
# Sops will try every location, see age/keysource.go
|
||||||
if key_path := os.environ.get("SOPS_AGE_KEY_FILE"):
|
elif key_path := os.environ.get("SOPS_AGE_KEY_FILE"):
|
||||||
maybe_read_from_path(Path(key_path))
|
maybe_read_from_path(Path(key_path))
|
||||||
maybe_read_from_path(user_config_dir() / "sops/age/keys.txt")
|
else:
|
||||||
|
maybe_read_from_path(user_config_dir() / "sops/age/keys.txt")
|
||||||
|
|
||||||
return keyring
|
return keyring
|
||||||
|
|
||||||
|
|||||||
@@ -754,7 +754,7 @@ def test_secrets_key_generate_gpg(
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
assert "age private key" not in output.out
|
assert "age private key" not in output.out
|
||||||
assert re.match(r"PGP key.+is already set", output.out) is not None
|
assert re.match(r"PGP key.+is already set", output.err) is not None
|
||||||
|
|
||||||
with capture_output as output:
|
with capture_output as output:
|
||||||
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
||||||
|
|||||||
Reference in New Issue
Block a user