Skip to content

Authentication Results

VaultSandbox validates email authentication for every received email, providing detailed SPF, DKIM, DMARC, and reverse DNS results.

Email authentication helps verify that an email:

  • Came from the claimed sender domain (SPF)
  • Wasn’t modified in transit (DKIM)
  • Complies with the domain’s policy (DMARC)
  • Came from a legitimate mail server (Reverse DNS)

Every email has an authResults property:

Email email = inbox.waitForEmail(Duration.ofSeconds(10));
AuthResults auth = email.getAuthResults();
System.out.println(auth.getSpf()); // SPF result
System.out.println(auth.getDkim()); // DKIM results (list)
System.out.println(auth.getDmarc()); // DMARC result
System.out.println(auth.getReverseDns()); // Reverse DNS result

Verifies the sending server is authorized to send from the sender’s domain.

SpfResult spf = email.getAuthResults().getSpf();
if (spf != null) {
System.out.println(spf.getResult()); // "pass", "fail", "softfail", etc.
System.out.println(spf.getDomain()); // Domain checked
System.out.println(spf.getIp()); // IP address being validated
System.out.println(spf.getDetails()); // Additional explanation
}
StatusMeaning
passSending server is authorized
failSending server is NOT authorized
softfailProbably not authorized (policy says ~all)
neutralDomain makes no assertion
temperrorTemporary error during check
permerrorPermanent error in SPF record
noneNo SPF record found
PropertyTypeDescription
resultStringSPF check result: pass, fail, softfail, neutral, none, temperror, permerror
domainStringDomain being checked
ipStringIP address of the sending server
detailsStringAdditional explanation about the result
MethodReturn TypeDescription
getResult()StringReturns the SPF result
getDomain()StringReturns the checked domain
getIp()StringReturns the sending server IP
getDetails()StringReturns additional explanation
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
SpfResult spf = email.getAuthResults().getSpf();
if (spf != null) {
assertThat(spf.getResult()).isEqualTo("pass");
assertThat(spf.getDomain()).isEqualTo("example.com");
System.out.printf("SPF %s for %s%n", spf.getResult(), spf.getDomain());
}

Cryptographically verifies the email hasn’t been modified and came from the claimed domain.

List<DkimResult> dkim = email.getAuthResults().getDkim(); // List of results
if (dkim != null && !dkim.isEmpty()) {
for (DkimResult result : dkim) {
System.out.println(result.getResult()); // "pass", "fail", "none"
System.out.println(result.getDomain()); // Signing domain
System.out.println(result.getSelector()); // DKIM selector
System.out.println(result.getSignature()); // DKIM signature info
}
}

Note: An email can have multiple DKIM signatures (one per signing domain).

StatusMeaning
passSignature is valid
failSignature is invalid
noneNo DKIM signature found
PropertyTypeDescription
resultStringDKIM verification result: pass, fail, none
domainStringSigning domain
selectorStringDKIM selector (identifies the public key in DNS)
signatureStringDKIM signature information
MethodReturn TypeDescription
getResult()StringReturns the DKIM result
getDomain()StringReturns the signing domain
getSelector()StringReturns the DKIM selector
getSignature()StringReturns DKIM signature info
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
List<DkimResult> dkim = email.getAuthResults().getDkim();
if (dkim != null && !dkim.isEmpty()) {
DkimResult first = dkim.get(0);
assertThat(first.getResult()).isEqualTo("pass");
assertThat(first.getDomain()).isEqualTo("example.com");
System.out.printf("DKIM %s (%s._domainkey.%s)%n",
first.getResult(), first.getSelector(), first.getDomain());
}
List<DkimResult> dkim = email.getAuthResults().getDkim();
boolean anyPass = dkim != null && dkim.stream()
.anyMatch(d -> "pass".equalsIgnoreCase(d.getResult()));

DMARC (Domain-based Message Authentication)

Section titled “DMARC (Domain-based Message Authentication)”

Checks that SPF or DKIM align with the From address and enforces the domain’s policy.

DmarcResult dmarc = email.getAuthResults().getDmarc();
if (dmarc != null) {
System.out.println(dmarc.getResult()); // "pass", "fail", "none"
System.out.println(dmarc.getDomain()); // Domain checked
System.out.println(dmarc.getPolicy()); // Domain's policy
System.out.println(dmarc.getAligned()); // Whether SPF/DKIM align with From header
System.out.println(dmarc.isAligned()); // Convenience: true if aligned
}
StatusMeaning
passDMARC check passed (SPF or DKIM aligned)
failDMARC check failed
noneNo DMARC policy found
PolicyMeaning
noneNo action (monitoring only)
quarantineTreat suspicious emails as spam
rejectReject emails that fail DMARC
PropertyTypeDescription
resultStringDMARC check result: pass, fail, none
domainStringFrom domain being checked
policyStringDomain’s DMARC policy: none, quarantine, or reject
alignedBooleanWhether SPF/DKIM results align with the From header domain
MethodReturn TypeDescription
getResult()StringReturns the DMARC result
getDomain()StringReturns the From domain
getPolicy()StringReturns the domain’s DMARC policy
getAligned()BooleanReturns alignment status (may be null)
isAligned()booleanConvenience: true if aligned, false otherwise
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
DmarcResult dmarc = email.getAuthResults().getDmarc();
if (dmarc != null) {
assertThat(dmarc.getResult()).isEqualTo("pass");
assertThat(dmarc.getDomain()).isEqualTo("example.com");
System.out.printf("DMARC %s (policy: %s)%n",
dmarc.getResult(), dmarc.getPolicy());
}

