diff --git a/AGENTS.md b/AGENTS.md index 8fb2c9b..7131cae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -553,6 +553,15 @@ Estado atual: - `secrets/openai_api_key.age` - `secrets/openclaw_gateway_token.age` +- `secrets/forgejo_api_token.age` +- `secrets/android_release_keystore.age` +- `secrets/android_release_store_password.age` +- `secrets/android_release_key_password.age` +- `secrets/matrix_android_firebase_service_account.age` +- `secrets/matrix_android_google_services.age` +- `secrets/matrix_android_commander_credentials.age` +- `secrets/cloudflare_worker_api_token.age` +- `secrets/cloudflare_dns_api_token.age` - `secrets/minecraft_rcon_password.age` - `secrets/wireguard_private_key.age` @@ -567,9 +576,33 @@ Estado atual: - `fish.shellInit` exporta: - `OPENAI_API_KEY` - `OPENCLAW_GATEWAY_TOKEN` -- `/etc/profile.d/openai.sh` e `/etc/profile.d/openclaw.sh` fazem o mesmo para shells de login. + - `FORGEJO_API_TOKEN` +- `/etc/profile.d/openai.sh`, `/etc/profile.d/openclaw.sh` e `/etc/profile.d/forgejo.sh` fazem o mesmo para shells de login. - O token do Home Assistant do Waybar AC NAO esta sob agenix neste repo; ele e lido diretamente de `~/.config/secrets/ha_token`. +### Android signing + +- A chave de assinatura Android para distribuicao fora da Play Store fica em `secrets/android_release_keystore.age`. +- As senhas ficam em `secrets/android_release_store_password.age` e `secrets/android_release_key_password.age`. +- O alias padrao da chave e `release`. +- O helper `android-signing-env` exporta `ANDROID_KEYSTORE_PATH`, `ANDROID_KEYSTORE_TYPE`, `ANDROID_KEY_ALIAS`, `ANDROID_KEYSTORE_PASSWORD`, `ANDROID_KEY_PASSWORD` e `PUSH_GATEWAY_URL` apenas para o comando filho. +- `PUSH_GATEWAY_URL` aponta para `https://matrix-push-gateway.ltadeu6.workers.dev`. +- Use `android-signing-env ./gradlew assembleRelease` ou `android-signing-env ./gradlew bundleRelease`; nao exporte essas senhas globalmente. +- Secrets locais do projeto `matrix-android` tambem ficam sob agenix: + - `matrix_android_firebase_service_account` materializa `.secrets/firebase-service-account.json`. + - `matrix_android_google_services` materializa `app/google-services.json`. + - `matrix_android_commander_credentials` materializa `.mc/credentials.json`. +- O helper `matrix-android-secrets [project-dir]` cria symlinks desses tres arquivos para `/run/agenix`; por default usa o diretorio atual. +- Nao migre `local.properties`, debug keystores, `.gradle`, `.wrangler` ou caches locais do `matrix-android` para este repo sem um motivo explicito. + +### Cloudflare + +- `secrets/cloudflare_worker_api_token.age` contem um token para deploy de Workers no account local. +- `secrets/cloudflare_dns_api_token.age` contem um token para DNS/Zone Read. +- `cloudflare-worker-env ` exporta `CLOUDFLARE_API_TOKEN` apenas para o comando filho usando o token de Workers. +- `cloudflare-dns-env ` exporta `CLOUDFLARE_API_TOKEN` apenas para o comando filho usando o token de DNS. +- O token bootstrap usado para criar outros tokens e temporario; nao mantenha `cloudflare_bootstrap_api_token.age` no repo depois de revogar o token na Cloudflare. + ## Dependencias implicitas e pontos de atencao Itens que um agente deve verificar antes de mexer: diff --git a/hosts/Nixos/configuration.nix b/hosts/Nixos/configuration.nix index 5dd6ea2..fd912ec 100644 --- a/hosts/Nixos/configuration.nix +++ b/hosts/Nixos/configuration.nix @@ -9,6 +9,95 @@ let repoDir = "${homeDir}/Projetos/Sistemas/nixos-config"; codexStatusPath = "/var/lib/hass/codex_status.json"; claudeUsagePath = "/var/lib/hass/claude_usage.json"; + androidSigningEnv = pkgs.writeShellScriptBin "android-signing-env" '' + set -eu + + secret_dir=/run/agenix + for secret in \ + android_release_keystore \ + android_release_store_password \ + android_release_key_password + do + if [ ! -r "$secret_dir/$secret" ]; then + echo "Missing readable Android signing secret: $secret_dir/$secret" >&2 + exit 1 + fi + done + + export ANDROID_KEYSTORE_PATH="$secret_dir/android_release_keystore" + export ANDROID_KEYSTORE_TYPE=PKCS12 + export ANDROID_KEY_ALIAS=release + export ANDROID_KEYSTORE_PASSWORD="$(${pkgs.coreutils}/bin/cat "$secret_dir/android_release_store_password")" + export ANDROID_KEY_PASSWORD="$(${pkgs.coreutils}/bin/cat "$secret_dir/android_release_key_password")" + export PUSH_GATEWAY_URL="https://matrix-push-gateway.ltadeu6.workers.dev" + + if [ "$#" -eq 0 ]; then + echo "Android signing environment is ready." + echo "Run: android-signing-env ./gradlew assembleRelease" + exit 0 + fi + + exec "$@" + ''; + matrixAndroidSecrets = pkgs.writeShellScriptBin "matrix-android-secrets" '' + set -eu + + project_dir=''${1:-"$PWD"} + if [ ! -f "$project_dir/app/build.gradle.kts" ]; then + echo "Usage: matrix-android-secrets [matrix-android-project-dir]" >&2 + echo "Could not find app/build.gradle.kts in: $project_dir" >&2 + exit 1 + fi + + link_secret() { + source_path=$1 + target_path=$2 + + if [ ! -r "$source_path" ]; then + echo "Missing readable secret: $source_path" >&2 + exit 1 + fi + + target_dir=$(${pkgs.coreutils}/bin/dirname "$target_path") + ${pkgs.coreutils}/bin/mkdir -p "$target_dir" + + if [ -e "$target_path" ] || [ -L "$target_path" ]; then + current_target=$(${pkgs.coreutils}/bin/readlink "$target_path" || true) + if [ "$current_target" = "$source_path" ]; then + return + fi + echo "Refusing to replace existing file: $target_path" >&2 + exit 1 + fi + + ${pkgs.coreutils}/bin/ln -s "$source_path" "$target_path" + } + + link_secret /run/agenix/matrix_android_firebase_service_account "$project_dir/.secrets/firebase-service-account.json" + link_secret /run/agenix/matrix_android_google_services "$project_dir/app/google-services.json" + link_secret /run/agenix/matrix_android_commander_credentials "$project_dir/.mc/credentials.json" + ''; + cloudflareEnv = name: secret: pkgs.writeShellScriptBin name '' + set -eu + + secret_path=/run/agenix/${secret} + if [ ! -r "$secret_path" ]; then + echo "Missing readable Cloudflare token: $secret_path" >&2 + exit 1 + fi + + export CLOUDFLARE_API_TOKEN="$(${pkgs.coreutils}/bin/cat "$secret_path")" + + if [ "$#" -eq 0 ]; then + echo "Cloudflare API token environment is ready." + exit 0 + fi + + exec "$@" + ''; + cloudflareWorkerEnv = + cloudflareEnv "cloudflare-worker-env" "cloudflare_worker_api_token"; + cloudflareDnsEnv = cloudflareEnv "cloudflare-dns-env" "cloudflare_dns_api_token"; haAirConditioner = "climate.ar"; haLaundryDryingToggle = "input_boolean.secar_roupas"; haClimateAction = action: data: { @@ -173,6 +262,78 @@ in { mode = "0400"; }; } // lib.optionalAttrs + (builtins.pathExists ../../secrets/forgejo_api_token.age) { + forgejo_api_token = { + file = ../../secrets/forgejo_api_token.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/android_release_keystore.age) { + android_release_keystore = { + file = ../../secrets/android_release_keystore.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/android_release_store_password.age) { + android_release_store_password = { + file = ../../secrets/android_release_store_password.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/android_release_key_password.age) { + android_release_key_password = { + file = ../../secrets/android_release_key_password.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/matrix_android_firebase_service_account.age) { + matrix_android_firebase_service_account = { + file = ../../secrets/matrix_android_firebase_service_account.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/matrix_android_google_services.age) { + matrix_android_google_services = { + file = ../../secrets/matrix_android_google_services.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/matrix_android_commander_credentials.age) { + matrix_android_commander_credentials = { + file = ../../secrets/matrix_android_commander_credentials.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/cloudflare_worker_api_token.age) { + cloudflare_worker_api_token = { + file = ../../secrets/cloudflare_worker_api_token.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs + (builtins.pathExists ../../secrets/cloudflare_dns_api_token.age) { + cloudflare_dns_api_token = { + file = ../../secrets/cloudflare_dns_api_token.age; + owner = username; + group = "users"; + mode = "0400"; + }; + } // lib.optionalAttrs (builtins.pathExists ../../secrets/minecraft_rcon_password.age) { minecraft_rcon_password.file = ../../secrets/minecraft_rcon_password.age; @@ -292,6 +453,9 @@ in { if test -r /run/agenix/openclaw_gateway_token set -gx OPENCLAW_GATEWAY_TOKEN (cat /run/agenix/openclaw_gateway_token) end + if test -r /run/agenix/forgejo_api_token + set -gx FORGEJO_API_TOKEN (cat /run/agenix/forgejo_api_token) + end ''; shellAliases = { la = "exa --icons --git"; @@ -1154,6 +1318,11 @@ in { export OPENCLAW_GATEWAY_TOKEN="$(cat /run/agenix/openclaw_gateway_token)" fi ''; + environment.etc."profile.d/forgejo.sh".text = '' + if [ -r /run/agenix/forgejo_api_token ]; then + export FORGEJO_API_TOKEN="$(cat /run/agenix/forgejo_api_token)" + fi + ''; users.groups.libvirtd.members = [ username ]; @@ -1365,6 +1534,10 @@ in { nodePackages.prettier nodePackages.pnpm fishPlugins.z + androidSigningEnv + matrixAndroidSecrets + cloudflareWorkerEnv + cloudflareDnsEnv ]; # environment.loginShellInit = '' diff --git a/secrets/android_release_key_password.age b/secrets/android_release_key_password.age new file mode 100644 index 0000000..73871af Binary files /dev/null and b/secrets/android_release_key_password.age differ diff --git a/secrets/android_release_keystore.age b/secrets/android_release_keystore.age new file mode 100644 index 0000000..9f9f3d6 Binary files /dev/null and b/secrets/android_release_keystore.age differ diff --git a/secrets/android_release_store_password.age b/secrets/android_release_store_password.age new file mode 100644 index 0000000..42760e7 --- /dev/null +++ b/secrets/android_release_store_password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 PLsDCw gBKNuM+9I8jE0FR2MQBQIqkLvwb3zq0LKf0bwB8yIXk +spy1+Ok6fFoEGsVrnPHrWeNL49cpyBc+RxDjfmk3r6E +-> ssh-ed25519 PLsDCw b982WTJWcZfyQ0yu1NFYzOsE761V3AbciXYN4TngL3U +b3hXtIY24EPP4mcCGn4BPtsHk46YLGQr7ZOheghyS6w +--- viMGGTPm8ItU7jb1OK7045U0o1BM2SbDwVJ7qXVp9E4 +b.q`io9~+78-! @LEWf§Ywx(`z8pK~3 OtKX{cWЉY}4Pdzdf!,죫W \ No newline at end of file diff --git a/secrets/cloudflare_dns_api_token.age b/secrets/cloudflare_dns_api_token.age new file mode 100644 index 0000000..bae5877 Binary files /dev/null and b/secrets/cloudflare_dns_api_token.age differ diff --git a/secrets/cloudflare_worker_api_token.age b/secrets/cloudflare_worker_api_token.age new file mode 100644 index 0000000..cdd3f98 Binary files /dev/null and b/secrets/cloudflare_worker_api_token.age differ diff --git a/secrets/forgejo_api_token.age b/secrets/forgejo_api_token.age new file mode 100644 index 0000000..cea8e49 Binary files /dev/null and b/secrets/forgejo_api_token.age differ diff --git a/secrets/matrix_android_commander_credentials.age b/secrets/matrix_android_commander_credentials.age new file mode 100644 index 0000000..bd35b1c Binary files /dev/null and b/secrets/matrix_android_commander_credentials.age differ diff --git a/secrets/matrix_android_firebase_service_account.age b/secrets/matrix_android_firebase_service_account.age new file mode 100644 index 0000000..a6c811d Binary files /dev/null and b/secrets/matrix_android_firebase_service_account.age differ diff --git a/secrets/matrix_android_google_services.age b/secrets/matrix_android_google_services.age new file mode 100644 index 0000000..bdc337c Binary files /dev/null and b/secrets/matrix_android_google_services.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index cbbb84e..c3ae664 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -9,6 +9,15 @@ let in { "secrets/openai_api_key.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; "secrets/openclaw_gateway_token.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/forgejo_api_token.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/android_release_keystore.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/android_release_store_password.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/android_release_key_password.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/matrix_android_firebase_service_account.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/matrix_android_google_services.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/matrix_android_commander_credentials.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/cloudflare_worker_api_token.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; + "secrets/cloudflare_dns_api_token.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; "secrets/minecraft_rcon_password.age".publicKeys = [ users.ltadeu6 systems.Nixos ]; "secrets/wireguard_private_key.age".publicKeys = [ users.ltadeu6 systems.Nixos ];