Use a custom server to send Ory Identity messages to users
The Ory Network comes with SMTP email sending configured out of the box. Ory emails are sent from this address:
{project.name} via Ory <no-reply@courier-eu.mg.oryapis.com>
You must send emails using your SMTP server to change the sender address (from_address
) and sender name (from_name
).
Send emails using your SMTP server
You can send emails from your own SMTP server. Follow these steps to configure Ory to use a custom SMTP server:
- Ory Console
- Ory CLI
- Go to Branding → Email configuration in the Ory Console
- Toggle the Advanced Settings switch
- Provide the configuration for your SMTP server
-
Download the Ory Identities config from your project and save it to a file:
## List all available workspaces
ory list workspaces
## List all available projects
ory list projects --workspace <workspace-id>
## Get config
ory get identity-config --project <project-id> --workspace <workspace-id> --format yaml > identity-config.yaml -
Add the configuration for your custom SMTP server
config.ymlcourier:
smtp:
connection_uri: smtp://username:password@server:port/
from_address: hello@example.org
from_name: My Company
Note: The username and password must be URI encoded.
-
Update the Ory Identities configuration using the file you worked with:
ory update identity-config --project <project-id> --workspace <workspace-id> --file updated_config.yaml
SMTP security mechanisms
SMTP has six different security mechanisms. Most SMTP services today use Explicit StartTLS with trusted certificates.
- Recommended: StartTLS with certificate trust verification. This is the most common option today:
smtp://username:password@server:port/
- StartTLS without certificate trust verification:
smtp://username:password@server:port/?skip_ssl_verify=true
- Cleartext SMTP uses no encryption and is not secure. This option is often used in development environments:
smtp://username:password@server:port/?disable_starttls=true
- Implicit TLS with certificate trust verification:
smtps://username:password@server:port/
- Implicit TLS without certificate trust verification:
smtps://username:password@server:port/?skip_ssl_verify=true
- Implicit TLS with certificate verification which works if the server is hosted on a subdomain and uses a non-wildcard domain
certificate:
smtps://username:password@subdomain.my-mailserver.com:1234/?server_name=my-mailserver.com
SMTP Integrations
Sample connection URIs to send emails via SMTP using different providers.
Mailgun
Use the following connection URI to send emails using Mailgun via SMTP.
Note: The username and password must be URI encoded.
smtp://{smtp-user}:{smtp-password}@smtp.mailgun.org:587
# For example:
# smtp://some-user%40mailgun.example.org:df2a2c4e-5caa-4f04-85b9-72d54a2468ad@smtp.eu.mailgun.org:587
AWS SES SMTP
Use the following connection URI to send emails using AWS SES SMTP via SMTP.
Note: The username and password must be URI encoded.
smtp://{smtp-user}:{smtp-password}@email-smtp.{region}.amazonaws.com:587/
# For example:
# smtp://theuser:the-password@email-smtp.eu-central-1.amazonaws.com:587/
Postmark
Use the following connection URI to send emails using Postmark via SMTP.
Note: The username and password must be URI encoded.
smtp://{YOUR_POSTMARK_SEVER_API_TOKEN}:{YOUR_POSTMARK_SEVER_API_TOKEN}@smtp.postmarkapp.com:587/
# For example:
# smtp://thetoken:thetoken@smtp.postmarkapp.com:587/
Sendgrid
Use the following connection URI and settings to send emails using Sendgrid via SMTP.
- Sender address: an email address for a domain that has been verified in SendGrid via Domain Authentication
- Hostname: smtp.sendgrid.net
- Port: 587
- Security Mode: STARTTLS
- Username: apikey
- Password: the API key created in SendGrid, with the full “Mail Send” permission (no other permissions needed)
- SMTP Headers: none If you are unsure which port to use, a TLS connection on port 587 is typically recommended.
smtp://apikey:<YOUR_SENDGRID_API_KEY>@smtp.sendgrid.net:587/
# For example:
smtp://apikey:somekey@smtp.sendgrid.net:587/
Send emails using an HTTP server
Ory Identities supports sending emails using an HTTP server. This is useful if you want to customize the email content or use a service that doesn't provide an SMTP server.
- Ory Console
- Ory CLI
- Go to Branding → Email configuration in the Ory Console.
- Select HTTP Server.
- Configure your HTTP server.
- Click Save.
-
Download the Ory Identities config from your project and save it to a file:
## List all available workspaces
ory list workspaces
## List all available projects
ory list projects --workspace <workspace-id>
## Get config
ory get identity-config --project <project-id> --workspace <workspace-id> --format yaml > identity-config.yaml -
Add the configuration for your custom HTTP server
config.ymlcourier:
delivery_strategy: http
http:
request_config:
url: https://mail-sender.example.com
method: POST
body: base64://... # See below for the default payload and available variables
headers:
Content-Type: application/json
auth: # leave out, if your server doesn't require authentication, but note that we don't recommend that
type: basic_auth # or api_key
config:
user: my-username
password: my-password
# if you want to use an API key (type: api_key), use the following config instead:
# name: my-api-name
# value: my-api-key-value
# in: header # or cookie -
Update the Ory Identities configuration using the file you worked with:
ory update identity-config --project <project-id> --workspace <workspace-id> --file updated_config.yaml
Payload
The payload of the HTTP request is a JSON object that's generated using a Jsonnet template. By default, the following Jsonnet template is used:
function(ctx) {
recipient: ctx.recipient,
template_type: ctx.template_type,
to: if "template_data" in ctx && "to" in ctx.template_data then ctx.template_data.to else null,
recovery_code: if "template_data" in ctx && "recovery_code" in ctx.template_data then ctx.template_data.recovery_code else null,
recovery_url: if "template_data" in ctx && "recovery_url" in ctx.template_data then ctx.template_data.recovery_url else null,
verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null,
verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null,
login_code: if "template_data" in ctx && "login_code" in ctx.template_data then ctx.template_data.login_code else null,
registration_code: if "template_data" in ctx && "registration_code" in ctx.template_data then ctx.template_data.registration_code else null,
subject: if "template_data" in ctx && "subject" in ctx.template_data then ctx.template_data.subject else null,
body: if "template_data" in ctx && "body" in ctx.template_data then ctx.template_data.body else null
}
The courier passes the following object as the ctx
parameter into the Jsonnet template:
Variable | Type | Description |
---|---|---|
recipient | String | The email address of the recipient. |
template_type | String | The type of the template. See the list of available templates for a full list |
template_data | Object | The data that should be included in the email. See the list of variables for each template for a full list. |
In most cases, the default payload should be sufficient.
HTTP Integrations
Sample configurations to send emails via HTTP using different providers.
Sendgrid
Use the following connection URI and settings to send emails using Sendgrid via HTTP.
...
courier:
delivery_strategy: http
http:
request_config:
url: https://api.sendgrid.com/v3/mail/send
method: POST
body: file:///etc/config/kratos/mail.template.jsonnet
headers:
"Content-Type": "application/json"
auth:
type: api_key
config:
name: Authorization
value: Bearer <API_KEY>
in: header
...
Here is one example of a Jsonnet body:
function(ctx) {
"personalizations": [
{
"to": [
{
"email": if "TemplateData" in ctx && "To" in ctx.TemplateData then ctx.TemplateData.To else null)
}
],
"verificationCode": if "TemplateData" in ctx && "VerificationCode" in ctx.TemplateData then ctx.TemplateData.VerificationCode else null
}
],
// Other values and personalizations .......
}
Troubleshooting
In general, if you have problems setting up email delivery, you can view outgoing messages on the Monitoring → Email Delivery page in the Ory Console.
The Sent
state of an email only indicates whether Ory Identities successfully "handed" off the email to the SMTP server.
Emails do not arrive
The best way to figure out, why an email did not arrive is checking the Email Delivery dashboard in the Ory Console. It will show all emails sent by your project, along with its delivery state. If the Ory Network could not reach your SMTP server or there was an authentication failure, it will be indicated here along with the error message.
If the email's status is Sent
, but it did not arrive, please check the spam folder or the logs of your custom SMTP server (if
configured).
Emails are marked as spam
If you're using a custom domain, but no custom SMTP server, some (or all) emails the Ory Network sends, can be marked as spam or blocked by the email providers of your users, such as Gmail. This is due to the phishing/spam protection these providers have in place to protect their users.
To read more, see Automated Emails but in short: we recommend setting up a custom SMTP server, if you use custom domains.