Skip to content

Audit remediation: docs correctness, TLS safe-by-default, narrowed error handling#8

Merged
nyo16 merged 2 commits into
masterfrom
chore/audit-remediation
Jun 2, 2026
Merged

Audit remediation: docs correctness, TLS safe-by-default, narrowed error handling#8
nyo16 merged 2 commits into
masterfrom
chore/audit-remediation

Conversation

@nyo16

@nyo16 nyo16 commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Summary

Remediation of every finding from a project health audit (/phx:audit).
Three groups of changes — documentation correctness, security hardening,
and error-handling/robustness — plus a new test that closes a real
connect-path coverage gap. No hot-path or architecture changes.

Reviewable commit-by-commit:

Commit Scope
d9e0a84 Docs (H1/H2/L1–L3) + Security (M1/M2) + Robustness (L4/L5/L6)
b0c2925 M3 — real connect-path test via an in-process gRPC server

Documentation

  • H1 — README documented a non-existent GrpcConnectionPool.execute/1. The
    module exposes get_channel/1 (+ start/stop/scale/status), not execute.
    Anyone following the README's main "call a service" examples hit
    UndefinedFunctionError. Rewrote all of them (lines 98/492/514–515/526/846) to
    the real get_channel/1 + Stub.call pattern. No new API.
  • H2 — fixed the stale install snippet in the GrpcConnectionPool moduledoc
    (~> 0.1.0 / grpc ~> 0.10.2~> 0.3 / ~> 0.11).
  • L2 — documented telemetry_sample_rate and the full pool option set
    (README + Config moduledoc); corrected the :get_channel telemetry row
    (emits no measurements, not duration) and the PowerOfTwo description
    ("least-recently-used" → "least-frequently-used", lock-free atomics).
  • L1mix.exs @version 0.3.00.3.5 to match the released tag; added
    CHANGELOG [0.3.5] and [Unreleased] sections.
  • L3 — fixed 0.2.2/0.2.3 CHANGELOG date typos (2025-01-292026-01-29).

Security (⚠️ behavior change)

  • M1 — an explicit type: :production endpoint built without :ssl or
    :credentials now raises instead of silently connecting over plaintext
    h2c. Scoped to explicit production so defaulted/:local configs (and existing
    local/test usage) are unaffected.
  • M2Config.production/1 now defaults to verifying TLS on OTP 25+
    (verify_peer + system CA store + hostname check via
    :public_key.pkix_verify_hostname_match_fun/1); on OTP 24 (no system-CA
    accessor) it warns and falls back, prompting an explicit :ssl. Exposed as
    Config.default_production_ssl/0.
  • Added config tests for both, and updated the production+interceptors test to
    use TLS.

Upgrade note: callers relying on the old insecure ssl: [] default (no
peer verification), or on an explicit type: :production without TLS, will now
get verified TLS or a clear error. Intentional — flagged under [Unreleased]
as Changed; warrants at least a minor bump on release.

Robustness

  • L4Pool.scale_up/scale_down/resize rescues narrowed: ArgumentError
    (pool not started / ETS missing) → {:error, :pool_not_found}; any other
    exception now propagates instead of being swallowed as an opaque struct.
    TelemetryReporter logs a warning before recovering instead of swallowing
    silently.
  • L5 — dropped Worker.send_ping/1's blanket rescue _ / catch _ (the body
    is total), so a future programming error surfaces instead of masquerading as a
    ping failure.
  • L6 — demoted expected reconnect/retry logs to :debug and gated the
    connection-failure :error log on suppress_connection_errors (reduces
    reconnect-storm log spam).

Tests

  • M3 — new connect_path_test.exs starts an in-process gRPC server
    (reusing a service from the test-only googleapis_proto_ex, port 0 =
    OS-assigned) and points a pool at it, asserting workers connect, all slots
    populate (current_size == pool_size, status :healthy), and get_channel/1
    returns a real %GRPC.Channel{}. Covers worker → GRPC.Stub.connect → slot
    claim → get_channel in CI without the external Pub/Sub emulator. Stable
    across repeated seeded runs.

Verification

  • mix compile --warnings-as-errors — clean
  • mix format --check-formatted — clean
  • mix credo --strict — no issues
  • mix test91 passed, 3 excluded (emulator-tagged)

nyo16 added 2 commits June 1, 2026 20:07
…scues

From a /phx:audit health check. Three groups of fixes:

Docs (H1/H2/L2/L3):
- Rewrite README examples that called a non-existent
  GrpcConnectionPool.execute/1 to the real get_channel/1 + Stub.call pattern;
  no new API.
- Fix stale install snippet in the GrpcConnectionPool moduledoc
  (0.1.0/0.10.2 -> 0.3/0.11).
- Document telemetry_sample_rate and the full pool option set in README +
  Config moduledoc; correct the :get_channel telemetry row (empty
  measurements) and the PowerOfTwo "least-recently-used" -> "least-frequently-used".
- mix.exs @Version 0.3.0 -> 0.3.5 (match the released tag); add CHANGELOG
  [0.3.5] + [Unreleased]; fix 0.2.2/0.2.3 date typos (2025 -> 2026).

Security (M1/M2):
- Config.production/1 now defaults to verifying TLS on OTP 25+
  (verify_peer + system cacerts + hostname check); warns and falls back on
  older OTP. Exposed as Config.default_production_ssl/0.
- An *explicit* `type: :production` endpoint built without :ssl/:credentials
  now raises instead of silently connecting over plaintext h2c. Defaulted
  type stays permissive for local/test use.
- Tests for both, plus updated the production+interceptors test to use TLS.

Robustness (L4/L5/L6):
- Pool.scale_up/scale_down/resize rescue ArgumentError -> {:error,
  :pool_not_found}; other exceptions propagate instead of being returned as
  opaque structs.
- TelemetryReporter logs a warning before recovering instead of swallowing
  errors silently.
- Worker.send_ping/1 drops the broad rescue/catch (the body is total).
- Demote expected reconnect/retry logs to :debug; gate the connection-failure
  error log on suppress_connection_errors.
Adds a test that starts an in-process GRPC server (reusing a service from the
test-only googleapis_proto_ex, port 0 = OS-assigned) and points a pool at it,
asserting workers connect, all slots populate (current_size == pool_size,
status :healthy), and get_channel/1 returns a real %GRPC.Channel{}. Covers the
worker -> GRPC.Stub.connect -> slot claim -> get_channel path in CI without the
external Pub/Sub emulator. Stable across repeated seeded runs.
@nyo16 nyo16 merged commit a07e03b into master Jun 2, 2026
6 checks passed
@nyo16 nyo16 deleted the chore/audit-remediation branch June 2, 2026 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant