Skip to content

Authentication and email

Configure SMTP delivery, OAuth providers, optional TOTP MFA, and signup policy for self-hosted Dreadnode.

The authentication, email, and signup settings on this page are chart configuration, applied by a redeploy. Configure them in a Helm overlay, under Authentication & Email in the Admin Console, or with matching KOTS ConfigValues items. The email allow-list and other settings without a dedicated field use Advanced Helm Values. Every credential on this page has a protected Embedded Cluster field.

Helm commands on this page use $NAMESPACE. Set it to your release namespace before creating Secrets:

Terminal window
export NAMESPACE=dreadnode

The runtime signup controls under Admin → Security — IP rate limits, CIDR deny and allow policies, and disposable-domain rules — are a separate plane and need no redeploy. See Users and organizations.

Users enable authenticator-app MFA under Account Settings → Security. The behavior is the same in SaaS and Enterprise deployments: password and OAuth/OIDC sign-in requires a TOTP or unused recovery code before Dreadnode issues access and refresh tokens. API keys and service credentials remain unchanged.

TOTP secrets use the existing SECRETS_ENCRYPTION_KEY. Keep that key stable across API replicas and upgrades; changing it makes enrolled factors unreadable. Recovery codes and five-minute challenge tokens are stored only as hashes.

Enabling, disabling, or resetting MFA revokes every refresh session for the user. Existing stateless access tokens can remain valid until the configured access-token TTL expires, which defaults to 30 minutes.

Verify the account owner’s identity using your organization’s recovery procedure, then call the remediation endpoint with a recorded reason:

Terminal window
curl -X POST 'https://<your-domain>/api/v1/admin/users/<user-id>/mfa/reset' \
-H 'Authorization: Bearer <operator-access-token>' \
-H 'Content-Type: application/json' \
--data '{"reason":"Identity verified through the approved recovery procedure"}'
# {"enabled":false}

The operator needs the platform:account_remediation scope. The reset removes the factor, invalidates pending MFA challenges, revokes refresh sessions, and writes an audit event containing the operator, subject, reason, and timestamp.

Security operators can export evidence from GET /api/v1/admin/auth/mfa/audit, optionally filtering by subject_user_id. Audit rows never contain TOTP secrets, submitted codes, recovery codes, provider tokens, or MFA transaction tokens.

By default, Dreadnode does not send email. The API logs invitation, password-reset, account-setup, and verification links at WARNING level so an operator can deliver them manually.

When an administrator assigns organization ownership to an email without an account, Dreadnode sends a 24-hour account setup link. The recipient uses that link to set a password, verify the email, and sign in. Dreadnode never sends a temporary password. Configure email delivery before assigning owners if recipients must claim accounts without operator help.

Loops deployments can add an account-setup template ID to EMAIL_LOOPS_TRANSACTIONAL_IDS for dedicated setup copy. When that key is absent, Dreadnode uses the configured confirm-email template so existing deployments keep sending links.

Configure the API chart:

dreadnode-api:
config:
email:
provider: smtp
fromAddress: [email protected]
fromName: Dreadnode
smtp:
host: smtp.example.com
port: 587
user: apikey
useTls: true
existingSecret: dreadnode-smtp-password
passwordKey: password

Create the referenced Secret in the Helm release namespace:

Terminal window
kubectl -n "$NAMESPACE" create secret generic dreadnode-smtp-password \
--from-literal=password='<smtp-password>'

Local password authentication remains available when you configure OAuth. Each provider can be enabled independently.

Use the generic provider for Authentik, Keycloak, Okta, and other OpenID Connect issuers. metadataUrl, clientId, and the client Secret are all required.

dreadnode-api:
config:
oauth:
oidc:
clientId: <oidc-client-id>
metadataUrl: https://idp.example.com/.well-known/openid-configuration
existingSecret: dreadnode-oidc-oauth
clientSecretKey: clientSecret
displayName: Authentik
scopes: openid email profile

Create the referenced Secret:

Terminal window
kubectl -n "$NAMESPACE" create secret generic dreadnode-oidc-oauth \
--from-literal=clientSecret='<oidc-client-secret>'

Register this redirect URI with the provider:

https://<your-domain>/auth/oidc/callback

Use the scheme and domain configured for Dreadnode. The scopes must include openid and must cause the issuer to return an email claim in either the ID token or userinfo response; openid email profile is the usual configuration. New users receive the default role on first login; group and role claim mapping is not currently supported. An issuer that sends group claims logs in normally, and Dreadnode ignores those claims.

Create an OIDC Web Application in Okta. Dreadnode authenticates with a client secret, so do not choose the SPA application type. Keep the default Client secret authentication method (client_secret_basic); post-only client authentication is not supported. Configure:

  • Sign-in redirect URI: https://<your-domain>/auth/oidc/callback, matching exactly
  • Grant type: Authorization Code
  • Scopes: openid email profile

Okta exposes two authorization-server shapes:

ServerMetadata URL
Orghttps://<your-okta-domain>/.well-known/openid-configuration
Custom (including default)https://<your-okta-domain>/oauth2/<server-id>/.well-known/openid-configuration

Use the org authorization server for ordinary Okta sign-in. Choose a custom authorization server only when you need its customized claims or access policies, and make sure that server has an access policy covering the Dreadnode application. The generic connector accepts either discovery URL.

Dreadnode matches returning users by email address. The sub claim is retained with the identity data and is checked when ID-token claims are supplemented from the userinfo endpoint, but it is not used for account lookup. Changing a user’s Okta email can therefore create a separate Dreadnode account.

OAuth-created accounts are treated as email-confirmed even when Okta omits email_verified. Restrict the Okta application’s assignment and authorization policy to users whose email addresses your organization trusts.

GitHub and Google use the same secret-backed pattern:

dreadnode-api:
config:
oauth:
github:
clientId: <github-client-id>
existingSecret: dreadnode-github-oauth
clientSecretKey: clientSecret
google:
clientId: <google-client-id>
existingSecret: dreadnode-google-oauth
clientSecretKey: clientSecret

Create one Secret for each configured provider:

Terminal window
kubectl -n "$NAMESPACE" create secret generic dreadnode-github-oauth \
--from-literal=clientSecret='<github-client-secret>'
kubectl -n "$NAMESPACE" create secret generic dreadnode-google-oauth \
--from-literal=clientSecret='<google-client-secret>'

Remove the provider you do not use. The Embedded Cluster secrets are protected in stored configuration and written to Kubernetes Secrets without a cluster-shell step.

Register these callback URLs with each provider:

  • GitHub: https://<your-domain>/auth/github/callback
  • Google: https://<your-domain>/auth/google/callback

Both providers reach the public GitHub and Google endpoints, so neither works on an airgapped install. To use Google Workspace as your enterprise identity provider, prefer OpenID Connect instead, which centralizes sign-in at your own tenant. Dreadnode does not currently map identity-provider groups to platform or organization roles.

Raise the minimum password length or restrict new accounts to email patterns:

dreadnode-api:
config:
auth:
minPasswordLength: 12
emailRegexes:
- '^.*@example\.com$'

An empty emailRegexes list allows any email address. Omitting minPasswordLength uses the API default of 8.