go-notificationgo-notification
Features

Security & Redaction

API keys stay out of logs. Drivers use raw HTTP with no third-party SDKs.

Redaction is opt-in, not automatic

go-notification does not auto-redact via struct tags or a custom String(). If you log a Config, an error message, or a request URL that embeds credentials, the secret will appear in plain text. Wrap anything you log around the library through middleware.Redact / middleware.RedactAttr (see below). Never log a whole config struct.

go-notification is built around two security defaults:

  1. No secrets logged by the library itself — the notifier's own logging never prints your API keys. But anything you log around it is your responsibility — use the helper below.
  2. Zero third-party SDKs — every driver uses net/http directly.

Redaction helper

Redaction is a regex-based string scrubber in the middleware package — not a struct-tag or String() mechanism. It replaces bearer tokens, api_key=…, password=…, and token=… patterns with ***:

main.go
import "github.com/gopackx/go-notification/middleware"

safe := middleware.Redact(`Authorization: Bearer abc123 api_key=key-secret`)
// "Authorization: Bearer *** api_key=***"

For structured logging, RedactAttr returns a redacted slog.Attr:

main.go
slog.Info("calling provider", middleware.RedactAttr("url", requestURL))

There is no redact:"true" struct tag, no notification.Redact(cfg), and no redacting String() on config types. Don't log whole config structs with %+v — pass individual values through middleware.Redact instead.

Keeping secrets out of logs

The notifier's own logging never prints credentials. When you log around the library — request URLs, headers, error strings that may embed a key — run the value through middleware.Redact/RedactAttr first. That covers the common leak vectors (bearer tokens, api_key/token/password pairs).

Zero SDK dependencies

Every driver uses net/http. No Twilio Go SDK, no AWS SDK, no SendGrid client library.

Why it matters:

  • Tiny binary. Adding WhatsApp support doesn't pull in the Twilio SDK's ~10MB dependency tree.
  • Audit surface. You audit this library's raw HTTP calls. You don't transitively audit six SDK versions with their own CVE history.
  • Upgradeability. If an upstream API changes, fixing the driver is editing one file — no waiting for the SDK maintainer.

Trade-off: when upstream APIs add brand-new features (e.g., FCM's new batching API), this library has to catch up manually. That's explicit project scope.

Secrets in environment variables

A common pitfall: shell scripts that print env vars. Don't echo $FCM_SERVICE_ACCOUNT_JSON. Don't include API keys in git-committed .env.example files.

Recommended:

  • Use a secrets manager in production (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault).
  • Load secrets at application boot, pass them as []byte where possible, and avoid roundtripping through the environment after boot.

TLS

Every HTTP driver talks HTTPS using Go's default transport and the system CA bundle; each builds its own client from the Timeout you configure. There is no HTTPClient config field to inject a custom CA or mutual-TLS client. If you need a custom CA or client certificates, the supported path is a network-level egress proxy or a custom channel (Writing a Custom Channel) where you control the http.Client.

Reporting a vulnerability

Email the maintainer directly (not a public issue) per the SECURITY.md in the repo. Don't disclose publicly until a fix ships.