Split org-api secrets into auth password and SSH key
- Auth password uses env file format for systemd EnvironmentFile - SSH key is mounted as a file at /secrets/ssh_key in container - Fixes multi-line SSH key parsing issue in environment files - Update codex PR patch hash Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -228,7 +228,7 @@
|
|||||||
defaultConfigurationParams =
|
defaultConfigurationParams =
|
||||||
builtins.listToAttrs (map mkConfigurationParams machineFilenames);
|
builtins.listToAttrs (map mkConfigurationParams machineFilenames);
|
||||||
# Build org-agenda-api container for a given system
|
# Build org-agenda-api container for a given system
|
||||||
mkOrgAgendaApiContainer = system: let
|
mkOrgAgendaApiContainerInfo = system: let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
orgApiRev = builtins.substring 0 7 (org-agenda-api.rev or "unknown");
|
orgApiRev = builtins.substring 0 7 (org-agenda-api.rev or "unknown");
|
||||||
dotfilesRev = builtins.substring 0 7 (self.rev or self.dirtyRev or "dirty");
|
dotfilesRev = builtins.substring 0 7 (self.rev or self.dirtyRev or "dirty");
|
||||||
@@ -239,7 +239,11 @@
|
|||||||
containerLib = import ../org-agenda-api/container.nix {
|
containerLib = import ../org-agenda-api/container.nix {
|
||||||
inherit pkgs system tangledConfig org-agenda-api orgApiRev dotfilesRev;
|
inherit pkgs system tangledConfig org-agenda-api orgApiRev dotfilesRev;
|
||||||
};
|
};
|
||||||
in containerLib.containers.colonelpanic;
|
tag = "colonelpanic-${orgApiRev}-${dotfilesRev}";
|
||||||
|
in {
|
||||||
|
imageFile = containerLib.containers.colonelpanic;
|
||||||
|
imageName = "org-agenda-api:${tag}";
|
||||||
|
};
|
||||||
|
|
||||||
customParams = {
|
customParams = {
|
||||||
biskcomp = {
|
biskcomp = {
|
||||||
@@ -249,8 +253,11 @@
|
|||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
};
|
};
|
||||||
railbird-sf = {
|
railbird-sf = {
|
||||||
specialArgs = {
|
specialArgs = let
|
||||||
orgAgendaApiContainer = mkOrgAgendaApiContainer "x86_64-linux";
|
containerInfo = mkOrgAgendaApiContainerInfo "x86_64-linux";
|
||||||
|
in {
|
||||||
|
orgAgendaApiContainer = containerInfo.imageFile;
|
||||||
|
orgAgendaApiImageName = containerInfo.imageName;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, lib, pkgs, forEachUser, inputs, orgAgendaApiContainer ? null, ... }:
|
{ config, lib, pkgs, forEachUser, inputs, orgAgendaApiContainer ? null, orgAgendaApiImageName ? "org-agenda-api", ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../configuration.nix
|
../configuration.nix
|
||||||
@@ -8,17 +8,22 @@
|
|||||||
networking.hostName = "railbird-sf";
|
networking.hostName = "railbird-sf";
|
||||||
|
|
||||||
# org-agenda-api hosting with nginx + Let's Encrypt
|
# org-agenda-api hosting with nginx + Let's Encrypt
|
||||||
age.secrets.org-api-env = {
|
# Separate secrets for org-agenda-api: auth password (env format) and SSH key (raw file)
|
||||||
file = ../secrets/org-api-passwords.age;
|
age.secrets.org-api-auth-password = {
|
||||||
# Readable by the podman container service
|
file = ../secrets/org-api-auth-password.age;
|
||||||
|
};
|
||||||
|
age.secrets.org-api-ssh-key = {
|
||||||
|
file = ../secrets/org-api-ssh-key.age;
|
||||||
|
mode = "0400"; # Restrictive permissions for SSH key
|
||||||
};
|
};
|
||||||
|
|
||||||
services.org-agenda-api-host = {
|
services.org-agenda-api-host = {
|
||||||
enable = true;
|
enable = true;
|
||||||
domain = "rbsf.tplinkdns.com";
|
domain = "rbsf.tplinkdns.com";
|
||||||
containerImage = "colonelpanic-org-agenda-api";
|
containerImage = orgAgendaApiImageName;
|
||||||
containerImageFile = orgAgendaApiContainer;
|
containerImageFile = orgAgendaApiContainer;
|
||||||
secretsFile = config.age.secrets.org-api-env.path;
|
secretsFile = config.age.secrets.org-api-auth-password.path;
|
||||||
|
sshKeyFile = config.age.secrets.org-api-ssh-key.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
hardware.enableRedistributableFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ in
|
|||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "rbsf.tplinkdns.com";
|
default = "rbsf.tplinkdns.com";
|
||||||
description = "Domain name for the service (used for Let's Encrypt)";
|
description = "Base domain name (service will be at org-agenda-api.<domain>)";
|
||||||
};
|
};
|
||||||
|
|
||||||
acmeEmail = mkOption {
|
acmeEmail = mkOption {
|
||||||
@@ -62,7 +62,13 @@ in
|
|||||||
|
|
||||||
secretsFile = mkOption {
|
secretsFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = "Path to agenix-decrypted secrets file containing AUTH_PASSWORD and GIT_SSH_PRIVATE_KEY";
|
description = "Path to agenix-decrypted secrets file containing AUTH_PASSWORD";
|
||||||
|
};
|
||||||
|
|
||||||
|
sshKeyFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = "Path to agenix-decrypted SSH private key file (mounted at /secrets/ssh_key in container)";
|
||||||
};
|
};
|
||||||
|
|
||||||
timezone = mkOption {
|
timezone = mkOption {
|
||||||
@@ -87,7 +93,7 @@ in
|
|||||||
recommendedOptimisation = true;
|
recommendedOptimisation = true;
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
|
|
||||||
virtualHosts.${cfg.domain} = {
|
virtualHosts."org-agenda-api.${cfg.domain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
@@ -120,6 +126,9 @@ in
|
|||||||
AUTH_USER = cfg.authUser;
|
AUTH_USER = cfg.authUser;
|
||||||
};
|
};
|
||||||
environmentFiles = [ cfg.secretsFile ];
|
environmentFiles = [ cfg.secretsFile ];
|
||||||
|
volumes = lib.optionals (cfg.sshKeyFile != null) [
|
||||||
|
"${cfg.sshKeyFile}:/secrets/ssh_key:ro"
|
||||||
|
];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
"--pull=never" # Image is from nix store, don't try to pull
|
"--pull=never" # Image is from nix store, don't try to pull
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ in
|
|||||||
"discourse-secret-key-base.age".publicKeys = keys.hostKeys;
|
"discourse-secret-key-base.age".publicKeys = keys.hostKeys;
|
||||||
"vaultwarden-environment-file.age".publicKeys = keys.hostKeys;
|
"vaultwarden-environment-file.age".publicKeys = keys.hostKeys;
|
||||||
"org-api-passwords.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys ++ keys.railbird-sf;
|
"org-api-passwords.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys ++ keys.railbird-sf;
|
||||||
|
"org-api-auth-password.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys ++ keys.railbird-sf;
|
||||||
|
"org-api-ssh-key.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys ++ keys.railbird-sf;
|
||||||
"google-assistant-integration-service-key.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
|
"google-assistant-integration-service-key.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
|
||||||
"zwave-js.json.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
|
"zwave-js.json.age".publicKeys = keys.hostKeys ++ keys.kanivanKeys;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user