Verifies the sending server’s IP resolves to a hostname that matches the sending domain.

ReverseDnsResult reverseDns = email.getAuthResults().getReverseDns();
if (reverseDns != null) {
System.out.println(reverseDns.isVerified()); // true if verified, false otherwise
System.out.println(reverseDns.getIp()); // IP address being validated
System.out.println(reverseDns.getHostname()); // Resolved hostname
}
PropertyTypeDescription
verifiedbooleanWhether reverse DNS verification passed
ipStringIP address of the sending server
hostnameStringResolved hostname from PTR record
MethodReturn TypeDescription
isVerified()booleanReturns true if reverse DNS is verified
getIp()StringReturns the IP address being validated
getHostname()StringReturns the resolved hostname
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
ReverseDnsResult rdns = email.getAuthResults().getReverseDns();
if (rdns != null) {
System.out.printf("Reverse DNS: %s for %s -> %s%n",
rdns.isVerified() ? "verified" : "not verified",
rdns.getIp(), rdns.getHostname());
if (rdns.isVerified()) {
System.out.println("Reverse DNS verification passed");
}
}

The validate() method provides a summary of all authentication checks:

AuthValidation validation = email.getAuthResults().validate();
System.out.println(validation.isFullyAuthenticated()); // All checks passed
System.out.println(validation.isPassed()); // Alias for isFullyAuthenticated()
System.out.println(validation.hasSpf()); // SPF check passed
System.out.println(validation.hasDkim()); // DKIM check passed
System.out.println(validation.hasDmarc()); // DMARC check passed
System.out.println(validation.hasReverseDns()); // Reverse DNS check passed
System.out.println(validation.getPassed()); // List of passed checks
System.out.println(validation.getFailed()); // List of failure reasons
System.out.println(validation.getFailures()); // Alias for getFailed()
MethodReturn TypeDescription
isFullyAuthenticated()booleanTrue if all checks passed and at least one exists
isPassed()booleanAlias for isFullyAuthenticated()
hasSpf()booleanSPF check passed
hasDkim()booleanAt least one DKIM signature passed
hasDmarc()booleanDMARC check passed
hasReverseDns()booleanReverse DNS check passed
getPassed()List<String>List of passed check names
getFailed()List<String>List of failure descriptions
getFailures()List<String>Alias for getFailed()

All checks pass:

AuthValidation validation = email.getAuthResults().validate();
// validation.getPassed() = ["SPF", "DKIM", "DMARC", "ReverseDNS"]
// validation.getFailed() = []
// validation.isFullyAuthenticated() = true
assertThat(validation.isFullyAuthenticated()).isTrue();
assertThat(validation.getFailed()).isEmpty();

Some checks fail:

AuthValidation validation = email.getAuthResults().validate();
// validation.getPassed() = ["DKIM", "ReverseDNS"]
// validation.getFailed() = ["SPF: fail", "DMARC: fail"]
// validation.isFullyAuthenticated() = false
if (!validation.isFullyAuthenticated()) {
System.err.println("Authentication failures:");
for (String failure : validation.getFailed()) {
System.err.println(" - " + failure);
}
}
@Test
void shouldPassAllAuthenticationChecks() {
sendEmail(inbox.getEmailAddress());
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
AuthValidation validation = email.getAuthResults().validate();
assertThat(validation.isFullyAuthenticated()).isTrue();
assertThat(validation.hasSpf()).isTrue();
assertThat(validation.hasDkim()).isTrue();
assertThat(validation.hasDmarc()).isTrue();
}
@Test
void shouldHaveValidDkimSignature() {
sendEmail(inbox.getEmailAddress());
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
List<DkimResult> dkim = email.getAuthResults().getDkim();
// Only check DKIM (most reliable)
assertThat(dkim).isNotNull();
assertThat(dkim).isNotEmpty();
assertThat(dkim.get(0).getResult()).isEqualTo("pass");
}
@Test
void shouldHandleEmailsWithoutAuthentication() {
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
AuthResults auth = email.getAuthResults();
// Auth may be null for some email sources
if (auth != null) {
AuthValidation validation = auth.validate();
// Log results for debugging
if (!validation.isFullyAuthenticated()) {
System.out.println("Auth failures (expected for test emails): "
+ validation.getFailed());
}
}
}
class EmailAuthenticationTest {
private Inbox inbox;
private Email email;
@BeforeEach
void setUp() {
inbox = client.createInbox();
sendEmail(inbox.getEmailAddress());
email = inbox.waitForEmail(Duration.ofSeconds(10));
}
@AfterEach
void tearDown() {
inbox.delete();
}
@Test
void shouldPassSpfCheck() {
SpfResult spf = email.getAuthResults().getSpf();
if (spf != null) {
assertThat(spf.getResult()).isIn("pass", "neutral", "softfail");
}
}
@Test
void shouldPassDkimCheck() {
List<DkimResult> dkim = email.getAuthResults().getDkim();
if (dkim != null && !dkim.isEmpty()) {
boolean anyPassed = dkim.stream()
.anyMatch(d -> "pass".equalsIgnoreCase(d.getResult()));
assertThat(anyPassed).isTrue();
}
}
@Test
void shouldPassDmarcCheck() {
DmarcResult dmarc = email.getAuthResults().getDmarc();
if (dmarc != null) {
assertThat(dmarc.getResult()).isIn("pass", "none");
}
}
}

