7 Notifications and Email

TraxrGRC sends plain-text email for reminders, decisions, rule matches, scheduled reports, security alerts and outside assessments. This chapter covers the mail server, the templates every email is built from, the daily sweeps that find due work, notification rules, scheduled report delivery, testing and troubleshooting.

7.1 How email is sent

  1. Something in the application decides an email is due: a status change, a daily sweep finding an overdue review, a rule matching, a scheduled report coming round.
  2. The application renders the template (subject and body with the placeholders filled in) and writes a row to the delivery log with status Queued.
  3. It hands a job to the background worker service through the job queue in the database.
  4. The worker connects to the SMTP server from Settings → Integrations and sends the message, then marks the row Sent, or Failed with the server's error.

The consequences for an administrator:

7.2 Configuring SMTP

The mail server is configured on Settings → Integrations, in the SMTP card. There are no environment variables for it: the settings live in the database and are included in backups. Until it is configured, TraxrGRC tries localhost port 25 with the sender grc@localhost, which fails in a container, so every email is logged as Failed.

Saving and testing are administrator operations.

The Integrations screen with the SMTP and LDAP cards; the SAML SSO card follows below.
Figure 7.1. The Integrations screen with the SMTP and LDAP cards; the SAML SSO card follows below.
FieldWhat to enter
HostThe SMTP server or relay hostname. Required.
Port587 for submission with STARTTLS, 465 for implicit TLS, 25 for an internal relay.
UsernameThe account to authenticate with. Leave empty for a relay that accepts the server without authentication.
PasswordThe account's password. Stored encrypted and never sent back to the browser; a stored one shows "Stored. Type to replace."
From addressThe sender on every email, for example [email protected]. Required.
Use TLS (port 465)On for implicit TLS (port 465). Off for STARTTLS or a plain relay.

Rules the server enforces:

To configure the mail server:

  1. Open Settings → Integrations.
  2. Fill in the SMTP card and click Save. The save is recorded in the Audit Log with the values before and after (the password only as changed or unchanged), and every administrator is sent a security alert.
  3. Click Send test email (see below).

When an instance is restored onto a server with a different settings key, the SMTP password cannot be decrypted: it reads as empty, the server logs settings.decrypt_failed, and authenticated sending fails until you type the password again (see Backup and Restore).

7.3 Testing email

Send test email on the SMTP card sends a message to your own account's address, with the product name and "SMTP test" in the subject. The result appears at once: "Test email sent to your address." or "Test email failed:" with the server's reason.

The test is sent directly by the web service. To prove the whole path through the worker, check a real email in the delivery log:

  1. Save the SMTP card. Saving emails every administrator a security alert.
  2. Open /settings/notifications, tab Delivery log.
  3. Find the security.alert rows for the save. Sent means the worker delivered them; Failed shows the reason in Error; Queued that stays queued means the worker is not running.

For a test instance, the deployment includes a mail catcher that accepts every message and shows it in a web page. It is meant for trying things out, never for production:

docker compose --profile dev up -d mailpit

Then set Host mailpit, Port 1025, no username and Use TLS off, and open http://127.0.0.1:8025 on the server to read the messages.

7.4 The Notifications page

Settings → Notifications (address /settings/notifications) has four tabs:

TabWho sees itWhat it holds
Templatesnotifications:read; editing needs notifications:updateEvery email's subject and body
RulesAdministratorsNotification rules
Delivery lognotifications:readEvery email queued; rule and scheduled report emails only for administrators
Schedulernotifications:read; saving needs notifications:updateWhen the daily sweeps run and their lead times

The built-in GRC Manager role holds read and update on Notifications. All changes are recorded in the Audit Log under the module notifications.

7.5 Templates

Every email TraxrGRC sends is built from a template with a fixed key. The Templates tab lists each one with its Key, Name, Module, Subject and an Enabled switch, with search and column filters. The Module filter offers Risks, Compliance, Policies, Controls, Awareness, Data privacy, Assessments, Reports and Platform.

The Templates tab listing the email templates with their keys, modules, subjects and Enabled switches.
Figure 7.2. The Templates tab listing the email templates with their keys, modules, subjects and Enabled switches.

7.5.1 Template keys and their variables

The variables below are the ones each default template uses. {{app.name}} (the product name from Branding) works in every template.

