{
  "generated_at": "2026-09-19T09:03:24Z",
  "generated_by": "tools/audit-report.rb (site build)",
  "what_this_is": "Verification record for the published no-log audit. Every signature listed here was checked with stock ssh-keygen against the key pinned in _data/audit-pins.json at build time. If this file says verified:false, the build fails; if it says available:false, the artifact could not be retrieved and the page renders that instead.",
  "namespace": "logging-audit",
  "verify_recipe": "curl -O <base>/logging-audit/logging-audit.allowed_signers && curl -O <base>/logging-audit/logging-audit.json && curl -O <base>/logging-audit/logging-audit.json.sig && ssh-keygen -Y verify -f logging-audit.allowed_signers -I logging-audit@<host> -n logging-audit -s logging-audit.json.sig < logging-audit.json",
  "pins": {
    "vpn": {
      "role": "VPN edge",
      "principal": "logging-audit@vpn",
      "fingerprint": "SHA256:nLZOwc5NYNz4dWnTI6ZDOYi3IGsiFj9yhKEs/VzCpzY"
    },
    "public": {
      "role": "Public web / API",
      "principal": "logging-audit@public",
      "fingerprint": "SHA256:NkQoFKJH/tiH+K+8fICk3nCukwo35G+P4BdZDVnA/vU"
    }
  },
  "hosts": [
    {
      "host": "vpn",
      "role": "VPN edge",
      "base_url": "https://vpn.ymrtech.com",
      "principal": "logging-audit@vpn",
      "pinned_fingerprint": "SHA256:nLZOwc5NYNz4dWnTI6ZDOYi3IGsiFj9yhKEs/VzCpzY",
      "available": true,
      "allowed_signers_http": 200,
      "verified": true,
      "verify_output": "Good \"logging-audit\" signature for logging-audit@vpn with ED25519 key SHA256:nLZOwc5NYNz4dWnTI6ZDOYi3IGsiFj9yhKEs/VzCpzY",
      "report_sha256": "ffc0a6fdd0119811bf9949bb3fd9ae02c2418eaacdd43eda109805a4e68ba73f",
      "report_bytes": 4632,
      "generated_at": "2026-09-19T08:22:21Z",
      "generated_age": "41 min ago",
      "report_host_field": "vpn",
      "all_ok": true,
      "report_version": 1,
      "system_generation": "/nix/store/lchdcpqjgh6p2h0yf7g4y7gr8jpy8iqw-nixos-system-vpn-26.11.20260909.7b66dac",
      "signer_type": "ssh-ed25519",
      "signer_fingerprint": "SHA256:nLZOwc5NYNz4dWnTI6ZDOYi3IGsiFj9yhKEs/VzCpzY",
      "retention": {
        "adguard-querylog": "disabled on both instances",
        "journald": "14d in VictoriaLogs (whole journal shipped off-host)",
        "victorialogs": "14d",
        "victoriametrics": "365d (no client identity: per-interface counters only)"
      },
      "checks": [
        {
          "id": "adguard:fleet:querylog_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:fleet:stats_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:fleet:no-querylog-file",
          "ok": true,
          "status": "ok",
          "detail": "/var/lib/AdGuardHome/data/querylog.json absent after live queries; purge=False; probe reached the resolver=True (rc=0 after 1 attempt(s): dig @127.0.0.1 example.com A +time=3 +tries=1)"
        },
        {
          "id": "adguard:fleet:buffer",
          "ok": true,
          "status": "ok",
          "detail": "in-memory entries=0 (before the probe: 0); canary audit-canary-ab81cf7bd4.ymrtech.invalid present=False; grew=False — a present canary or growth means the resolver still logs, and that is a violation on every tier; a non-zero count that does neither is residue from before the disable, which only a restart clears"
        },
        {
          "id": "adguard:wg2:querylog_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:wg2:stats_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:wg2:no-querylog-file",
          "ok": true,
          "status": "ok",
          "detail": "/var/lib/adguardhome-client/data/querylog.json absent after live queries; purge=False; probe reached the resolver=True (rc=0 after 1 attempt(s): dig -b 172.16.41.1 @172.16.41.1 example.com A +time=3 +tries=1)"
        },
        {
          "id": "adguard:wg2:buffer",
          "ok": true,
          "status": "ok",
          "detail": "in-memory entries=0 (before the probe: 0); canary audit-canary-a0e8c13887.ymrtech.invalid present=False; grew=False — a present canary or growth means the resolver still logs, and that is a violation on every tier; a non-zero count that does neither is residue from before the disable, which only a restart clears"
        },
        {
          "id": "unbound:/etc/unbound/unbound.conf",
          "ok": true,
          "status": "ok",
          "detail": "log-queries lines=none"
        },
        {
          "id": "unbound:/etc/unbound-client/unbound.conf",
          "ok": true,
          "status": "ok",
          "detail": "log-queries lines=none"
        },
        {
          "id": "journal:no-client-tier-address",
          "ok": true,
          "status": "ok",
          "detail": "0 client match(es) in 6938 line(s) of units adguardhome,adguardhome-client,unbound,unbound-client since 14 days ago; 373 non-client line(s) ignored (sudo audit trail, or this host's own gateway addresses)"
        },
        {
          "id": "nolog:adguardhome-nolog",
          "ok": true,
          "status": "ok",
          "detail": "ActiveState=active ExecMainStatus=0 behavioural_ok=True"
        },
        {
          "id": "nolog:clientsv-nolog-primary",
          "ok": true,
          "status": "ok",
          "detail": "ActiveState=active ExecMainStatus=0 behavioural_ok=True"
        }
      ],
      "notes": [
        "adguard:* checks ENFORCE the setting (idempotent POST), purge any persisted querylog, then require that a real query wrote nothing: the API has no read endpoint for this setting and its querylog GET serves stale memory.",
        "nolog:<unit> checks re-read the deploy-gated behavioural assertion (unit state + its NO-LOG OK journal line); they do not re-run the probe themselves.",
        "journal:no-client-tier-address scans only the resolver units named in queryUnits, and counts only lines naming a tier address this host does not own: provisioning output (the sudo audit trail, `ip route`/`ip address` commands) is counted and reported as non-client. It has still never seen real client traffic (no wg1/wg2 client has connected yet).",
        "retention values are DECLARED claims from the configuration, recorded here so a change to them is visible as a diff."
      ],
      "checks_total": 13,
      "checks_failed": 0,
      "monthly_index_verified": true,
      "monthly_index_sha256": "9bb3cae35e2b9a4abe87e10dbdd736a4a64ba7bac86d46e3d1331ee61acdff0e",
      "monthly_index_verify_output": "Good \"logging-audit\" signature for logging-audit@vpn with ED25519 key SHA256:nLZOwc5NYNz4dWnTI6ZDOYi3IGsiFj9yhKEs/VzCpzY",
      "monthly_index_generated_at": "2026-09-19T08:22:21Z",
      "months": [
        {
          "month": "2026-09",
          "state": "month-to-date",
          "status": "incomplete",
          "all_ok": false,
          "days_with_report": 2,
          "days_expected": 19,
          "violations": 0,
          "sha256": "c04d36cd0db67f84fffff238187091353c8d5477963622d34edc972eef866325",
          "urls": null,
          "signature_verified": true,
          "actual_sha256": "c04d36cd0db67f84fffff238187091353c8d5477963622d34edc972eef866325",
          "sha256_matches": true,
          "archive_starts": "2026-09-18",
          "days_missing": [
            "2026-09-01",
            "2026-09-02",
            "2026-09-03",
            "2026-09-04",
            "2026-09-05",
            "2026-09-06",
            "2026-09-07",
            "2026-09-08",
            "2026-09-09",
            "2026-09-10",
            "2026-09-11",
            "2026-09-12",
            "2026-09-13",
            "2026-09-14",
            "2026-09-15",
            "2026-09-16",
            "2026-09-17"
          ]
        }
      ]
    },
    {
      "host": "public",
      "role": "Public web / API",
      "base_url": "https://ymrtech.com",
      "principal": "logging-audit@public",
      "pinned_fingerprint": "SHA256:NkQoFKJH/tiH+K+8fICk3nCukwo35G+P4BdZDVnA/vU",
      "available": true,
      "allowed_signers_http": 200,
      "verified": true,
      "verify_output": "Good \"logging-audit\" signature for logging-audit@public with ED25519 key SHA256:NkQoFKJH/tiH+K+8fICk3nCukwo35G+P4BdZDVnA/vU",
      "report_sha256": "4886a6ceee1b8e71d0aaa0bfff974d80ef12eacae37eeb630f4a0d3f09c0c63a",
      "report_bytes": 3300,
      "generated_at": "2026-09-19T08:58:33Z",
      "generated_age": "5 min ago",
      "report_host_field": "public",
      "all_ok": true,
      "report_version": 1,
      "system_generation": "/nix/store/hmkb977rmly1s0mzghqjm6c12kx7s0hs-nixos-system-public-26.11.20260909.7b66dac",
      "signer_type": "ssh-ed25519",
      "signer_fingerprint": "SHA256:NkQoFKJH/tiH+K+8fICk3nCukwo35G+P4BdZDVnA/vU",
      "retention": {
        "adguard-querylog": "disabled (no querylog.json, no retrievable tier entries)",
        "journald": "14d (local; public's journal is NOT shipped off-host)"
      },
      "checks": [
        {
          "id": "adguard:wg2-standby:querylog_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:wg2-standby:stats_config",
          "ok": true,
          "status": "ok",
          "detail": "enforce POST accepted after 1 attempt(s); behavioural check below"
        },
        {
          "id": "adguard:wg2-standby:no-querylog-file",
          "ok": true,
          "status": "ok",
          "detail": "/var/lib/adguardhome-client-standby/data/querylog.json absent after live queries; purge=False; probe reached the resolver=True (rc=0 after 1 attempt(s): dig @127.0.0.1 example.com A +time=3 +tries=1)"
        },
        {
          "id": "adguard:wg2-standby:buffer",
          "ok": true,
          "status": "ok",
          "detail": "in-memory entries=1 (before the probe: 1); canary audit-canary-3949dfd072.ymrtech.invalid present=False; grew=False — a present canary or growth means the resolver still logs, and that is a violation on every tier; a non-zero count that does neither is residue from before the disable, which only a restart clears"
        },
        {
          "id": "unbound:/etc/unbound/unbound.conf",
          "ok": true,
          "status": "ok",
          "detail": "log-queries lines=none"
        },
        {
          "id": "journal:no-client-tier-address",
          "ok": true,
          "status": "ok",
          "detail": "0 client match(es) in 1199 line(s) of units adguardhome-client-standby,unbound since 14 days ago; 58 non-client line(s) ignored (sudo audit trail, or this host's own gateway addresses)"
        },
        {
          "id": "nolog:clientsv-nolog-standby",
          "ok": true,
          "status": "ok",
          "detail": "ActiveState=active ExecMainStatus=0 behavioural_ok=True"
        }
      ],
      "notes": [
        "adguard:* checks ENFORCE the setting (idempotent POST), purge any persisted querylog, then require that a real query wrote nothing: the API has no read endpoint for this setting and its querylog GET serves stale memory.",
        "nolog:<unit> checks re-read the deploy-gated behavioural assertion (unit state + its NO-LOG OK journal line); they do not re-run the probe themselves.",
        "journal:no-client-tier-address scans only the resolver units named in queryUnits, and counts only lines naming a tier address this host does not own: provisioning output (the sudo audit trail, `ip route`/`ip address` commands) is counted and reported as non-client. It has still never seen real client traffic (no wg1/wg2 client has connected yet).",
        "retention values are DECLARED claims from the configuration, recorded here so a change to them is visible as a diff."
      ],
      "checks_total": 7,
      "checks_failed": 0,
      "monthly_index_verified": true,
      "monthly_index_sha256": "dff5a4b1df07136a1ebac7b65e582e5aebf472547dfcd4ef6787f83c7c5ee798",
      "monthly_index_verify_output": "Good \"logging-audit\" signature for logging-audit@public with ED25519 key SHA256:NkQoFKJH/tiH+K+8fICk3nCukwo35G+P4BdZDVnA/vU",
      "monthly_index_generated_at": "2026-09-19T08:58:34Z",
      "months": [
        {
          "month": "2026-09",
          "state": "month-to-date",
          "status": "incomplete",
          "all_ok": false,
          "days_with_report": 2,
          "days_expected": 19,
          "violations": 0,
          "sha256": "97b3d7ba10803ce5490f7e42e761a51f58b50b52eb606ad3a11ec2f879c8cfc3",
          "urls": null,
          "signature_verified": true,
          "actual_sha256": "97b3d7ba10803ce5490f7e42e761a51f58b50b52eb606ad3a11ec2f879c8cfc3",
          "sha256_matches": true,
          "archive_starts": "2026-09-18",
          "days_missing": [
            "2026-09-01",
            "2026-09-02",
            "2026-09-03",
            "2026-09-04",
            "2026-09-05",
            "2026-09-06",
            "2026-09-07",
            "2026-09-08",
            "2026-09-09",
            "2026-09-10",
            "2026-09-11",
            "2026-09-12",
            "2026-09-13",
            "2026-09-14",
            "2026-09-15",
            "2026-09-16",
            "2026-09-17"
          ]
        }
      ]
    }
  ]
}
