BIMI
Brand Indicators for Message Identification — RFC 9091. BIMI records publish a sender's brand-logo URL in DNS so receiving MTAs can render it next to the message in supported clients (Gmail, Yahoo, Apple Mail). The TXT record format is:
default._bimi.
l=URL to the SVG logo file (Tiny PS Profile per RFC 9091 §5)a=URL to the Verified Mark Certificate (VMC / CMC) — §6
BIMI is layered on a passing DMARC posture (the receiver requires DMARC at quarantine or reject). No-op for senders without DMARC enforcement.
Surface:
b.mail.bimi.recordShape({ logoUrl, vmcUrl?, selector? }) -> string b.mail.bimi.fetchPolicy(domain, opts?) -> record | null b.mail.bimi.parseRecord(text) -> record | null b.mail.bimi.fetchAndVerifyMark({ domain, vmcUrl, ... }) -> verified mark b.mail.bimi.validateTinyPsSvg(svgBytes) -> { ok, violations }
fetchAndVerifyMark fetches a VMC / CMC over HTTPS via b.httpClient, parses it as X.509, validates the chain against the BIMI Group trust anchors (vendored at lib/vendor/bimi-trust-anchors.pem, operator-overridable via trustAnchorsPem), confirms the cert's subjectAltName URI matches the BIMI domain, and confirms the cert carries the BIMI mark-verification policy OID (1.3.6.1.5.5.7.3.31). The verified mark is returned as { svg, evidenceDocument } — svg pulled from the RFC 3709 logotype extension when present, evidenceDocument echoed from the operator-supplied opts.evidenceDocument.
validateTinyPsSvg enforces the AuthIndicators-WG Tiny PS subset: single root
b.mail.bimi.recordShape(opts) #
{
{
logoUrl: string, // required - https:// URL to Tiny-PS SVG
vmcUrl: string?, // optional - https:// URL to VMC / CMC PEM
selector: string?, // unused at record-shape time; reserved
// for future per-selector behavior
}
}
Builds the canonical RFC 9091 BIMI TXT-record string from a logo URL and optional VMC URL. Throws on missing or non-https URLs and on control / record-separator characters in the URLs. Operators publish the returned string at default._bimi. (or the selector subdomain if they're using non-default selectors).
var rec = b.mail.bimi.recordShape({
logoUrl: "https://example.com/bimi/logo.svg",
vmcUrl: "https://example.com/bimi/cert.pem",
});
// -> "v=BIMI1; l=https://example.com/bimi/logo.svg; a=https://example.com/bimi/cert.pem"
b.mail.bimi.parseRecord(text) #
Parses a BIMI TXT record into { v, l, a }. Returns null when the text is not a v=BIMI1 record, the l= URL is missing, or the total bytes exceed the 2 KiB sanity cap. Use this when the operator already has the TXT bytes in hand (e.g. an inbound auth-results pipeline carrying the resolved record).
var rv = b.mail.bimi.parseRecord("v=BIMI1; l=https://example.com/logo.svg");
// -> { v: "BIMI1", l: "https://example.com/logo.svg", a: null }
b.mail.bimi.fetchPolicy(domain, opts?) #
{
{
selector: string?, // default "default"
dnsLookup: async (qname, type) => rows?, // operator-supplied resolver
// (DoH / cache / fixture);
// default: node:dns.resolveTxt
}
}
Resolves default._bimi. (or if opts.selector is set) and returns the parsed { v, l, a }. Returns null when no TXT record exists or no record on the resolved name parses as v=BIMI1. Operators feed the returned l= / a= URLs into fetchAndVerifyMark to retrieve the verified mark.
var pol = await b.mail.bimi.fetchPolicy("example.com");
if (pol && pol.a) {
var verified = await b.mail.bimi.fetchAndVerifyMark({
domain: "example.com",
vmcUrl: pol.a,
});
}
b.mail.bimi.validateTinyPsSvg(svgBytes) #
{
svgBytes: Buffer | string
}
Validates a brand-mark SVG against the AuthIndicators-WG Tiny PS profile (RFC 9091 5). Tiny-PS is a strict subset of SVG 1.2: single
var rv = b.mail.bimi.validateTinyPsSvg('');
// -> { ok: true, violations: [] }
b.mail.bimi.fetchAndVerifyMark(opts) #
{
{
domain: string, // required - BIMI domain to assert
// matches subjectAltName URI
vmcUrl: string?, // VMC PEM URL (https://); operator
// passes one of vmcUrl / cmcUrl
cmcUrl: string?, // CMC PEM URL (https://); same
trustAnchorsPem: string?, // operator-supplied PEM bundle;
// defaults to the vendored
// bimi-trust-anchors.pem
timeoutMs: number?, // default 15s
maxResponseBytes: number?, // default 256 KiB
audit: { safeEmit }, // operator-supplied audit dispatcher
httpClient: object?, // default b.httpClient - test-only
// override for unit tests that
// want to stub the network call
evidenceDocument: string?, // operator-supplied trademark
// evidence URL; surfaced on
// the result for audit logging
}
}
Fetches a VMC / CMC PEM from opts.vmcUrl (or opts.cmcUrl) over HTTPS, parses it as X.509, validates the chain against the BIMI Group trust anchors (vendored at lib/vendor/bimi-trust-anchors.pem, operator-overridable via trustAnchorsPem), confirms the cert's subjectAltName URI matches the BIMI domain, and confirms the cert carries the BIMI mark-verification ExtendedKeyUsage OID (1.3.6.1.5.5.7.3.31). Returns { ok, mark, certificate, vmcType } where vmcType is "vmc" or "cmc" derived from the cert's policyOIDs, and mark carries the SVG bytes when the cert's RFC 3709 logotype extension is present (or null when not). Throws MailBimiError with one of the documented codes on any failure.
var rv = await b.mail.bimi.fetchAndVerifyMark({
domain: "example.com",
vmcUrl: "https://example.com/bimi/cert.pem",
trustAnchorsPem: "-----BEGIN CERTIFICATE-----\n...",
});
// -> { ok, mark: { svg, evidenceDocument }, certificate, vmcType: "vmc" }
Last updated 2026-08-08T16:39:49.652Z by seeder.