Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ssl Certification Health Check Laravel Package

victord11/ssl-certification-health-check

Monitor SSL certificate health in Laravel: check expiry dates, validity, issuer, and chain issues before they break your site. Run automated checks and get alerted when certificates are nearing expiration or misconfigured.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a thin wrapper that plugs an SSL-certificate probe into spatie/laravel-health, so it makes sense only in projects that already use (or will use) that health-check framework. Start by confirming that dependency, then add the package:

composer require victord11/ssl-certification-health-check

If the package ships a config file, publish it:

php artisan vendor:publish --provider="Victord11\SslCertificationHealthCheck\SslCertificationHealthCheckServiceProvider"

The service provider auto-registers; there is nothing to wire up manually in recent Laravel versions. Your first move after installation is to open the source under vendor/victord11/ssl-certification-health-check/src/ and look for:

  • the check class implementing Spatie\Health\Checks\Check (its constructor and run() method tell you exactly which options are supported),
  • a config file under config/ (usually holding a list of domains and an expiry threshold).

These two files are the most reliable documentation because the README on a 17-star package can lag behind the code.

First use case. Register the check against a single domain and confirm it works before broadening:

use Spatie\Health\Facades\Health;
use VictorD11\SslCertificationHealthCheck\Checks\SslCertificationCheck;

Health::checks([
    SslCertificationCheck::make('example.com'),
]);

Then run:

php artisan health:check --only=ssl-certification

A green result means the TLS handshake succeeded and the certificate's valid_to is comfortably in the future. A failing result should surface the expiry date or handshake error in the check's notificationMessage/meta output — verify that before proceeding, because a health check that fails silently is worse than none.

Implementation Patterns

Domain list in config, not in code. The idiomatic pattern is to drive the check from configuration rather than hardcoding domains in AppServiceProvider. Use config('app.url'), an env-driven list, or parse_url(config('app.url'), PHP_URL_HOST) so staging and production deployments check their own hostnames automatically:

// config/health.php (or app/Providers/HealthServiceProvider.php)
$domains = array_filter([
    parse_url(config('app.url'), PHP_URL_HOST),
    config('services.ssl_check.extra_domain'),
]);

Health::checks([
    SslCertificationCheck::make($domains),
]);

If the package's make() only accepts a single string, instantiate the check once per domain in a foreach or collect()->map().

Run on a schedule, not on every request. Wire the check into the scheduler so it does not slow down user traffic and does not hammer the remote hosts:

// routes/console.php or app/Console/Kernel.php
$schedule->command('health:check')->hourly();
$schedule->command('health:schedule-check-heartbeat')->everyMinute();

Spatie's health:check already persists results to the database and triggers notifications (mail/Slack) when a check fails — the SSL check benefits from that infrastructure for free. Keep the schedule coarse (hourly or every few hours); certificate expiry is not a second-by-second concern.

Split "expiring soon" from "invalid". A certificate that expires in 20 days is not down; one that expired yesterday is. If the check class doesn't expose a warning threshold, subclass it or wrap it with a Checks\Check of your own that reads the expiry from the returned Meta and downgrades the status to warning above a configurable cutoff:

Health::checks([
    SslCertificationCheck::make($domain)->timeout(10),
]);

Use for canary/status endpoints. Because Spatie's health package can expose JSON via Route::get('/health', HealthCheckController::class), this check becomes your uptime monitor's data source. Point Better Uptime/Pingdom at it and let them alert on the ssl-certification field specifically.

Test in two layers. Unit-test your provider wiring with Health::checks() assertions, and cover the check itself with an HTTP fake or by pointing it at a known-good domain (google.com) in CI. Do not depend on your own staging domain having a valid cert in tests.

Gotchas and Tips

SNI is not negotiable. The probe must pass a hostname for SNI; checking https://1.2.3.4 or a CDN edge IP will present the wrong certificate. Always check domains, not IPs, and be aware that Cloudflare / AWS ALB front-ends return their certificate, not yours. If you need to verify the origin cert, target the origin hostname and port directly.

Custom ports and non-443 endpoints. Many internal services sit behind :8443 or :636. Confirm the check constructor accepts a port (or host:port); if it doesn't, it will silently connect to 443 and either fail or — worse — pass by validating an unrelated edge. Verify the port is threaded through to stream_socket_client/fsockopen when you read the source.

Timeouts. DNS and handshakes can hang. Set a short timeout (5–10s) so a single unreachable host does not stall the entire health:check run. If the package doesn't expose a timeout option, wrap the call in your own Check or open an issue — the current release (March 2024) is not guaranteed to have it.

Self-signed and internal CAs. The default behavior almost certainly rejects untrusted chains. For internal services, you need a way to accept a custom CA bundle (openssl.cafile) or skip verification — do not monkey-patch stream_context from application code. Prefer checking only public-facing certs with this package.

Clock skew and timezones. valid_to from the remote cert is UTC; comparing against now() in the app is fine, but beware containers with badly skewed clocks — a drifting host can report every cert as expired or every cert as valid. Run with an up-to-date NTP daemon.

Expiry thresholds are a policy, not a default. Pick your warning window (often 14–30 days for manual renewal, 7 for ACME-automated). If the package ships a default of, say, 30 days, expect it to fail for short-lived Let's Encrypt certs unless you disable auto-renewal checks. Override it explicitly rather than relying on the default.

Debugging. The check's meta array is your friend. Log it on failure:

$result = (new SslCertificationCheck)->run();
logger()->debug('ssl check', ['status' => $result->status, 'meta' => $result->meta]);

If meta is empty on failure, the exception was swallowed upstream — inspect the vendor source for a bare try/catch and consider adding your own logging wrapper.

Extension point. The cleanest long-term extension is to implement your own Check that composes this one, normalizes the status (expiring-soon → warning), and adds your organization's metadata. That keeps you insulated from upstream changes on a low-traffic package.

Version pinning. With a last release in March 2024 and a small user base, pin to a specific version ("victord11/ssl-certification-health-check": "1.*") and watch for breaking changes to Spatie's Check contract, which has evolved across major versions of spatie/laravel-health. If you're on Spatie 2.x and the package targets 1.x, expect a compatibility error at boot — check composer.json's require block first.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle