Skip to content

Email and OAuth2

This page covers two login-related areas:

  • static email configuration
  • runtime OAuth2 provider configuration

OAuth2 providers are no longer declared in the config file, environment variables, or Helm values. They live in runtime settings under oauth2.providers.

Email settings remain static and are used for SMTP connectivity and sender identity.

email:
smtp_host: "smtp.example.com"
smtp_port: 587
smtp_username: "synctv@example.com"
smtp_password_file: "/run/secrets/smtp_password"
from_email: "synctv@example.com"
from_name: "SyncTV"
use_tls: true
FieldDefaultMeaning
email.smtp_host""SMTP server host. Empty means email sending is not configured
email.smtp_port587SMTP port
email.smtp_username""SMTP login username
email.smtp_password""SMTP login password; supports smtp_password_file
email.from_email""Sender email address. Required and validated when SMTP is configured
email.from_nameSyncTVSender display name
email.use_tlstrueWhether SMTP uses TLS

Email verification codes, password reset, and email MFA depend on these SMTP settings. Standalone email login only serves existing accounts; the code request API intentionally returns a generic message to avoid account enumeration. Whether email signup is open or requires review is a runtime setting; see Runtime Settings.

oauth2.providers is a dynamic object. Each key is a provider instance name such as github, logto1, or corp_oidc. Instance names may contain only ASCII letters, digits, _, and -.

Every instance uses the same outer envelope:

{
"type": "github",
"enable_signup": true,
"signup_need_review": false,
"config": {
"client_id": "github-client-id",
"client_secret": "github-client-secret",
"redirect_url": "https://app.example.com/oauth2/callback"
}
}

Outer fields:

FieldMeaning
typeProvider type. Supported values are defined by the built-in provider registry
enable_signupWhether first-time login through this provider can create a local account
signup_need_reviewWhether first-time signup should enter the review queue
configProvider-private configuration. The outer layer does not enumerate it
{
"github": {
"type": "github",
"enable_signup": true,
"signup_need_review": false,
"config": {
"client_id": "github-client-id",
"client_secret": "github-client-secret",
"redirect_url": "https://app.example.com/oauth2/callback"
}
}
}
  • When runtime settings change, the OAuth2 service rebuilds its provider map from the new value.
  • Missing instance names mean the login entry point is unavailable.
  • enable_signup=false only blocks first-time account creation through that provider. Existing linked OAuth2 logins still work.
  • signup_need_review=true sends first-time OAuth2 signup into the review flow.

The redirect URL is now written directly in each provider’s config.redirect_url. That keeps the scheme local to each provider instance instead of making it a global knob.

Put it in config.client_secret and manage it through runtime settings. Do not keep it in the static config file.