Testing authentication catches issues like:

  • Misconfigured SPF records - emails rejected by Gmail/Outlook
  • Missing DKIM signatures - reduced deliverability
  • DMARC failures - emails sent to spam
  • Reverse DNS mismatches - flagged as suspicious
@Test
void shouldHaveProductionReadyEmailConfiguration() {
app.sendWelcomeEmail(inbox.getEmailAddress());
Email email = inbox.waitForEmail(Duration.ofSeconds(10));
AuthValidation validation = email.getAuthResults().validate();
// In production, these should all pass
if (!validation.isFullyAuthenticated()) {
System.err.println("Email authentication issues detected:");
validation.getFailed().forEach(f -> System.err.println(" " + f));
System.err.println();
System.err.println("Action required:");
if (!validation.hasSpf()) {
System.err.println("- Fix SPF record for your domain");
}
if (!validation.hasDkim()) {
System.err.println("- Configure DKIM signing in your email service");
}
if (!validation.hasDmarc()) {
System.err.println("- Add/fix DMARC policy");
}
}
// Fail test if authentication fails
assertThat(validation.isFullyAuthenticated()).isTrue();
}
AuthResults auth = email.getAuthResults();
if (auth == null) {
System.out.println("No authentication results available");
System.out.println("This may happen for:");
System.out.println("- Emails sent from localhost/internal servers");
System.out.println("- Test SMTP servers without authentication");
return;
}
if (auth.getSpf() == null && auth.getDkim() == null && auth.getDmarc() == null) {
System.out.println("No authentication performed");
}
AuthValidation validation = email.getAuthResults().validate();
if (!validation.isFullyAuthenticated()) {
System.err.println("Authentication failed: " + validation.getFailed());
// Common causes:
// 1. No SPF record: Add "v=spf1 ip4:YOUR_IP -all" to DNS
// 2. No DKIM: Configure your mail server to sign emails
// 3. No DMARC: Add "v=DMARC1; p=none" to DNS
// 4. Wrong IP: Update SPF record with correct server IP
}
AuthValidation validation = email.getAuthResults().validate();
for (String failure : validation.getFailed()) {
if (failure.contains("SPF")) {
System.out.println("Fix SPF: Update DNS TXT record for your domain");
}
if (failure.contains("DKIM")) {
System.out.println("Fix DKIM: Enable DKIM signing in your email service");
}
if (failure.contains("DMARC")) {
System.out.println("Fix DMARC: Add DMARC policy to DNS");
}
if (failure.contains("ReverseDNS")) {
System.out.println("Fix rDNS: Configure PTR record for mail server IP");
}
}
void debugAuthResults(Email email) {
AuthResults auth = email.getAuthResults();
if (auth == null) {
System.out.println("No authentication results");
return;
}
SpfResult spf = auth.getSpf();
System.out.println("SPF: " + (spf != null ? spf.getResult() : "N/A"));
List<DkimResult> dkim = auth.getDkim();
System.out.println("DKIM: " + (dkim != null && !dkim.isEmpty()
? dkim.get(0).getResult() : "N/A"));
DmarcResult dmarc = auth.getDmarc();
System.out.println("DMARC: " + (dmarc != null ? dmarc.getResult() : "N/A"));
ReverseDnsResult rdns = auth.getReverseDns();
System.out.println("rDNS: " + (rdns != null ? rdns.isVerified() : "N/A"));
AuthValidation validation = auth.validate();
System.out.println("Passed: " + validation.getPassed());
System.out.println("Failed: " + validation.getFailed());
}