Alerts & Notifications¶
Configure email and webhook notifications to stay informed about expiring credentials, failed operations, and security events.
Overview¶
CertifyClouds alerts keep your team notified:
- Multiple channels: Email, Slack, Microsoft Teams, PagerDuty, custom webhooks
- 8 consolidated alert types covering expiry, rotation, sync, credential status, and operational events
- Source and Status scoping: One rule per concern, refined with optional filters
- Delivery modes: Realtime (on trigger) or scheduled digest
- Flexible scheduling: Configure when digests are sent
- Subscription filtering: Scope alert rules to specific Azure subscriptions (via the API)
Alert Types¶
CertifyClouds has 8 alert types. The multi-variant ones (expiry, rotation, sync, credential_status) cover all their sub-cases with one type; optional Source and Status scopes narrow a rule instead of separate types.
| Alert Type | Trigger |
|---|---|
expiry | A credential is expiring within the rule's threshold, or has already expired |
rotation | A rotation run completed or failed |
credential_status | A managed credential went missing in Azure or was re-adopted |
sync | A sync operation completed, failed, hit a conflict, or has source lag |
scan_completed | Key Vault scan finished |
discovery_completed | Rotation discovery finished |
vault_error | Error accessing a Key Vault |
worker_stale | A background worker stopped heartbeating |
Source scope (expiry only)¶
An expiry rule covers all credential sources by default; the Source select narrows it to one:
| Source | Covers | Tier |
|---|---|---|
| All sources | Everything below | Any |
| Key Vault secrets | Key Vault secrets, certificates, and keys | STARTER+ |
| App Registration credentials | App Registration secrets and certificates | STARTER+ |
| Enterprise Application credentials | Service-principal secrets, non-SAML certificates, and active SAML signing certificates | STARTER+ |
| TLS endpoints | Certificates uploaded directly to Azure service endpoints | STARTER+ |
| External tenant credentials (B2C / External ID) | Credentials of apps in a registered Azure AD B2C or Entra External ID tenant | PRO |
| Service credentials | CertifyClouds' own managed credentials | PRO |
On STARTER, B2C and Service rows are never evaluated, even by an "All sources" rule.
Inactive SAML rollover certificates remain in the Enterprise Applications inventory but never trigger expiry alerts. See Enterprise Applications (monitor-only).
TLS endpoint certificates¶
A certificate uploaded straight to an Azure service (App Service, Application Gateway, Front Door, API Management or Container Apps) is not in Key Vault. An expiry rule with Source set to TLS endpoints or All sources covers these certificates on every tier. The alert tells you to renew the certificate with its issuer and upload it again, or to store it in Key Vault and point the resource at it without a version number.
A certificate an endpoint serves from Key Vault alerts as a Key Vault certificate, so it never alerts twice. On PRO, that alert names the endpoints that use it. Certificates Azure renews itself do not alert. See TLS Endpoints.
CertifyClouds' own secrets¶
CertifyClouds signs in to your onboarded tenants, and to your SSO provider, with secrets of its own (see Rotating CertifyClouds' Own Credentials). If one expires, discovery of that tenant or SSO sign-in stops, so these always warn before they expire:
- If an enabled
expiryrule covers Service credentials (or All sources), that rule decides who is told and when, like any other alert. - If no rule covers them, CertifyClouds emails every active admin who has an email address once a secret is within the Warning band (Settings → Advanced → Alert defaults, 30 days by default), and records a warning in the audit log. The email links to Settings → Access, or to the SSO settings when only the SSO secret is expiring. The email needs an email provider to be configured; the audit log entry is written either way.
Status scope¶
expiry, rotation, sync, and credential_status rules accept an optional Scope that narrows which sub-statuses fire. Default is all.
| Alert Type | Scope values |
|---|---|
expiry | Expiring only, Expired only |
rotation | Completed only, Failed only |
sync | Completed, Failed, Conflict, Source lag |
credential_status | Missing only, Re-adopted only |
For example, a failure-only rotation rule is rotation with Scope = Failed only; there is no separate rotation_failed type.
Upgrading from pre-1.6.2
Rules from releases before 1.6.2 are converted automatically when you upgrade and keep firing on exactly what they fired on before. Alert history from before the upgrade shows the old alert names.
When expiry alerts fire¶
Expiry alerts are checked every day without needing a new scan, and again straight after each Key Vault scan, so a newly expiring credential alerts straight away.
Notification Channels¶
Email¶
Send alerts to individuals or distribution lists.
Configuration (Settings > Alerts):
- Click Create Alert Rule
- Select alert type (e.g., Credential Expiry)
- Enable Email delivery
- Enter recipient(s)
- Set threshold (for expiry rules)
- Save
Unified expiry email
Realtime and digest expiry emails render the same table: one Source column covering every credential source, grouped into Expired, Critical (inside the critical window), and Warning sections.
Owner-aware fan-out
For expiry, rotation, and credential-status alerts, credential owners each receive a separate email containing only their own credentials. The rule's configured recipients still receive the full batch. Owner emails come only from rules with Realtime delivery and email on; digests never go to owners. Owner fan-out is email-only; webhooks always carry the full batch to the team channel.
The owner contact set on a rotation record (see Credential Ownership) and the owner in a Key Vault secret's certifyclouds-owner-email tag are always emailed. For App Registration alerts, the tag is used only when the record has no owner contact. Owners CertifyClouds finds in Microsoft Entra are emailed only if an admin chooses to; see App Owner Emails.
Email setup required:
Sign in as an administrator and open Settings → Advanced → Email. Configure either SMTP or SendGrid, save it, and send a test email. Provider credentials are stored encrypted. Email is set up only on this page; email environment variables are not read.
Slack¶
Post alerts to Slack channels using incoming webhooks.
Setup:
- In Slack, create an Incoming Webhook:
- Go to your Slack workspace settings
- Apps > Manage > Custom Integrations > Incoming Webhooks
- Create webhook and copy URL
- In CertifyClouds:
- Settings → Alerts → Create Alert Rule
- Select Webhook delivery
- Choose type: Slack
- Paste webhook URL
- Save
Payload Format:
{
"attachments": [
{
"color": "#EF4444",
"title": "Credential Expiry Alert",
"text": "Found 3 credentials expiring within 30 days",
"footer": "CertifyClouds",
"fields": [
{"title": "Vault", "value": "kv-production", "short": true},
{"title": "Items", "value": "api-key, db-password", "short": true}
]
}
]
}
Microsoft Teams¶
Post to Teams channels using Incoming Webhooks.
Setup:
- In Teams, create an Incoming Webhook:
- Go to channel settings > Connectors
- Add Incoming Webhook
- Copy webhook URL
- In CertifyClouds:
- Settings → Alerts → Create Alert Rule
- Select Webhook delivery
- Choose type: Teams
- Paste webhook URL
- Save
Payload Format:
{
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"themeColor": "EF4444",
"title": "Credential Expiry Alert",
"text": "Found 3 credentials expiring within 30 days",
"sections": [
{
"facts": [
{"name": "Vault", "value": "kv-production"},
{"name": "Items", "value": "api-key, db-password"}
]
}
]
}
Generic Webhook¶
For custom integrations not covered by Slack / Teams / PagerDuty.
Payload Format:
{
"title": "Credential Expiry Alert",
"message": "Found 3 credentials expiring within 30 days",
"color": "#EF4444",
"timestamp": "2026-05-20T12:00:00+00:00",
"source": "CertifyClouds",
"fields": [
{"title": "Vault", "value": "kv-production"},
{"title": "Items", "value": "api-key, db-password"}
]
}
For Slack and Microsoft Teams payload shapes see Webhook Delivery.
PagerDuty¶
Page on-call directly via the PagerDuty Events API v2. CertifyClouds posts to https://events.pagerduty.com/v2/enqueue; the per-service Integration Key is the credential.
Setup
- In PagerDuty: Services → Service Directory → New Service → "Events API v2" integration. Name it "CertifyClouds".
- Copy the 32-character Integration Key.
- In CertifyClouds: Settings → Alerts → Create Alert Rule → Webhook → Type: PagerDuty, paste the Integration Key in the "Routing Key" field.
- Click Send test message. A test incident appears in PagerDuty.
Per-item incidents for expiry alerts
Expiry alerts page one PagerDuty event per credential, not one per batch. Each credential gets its own incident with its own trigger/resolve lifecycle, keyed on a stable per-credential dedup key, so repeated alerts about the same credential collapse into one incident instead of flooding the on-call. Email, Slack, Teams, and generic webhooks keep a single batched message; only PagerDuty splits per item.
Severity mapping
Expiry severity is computed per credential:
| Expiry state | PagerDuty severity |
|---|---|
| Already expired | critical |
| Inside the critical window (default 7 days) | error |
| Otherwise (expiring within threshold) | warning |
Other alert types page per batch:
| Event | PagerDuty severity |
|---|---|
rotation failed | error |
sync failed | error |
sync conflict / source lag | warning |
credential_status missing in Azure (orphaned) | error |
credential_status adopted | warning |
vault_error, worker_stale | error |
Auto-resolve
When a previously-paged credential is positively healthy in a fresh live scan (rotated or its expiry pushed beyond the rule's threshold), CertifyClouds sends event_action: resolve with the same dedup key, closing the PagerDuty incident automatically. Auto-resolve is PagerDuty-only and applies to realtime rules.
Routine completion events filtered
Successful rotations and syncs, scan_completed, and discovery_completed are not forwarded to PagerDuty by design - PagerDuty is for paging, not log stream. Use email / Slack / Teams for routine confirmations.
Dedup key
Each credential maps to one PagerDuty incident, so repeat expiry alerts and their resolution update the same incident. Repeat alerts of other types about the same set of resources also collapse into one incident.
Networking requirement
CertifyClouds must reach events.pagerduty.com:443 outbound. If your deployment sits behind an egress proxy or in an air-gapped network, this hostname must be allow-listed; CertifyClouds does not currently support proxy-routed PagerDuty delivery.
Payload sent (one per credential for expiry alerts)
{
"routing_key": "<your-integration-key>",
"event_action": "trigger",
"dedup_key": "kv:<subscription-id>/kv-prod/client-secret/secret",
"client": "CertifyClouds",
"payload": {
"summary": "Key Vault: client-secret expired",
"source": "CertifyClouds",
"severity": "critical",
"timestamp": "2026-05-20T15:00:00+00:00",
"component": "expiry",
"custom_details": {
"message": "kv-prod / client-secret (secret) expired.",
"alert_type": "expiry",
"fields": [
{"name": "Source", "value": "Key Vault"},
{"name": "Resource", "value": "kv-prod"},
{"name": "Credential", "value": "client-secret"}
]
}
}
}
App Owner Emails¶
Discovery finds who owns each app in Microsoft Entra. Those owners never asked for alert email, so emailing them is off until an admin turns on Email app owners in Settings → Advanced → App behaviour. The change is recorded in the audit log.
Who gets emailed¶
| Recipient | Email app owners on | Email app owners off |
|---|---|---|
| Owners found in Entra: App Registrations, Enterprise Applications, and External ID and B2C app registrations | Yes | No |
The owner in a Key Vault secret's certifyclouds-owner-email tag | Yes | Yes |
| The owner contact set on a rotation record | Yes | Yes |
| Each alert rule's own recipients | Yes | Yes |
Owners get emails only about the apps they own, from rules with Realtime delivery and email on. Never digests.
Before owner emails can go out¶
- Permission to read owners' email addresses. The identity CertifyClouds uses in each tenant needs the optional Microsoft Graph permission
User.ReadBasic.All. For the home tenant, run the setup script again with--owner-notifications(see Azure Permissions). Settings → Access shows whether it is granted. You can turn the setting on before it is granted; emails start once it is. - An alert rule with Realtime delivery and email on, for Expiry, Rotation or Credential status alerts.
- An email provider configured for alert email.
Delivery Modes¶
Each rule delivers in exactly one mode: Realtime or Digest.
Realtime¶
Alerts sent when the triggering event is evaluated.
Best for:
- Critical alerts (expired credentials)
- Rotation failures
- Security events
Digest¶
Alerts batched and sent on a schedule.
Best for:
- Warning-level alerts (expiring soon)
- Reducing notification fatigue
- Non-urgent monitoring
Only expiry, rotation, and credential_status rules can use digest delivery. The remaining types are realtime-only; the UI hides the digest option and the API rejects it for them.
Scheduling¶
Digest Schedule¶
Configure when digest emails are sent:
| Schedule | Description |
|---|---|
| Daily 8:00 AM | Once per day |
| Daily 9:00 AM + 5:00 PM | Twice per day |
| Weekly Monday 9:00 AM | Weekly summary |
Configure Schedule¶
- Go to Settings > Alerts
- Click Digest Settings
- Select timezone; it defaults to your browser's local zone. Dropdown includes UTC, Europe/London, America/New_York, America/Chicago, America/Denver, America/Los_Angeles, Asia/Tokyo, Asia/Singapore, Australia/Sydney.
- Set delivery times
Timezone + DST handling¶
Digest schedules are stored alongside their IANA timezone (e.g. Europe/London, America/New_York). The scheduler handles Daylight Saving Time transitions automatically: a rule scheduled for 09:00 Europe/London fires at 08:00 UTC during BST (summer) and 09:00 UTC during GMT (winter) with no re-edit needed when clocks change.
Upgrading existing UTC-only rules¶
Rules created before timezone-aware scheduling are stored with the zone set to UTC so their original fire moment is preserved exactly (no behaviour change at upgrade time).
If you want one of those rules to follow your local timezone going forward (so DST is handled automatically), you must do both steps when you edit it:
- Re-enter the time as your desired local time (e.g.
09:00to mean "9 AM my local time"). - Change the timezone dropdown from
UTCto your real IANA zone (e.g.Europe/London).
Don't change the timezone without re-entering the time
Changing only the timezone dropdown re-interprets the stored time as local, which silently shifts the fire moment by your UTC offset. Example: a rule that was firing at 09:00 UTC (= 10:00 London time in summer) becomes a rule that fires at 09:00 London time (= 08:00 UTC). That's a 2-hour shift, easy to miss.
Always re-enter the picker time alongside the timezone change.
- Save
Creating Alert Rules¶
Step-by-Step¶
- Navigate: Settings > Alerts
- Create: Click "Create Alert Rule"
- Configure:
- Alert Name: Descriptive rule name
- Type: One of the 8 alert types
- Source (
expiryonly): All sources, Key Vault secrets, App Registration credentials, Enterprise Application credentials, TLS endpoints, B2C credentials (PRO), or Service credentials (PRO) - Scope (
expiry,rotation,sync,credential_status): sub-status filter, defaults to all - Alert X days before expiry (
expiryonly): 1-365, default 30 - Delivery Mode: Realtime Only or Digest Only (digest-eligible types only)
- Digest Schedule (digest rules): time, frequency, timezone
- Email: enable and enter recipient(s)
- Webhook: enable, choose Slack / Teams / Generic / PagerDuty, and enter the URL (or Integration Key for PagerDuty)
- Save: Enable and save the rule
Example Rules¶
Critical: Expired Key Vault assets (realtime)
- Type:
expiry - Source: Key Vault secrets
- Scope: Expired only
- Delivery: Email + Slack
- Mode: Realtime
- Recipients: [email protected]
Warning: Credentials expiring in 30 days (digest)
- Type:
expiry - Source: All sources
- Threshold: 30 days
- Delivery: Email
- Mode: Digest (daily)
- Recipients: [email protected]
Info: Successful rotations (realtime)
- Type:
rotation - Scope: Completed only
- Delivery: Teams webhook
- Mode: Realtime
Testing Alerts¶
Test from the rule form¶
The rule create/edit form has a Send test message button for the configured webhook:
- Go to Settings > Alerts
- Open the rule (or start creating one) and configure the webhook
- Click Send test message
- Verify the notification arrived
Programmatic test¶
POST /api/alerts/test dispatches a test notification to the email recipients and/or webhook configuration supplied in the request body; no saved rule is needed. Admin-only and rate-limited. Request and response shapes are in your deployment's /docs.
Alert History¶
View all sent alerts:
- Go to Alerts tab
- Click History
- Filter by:
- Date range
- Alert type
- Delivery status
Statuses¶
| Status | Description |
|---|---|
| Delivered | Successfully sent |
| Failed | Delivery failed (check logs) |
| Pending | In digest queue |
| Retrying | Retry in progress |
Retry Logic¶
Failed webhook deliveries are retried with exponential backoff. 2xx responses are treated as success; 4xx responses (except 408 / 429) are treated as permanent client errors and not retried; 5xx, 408, 429, timeouts, and connection errors are retried. Persistent failures eventually mark the alert as failed and surface in the rule's delivery history.
See Webhook Delivery for the receiver payload shapes.
Troubleshooting¶
Emails not received¶
- Check the active provider in Settings → Advanced → Email
- Verify recipient email address
- Check spam/junk folder
- Review application logs for errors
Webhook failures¶
- Verify webhook URL is correct
- Check if endpoint is accessible from CertifyClouds
- Ensure endpoint accepts POST requests
- Check for firewall/network restrictions
Duplicate notifications¶
- Check for overlapping rules (e.g. an "All sources" expiry rule alongside a source-scoped one)
- Review threshold settings
- Owners who are also rule recipients receive both the owner-scoped email and the full batch; this is by design
API access¶
Alert rules can be managed programmatically via /api/alerts/rules and delivery history queried via /api/alerts/history. The full endpoint catalogue is in API Endpoints; exact request and response shapes are in your deployment's /docs.
Best Practices¶
- Don't over-alert: Use digests for warnings, real-time for critical
- Route appropriately: Send security alerts to security team, ops alerts to ops
- Test regularly: Use the test button to verify delivery
- Monitor failures: Check alert history for delivery issues
- Use thresholds wisely: 30 days gives time to act without noise