Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7ae8cfec2 |
+1
-3
@@ -1,3 +1 @@
|
|||||||
AGENTS.md
|
AGENTS.md
|
||||||
*.dec
|
|
||||||
keys.txt
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
keys:
|
|
||||||
- &admin_finn age1a0v442ct2qfjcdhyktn25spw02yq4fl08plrrvuradwwxzsle4mq8thln4
|
|
||||||
- &host_mibook age1n3uqtee5ymykrls6k04dznq50cwmj99hw7ny83yxjndt4y2ncf5qhjwa2p
|
|
||||||
# - &host_jupiter age1... # TODO: Phase 9, see docs/secrets.md
|
|
||||||
|
|
||||||
creation_rules:
|
|
||||||
- path_regex: ^secrets/mibook\.yaml$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin_finn
|
|
||||||
- *host_mibook
|
|
||||||
# - path_regex: ^secrets/jupiter\.yaml$ # TODO: Phase 9
|
|
||||||
# key_groups:
|
|
||||||
# - age: [ *admin_finn, *host_jupiter ]
|
|
||||||
# - path_regex: ^secrets/common\.yaml$ # TODO: Phase 9
|
|
||||||
# key_groups:
|
|
||||||
# - age: [ *admin_finn, *host_mibook, *host_jupiter ]
|
|
||||||
@@ -35,7 +35,6 @@ flake.nix
|
|||||||
│ ├── core.nix # system packages, locale, timezone
|
│ ├── core.nix # system packages, locale, timezone
|
||||||
│ ├── network.nix
|
│ ├── network.nix
|
||||||
│ ├── nix.nix
|
│ ├── nix.nix
|
||||||
│ ├── sops.nix # sops-nix decryption config, sops/age/ssh-to-age on PATH
|
|
||||||
│ └── users.nix
|
│ └── users.nix
|
||||||
├── modules/ # custom NixOS option modules (my.profiles.*, my.hardware.*, my.services.*)
|
├── modules/ # custom NixOS option modules (my.profiles.*, my.hardware.*, my.services.*)
|
||||||
│ ├── environments/ # per-service/app profiles
|
│ ├── environments/ # per-service/app profiles
|
||||||
@@ -44,21 +43,10 @@ flake.nix
|
|||||||
└── machines/<name>/
|
└── machines/<name>/
|
||||||
├── configuration.nix # machine-specific NixOS settings
|
├── configuration.nix # machine-specific NixOS settings
|
||||||
├── environments.nix # enables profiles via my.profiles.* / my.hardware.* options
|
├── environments.nix # enables profiles via my.profiles.* / my.hardware.* options
|
||||||
├── secrets.nix # sops.secrets declared for this host
|
|
||||||
├── disks.nix
|
├── disks.nix
|
||||||
└── hardware-configuration.nix
|
└── hardware-configuration.nix
|
||||||
```
|
```
|
||||||
|
|
||||||
### Secrets (sops-nix)
|
|
||||||
|
|
||||||
Secrets are encrypted with sops, decrypted per-host from that host's SSH host
|
|
||||||
key. `.sops.yaml` defines who can decrypt what; `secrets/<host>.yaml` holds
|
|
||||||
the encrypted values; `machines/<host>/secrets.nix` declares which secrets
|
|
||||||
that host exposes and consumes them via `config.sops.secrets.<name>.path`.
|
|
||||||
Always `git add` a secrets file before `nix build` — untracked files are
|
|
||||||
invisible to flake evaluation. Full workflow (adding a secret, adding a host,
|
|
||||||
rotating keys): see [`docs/secrets.md`](docs/secrets.md).
|
|
||||||
|
|
||||||
### Profile / Module Pattern
|
### Profile / Module Pattern
|
||||||
|
|
||||||
Every module under `modules/` follows the same structure:
|
Every module under `modules/` follows the same structure:
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
# Secrets (sops-nix)
|
|
||||||
|
|
||||||
Secrets are encrypted with [sops](https://github.com/getsops/sops) and decrypted
|
|
||||||
at activation by [sops-nix](https://github.com/Mic92/sops-nix). Each host decrypts
|
|
||||||
with its own SSH host key (converted to an age key in-memory — no separate host
|
|
||||||
private key is ever stored on disk).
|
|
||||||
|
|
||||||
Tooling (`sops`, `age`, `ssh-to-age`) is available via `nix develop` in this repo,
|
|
||||||
and installed system-wide on every machine via `machines/core/sops.nix`.
|
|
||||||
|
|
||||||
## Adding a secret to an existing host
|
|
||||||
|
|
||||||
```
|
|
||||||
nix develop -c sops secrets/<host>.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
This opens `$EDITOR` on the decrypted content. Add your key, save, quit — sops
|
|
||||||
re-encrypts on write. Then declare it in `machines/<host>/secrets.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
sops.secrets.my-secret = {
|
|
||||||
owner = "someuser"; # defaults to root
|
|
||||||
group = "someuser";
|
|
||||||
mode = "0400";
|
|
||||||
restartUnits = [ "foo.service" ]; # if a running service needs to pick it up
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Consume it in the owning module as `config.sops.secrets.my-secret.path`
|
|
||||||
(resolves to `/run/secrets/my-secret`) — never inline the decrypted value into
|
|
||||||
a Nix string, since that copies it into the world-readable `/nix/store`.
|
|
||||||
|
|
||||||
Then:
|
|
||||||
|
|
||||||
```
|
|
||||||
nix build '.#nixosConfigurations.<host>.config.system.build.toplevel'
|
|
||||||
sudo nixos-rebuild test --flake '.#<host>'
|
|
||||||
# verify, then:
|
|
||||||
sudo nixos-rebuild switch --flake '.#<host>'
|
|
||||||
```
|
|
||||||
|
|
||||||
**The secrets file must be `git add`ed before `nix build`** — untracked files
|
|
||||||
are invisible to flake evaluation, and `sops.validateSopsFiles` needs it in the
|
|
||||||
Nix store.
|
|
||||||
|
|
||||||
## Adding a new host
|
|
||||||
|
|
||||||
1. On the new host: `ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub` to get its
|
|
||||||
age public key.
|
|
||||||
2. In `.sops.yaml`: add a `&host_<name>` anchor with that key, and a
|
|
||||||
`creation_rules` entry for `secrets/<name>.yaml` including both the new
|
|
||||||
host key and `*admin_finn`.
|
|
||||||
3. Create `machines/<name>/secrets.nix`, add it to that machine's
|
|
||||||
`configuration.nix` imports.
|
|
||||||
4. If the host needs to read an existing shared file, run
|
|
||||||
`sops updatekeys secrets/<file>.yaml` after step 2 so it's re-encrypted to
|
|
||||||
include the new recipient.
|
|
||||||
|
|
||||||
## Rotating keys
|
|
||||||
|
|
||||||
```
|
|
||||||
# after editing .sops.yaml (new/removed recipient):
|
|
||||||
nix develop -c sops updatekeys secrets/<file>.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
for every file the change affects. `updatekeys` requires you to already be
|
|
||||||
able to decrypt the file — this is why `*admin_finn` is a recipient on every
|
|
||||||
rule, as the standing fallback.
|
|
||||||
|
|
||||||
Reinstalling a host regenerates its SSH host key, which changes its age
|
|
||||||
identity. Any file previously encrypted to that host must be `updatekeys`'d
|
|
||||||
with the new key, or the host's next activation fails to decrypt.
|
|
||||||
|
|
||||||
## Where private keys live
|
|
||||||
|
|
||||||
- **Operator** (you): `~/.config/sops/age/keys.txt` — sops' default lookup
|
|
||||||
path, so `SOPS_AGE_KEY_FILE` never needs to be set. Never committed. Back
|
|
||||||
this up out-of-band (password manager, offline copy) — if it's lost, only
|
|
||||||
the surviving host keys can still decrypt their own files, and any file that
|
|
||||||
was only ever readable by an operator-only rule becomes permanently
|
|
||||||
unreadable.
|
|
||||||
- **Hosts**: `/etc/ssh/ssh_host_ed25519_key` — already managed by NixOS,
|
|
||||||
converted to age in-memory at activation time. Nothing extra to back up.
|
|
||||||
|
|
||||||
## Layout
|
|
||||||
|
|
||||||
```
|
|
||||||
.sops.yaml # age recipients + creation rules (which keys can decrypt which files)
|
|
||||||
secrets/<host>.yaml # per-host encrypted secrets (default sopsFile for that host)
|
|
||||||
machines/core/sops.nix # applied to every machine: decryption config, sops/age/ssh-to-age on PATH
|
|
||||||
machines/<host>/secrets.nix # per-host: which secrets exist, owner/group/mode
|
|
||||||
```
|
|
||||||
Generated
+1
-22
@@ -264,28 +264,7 @@
|
|||||||
"nixos-generators": "nixos-generators",
|
"nixos-generators": "nixos-generators",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"nixpkgs": "nixpkgs_3",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
"sops-nix": "sops-nix"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sops-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1788337237,
|
|
||||||
"narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,10 +11,6 @@
|
|||||||
url = "github:nix-community/nixos-generators";
|
url = "github:nix-community/nixos-generators";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
sops-nix = {
|
|
||||||
url = "github:Mic92/sops-nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,15 +36,6 @@
|
|||||||
_module.args.pkgs = import inputs.nixpkgs {
|
_module.args.pkgs = import inputs.nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
packages = with pkgs; [
|
|
||||||
sops
|
|
||||||
age
|
|
||||||
ssh-to-age
|
|
||||||
nixfmt
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
systems = [ "x86_64-linux" ];
|
systems = [ "x86_64-linux" ];
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ let
|
|||||||
nixpkgs
|
nixpkgs
|
||||||
nixpkgs-unstable
|
nixpkgs-unstable
|
||||||
nixos-hardware
|
nixos-hardware
|
||||||
sops-nix
|
|
||||||
#hyprland
|
#hyprland
|
||||||
;
|
;
|
||||||
nixosSystem = nixpkgs.lib.makeOverridable nixpkgs.lib.nixosSystem;
|
nixosSystem = nixpkgs.lib.makeOverridable nixpkgs.lib.nixosSystem;
|
||||||
@@ -41,7 +40,6 @@ let
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
../modules
|
../modules
|
||||||
sops-nix.nixosModules.sops
|
|
||||||
# ../profiles
|
# ../profiles
|
||||||
];
|
];
|
||||||
defaultModules = baseModules ++ customModules;
|
defaultModules = baseModules ++ customModules;
|
||||||
|
|||||||
@@ -3,6 +3,5 @@
|
|||||||
./modules.nix
|
./modules.nix
|
||||||
./network.nix
|
./network.nix
|
||||||
./nix.nix
|
./nix.nix
|
||||||
./sops.nix
|
|
||||||
./users.nix
|
./users.nix
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
# sops-nix plumbing — applied to every machine.
|
|
||||||
# See docs/secrets.md for the day-to-day workflow.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
# Each host defaults to its own secrets/<hostname>.yaml. Override per-secret
|
|
||||||
# with sops.secrets.<name>.sopsFile for shared files.
|
|
||||||
sops.defaultSopsFile = lib.mkDefault (../../secrets + "/${config.networking.hostName}.yaml");
|
|
||||||
sops.defaultSopsFormat = "yaml";
|
|
||||||
sops.validateSopsFiles = true;
|
|
||||||
|
|
||||||
# Decrypt with the host's own SSH host key, converted to age.
|
|
||||||
# Explicit rather than inheriting the openssh-derived default, so this does
|
|
||||||
# not silently break if services.openssh is ever disabled.
|
|
||||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
|
||||||
sops.age.generateKey = false;
|
|
||||||
|
|
||||||
# Age only. The default here is the RSA host key imported as a GPG key,
|
|
||||||
# which is deprecated and an extra failure surface.
|
|
||||||
sops.gnupg.sshKeyPaths = [ ];
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
sops
|
|
||||||
age
|
|
||||||
ssh-to-age
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
# enabled profiles
|
# enabled profiles
|
||||||
_: {
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
secrets = config.sops.secrets;
|
||||||
|
in
|
||||||
|
{
|
||||||
my.profiles = {
|
my.profiles = {
|
||||||
hyprland.enable = false;
|
hyprland.enable = false;
|
||||||
zsh.enable = true;
|
zsh.enable = true;
|
||||||
@@ -18,6 +22,7 @@ _: {
|
|||||||
jellyfin.enable = true;
|
jellyfin.enable = true;
|
||||||
jellyseerr.enable = true;
|
jellyseerr.enable = true;
|
||||||
immich.enable = true;
|
immich.enable = true;
|
||||||
|
newsreader.enable = true;
|
||||||
development.enable = true;
|
development.enable = true;
|
||||||
home-assistant.enable = true;
|
home-assistant.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./environments.nix
|
./environments.nix
|
||||||
./network.nix
|
./network.nix
|
||||||
./secrets.nix
|
|
||||||
# ./system.nix use docker here
|
# ./system.nix use docker here
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -22,6 +21,7 @@
|
|||||||
useOSProber = true;
|
useOSProber = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Configure keymap in X11
|
# Configure keymap in X11
|
||||||
services.xserver.xkb = {
|
services.xserver.xkb = {
|
||||||
layout = "de";
|
layout = "de";
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
|
||||||
hardware.nvidia.prime = {
|
hardware.nvidia.prime = {
|
||||||
sync.enable = false;
|
sync.enable = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# enabled profiles
|
# enabled profiles
|
||||||
_: {
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
secrets = config.sops.secrets;
|
||||||
|
in
|
||||||
|
{
|
||||||
my.profiles = {
|
my.profiles = {
|
||||||
kde-desktop.enable = true;
|
kde-desktop.enable = true;
|
||||||
zsh.enable = true;
|
zsh.enable = true;
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# Secrets decrypted on mibook. sopsFile defaults to secrets/mibook.yaml
|
|
||||||
# via machines/core/sops.nix.
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Pipeline smoke test — proves host-key decryption works end to end.
|
|
||||||
# Safe to delete once a real secret is in place.
|
|
||||||
sops.secrets.placeholder = {
|
|
||||||
mode = "0400";
|
|
||||||
owner = "root";
|
|
||||||
group = "root";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -20,5 +20,6 @@
|
|||||||
./jellyfin
|
./jellyfin
|
||||||
./jellyseerr
|
./jellyseerr
|
||||||
./immich
|
./immich
|
||||||
|
./newsreader
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# X (Twitter) news reader: RSSHub feed bridge + Miniflux reader
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.my.profiles.newsreader;
|
||||||
|
hostName = config.networking.hostName;
|
||||||
|
|
||||||
|
# RSSHub only ever talks to Miniflux on the same host, so it stays on
|
||||||
|
# loopback and out of the firewall.
|
||||||
|
rsshubPort = 1200;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.my.profiles.newsreader = with lib; {
|
||||||
|
enable = mkEnableOption "RSSHub + Miniflux news reader";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 8085; # 8080 is taken by aria on jupiter
|
||||||
|
description = "Port Miniflux listens on.";
|
||||||
|
};
|
||||||
|
|
||||||
|
rsshubSecretFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/secrets/rsshub.env";
|
||||||
|
description = ''
|
||||||
|
EnvironmentFile holding RSSHub's X session, in the form
|
||||||
|
|
||||||
|
```
|
||||||
|
TWITTER_AUTH_TOKEN=<auth_token cookie>,<optional second cookie>
|
||||||
|
```
|
||||||
|
|
||||||
|
X removed guest access, so the bridge needs a logged-in session: copy
|
||||||
|
the `auth_token` cookie from a burner account and close the tab without
|
||||||
|
logging out, since logging out invalidates it. Listing several cookies
|
||||||
|
gives RSSHub rotation headroom when one gets suspended.
|
||||||
|
|
||||||
|
Create this file by hand, root-owned and chmod 600 — it must not end up
|
||||||
|
in the Nix store.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
minifluxSecretFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/secrets/miniflux.env";
|
||||||
|
description = ''
|
||||||
|
EnvironmentFile holding the Miniflux admin account:
|
||||||
|
|
||||||
|
```
|
||||||
|
ADMIN_USERNAME=finn
|
||||||
|
ADMIN_PASSWORD=<at least 6 characters>
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# Turns X accounts, lists and keyword searches into RSS. Feed URLs look
|
||||||
|
# like http://127.0.0.1:1200/twitter/user/<handle>, /twitter/list/<id> or
|
||||||
|
# /twitter/keyword/<query>.
|
||||||
|
services.rsshub = {
|
||||||
|
enable = true;
|
||||||
|
redis.enable = true;
|
||||||
|
secretFiles = [ cfg.rsshubSecretFile ];
|
||||||
|
settings = {
|
||||||
|
PORT = rsshubPort;
|
||||||
|
LISTEN_INADDR_ANY = false;
|
||||||
|
# X throttles aggressively and answers with an empty 200 rather than an
|
||||||
|
# error, so cache for an hour and keep retries low.
|
||||||
|
CACHE_EXPIRE = "3600";
|
||||||
|
REQUEST_RETRY = "3";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.miniflux = {
|
||||||
|
enable = true;
|
||||||
|
adminCredentialsFile = cfg.minifluxSecretFile;
|
||||||
|
config = {
|
||||||
|
LISTEN_ADDR = "0.0.0.0:${toString cfg.port}";
|
||||||
|
BASE_URL = "http://${hostName}:${toString cfg.port}/";
|
||||||
|
CREATE_ADMIN = 1;
|
||||||
|
# Minutes. Matched to RSSHub's cache; polling harder just burns the
|
||||||
|
# X session for nothing.
|
||||||
|
POLLING_FREQUENCY = 60;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
|
my.homepage.services = [
|
||||||
|
{
|
||||||
|
group = "Services";
|
||||||
|
name = "Miniflux";
|
||||||
|
description = "RSS reader";
|
||||||
|
href = "http://${hostName}:${toString cfg.port}";
|
||||||
|
icon = "miniflux.png";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
placeholder: ENC[AES256_GCM,data:tji/6di1F2GsD60TEBGAVvZR9m4jxQ8=,iv:BoBQVR735vq38iGx40VHIpk185ylf79mKmnpewcq/+o=,tag:lXNNk4/HYB0sw44KaQ2KYg==,type:str]
|
|
||||||
sops:
|
|
||||||
age:
|
|
||||||
- enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4ZUk5cjhGTlVveUFRdHdS
|
|
||||||
elpVV0pZVU54U3plYjNBai9ZZVBxTDhyRFFnCmpGWW81VGJoMnd4eWxCWnovQnFF
|
|
||||||
WXR1MVBTZ3VRUnNMUjI5Rko4NHpBdjQKLS0tIDkxYWNxTmhUS2dYTkFnTWZXaS9V
|
|
||||||
ejdtSmF2M1ZVdFNiWENMWlNraUYxVzAKdlz4xLhTKjJfFESDcym2xCOa71rXj6BE
|
|
||||||
mdeaCDhE11CAXqrpKU+j0/kwTsZRzyqlwQsfeI4ratu1K1vY66ONsw==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
recipient: age1a0v442ct2qfjcdhyktn25spw02yq4fl08plrrvuradwwxzsle4mq8thln4
|
|
||||||
- enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYT1hRSGt6TDRSMklQNDA3
|
|
||||||
Z2lYS2pMRWxxeEtGRGJSeXRDSlY5UTFBNEZvCm5RK0huT282MXpwWjdrTHByY3Ev
|
|
||||||
bTBMczR1MzVEcnNDVUxadlREbGg3UUUKLS0tIHhydUlmRExkbmNNNkVTcW1OSnpZ
|
|
||||||
aEtLZkRTRE9GZ0I1bEN0ZEl3RjVMeDgKoCY7NyxFMS+WuBUez2Irf91Xuy9QpM5g
|
|
||||||
RTmhK6mw2wd8oUMdgPOUESNwh1xkCz4hDHPrDQnfd4sPhSAvh28jwg==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
recipient: age1n3uqtee5ymykrls6k04dznq50cwmj99hw7ny83yxjndt4y2ncf5qhjwa2p
|
|
||||||
lastmodified: "2026-09-08T13:29:12Z"
|
|
||||||
mac: ENC[AES256_GCM,data:YjMMIUdfCl8dkuvtvBZTFIhLwsUjI6iSeN929O4igbwpRTyGVxgLmAMl81YYHJSyEibelT7ZBKiuVVnL2KjLvAKTj3H1O+AQrcAEJDPC9NwPJwbtAIpLl2li5060Kdj4kr8AY+UJ2kHycuS9dg6wPZTLBJcM/YCw0AoVftvzryM=,iv:GEQZF9RvW+MJlMIjn1ToD74RubWMQtCyE5LqW9KQQfA=,tag:NR6u88eBY1asQZM6f45hTw==,type:str]
|
|
||||||
unencrypted_suffix: _unencrypted
|
|
||||||
version: 3.13.3
|
|
||||||
Reference in New Issue
Block a user