# sops-nix wiring (D6 infra secrets). cc-ci decrypts secrets at activation using its own
# ed25519 SSH host key as the age identity (no separate key file to manage on the box).
# Encrypted material lives in the repo-root `secrets/` git SUBMODULE (the private `cc-ci-secrets`
# repo, Phase-1c). RL5 put this module under nix/modules/, so the relative path is
# ../../secrets/secrets.yaml. Readable only by the recipients in secrets/.sops.yaml (host key +
# off-box master recovery key).
{ config, ... }:
{
  sops = {
    defaultSopsFile = ../../secrets/secrets.yaml;
    # Decrypt using the host's SSH host key (converted to an age identity by sops-nix).
    age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
    # Phase-1c: also accept a bootstrap age key at a fixed path — THE one out-of-band secret,
    # provisioned to the host before the first rebuild. On the canonical cc-ci this holds the
    # host-derived age identity (== the sshKeyPaths recipient, no new exposure); on a fresh/cloned
    # host (e.g. the throwaway-VM rebuild) it holds the off-box recovery key, so a host whose SSH
    # host key is NOT a sops recipient can still decrypt every secret. NOTE: sops-install-secrets
    # aborts activation if this file is set but missing, so it must exist before `nixos-rebuild`.
    age.keyFile = "/var/lib/sops-nix/key.txt";
    # Do not also look for a GPG key.
    gnupg.sshKeyPaths = [ ];

    secrets = {
      # M0 proof secret — confirms the decrypt path works end to end.
      test_secret = { };

      # M2 Drone (A2 internal secrets). drone_rpc_secret is shared between the swarm-deployed
      # Drone server (inserted as the `rpc_secret` swarm secret by scripts/deploy-drone.sh) and
      # the host exec runner (read via the env template below). drone_gitea_client_secret is the
      # Gitea OAuth app secret, inserted as the server's `client_secret` swarm secret.
      drone_rpc_secret = { };
      drone_gitea_client_secret = { };

      # M3 comment-bridge (A2). Read by modules/bridge.nix's reconcile oneshot, which copies them
      # into swarm secrets the bridge container mounts. webhook_hmac is also set on the Gitea webhook.
      bridge_webhook_hmac = { };
      bridge_drone_token = { };
      bridge_gitea_token = { };

      # Phase-1c C2: the wildcard TLS cert+key are now sops secrets (in cc-ci-secrets), decrypted at
      # activation to /var/lib/ci-certs/live/{fullchain.pem,privkey.pem} — the exact path the traefik
      # reconcile (modules/proxy.nix) already reads. Replaces the prior operator-drops-a-cert-file step.
      wildcard_cert = {
        path = "/var/lib/ci-certs/live/fullchain.pem";
        mode = "0444"; # leaf+intermediate chain — not secret
      };
      wildcard_key = {
        path = "/var/lib/ci-certs/live/privkey.pem";
        mode = "0400"; # private key — root only
      };

      # Phase-2 rate-limit fix (Class A1 registry creds, operator-2026-05-28). Authenticated Docker
      # Hub pulls (200/6h per-account) replace the exhausted 100/6h shared-IP anonymous limit that
      # was blocking heavy recipe deploys with `toomanyrequests`. Value is base64("nptest2:<PAT>")
      # — i.e. the exact `auth` field docker config.json expects — so the template below is a pure
      # render with no runtime base64. Read-only PAT; both the host exec runner and manual root
      # deploys run as root (drone-runner-exec User=root), so /root/.docker/config.json covers both.
      dockerhub_auth = { };
    };

    # EnvironmentFile for the host exec runner: DRONE_RPC_SECRET rendered from the sops secret.
    templates."drone-runner.env".content = ''
      DRONE_RPC_SECRET=${config.sops.placeholder.drone_rpc_secret}
    '';

    # Declarative root docker auth — survives a 1c rebuild (replaces the imperative `docker login`).
    # abra runs `docker stack deploy` as root and reads this config.json to authenticate Docker Hub
    # pulls (manifest resolution + image pulls). 0600/root-only since it embeds the PAT.
    templates."docker-config.json" = {
      path = "/root/.docker/config.json";
      mode = "0600";
      owner = "root";
      content = ''
        {"auths":{"https://index.docker.io/v1/":{"auth":"${config.sops.placeholder.dockerhub_auth}"}}}
      '';
    };
  };
}