KeySent whenVariables
risk.review.dueA risk review falls within the review lead daysrisk.title, review.dueDate
risk.review.overdueA risk review is past duerisk.title, review.dueDate
risk.appetite.breachA risk's residual score moves into an over-appetite bandrisk.title, risk.score, risk.band
risk.exception.expiringAn approved risk exception expires within the exception lead daysexception.title, exception.expiresAt, risk.title
risk.acceptance.rejectedSomeone rejects the exception request a review's "Accepted over appetite" result raised; sent to the reviewerrisk.title, exception.decidedBy, risk.url
compliance.exception.expiringAn approved compliance exception is expiringexception.title, exception.expiresAt, item.code, item.name
policy.review.dueA policy review is coming duepolicy.title, review.dueDate
policy.review.overdueA policy review is past duepolicy.title, review.dueDate
policy.exception.expiringAn approved policy exception is expiringexception.title, exception.expiresAt, policy.title
policy.acknowledgement.requestedPeople are asked to acknowledge a policypolicy.title, policy.version, acknowledgement.dueDate, acknowledgement.url
policy.acknowledgement.dueAn acknowledgement is coming duesame as above
policy.acknowledgement.overdueAn acknowledgement is overduesame as above
awareness.dueAn awareness program is due and not completedprogram.title, program.dueDate
control.audit.dueA control audit is coming duecontrol.name, test.dueDate, control.successCriteria
control.audit.overdueA control audit is overduecontrol.name, test.dueDate, control.successCriteria
control.audit.failedA control audit is recorded as failedcontrol.name, test.completedAt, test.notes
control.maintenance.dueControl maintenance is coming duecontrol.name, test.dueDate, control.maintenanceTask
control.maintenance.overdueControl maintenance is overduecontrol.name, test.dueDate, control.maintenanceTask
dataprivacy.review.dueA record of processing review is coming duerecord.name, review.dueDate
dataprivacy.review.overdueA record of processing review is overduerecord.name, review.dueDate
dataprivacy.dpa.expiringA third party's data processing agreement is expiringthirdParty.name, dpa.expiresAt
dataprivacy.dpa.expiredA data processing agreement has expiredthirdParty.name, dpa.expiresAt
evidence.expiringEvidence is within 30 days of its valid-until date (to its owner and, for a third-party report, the third party's owner; one email if they are the same person)evidence.title, evidence.type, evidence.thirdParty (", name" or empty), evidence.validUntil, evidence.url
evidence.expiredEvidence has passed its valid-until date (to the same people as evidence.expiring)as evidence.expiring
dataprivacy.tia.dueA transfer impact assessment review is coming duethirdParty.name, tia.country, tia.reviewDue
dataprivacy.tia.overdueA transfer impact assessment review is overduethirdParty.name, tia.country, tia.reviewDue
dataprivacy.questionnaire.sentA data mapping questionnaire is sent to a Data Liaisonrequest.subject, request.requester, request.template, request.dueDate, request.message, request.url
dataprivacy.questionnaire.submittedA Data Liaison submits answersrequest.subject, request.respondent, request.template, request.url
dataprivacy.dpia.approvedAgainstAdviceA DPIA is approved after the DPO advised changes or not proceeding (to the DPO)dpia.title, dpia.record, dpia.approver, dpia.recommendation, dpia.reason, dpia.url
dataprivacy.attestation.sentThe annual check of a record goes to its Data Liaisonrequest.subject, request.dueDate, request.url
dataprivacy.questionnaire.dueA questionnaire is coming duerequest.subject, request.dueDate, request.url
dataprivacy.questionnaire.overdueA questionnaire is overduerequest.subject, request.dueDate, request.url
assessment.sentAn assessment is sent to an outside contactassessment.title, assessment.contactName, assessment.dueNote, assessment.url
assessment.reminderAn unanswered assessment is coming dueassessment.title, assessment.contactName, assessment.dueDate, assessment.url
assessment.returnedAnswers are returned to the contact for reworkassessment.title, assessment.contactName, assessment.flaggedCount, assessment.dueNote, assessment.url
assessment.overdueAn assessment was not answered by its due dateassessment.title, assessment.contact, assessment.dueDate, assessment.url
assessment.completedAn assessment is completedassessment.title, assessment.contact, assessment.score
report.scheduledA scheduled report is sentschedule.name, report.title, report.generatedAt, attachment.note, report.url, profile.url
notification.ruleA notification rule matchesevent.summary, event.detail, record.label, record.title, record.url, rule.name, profile.url
digest.dailyThe daily digest, when turned ondigest.date, digest.body
security.alertA security event (see Audit Log and Evidence Integrity)alert.title, alert.detail, alert.actor, alert.ip, alert.time, alert.url
user.password.resetAn administrator resets a user's passwordreset.by, reset.time
user.password.changedA user changes their own password on My profilechange.time
user.mfa.resetAn administrator resets a user's two-step verificationreset.by, reset.time

Dates in reminder variables are written yyyy-MM-dd. alert.time, reset.time and change.time are shown in the recipient's time zone. The digest.daily subject defaults to "{{app.name}} daily digest: {{digest.date}}".

7.5.2 Editing a template

  1. Click the template's key. The edit dialog opens.
  2. Change the Name (up to 120 characters), Subject (up to 300) or Body. Placeholders are written {{variable.name}}.
  3. Check the Available vars panel beside the fields. It lists each variable the template receives, with its meaning, plus app.name.
  4. Click Save template. The next email queued from that template uses the new text; emails already queued keep the old text.
The Edit template dialog for risk.appetite.breach with the subject, body and the Available vars panel.
Figure 7.3. The Edit template dialog for risk.appetite.breach with the subject, body and the Available vars panel.

Things to know:

7.5.3 Turning a template off

The Enabled switch stops a template without editing it. Nothing is sent from a disabled template: fixed notifications are logged as Skipped with the reason template-disabled, and rule and scheduled report emails as Suppressed. Disabling security.alert stops security alerts to administrators; leave it on.

7.6 Scheduler

The Scheduler tab holds the Daily sweeps scheduler card. Once a day the worker scans reviews, exceptions, control tests, awareness programs, data processing agreements, transfer impact assessments and questionnaires and queues the reminders above. The same run handles deadline notification rules, assessment reminders and repeats, and policy acknowledgement reminders.

The Scheduler tab with the daily digest switch, cron schedule and lead days.
Figure 7.4. The Scheduler tab with the daily digest switch, cron schedule and lead days.
SettingDefaultWhat it means
Daily digestOffWhen on, each person gets one digest.daily email listing their items instead of one email per item.
Cron schedule (UTC)0 7 * * *When the sweep runs: five fields (minute hour day month weekday) in UTC. 0 7 * * * is 07:00 UTC every day; 30 5 * * 1-5 is 05:30 UTC on weekdays. Invalid expressions are refused.
Review lead days7Reviews (risk, policy, data privacy), control tests and awareness programs due within this many days are reminded as "due". Earlier ones are "overdue". 0 to 365.
Exception lead days14Approved risk, compliance and policy exceptions expiring within this many days are flagged. 0 to 365.
Organization time zoneAmerica/New_YorkThe IANA zone that decides which calendar day it is for everyone: due and overdue (My Tasks, control status, lists, reports, the AI assistant), expiry of exceptions and evidence, new review and test dates, POA&M opened and due dates, the sweep's due and overdue buckets, form defaults and export file names. Each person's own zone still decides how times are shown. Stored as organization.timeZone; audited with the scheduler settings. Choose the zone your staff and auditors work in; the cron schedule stays in UTC.

Click Save settings to store them. Saving applies a changed Cron schedule (UTC) to the job queue at once, and the confirmation reads "Scheduler settings saved. The new schedule is active." If the queue cannot be reached (for example because the worker has never run), the save still succeeds and a warning says "The new schedule takes effect when the background worker next starts"; start or restart the worker in that case:

docker compose restart worker

The digest switch and the lead days apply at the next run.

Run sweeps now runs the whole sweep at once and reports how many items it found, for how many recipients, and how many digests it queued. It sends real email. An item already reminded in the last 20 hours is skipped, so running it next to the scheduled run sends nothing twice. A reminder goes only to a person who can still read the record it names. The run is recorded in the Audit Log.

7.7 Notification rules

Fixed notifications go to record owners on fixed events. Notification rules let an administrator email other people about other events. The Rules tab and every rule action are for administrators only. A new or upgraded installation has no rules.

The Rules tab listing the demo's notification rules with their triggers, records, recipients and opt-out counts.
Figure 7.5. The Rules tab listing the demo's notification rules with their triggers, records, recipients and opt-out counts.

7.7.1 Creating a rule

  1. Click New rule. The New notification rule dialog opens.
  2. Fill in the fields and click Create rule (Save rule when editing).
The New notification rule dialog with the trigger, record types, status condition and recipient choices.
Figure 7.6. The New notification rule dialog with the trigger, record types, status condition and recipient choices.
FieldWhat it means
NameUp to 120 characters. Shown in the email, in the delivery log and on each person's My profile page.
TriggerComment added, Record created, Status changed, Audit finding created, Control test failed, Deadline approaching or Deadline overdue.
RecordsRisk, Control, Compliance requirement, Policy, Risk exception, Compliance exception, Policy exception, Incident, Project, Third party, Audit finding, as far as the trigger applies to them. None ticked means every kind the trigger supports.
Only when the record's status isOptional. For Status changed, the new status; for other triggers, the status at the time. None ticked means any status.
RecipientsAny mix of: the record's owner; the members of the record's owner group; people @mentioned in the comment (Comment added only); named users; members of chosen groups; members of every group carrying a chosen role. Active users only; no outside addresses. At least one recipient is required.
EnabledUntick to pause the rule.

7.7.2 How rules are delivered

7.7.3 Bulk changes and rules

Changes made through an API token (including the bundle loader) and through a CSV import send no rule emails by default; the delivery log lists them as Suppressed with the reason api-write. This keeps a data load from flooding people's inboxes. To include them, turn on Notify on API changes and CSV imports below the rules list. The hourly cap still applies. Fixed notifications (reminders, decisions) are not affected by this switch.

7.8 Scheduled reports delivery

Scheduled reports are set up by users with Reports rights on Reports → Scheduled (see the User Manual, Report Center). For the administrator:

A new or upgraded installation has no schedules. On an upgraded installation, add Create, Update and Delete on Reports to the roles that should manage schedules (see Users, Groups and Roles).

7.9 The delivery log

The Delivery log tab lists every email, newest first, with Created, Template, To, Rule or schedule, Subject, Status, Error and Sent at. Filter by status and search across the recipient, subject, template key and error. Users who are not administrators do not see rule or scheduled report emails.

StatusMeaning
QueuedWaiting for the worker.
SendingA rule or report email being sent.
SentAccepted by the mail server.
FailedThe mail server refused it or could not be reached; Error holds the reason.
SkippedA fixed notification deliberately not sent: template-disabled, template-not-found, no-recipient, recipient-unavailable (the user is inactive or gone), or "sent in digest" when the item went into a digest.
SuppressedA rule or scheduled report email deliberately not sent: no-access, opted-out, api-write, rate-limit, recipient-inactive, record-deleted, rule-disabled, template-disabled, schedule-paused, schedule-deleted or report-unavailable.

A fixed notification that fails is not retried: it stays Failed. Review, exception, control test and awareness reminders come again with the next daily sweep while the item is still due. Reminders sent once per state (data processing agreements, transfer impact assessments and data mapping questionnaires) and event emails such as risk.appetite.breach may not be sent again, so fix the mail server and tell the people concerned.

7.9.1 Troubleshooting

SymptomLikely cause and fix
Every row Failed, error mentions localhost or ECONNREFUSEDSMTP was never configured. Fill in Settings → Integrations → SMTP.
Rows stay QueuedThe worker is not running. Check docker compose ps and docker compose logs worker.
Failed with an authentication errorWrong username or password, or the password was cleared by a host or port change. Type it again and save.
Failed with a TLS or STARTTLS errorPort and Use TLS do not match the server: 465 needs Use TLS on, 587 needs it off. A relay without STARTTLS cannot take a username.
Sent, but nothing arrivesThe mail was accepted and then filtered or rejected downstream. See deliverability below and check the relay's own logs.
Reminders arrive at the wrong hourThe cron is in UTC. If saving showed the warning that the schedule takes effect when the worker next starts, restart the worker.
Links in emails point to the wrong addressAPP_URL is wrong. Fix it in the deployment's .env and restart.
Nobody gets rule emails after a data loadExpected: API and import changes are suppressed (api-write).

7.10 Deliverability

TraxrGRC hands mail to your SMTP server; whether it reaches inboxes depends on how that server and your domain are set up.